xref: /openbmc/linux/sound/firewire/isight.c (revision 7fe2f639)
1 /*
2  * Apple iSight audio driver
3  *
4  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5  * Licensed under the terms of the GNU General Public License, version 2.
6  */
7 
8 #include <asm/byteorder.h>
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/firewire.h>
12 #include <linux/firewire-constants.h>
13 #include <linux/module.h>
14 #include <linux/mod_devicetable.h>
15 #include <linux/mutex.h>
16 #include <linux/string.h>
17 #include <sound/control.h>
18 #include <sound/core.h>
19 #include <sound/initval.h>
20 #include <sound/pcm.h>
21 #include <sound/tlv.h>
22 #include "lib.h"
23 #include "iso-resources.h"
24 #include "packets-buffer.h"
25 
26 #define OUI_APPLE		0x000a27
27 #define MODEL_APPLE_ISIGHT	0x000008
28 #define SW_ISIGHT_AUDIO		0x000010
29 
30 #define REG_AUDIO_ENABLE	0x000
31 #define  AUDIO_ENABLE		0x80000000
32 #define REG_DEF_AUDIO_GAIN	0x204
33 #define REG_GAIN_RAW_START	0x210
34 #define REG_GAIN_RAW_END	0x214
35 #define REG_GAIN_DB_START	0x218
36 #define REG_GAIN_DB_END		0x21c
37 #define REG_SAMPLE_RATE_INQUIRY	0x280
38 #define REG_ISO_TX_CONFIG	0x300
39 #define  SPEED_SHIFT		16
40 #define REG_SAMPLE_RATE		0x400
41 #define  RATE_48000		0x80000000
42 #define REG_GAIN		0x500
43 #define REG_MUTE		0x504
44 
45 #define MAX_FRAMES_PER_PACKET	475
46 
47 #define QUEUE_LENGTH		20
48 
49 struct isight {
50 	struct snd_card *card;
51 	struct fw_unit *unit;
52 	struct fw_device *device;
53 	u64 audio_base;
54 	struct fw_address_handler iris_handler;
55 	struct snd_pcm_substream *pcm;
56 	struct mutex mutex;
57 	struct iso_packets_buffer buffer;
58 	struct fw_iso_resources resources;
59 	struct fw_iso_context *context;
60 	bool pcm_active;
61 	bool pcm_running;
62 	bool first_packet;
63 	int packet_index;
64 	u32 total_samples;
65 	unsigned int buffer_pointer;
66 	unsigned int period_counter;
67 	s32 gain_min, gain_max;
68 	unsigned int gain_tlv[4];
69 };
70 
71 struct audio_payload {
72 	__be32 sample_count;
73 	__be32 signature;
74 	__be32 sample_total;
75 	__be32 reserved;
76 	__be16 samples[2 * MAX_FRAMES_PER_PACKET];
77 };
78 
79 MODULE_DESCRIPTION("iSight audio driver");
80 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
81 MODULE_LICENSE("GPL v2");
82 
83 static struct fw_iso_packet audio_packet = {
84 	.payload_length = sizeof(struct audio_payload),
85 	.interrupt = 1,
86 	.header_length = 4,
87 };
88 
89 static void isight_update_pointers(struct isight *isight, unsigned int count)
90 {
91 	struct snd_pcm_runtime *runtime = isight->pcm->runtime;
92 	unsigned int ptr;
93 
94 	smp_wmb(); /* update buffer data before buffer pointer */
95 
96 	ptr = isight->buffer_pointer;
97 	ptr += count;
98 	if (ptr >= runtime->buffer_size)
99 		ptr -= runtime->buffer_size;
100 	ACCESS_ONCE(isight->buffer_pointer) = ptr;
101 
102 	isight->period_counter += count;
103 	if (isight->period_counter >= runtime->period_size) {
104 		isight->period_counter -= runtime->period_size;
105 		snd_pcm_period_elapsed(isight->pcm);
106 	}
107 }
108 
109 static void isight_samples(struct isight *isight,
110 			   const __be16 *samples, unsigned int count)
111 {
112 	struct snd_pcm_runtime *runtime;
113 	unsigned int count1;
114 
115 	if (!ACCESS_ONCE(isight->pcm_running))
116 		return;
117 
118 	runtime = isight->pcm->runtime;
119 	if (isight->buffer_pointer + count <= runtime->buffer_size) {
120 		memcpy(runtime->dma_area + isight->buffer_pointer * 4,
121 		       samples, count * 4);
122 	} else {
123 		count1 = runtime->buffer_size - isight->buffer_pointer;
124 		memcpy(runtime->dma_area + isight->buffer_pointer * 4,
125 		       samples, count1 * 4);
126 		samples += count1 * 2;
127 		memcpy(runtime->dma_area, samples, (count - count1) * 4);
128 	}
129 
130 	isight_update_pointers(isight, count);
131 }
132 
133 static void isight_pcm_abort(struct isight *isight)
134 {
135 	unsigned long flags;
136 
137 	if (ACCESS_ONCE(isight->pcm_active)) {
138 		snd_pcm_stream_lock_irqsave(isight->pcm, flags);
139 		if (snd_pcm_running(isight->pcm))
140 			snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN);
141 		snd_pcm_stream_unlock_irqrestore(isight->pcm, flags);
142 	}
143 }
144 
145 static void isight_dropped_samples(struct isight *isight, unsigned int total)
146 {
147 	struct snd_pcm_runtime *runtime;
148 	u32 dropped;
149 	unsigned int count1;
150 
151 	if (!ACCESS_ONCE(isight->pcm_running))
152 		return;
153 
154 	runtime = isight->pcm->runtime;
155 	dropped = total - isight->total_samples;
156 	if (dropped < runtime->buffer_size) {
157 		if (isight->buffer_pointer + dropped <= runtime->buffer_size) {
158 			memset(runtime->dma_area + isight->buffer_pointer * 4,
159 			       0, dropped * 4);
160 		} else {
161 			count1 = runtime->buffer_size - isight->buffer_pointer;
162 			memset(runtime->dma_area + isight->buffer_pointer * 4,
163 			       0, count1 * 4);
164 			memset(runtime->dma_area, 0, (dropped - count1) * 4);
165 		}
166 		isight_update_pointers(isight, dropped);
167 	} else {
168 		isight_pcm_abort(isight);
169 	}
170 }
171 
172 static void isight_packet(struct fw_iso_context *context, u32 cycle,
173 			  size_t header_length, void *header, void *data)
174 {
175 	struct isight *isight = data;
176 	const struct audio_payload *payload;
177 	unsigned int index, length, count, total;
178 	int err;
179 
180 	if (isight->packet_index < 0)
181 		return;
182 	index = isight->packet_index;
183 	payload = isight->buffer.packets[index].buffer;
184 	length = be32_to_cpup(header) >> 16;
185 
186 	if (likely(length >= 16 &&
187 		   payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
188 		count = be32_to_cpu(payload->sample_count);
189 		if (likely(count <= (length - 16) / 4)) {
190 			total = be32_to_cpu(payload->sample_total);
191 			if (unlikely(total != isight->total_samples)) {
192 				if (!isight->first_packet)
193 					isight_dropped_samples(isight, total);
194 				isight->first_packet = false;
195 				isight->total_samples = total;
196 			}
197 
198 			isight_samples(isight, payload->samples, count);
199 			isight->total_samples += count;
200 		}
201 	}
202 
203 	err = fw_iso_context_queue(isight->context, &audio_packet,
204 				   &isight->buffer.iso_buffer,
205 				   isight->buffer.packets[index].offset);
206 	if (err < 0) {
207 		dev_err(&isight->unit->device, "queueing error: %d\n", err);
208 		isight_pcm_abort(isight);
209 		isight->packet_index = -1;
210 		return;
211 	}
212 	fw_iso_context_queue_flush(isight->context);
213 
214 	if (++index >= QUEUE_LENGTH)
215 		index = 0;
216 	isight->packet_index = index;
217 }
218 
219 static int isight_connect(struct isight *isight)
220 {
221 	int ch, err, rcode, errors = 0;
222 	__be32 value;
223 
224 retry_after_bus_reset:
225 	ch = fw_iso_resources_allocate(&isight->resources,
226 				       sizeof(struct audio_payload),
227 				       isight->device->max_speed);
228 	if (ch < 0) {
229 		err = ch;
230 		goto error;
231 	}
232 
233 	value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT));
234 	for (;;) {
235 		rcode = fw_run_transaction(
236 				isight->device->card,
237 				TCODE_WRITE_QUADLET_REQUEST,
238 				isight->device->node_id,
239 				isight->resources.generation,
240 				isight->device->max_speed,
241 				isight->audio_base + REG_ISO_TX_CONFIG,
242 				&value, 4);
243 		if (rcode == RCODE_COMPLETE) {
244 			return 0;
245 		} else if (rcode == RCODE_GENERATION) {
246 			fw_iso_resources_free(&isight->resources);
247 			goto retry_after_bus_reset;
248 		} else if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
249 			err = -EIO;
250 			goto err_resources;
251 		}
252 		msleep(5);
253 	}
254 
255 err_resources:
256 	fw_iso_resources_free(&isight->resources);
257 error:
258 	return err;
259 }
260 
261 static int isight_open(struct snd_pcm_substream *substream)
262 {
263 	static const struct snd_pcm_hardware hardware = {
264 		.info = SNDRV_PCM_INFO_MMAP |
265 			SNDRV_PCM_INFO_MMAP_VALID |
266 			SNDRV_PCM_INFO_BATCH |
267 			SNDRV_PCM_INFO_INTERLEAVED |
268 			SNDRV_PCM_INFO_BLOCK_TRANSFER,
269 		.formats = SNDRV_PCM_FMTBIT_S16_BE,
270 		.rates = SNDRV_PCM_RATE_48000,
271 		.rate_min = 48000,
272 		.rate_max = 48000,
273 		.channels_min = 2,
274 		.channels_max = 2,
275 		.buffer_bytes_max = 4 * 1024 * 1024,
276 		.period_bytes_min = MAX_FRAMES_PER_PACKET * 4,
277 		.period_bytes_max = 1024 * 1024,
278 		.periods_min = 2,
279 		.periods_max = UINT_MAX,
280 	};
281 	struct isight *isight = substream->private_data;
282 
283 	substream->runtime->hw = hardware;
284 
285 	return iso_packets_buffer_init(&isight->buffer, isight->unit,
286 				       QUEUE_LENGTH,
287 				       sizeof(struct audio_payload),
288 				       DMA_FROM_DEVICE);
289 }
290 
291 static int isight_close(struct snd_pcm_substream *substream)
292 {
293 	struct isight *isight = substream->private_data;
294 
295 	iso_packets_buffer_destroy(&isight->buffer, isight->unit);
296 
297 	return 0;
298 }
299 
300 static int isight_hw_params(struct snd_pcm_substream *substream,
301 			    struct snd_pcm_hw_params *hw_params)
302 {
303 	struct isight *isight = substream->private_data;
304 	int err;
305 
306 	err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
307 					       params_buffer_bytes(hw_params));
308 	if (err < 0)
309 		return err;
310 
311 	ACCESS_ONCE(isight->pcm_active) = true;
312 
313 	return 0;
314 }
315 
316 static int reg_read(struct isight *isight, int offset, __be32 *value)
317 {
318 	return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST,
319 				  isight->audio_base + offset, value, 4);
320 }
321 
322 static int reg_write(struct isight *isight, int offset, __be32 value)
323 {
324 	return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
325 				  isight->audio_base + offset, &value, 4);
326 }
327 
328 static void isight_stop_streaming(struct isight *isight)
329 {
330 	if (!isight->context)
331 		return;
332 
333 	fw_iso_context_stop(isight->context);
334 	fw_iso_context_destroy(isight->context);
335 	isight->context = NULL;
336 	fw_iso_resources_free(&isight->resources);
337 	reg_write(isight, REG_AUDIO_ENABLE, 0);
338 }
339 
340 static int isight_hw_free(struct snd_pcm_substream *substream)
341 {
342 	struct isight *isight = substream->private_data;
343 
344 	ACCESS_ONCE(isight->pcm_active) = false;
345 
346 	mutex_lock(&isight->mutex);
347 	isight_stop_streaming(isight);
348 	mutex_unlock(&isight->mutex);
349 
350 	return snd_pcm_lib_free_vmalloc_buffer(substream);
351 }
352 
353 static int isight_start_streaming(struct isight *isight)
354 {
355 	unsigned int i;
356 	int err;
357 
358 	if (isight->context) {
359 		if (isight->packet_index < 0)
360 			isight_stop_streaming(isight);
361 		else
362 			return 0;
363 	}
364 
365 	err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000));
366 	if (err < 0)
367 		goto error;
368 
369 	err = isight_connect(isight);
370 	if (err < 0)
371 		goto error;
372 
373 	err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE));
374 	if (err < 0)
375 		goto err_resources;
376 
377 	isight->context = fw_iso_context_create(isight->device->card,
378 						FW_ISO_CONTEXT_RECEIVE,
379 						isight->resources.channel,
380 						isight->device->max_speed,
381 						4, isight_packet, isight);
382 	if (IS_ERR(isight->context)) {
383 		err = PTR_ERR(isight->context);
384 		isight->context = NULL;
385 		goto err_resources;
386 	}
387 
388 	for (i = 0; i < QUEUE_LENGTH; ++i) {
389 		err = fw_iso_context_queue(isight->context, &audio_packet,
390 					   &isight->buffer.iso_buffer,
391 					   isight->buffer.packets[i].offset);
392 		if (err < 0)
393 			goto err_context;
394 	}
395 
396 	isight->first_packet = true;
397 	isight->packet_index = 0;
398 
399 	err = fw_iso_context_start(isight->context, -1, 0,
400 				   FW_ISO_CONTEXT_MATCH_ALL_TAGS/*?*/);
401 	if (err < 0)
402 		goto err_context;
403 
404 	return 0;
405 
406 err_context:
407 	fw_iso_context_destroy(isight->context);
408 	isight->context = NULL;
409 err_resources:
410 	fw_iso_resources_free(&isight->resources);
411 	reg_write(isight, REG_AUDIO_ENABLE, 0);
412 error:
413 	return err;
414 }
415 
416 static int isight_prepare(struct snd_pcm_substream *substream)
417 {
418 	struct isight *isight = substream->private_data;
419 	int err;
420 
421 	isight->buffer_pointer = 0;
422 	isight->period_counter = 0;
423 
424 	mutex_lock(&isight->mutex);
425 	err = isight_start_streaming(isight);
426 	mutex_unlock(&isight->mutex);
427 
428 	return err;
429 }
430 
431 static int isight_trigger(struct snd_pcm_substream *substream, int cmd)
432 {
433 	struct isight *isight = substream->private_data;
434 
435 	switch (cmd) {
436 	case SNDRV_PCM_TRIGGER_START:
437 		ACCESS_ONCE(isight->pcm_running) = true;
438 		break;
439 	case SNDRV_PCM_TRIGGER_STOP:
440 		ACCESS_ONCE(isight->pcm_running) = false;
441 		break;
442 	default:
443 		return -EINVAL;
444 	}
445 	return 0;
446 }
447 
448 static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream)
449 {
450 	struct isight *isight = substream->private_data;
451 
452 	return ACCESS_ONCE(isight->buffer_pointer);
453 }
454 
455 static int isight_create_pcm(struct isight *isight)
456 {
457 	static struct snd_pcm_ops ops = {
458 		.open      = isight_open,
459 		.close     = isight_close,
460 		.ioctl     = snd_pcm_lib_ioctl,
461 		.hw_params = isight_hw_params,
462 		.hw_free   = isight_hw_free,
463 		.prepare   = isight_prepare,
464 		.trigger   = isight_trigger,
465 		.pointer   = isight_pointer,
466 		.page      = snd_pcm_lib_get_vmalloc_page,
467 		.mmap      = snd_pcm_lib_mmap_vmalloc,
468 	};
469 	struct snd_pcm *pcm;
470 	int err;
471 
472 	err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm);
473 	if (err < 0)
474 		return err;
475 	pcm->private_data = isight;
476 	strcpy(pcm->name, "iSight");
477 	isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
478 	isight->pcm->ops = &ops;
479 
480 	return 0;
481 }
482 
483 static int isight_gain_info(struct snd_kcontrol *ctl,
484 			    struct snd_ctl_elem_info *info)
485 {
486 	struct isight *isight = ctl->private_data;
487 
488 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
489 	info->count = 1;
490 	info->value.integer.min = isight->gain_min;
491 	info->value.integer.max = isight->gain_max;
492 
493 	return 0;
494 }
495 
496 static int isight_gain_get(struct snd_kcontrol *ctl,
497 			   struct snd_ctl_elem_value *value)
498 {
499 	struct isight *isight = ctl->private_data;
500 	__be32 gain;
501 	int err;
502 
503 	err = reg_read(isight, REG_GAIN, &gain);
504 	if (err < 0)
505 		return err;
506 
507 	value->value.integer.value[0] = (s32)be32_to_cpu(gain);
508 
509 	return 0;
510 }
511 
512 static int isight_gain_put(struct snd_kcontrol *ctl,
513 			   struct snd_ctl_elem_value *value)
514 {
515 	struct isight *isight = ctl->private_data;
516 
517 	if (value->value.integer.value[0] < isight->gain_min ||
518 	    value->value.integer.value[0] > isight->gain_max)
519 		return -EINVAL;
520 
521 	return reg_write(isight, REG_GAIN,
522 			 cpu_to_be32(value->value.integer.value[0]));
523 }
524 
525 static int isight_mute_get(struct snd_kcontrol *ctl,
526 			   struct snd_ctl_elem_value *value)
527 {
528 	struct isight *isight = ctl->private_data;
529 	__be32 mute;
530 	int err;
531 
532 	err = reg_read(isight, REG_MUTE, &mute);
533 	if (err < 0)
534 		return err;
535 
536 	value->value.integer.value[0] = !mute;
537 
538 	return 0;
539 }
540 
541 static int isight_mute_put(struct snd_kcontrol *ctl,
542 			   struct snd_ctl_elem_value *value)
543 {
544 	struct isight *isight = ctl->private_data;
545 
546 	return reg_write(isight, REG_MUTE,
547 			 (__force __be32)!value->value.integer.value[0]);
548 }
549 
550 static int isight_create_mixer(struct isight *isight)
551 {
552 	static const struct snd_kcontrol_new gain_control = {
553 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
554 		.name = "Mic Capture Volume",
555 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
556 			  SNDRV_CTL_ELEM_ACCESS_TLV_READ,
557 		.info = isight_gain_info,
558 		.get = isight_gain_get,
559 		.put = isight_gain_put,
560 	};
561 	static const struct snd_kcontrol_new mute_control = {
562 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
563 		.name = "Mic Capture Switch",
564 		.info = snd_ctl_boolean_mono_info,
565 		.get = isight_mute_get,
566 		.put = isight_mute_put,
567 	};
568 	__be32 value;
569 	struct snd_kcontrol *ctl;
570 	int err;
571 
572 	err = reg_read(isight, REG_GAIN_RAW_START, &value);
573 	if (err < 0)
574 		return err;
575 	isight->gain_min = be32_to_cpu(value);
576 
577 	err = reg_read(isight, REG_GAIN_RAW_END, &value);
578 	if (err < 0)
579 		return err;
580 	isight->gain_max = be32_to_cpu(value);
581 
582 	isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX;
583 	isight->gain_tlv[1] = 2 * sizeof(unsigned int);
584 
585 	err = reg_read(isight, REG_GAIN_DB_START, &value);
586 	if (err < 0)
587 		return err;
588 	isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100;
589 
590 	err = reg_read(isight, REG_GAIN_DB_END, &value);
591 	if (err < 0)
592 		return err;
593 	isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100;
594 
595 	ctl = snd_ctl_new1(&gain_control, isight);
596 	if (ctl)
597 		ctl->tlv.p = isight->gain_tlv;
598 	err = snd_ctl_add(isight->card, ctl);
599 	if (err < 0)
600 		return err;
601 
602 	err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight));
603 	if (err < 0)
604 		return err;
605 
606 	return 0;
607 }
608 
609 static void isight_card_free(struct snd_card *card)
610 {
611 	struct isight *isight = card->private_data;
612 
613 	fw_iso_resources_destroy(&isight->resources);
614 	fw_unit_put(isight->unit);
615 	fw_device_put(isight->device);
616 	mutex_destroy(&isight->mutex);
617 }
618 
619 static u64 get_unit_base(struct fw_unit *unit)
620 {
621 	struct fw_csr_iterator i;
622 	int key, value;
623 
624 	fw_csr_iterator_init(&i, unit->directory);
625 	while (fw_csr_iterator_next(&i, &key, &value))
626 		if (key == CSR_OFFSET)
627 			return CSR_REGISTER_BASE + value * 4;
628 	return 0;
629 }
630 
631 static int isight_probe(struct device *unit_dev)
632 {
633 	struct fw_unit *unit = fw_unit(unit_dev);
634 	struct fw_device *fw_dev = fw_parent_device(unit);
635 	struct snd_card *card;
636 	struct isight *isight;
637 	int err;
638 
639 	err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
640 	if (err < 0)
641 		return err;
642 	snd_card_set_dev(card, unit_dev);
643 
644 	isight = card->private_data;
645 	isight->card = card;
646 	mutex_init(&isight->mutex);
647 	isight->unit = fw_unit_get(unit);
648 	isight->device = fw_device_get(fw_dev);
649 	isight->audio_base = get_unit_base(unit);
650 	if (!isight->audio_base) {
651 		dev_err(&unit->device, "audio unit base not found\n");
652 		err = -ENXIO;
653 		goto err_unit;
654 	}
655 	fw_iso_resources_init(&isight->resources, unit);
656 
657 	card->private_free = isight_card_free;
658 
659 	strcpy(card->driver, "iSight");
660 	strcpy(card->shortname, "Apple iSight");
661 	snprintf(card->longname, sizeof(card->longname),
662 		 "Apple iSight (GUID %08x%08x) at %s, S%d",
663 		 fw_dev->config_rom[3], fw_dev->config_rom[4],
664 		 dev_name(&unit->device), 100 << fw_dev->max_speed);
665 	strcpy(card->mixername, "iSight");
666 
667 	err = isight_create_pcm(isight);
668 	if (err < 0)
669 		goto error;
670 
671 	err = isight_create_mixer(isight);
672 	if (err < 0)
673 		goto error;
674 
675 	err = snd_card_register(card);
676 	if (err < 0)
677 		goto error;
678 
679 	dev_set_drvdata(unit_dev, isight);
680 
681 	return 0;
682 
683 err_unit:
684 	fw_unit_put(isight->unit);
685 	fw_device_put(isight->device);
686 	mutex_destroy(&isight->mutex);
687 error:
688 	snd_card_free(card);
689 	return err;
690 }
691 
692 static int isight_remove(struct device *dev)
693 {
694 	struct isight *isight = dev_get_drvdata(dev);
695 
696 	isight_pcm_abort(isight);
697 
698 	snd_card_disconnect(isight->card);
699 
700 	mutex_lock(&isight->mutex);
701 	isight_stop_streaming(isight);
702 	mutex_unlock(&isight->mutex);
703 
704 	snd_card_free_when_closed(isight->card);
705 
706 	return 0;
707 }
708 
709 static void isight_bus_reset(struct fw_unit *unit)
710 {
711 	struct isight *isight = dev_get_drvdata(&unit->device);
712 
713 	if (fw_iso_resources_update(&isight->resources) < 0) {
714 		isight_pcm_abort(isight);
715 
716 		mutex_lock(&isight->mutex);
717 		isight_stop_streaming(isight);
718 		mutex_unlock(&isight->mutex);
719 	}
720 }
721 
722 static const struct ieee1394_device_id isight_id_table[] = {
723 	{
724 		.match_flags  = IEEE1394_MATCH_SPECIFIER_ID |
725 				IEEE1394_MATCH_VERSION,
726 		.specifier_id = OUI_APPLE,
727 		.version      = SW_ISIGHT_AUDIO,
728 	},
729 	{ }
730 };
731 MODULE_DEVICE_TABLE(ieee1394, isight_id_table);
732 
733 static struct fw_driver isight_driver = {
734 	.driver   = {
735 		.owner	= THIS_MODULE,
736 		.name	= KBUILD_MODNAME,
737 		.bus	= &fw_bus_type,
738 		.probe	= isight_probe,
739 		.remove	= isight_remove,
740 	},
741 	.update   = isight_bus_reset,
742 	.id_table = isight_id_table,
743 };
744 
745 static int __init alsa_isight_init(void)
746 {
747 	return driver_register(&isight_driver.driver);
748 }
749 
750 static void __exit alsa_isight_exit(void)
751 {
752 	driver_unregister(&isight_driver.driver);
753 }
754 
755 module_init(alsa_isight_init);
756 module_exit(alsa_isight_exit);
757