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