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 ACCESS_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 (!ACCESS_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 (ACCESS_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 (!ACCESS_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
296 ACCESS_ONCE(isight->pcm_active) = true; in isight_hw_params()
301 static int reg_read(struct isight *isight, int offset, __be32 *value) in reg_read() argument
303 return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST, in reg_read()
304 isight->audio_base + offset, value, 4, 0); in reg_read()
307 static int reg_write(struct isight *isight, int offset, __be32 value) in reg_write() argument
309 return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST, in reg_write()
310 isight->audio_base + offset, &value, 4, 0); in reg_write()
313 static void isight_stop_streaming(struct isight *isight) in isight_stop_streaming() argument
317 if (!isight->context) in isight_stop_streaming()
320 fw_iso_context_stop(isight->context); in isight_stop_streaming()
321 fw_iso_context_destroy(isight->context); in isight_stop_streaming()
322 isight->context = NULL; in isight_stop_streaming()
323 fw_iso_resources_free(&isight->resources); in isight_stop_streaming()
325 snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST, in isight_stop_streaming()
326 isight->audio_base + REG_AUDIO_ENABLE, in isight_stop_streaming()
332 struct isight *isight = substream->private_data; in isight_hw_free() local
334 ACCESS_ONCE(isight->pcm_active) = false; in isight_hw_free()
336 mutex_lock(&isight->mutex); in isight_hw_free()
337 isight_stop_streaming(isight); in isight_hw_free()
338 mutex_unlock(&isight->mutex); in isight_hw_free()
343 static int isight_start_streaming(struct isight *isight) in isight_start_streaming() argument
348 if (isight->context) { in isight_start_streaming()
349 if (isight->packet_index < 0) in isight_start_streaming()
350 isight_stop_streaming(isight); in isight_start_streaming()
355 err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000)); in isight_start_streaming()
359 err = isight_connect(isight); in isight_start_streaming()
363 err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE)); in isight_start_streaming()
367 isight->context = fw_iso_context_create(isight->device->card, in isight_start_streaming()
369 isight->resources.channel, in isight_start_streaming()
370 isight->device->max_speed, in isight_start_streaming()
371 4, isight_packet, isight); in isight_start_streaming()
372 if (IS_ERR(isight->context)) { in isight_start_streaming()
373 err = PTR_ERR(isight->context); in isight_start_streaming()
374 isight->context = NULL; in isight_start_streaming()
379 err = fw_iso_context_queue(isight->context, &audio_packet, in isight_start_streaming()
380 &isight->buffer.iso_buffer, in isight_start_streaming()
381 isight->buffer.packets[i].offset); in isight_start_streaming()
386 isight->first_packet = true; in isight_start_streaming()
387 isight->packet_index = 0; in isight_start_streaming()
389 err = fw_iso_context_start(isight->context, -1, 0, in isight_start_streaming()
397 fw_iso_context_destroy(isight->context); in isight_start_streaming()
398 isight->context = NULL; in isight_start_streaming()
400 fw_iso_resources_free(&isight->resources); in isight_start_streaming()
401 reg_write(isight, REG_AUDIO_ENABLE, 0); in isight_start_streaming()
408 struct isight *isight = substream->private_data; in isight_prepare() local
411 isight->buffer_pointer = 0; in isight_prepare()
412 isight->period_counter = 0; in isight_prepare()
414 mutex_lock(&isight->mutex); in isight_prepare()
415 err = isight_start_streaming(isight); in isight_prepare()
416 mutex_unlock(&isight->mutex); in isight_prepare()
423 struct isight *isight = substream->private_data; in isight_trigger() local
427 ACCESS_ONCE(isight->pcm_running) = true; in isight_trigger()
430 ACCESS_ONCE(isight->pcm_running) = false; in isight_trigger()
440 struct isight *isight = substream->private_data; in isight_pointer() local
442 return ACCESS_ONCE(isight->buffer_pointer); in isight_pointer()
445 static int isight_create_pcm(struct isight *isight) in isight_create_pcm() argument
462 err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm); in isight_create_pcm()
465 pcm->private_data = isight; in isight_create_pcm()
467 isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; in isight_create_pcm()
468 isight->pcm->ops = &ops; in isight_create_pcm()
476 struct isight *isight = ctl->private_data; in isight_gain_info() local
480 info->value.integer.min = isight->gain_min; in isight_gain_info()
481 info->value.integer.max = isight->gain_max; in isight_gain_info()
489 struct isight *isight = ctl->private_data; in isight_gain_get() local
493 err = reg_read(isight, REG_GAIN, &gain); in isight_gain_get()
505 struct isight *isight = ctl->private_data; in isight_gain_put() local
507 if (value->value.integer.value[0] < isight->gain_min || in isight_gain_put()
508 value->value.integer.value[0] > isight->gain_max) in isight_gain_put()
511 return reg_write(isight, REG_GAIN, in isight_gain_put()
518 struct isight *isight = ctl->private_data; in isight_mute_get() local
522 err = reg_read(isight, REG_MUTE, &mute); in isight_mute_get()
534 struct isight *isight = ctl->private_data; in isight_mute_put() local
536 return reg_write(isight, REG_MUTE, in isight_mute_put()
540 static int isight_create_mixer(struct isight *isight) in isight_create_mixer() argument
562 err = reg_read(isight, REG_GAIN_RAW_START, &value); in isight_create_mixer()
565 isight->gain_min = be32_to_cpu(value); in isight_create_mixer()
567 err = reg_read(isight, REG_GAIN_RAW_END, &value); in isight_create_mixer()
570 isight->gain_max = be32_to_cpu(value); in isight_create_mixer()
572 isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX; in isight_create_mixer()
573 isight->gain_tlv[1] = 2 * sizeof(unsigned int); in isight_create_mixer()
575 err = reg_read(isight, REG_GAIN_DB_START, &value); in isight_create_mixer()
578 isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100; in isight_create_mixer()
580 err = reg_read(isight, REG_GAIN_DB_END, &value); in isight_create_mixer()
583 isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100; in isight_create_mixer()
585 ctl = snd_ctl_new1(&gain_control, isight); in isight_create_mixer()
587 ctl->tlv.p = isight->gain_tlv; in isight_create_mixer()
588 err = snd_ctl_add(isight->card, ctl); in isight_create_mixer()
592 err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight)); in isight_create_mixer()
601 struct isight *isight = card->private_data; in isight_card_free() local
603 fw_iso_resources_destroy(&isight->resources); in isight_card_free()
604 fw_unit_put(isight->unit); in isight_card_free()
605 mutex_destroy(&isight->mutex); in isight_card_free()
625 struct isight *isight; in isight_probe() local
629 sizeof(*isight), &card); in isight_probe()
633 isight = card->private_data; in isight_probe()
634 isight->card = card; in isight_probe()
635 mutex_init(&isight->mutex); in isight_probe()
636 isight->unit = fw_unit_get(unit); in isight_probe()
637 isight->device = fw_dev; in isight_probe()
638 isight->audio_base = get_unit_base(unit); in isight_probe()
639 if (!isight->audio_base) { in isight_probe()
644 fw_iso_resources_init(&isight->resources, unit); in isight_probe()
656 err = isight_create_pcm(isight); in isight_probe()
660 err = isight_create_mixer(isight); in isight_probe()
668 dev_set_drvdata(&unit->device, isight); in isight_probe()
673 fw_unit_put(isight->unit); in isight_probe()
674 mutex_destroy(&isight->mutex); in isight_probe()
682 struct isight *isight = dev_get_drvdata(&unit->device); in isight_bus_reset() local
684 if (fw_iso_resources_update(&isight->resources) < 0) { in isight_bus_reset()
685 isight_pcm_abort(isight); in isight_bus_reset()
687 mutex_lock(&isight->mutex); in isight_bus_reset()
688 isight_stop_streaming(isight); in isight_bus_reset()
689 mutex_unlock(&isight->mutex); in isight_bus_reset()
695 struct isight *isight = dev_get_drvdata(&unit->device); in isight_remove() local
697 isight_pcm_abort(isight); in isight_remove()
699 snd_card_disconnect(isight->card); in isight_remove()
701 mutex_lock(&isight->mutex); in isight_remove()
702 isight_stop_streaming(isight); in isight_remove()
703 mutex_unlock(&isight->mutex); in isight_remove()
705 snd_card_free_when_closed(isight->card); in isight_remove()