Lines Matching refs:isight
49 struct isight { struct
88 static void isight_update_pointers(struct isight *isight, unsigned int count) in isight_update_pointers() argument
90 struct snd_pcm_runtime *runtime = isight->pcm->runtime; in isight_update_pointers()
95 ptr = isight->buffer_pointer; in isight_update_pointers()
99 WRITE_ONCE(isight->buffer_pointer, ptr); in isight_update_pointers()
101 isight->period_counter += count; in isight_update_pointers()
102 if (isight->period_counter >= runtime->period_size) { in isight_update_pointers()
103 isight->period_counter -= runtime->period_size; in isight_update_pointers()
104 snd_pcm_period_elapsed(isight->pcm); in isight_update_pointers()
108 static void isight_samples(struct isight *isight, in isight_samples() argument
114 if (!READ_ONCE(isight->pcm_running)) in isight_samples()
117 runtime = isight->pcm->runtime; in isight_samples()
118 if (isight->buffer_pointer + count <= runtime->buffer_size) { in isight_samples()
119 memcpy(runtime->dma_area + isight->buffer_pointer * 4, in isight_samples()
122 count1 = runtime->buffer_size - isight->buffer_pointer; in isight_samples()
123 memcpy(runtime->dma_area + isight->buffer_pointer * 4, in isight_samples()
129 isight_update_pointers(isight, count); in isight_samples()
132 static void isight_pcm_abort(struct isight *isight) in isight_pcm_abort() argument
134 if (READ_ONCE(isight->pcm_active)) in isight_pcm_abort()
135 snd_pcm_stop_xrun(isight->pcm); in isight_pcm_abort()
138 static void isight_dropped_samples(struct isight *isight, unsigned int total) in isight_dropped_samples() argument
144 if (!READ_ONCE(isight->pcm_running)) in isight_dropped_samples()
147 runtime = isight->pcm->runtime; in isight_dropped_samples()
148 dropped = total - isight->total_samples; in isight_dropped_samples()
150 if (isight->buffer_pointer + dropped <= runtime->buffer_size) { in isight_dropped_samples()
151 memset(runtime->dma_area + isight->buffer_pointer * 4, in isight_dropped_samples()
154 count1 = runtime->buffer_size - isight->buffer_pointer; in isight_dropped_samples()
155 memset(runtime->dma_area + isight->buffer_pointer * 4, in isight_dropped_samples()
159 isight_update_pointers(isight, dropped); in isight_dropped_samples()
161 isight_pcm_abort(isight); in isight_dropped_samples()
168 struct isight *isight = data; in isight_packet() local
173 if (isight->packet_index < 0) in isight_packet()
175 index = isight->packet_index; in isight_packet()
176 payload = isight->buffer.packets[index].buffer; in isight_packet()
184 if (unlikely(total != isight->total_samples)) { in isight_packet()
185 if (!isight->first_packet) in isight_packet()
186 isight_dropped_samples(isight, total); in isight_packet()
187 isight->first_packet = false; in isight_packet()
188 isight->total_samples = total; in isight_packet()
191 isight_samples(isight, payload->samples, count); in isight_packet()
192 isight->total_samples += count; in isight_packet()
196 err = fw_iso_context_queue(isight->context, &audio_packet, in isight_packet()
197 &isight->buffer.iso_buffer, in isight_packet()
198 isight->buffer.packets[index].offset); in isight_packet()
200 dev_err(&isight->unit->device, "queueing error: %d\n", err); in isight_packet()
201 isight_pcm_abort(isight); in isight_packet()
202 isight->packet_index = -1; in isight_packet()
205 fw_iso_context_queue_flush(isight->context); in isight_packet()
209 isight->packet_index = index; in isight_packet()
212 static int isight_connect(struct isight *isight) in isight_connect() argument
218 ch = fw_iso_resources_allocate(&isight->resources, in isight_connect()
220 isight->device->max_speed); in isight_connect()
226 value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT)); in isight_connect()
227 err = snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST, in isight_connect()
228 isight->audio_base + REG_ISO_TX_CONFIG, in isight_connect()
230 isight->resources.generation); in isight_connect()
232 fw_iso_resources_free(&isight->resources); in isight_connect()
241 fw_iso_resources_free(&isight->resources); in isight_connect()
266 struct isight *isight = substream->private_data; in isight_open() local
270 return iso_packets_buffer_init(&isight->buffer, isight->unit, in isight_open()
278 struct isight *isight = substream->private_data; in isight_close() local
280 iso_packets_buffer_destroy(&isight->buffer, isight->unit); in isight_close()
288 struct isight *isight = substream->private_data; in isight_hw_params() local
290 WRITE_ONCE(isight->pcm_active, true); in isight_hw_params()
295 static int reg_read(struct isight *isight, int offset, __be32 *value) in reg_read() argument
297 return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST, in reg_read()
298 isight->audio_base + offset, value, 4, 0); in reg_read()
301 static int reg_write(struct isight *isight, int offset, __be32 value) in reg_write() argument
303 return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST, in reg_write()
304 isight->audio_base + offset, &value, 4, 0); in reg_write()
307 static void isight_stop_streaming(struct isight *isight) in isight_stop_streaming() argument
311 if (!isight->context) in isight_stop_streaming()
314 fw_iso_context_stop(isight->context); in isight_stop_streaming()
315 fw_iso_context_destroy(isight->context); in isight_stop_streaming()
316 isight->context = NULL; in isight_stop_streaming()
317 fw_iso_resources_free(&isight->resources); in isight_stop_streaming()
319 snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST, in isight_stop_streaming()
320 isight->audio_base + REG_AUDIO_ENABLE, in isight_stop_streaming()
326 struct isight *isight = substream->private_data; in isight_hw_free() local
328 WRITE_ONCE(isight->pcm_active, false); in isight_hw_free()
330 mutex_lock(&isight->mutex); in isight_hw_free()
331 isight_stop_streaming(isight); in isight_hw_free()
332 mutex_unlock(&isight->mutex); in isight_hw_free()
337 static int isight_start_streaming(struct isight *isight) in isight_start_streaming() argument
342 if (isight->context) { in isight_start_streaming()
343 if (isight->packet_index < 0) in isight_start_streaming()
344 isight_stop_streaming(isight); in isight_start_streaming()
349 err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000)); in isight_start_streaming()
353 err = isight_connect(isight); in isight_start_streaming()
357 err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE)); in isight_start_streaming()
361 isight->context = fw_iso_context_create(isight->device->card, in isight_start_streaming()
363 isight->resources.channel, in isight_start_streaming()
364 isight->device->max_speed, in isight_start_streaming()
365 4, isight_packet, isight); in isight_start_streaming()
366 if (IS_ERR(isight->context)) { in isight_start_streaming()
367 err = PTR_ERR(isight->context); in isight_start_streaming()
368 isight->context = NULL; in isight_start_streaming()
373 err = fw_iso_context_queue(isight->context, &audio_packet, in isight_start_streaming()
374 &isight->buffer.iso_buffer, in isight_start_streaming()
375 isight->buffer.packets[i].offset); in isight_start_streaming()
380 isight->first_packet = true; in isight_start_streaming()
381 isight->packet_index = 0; in isight_start_streaming()
383 err = fw_iso_context_start(isight->context, -1, 0, in isight_start_streaming()
391 fw_iso_context_destroy(isight->context); in isight_start_streaming()
392 isight->context = NULL; in isight_start_streaming()
394 fw_iso_resources_free(&isight->resources); in isight_start_streaming()
395 reg_write(isight, REG_AUDIO_ENABLE, 0); in isight_start_streaming()
402 struct isight *isight = substream->private_data; in isight_prepare() local
405 isight->buffer_pointer = 0; in isight_prepare()
406 isight->period_counter = 0; in isight_prepare()
408 mutex_lock(&isight->mutex); in isight_prepare()
409 err = isight_start_streaming(isight); in isight_prepare()
410 mutex_unlock(&isight->mutex); in isight_prepare()
417 struct isight *isight = substream->private_data; in isight_trigger() local
421 WRITE_ONCE(isight->pcm_running, true); in isight_trigger()
424 WRITE_ONCE(isight->pcm_running, false); in isight_trigger()
434 struct isight *isight = substream->private_data; in isight_pointer() local
436 return READ_ONCE(isight->buffer_pointer); in isight_pointer()
439 static int isight_create_pcm(struct isight *isight) in isight_create_pcm() argument
453 err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm); in isight_create_pcm()
456 pcm->private_data = isight; in isight_create_pcm()
459 isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; in isight_create_pcm()
460 isight->pcm->ops = &ops; in isight_create_pcm()
469 struct isight *isight = ctl->private_data; in isight_gain_info() local
473 info->value.integer.min = isight->gain_min; in isight_gain_info()
474 info->value.integer.max = isight->gain_max; in isight_gain_info()
482 struct isight *isight = ctl->private_data; in isight_gain_get() local
486 err = reg_read(isight, REG_GAIN, &gain); in isight_gain_get()
498 struct isight *isight = ctl->private_data; in isight_gain_put() local
500 if (value->value.integer.value[0] < isight->gain_min || in isight_gain_put()
501 value->value.integer.value[0] > isight->gain_max) in isight_gain_put()
504 return reg_write(isight, REG_GAIN, in isight_gain_put()
511 struct isight *isight = ctl->private_data; in isight_mute_get() local
515 err = reg_read(isight, REG_MUTE, &mute); in isight_mute_get()
527 struct isight *isight = ctl->private_data; in isight_mute_put() local
529 return reg_write(isight, REG_MUTE, in isight_mute_put()
533 static int isight_create_mixer(struct isight *isight) in isight_create_mixer() argument
555 err = reg_read(isight, REG_GAIN_RAW_START, &value); in isight_create_mixer()
558 isight->gain_min = be32_to_cpu(value); in isight_create_mixer()
560 err = reg_read(isight, REG_GAIN_RAW_END, &value); in isight_create_mixer()
563 isight->gain_max = be32_to_cpu(value); in isight_create_mixer()
565 isight->gain_tlv[SNDRV_CTL_TLVO_TYPE] = SNDRV_CTL_TLVT_DB_MINMAX; in isight_create_mixer()
566 isight->gain_tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(unsigned int); in isight_create_mixer()
568 err = reg_read(isight, REG_GAIN_DB_START, &value); in isight_create_mixer()
571 isight->gain_tlv[SNDRV_CTL_TLVO_DB_MINMAX_MIN] = in isight_create_mixer()
574 err = reg_read(isight, REG_GAIN_DB_END, &value); in isight_create_mixer()
577 isight->gain_tlv[SNDRV_CTL_TLVO_DB_MINMAX_MAX] = in isight_create_mixer()
580 ctl = snd_ctl_new1(&gain_control, isight); in isight_create_mixer()
582 ctl->tlv.p = isight->gain_tlv; in isight_create_mixer()
583 err = snd_ctl_add(isight->card, ctl); in isight_create_mixer()
587 err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight)); in isight_create_mixer()
596 struct isight *isight = card->private_data; in isight_card_free() local
598 fw_iso_resources_destroy(&isight->resources); in isight_card_free()
618 struct isight *isight; in isight_probe() local
622 sizeof(*isight), &card); in isight_probe()
626 isight = card->private_data; in isight_probe()
627 isight->card = card; in isight_probe()
628 mutex_init(&isight->mutex); in isight_probe()
629 isight->unit = fw_unit_get(unit); in isight_probe()
630 isight->device = fw_dev; in isight_probe()
631 isight->audio_base = get_unit_base(unit); in isight_probe()
632 if (!isight->audio_base) { in isight_probe()
637 fw_iso_resources_init(&isight->resources, unit); in isight_probe()
649 err = isight_create_pcm(isight); in isight_probe()
653 err = isight_create_mixer(isight); in isight_probe()
661 dev_set_drvdata(&unit->device, isight); in isight_probe()
667 mutex_destroy(&isight->mutex); in isight_probe()
668 fw_unit_put(isight->unit); in isight_probe()
675 struct isight *isight = dev_get_drvdata(&unit->device); in isight_bus_reset() local
677 if (fw_iso_resources_update(&isight->resources) < 0) { in isight_bus_reset()
678 isight_pcm_abort(isight); in isight_bus_reset()
680 mutex_lock(&isight->mutex); in isight_bus_reset()
681 isight_stop_streaming(isight); in isight_bus_reset()
682 mutex_unlock(&isight->mutex); in isight_bus_reset()
688 struct isight *isight = dev_get_drvdata(&unit->device); in isight_remove() local
690 isight_pcm_abort(isight); in isight_remove()
692 snd_card_disconnect(isight->card); in isight_remove()
694 mutex_lock(&isight->mutex); in isight_remove()
695 isight_stop_streaming(isight); in isight_remove()
696 mutex_unlock(&isight->mutex); in isight_remove()
699 snd_card_free(isight->card); in isight_remove()
701 mutex_destroy(&isight->mutex); in isight_remove()
702 fw_unit_put(isight->unit); in isight_remove()