Blame view

sound/usb/card.c 19.3 KB
e5779998b   Daniel Mack   ALSA: usb-audio: ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  /*
   *   (Tentative) USB Audio Driver for ALSA
   *
   *   Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
   *
   *   Many codes borrowed from audio.c by
   *	    Alan Cox (alan@lxorguk.ukuu.org.uk)
   *	    Thomas Sailer (sailer@ife.ee.ethz.ch)
   *
   *
   *   This program is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License as published by
   *   the Free Software Foundation; either version 2 of the License, or
   *   (at your option) any later version.
   *
   *   This program is distributed in the hope that it will be useful,
   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *   GNU General Public License for more details.
   *
   *   You should have received a copy of the GNU General Public License
   *   along with this program; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   *
   *
   *  NOTES:
   *
   *   - async unlink should be used for avoiding the sleep inside lock.
   *     2.4.22 usb-uhci seems buggy for async unlinking and results in
   *     oops.  in such a cse, pass async_unlink=0 option.
   *   - the linked URBs would be preferred but not used so far because of
   *     the instability of unlinking.
   *   - type II is not supported properly.  there is no device which supports
   *     this type *correctly*.  SB extigy looks as if it supports, but it's
   *     indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
   */
  
  
  #include <linux/bitops.h>
  #include <linux/init.h>
  #include <linux/list.h>
  #include <linux/slab.h>
  #include <linux/string.h>
3ffc1222b   Takashi Iwai   ALSA: usb - Remov...
44
  #include <linux/ctype.h>
e5779998b   Daniel Mack   ALSA: usb-audio: ...
45
46
47
48
  #include <linux/usb.h>
  #include <linux/moduleparam.h>
  #include <linux/mutex.h>
  #include <linux/usb/audio.h>
7e8478940   Daniel Mack   linux/usb/audio.h...
49
  #include <linux/usb/audio-v2.h>
da155d5b4   Paul Gortmaker   sound: Add module...
50
  #include <linux/module.h>
e5779998b   Daniel Mack   ALSA: usb-audio: ...
51

9e38658f7   Daniel Mack   ALSA: usb-audio: ...
52
  #include <sound/control.h>
e5779998b   Daniel Mack   ALSA: usb-audio: ...
53
54
55
56
57
58
59
60
61
  #include <sound/core.h>
  #include <sound/info.h>
  #include <sound/pcm.h>
  #include <sound/pcm_params.h>
  #include <sound/initval.h>
  
  #include "usbaudio.h"
  #include "card.h"
  #include "midi.h"
f0b5e634f   Daniel Mack   ALSA: usbmixer: r...
62
  #include "mixer.h"
e5779998b   Daniel Mack   ALSA: usb-audio: ...
63
64
65
66
67
68
  #include "proc.h"
  #include "quirks.h"
  #include "endpoint.h"
  #include "helper.h"
  #include "debug.h"
  #include "pcm.h"
e5779998b   Daniel Mack   ALSA: usb-audio: ...
69
  #include "format.h"
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
70
  #include "power.h"
e8e8babf5   Daniel Mack   ALSA: snd-usb: re...
71
  #include "stream.h"
e5779998b   Daniel Mack   ALSA: usb-audio: ...
72
73
74
75
76
77
78
79
80
  
  MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
  MODULE_DESCRIPTION("USB Audio");
  MODULE_LICENSE("GPL");
  MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
  
  
  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
a67ff6a54   Rusty Russell   ALSA: module_para...
81
  static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
e5779998b   Daniel Mack   ALSA: usb-audio: ...
82
83
84
85
  /* Vendor/product IDs for this card */
  static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
  static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
  static int nrpacks = 8;		/* max. number of packets per urb */
a67ff6a54   Rusty Russell   ALSA: module_para...
86
  static bool async_unlink = 1;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
87
  static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
a67ff6a54   Rusty Russell   ALSA: module_para...
88
  static bool ignore_ctl_error;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  
  module_param_array(index, int, NULL, 0444);
  MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
  module_param_array(id, charp, NULL, 0444);
  MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
  module_param_array(enable, bool, NULL, 0444);
  MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
  module_param_array(vid, int, NULL, 0444);
  MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
  module_param_array(pid, int, NULL, 0444);
  MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
  module_param(nrpacks, int, 0644);
  MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
  module_param(async_unlink, bool, 0444);
  MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
  module_param_array(device_setup, int, NULL, 0444);
  MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
  module_param(ignore_ctl_error, bool, 0444);
  MODULE_PARM_DESC(ignore_ctl_error,
  		 "Ignore errors from USB controller for mixer interfaces.");
  
  /*
   * we keep the snd_usb_audio_t instances by ourselves for merging
   * the all interfaces on the same card as one sound device.
   */
  
  static DEFINE_MUTEX(register_mutex);
  static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
  static struct usb_driver usb_audio_driver;
  
  /*
   * disconnect streams
   * called from snd_usb_audio_disconnect()
   */
  static void snd_usb_stream_disconnect(struct list_head *head)
  {
  	int idx;
  	struct snd_usb_stream *as;
  	struct snd_usb_substream *subs;
  
  	as = list_entry(head, struct snd_usb_stream, list);
  	for (idx = 0; idx < 2; idx++) {
  		subs = &as->substream[idx];
  		if (!subs->num_formats)
76195fb09   Takashi Iwai   ALSA: usb - Relea...
133
  			continue;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  		snd_usb_release_substream_urbs(subs, 1);
  		subs->interface = -1;
  	}
  }
  
  static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
  {
  	struct usb_device *dev = chip->dev;
  	struct usb_host_interface *alts;
  	struct usb_interface_descriptor *altsd;
  	struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
  
  	if (!iface) {
  		snd_printk(KERN_ERR "%d:%u:%d : does not exist
  ",
  			   dev->devnum, ctrlif, interface);
  		return -EINVAL;
  	}
  
  	if (usb_interface_claimed(iface)) {
  		snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed
  ",
  						dev->devnum, ctrlif, interface);
  		return -EINVAL;
  	}
  
  	alts = &iface->altsetting[0];
  	altsd = get_iface_desc(alts);
  	if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
  	     altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
  	    altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
  		int err = snd_usbmidi_create(chip->card, iface,
  					     &chip->midi_list, NULL);
  		if (err < 0) {
  			snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device
  ",
  						dev->devnum, ctrlif, interface);
  			return -EINVAL;
  		}
  		usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
  
  		return 0;
  	}
  
  	if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
  	     altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
  	    altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
  		snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d
  ",
  					dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
  		/* skip non-supported classes */
  		return -EINVAL;
  	}
  
  	if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
  		snd_printk(KERN_ERR "low speed audio streaming not supported
  ");
  		return -EINVAL;
  	}
e8e8babf5   Daniel Mack   ALSA: snd-usb: re...
193
  	if (! snd_usb_parse_audio_interface(chip, interface)) {
e5779998b   Daniel Mack   ALSA: usb-audio: ...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  		usb_set_interface(dev, interface, 0); /* reset the current interface */
  		usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
  		return -EINVAL;
  	}
  
  	return 0;
  }
  
  /*
   * parse audio control descriptor and create pcm/midi streams
   */
  static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
  {
  	struct usb_device *dev = chip->dev;
  	struct usb_host_interface *host_iface;
  	struct usb_interface_descriptor *altsd;
  	void *control_header;
  	int i, protocol;
  
  	/* find audiocontrol interface */
  	host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
  	control_header = snd_usb_find_csint_desc(host_iface->extra,
  						 host_iface->extralen,
  						 NULL, UAC_HEADER);
  	altsd = get_iface_desc(host_iface);
  	protocol = altsd->bInterfaceProtocol;
  
  	if (!control_header) {
  		snd_printk(KERN_ERR "cannot find UAC_HEADER
  ");
  		return -EINVAL;
  	}
  
  	switch (protocol) {
a2acad829   Clemens Ladisch   ALSA: usb-audio: ...
228
229
230
231
232
  	default:
  		snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1
  ",
  			    protocol);
  		/* fall through */
e5779998b   Daniel Mack   ALSA: usb-audio: ...
233
  	case UAC_VERSION_1: {
69da9bcb9   Daniel Mack   ALSA: usb-audio: ...
234
  		struct uac1_ac_header_descriptor *h1 = control_header;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
  
  		if (!h1->bInCollection) {
  			snd_printk(KERN_INFO "skipping empty audio interface (v1)
  ");
  			return -EINVAL;
  		}
  
  		if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
  			snd_printk(KERN_ERR "invalid UAC_HEADER (v1)
  ");
  			return -EINVAL;
  		}
  
  		for (i = 0; i < h1->bInCollection; i++)
  			snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
  
  		break;
  	}
  
  	case UAC_VERSION_2: {
e5779998b   Daniel Mack   ALSA: usb-audio: ...
255
256
257
258
259
260
261
262
  		struct usb_interface_assoc_descriptor *assoc =
  			usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
  
  		if (!assoc) {
  			snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association
  ");
  			return -EINVAL;
  		}
e5779998b   Daniel Mack   ALSA: usb-audio: ...
263
264
265
266
267
268
269
270
271
  		for (i = 0; i < assoc->bInterfaceCount; i++) {
  			int intf = assoc->bFirstInterface + i;
  
  			if (intf != ctrlif)
  				snd_usb_create_stream(chip, ctrlif, intf);
  		}
  
  		break;
  	}
e5779998b   Daniel Mack   ALSA: usb-audio: ...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
  	}
  
  	return 0;
  }
  
  /*
   * free the chip instance
   *
   * here we have to do not much, since pcm and controls are already freed
   *
   */
  
  static int snd_usb_audio_free(struct snd_usb_audio *chip)
  {
  	kfree(chip);
  	return 0;
  }
  
  static int snd_usb_audio_dev_free(struct snd_device *device)
  {
  	struct snd_usb_audio *chip = device->device_data;
  	return snd_usb_audio_free(chip);
  }
3ffc1222b   Takashi Iwai   ALSA: usb - Remov...
295
296
297
298
299
300
301
302
303
  static void remove_trailing_spaces(char *str)
  {
  	char *p;
  
  	if (!*str)
  		return;
  	for (p = str + strlen(str) - 1; p >= str && isspace(*p); p--)
  		*p = 0;
  }
e5779998b   Daniel Mack   ALSA: usb-audio: ...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
  
  /*
   * create a chip instance and set its names.
   */
  static int snd_usb_audio_create(struct usb_device *dev, int idx,
  				const struct snd_usb_audio_quirk *quirk,
  				struct snd_usb_audio **rchip)
  {
  	struct snd_card *card;
  	struct snd_usb_audio *chip;
  	int err, len;
  	char component[14];
  	static struct snd_device_ops ops = {
  		.dev_free =	snd_usb_audio_dev_free,
  	};
  
  	*rchip = NULL;
4f4e8f698   Paul Zimmerman   ALSA: usb: USB3 S...
321
322
323
324
325
326
327
  	switch (snd_usb_get_speed(dev)) {
  	case USB_SPEED_LOW:
  	case USB_SPEED_FULL:
  	case USB_SPEED_HIGH:
  	case USB_SPEED_SUPER:
  		break;
  	default:
e5779998b   Daniel Mack   ALSA: usb-audio: ...
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
  		snd_printk(KERN_ERR "unknown device speed %d
  ", snd_usb_get_speed(dev));
  		return -ENXIO;
  	}
  
  	err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
  	if (err < 0) {
  		snd_printk(KERN_ERR "cannot create card instance %d
  ", idx);
  		return err;
  	}
  
  	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
  	if (! chip) {
  		snd_card_free(card);
  		return -ENOMEM;
  	}
382225e62   Takashi Iwai   ALSA: usb-audio: ...
345
  	mutex_init(&chip->shutdown_mutex);
e5779998b   Daniel Mack   ALSA: usb-audio: ...
346
347
348
349
350
351
  	chip->index = idx;
  	chip->dev = dev;
  	chip->card = card;
  	chip->setup = device_setup[idx];
  	chip->nrpacks = nrpacks;
  	chip->async_unlink = async_unlink;
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
352
  	chip->probing = 1;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  
  	chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
  			      le16_to_cpu(dev->descriptor.idProduct));
  	INIT_LIST_HEAD(&chip->pcm_list);
  	INIT_LIST_HEAD(&chip->midi_list);
  	INIT_LIST_HEAD(&chip->mixer_list);
  
  	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
  		snd_usb_audio_free(chip);
  		snd_card_free(card);
  		return err;
  	}
  
  	strcpy(card->driver, "USB-Audio");
  	sprintf(component, "USB%04x:%04x",
  		USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
  	snd_component_add(card, component);
  
  	/* retrieve the device string as shortname */
3ffc1222b   Takashi Iwai   ALSA: usb - Remov...
372
  	if (quirk && quirk->product_name && *quirk->product_name) {
e5779998b   Daniel Mack   ALSA: usb-audio: ...
373
374
375
376
377
378
379
380
381
382
383
  		strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
  	} else {
  		if (!dev->descriptor.iProduct ||
  		    usb_string(dev, dev->descriptor.iProduct,
  		    card->shortname, sizeof(card->shortname)) <= 0) {
  			/* no name available from anywhere, so use ID */
  			sprintf(card->shortname, "USB Device %#04x:%#04x",
  				USB_ID_VENDOR(chip->usb_id),
  				USB_ID_PRODUCT(chip->usb_id));
  		}
  	}
3ffc1222b   Takashi Iwai   ALSA: usb - Remov...
384
  	remove_trailing_spaces(card->shortname);
e5779998b   Daniel Mack   ALSA: usb-audio: ...
385
386
  
  	/* retrieve the vendor and device strings as longname */
3ffc1222b   Takashi Iwai   ALSA: usb - Remov...
387
  	if (quirk && quirk->vendor_name && *quirk->vendor_name) {
e5779998b   Daniel Mack   ALSA: usb-audio: ...
388
389
390
391
392
393
394
395
396
  		len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
  	} else {
  		if (dev->descriptor.iManufacturer)
  			len = usb_string(dev, dev->descriptor.iManufacturer,
  					 card->longname, sizeof(card->longname));
  		else
  			len = 0;
  		/* we don't really care if there isn't any vendor string */
  	}
3ffc1222b   Takashi Iwai   ALSA: usb - Remov...
397
398
399
400
401
  	if (len > 0) {
  		remove_trailing_spaces(card->longname);
  		if (*card->longname)
  			strlcat(card->longname, " ", sizeof(card->longname));
  	}
e5779998b   Daniel Mack   ALSA: usb-audio: ...
402
403
404
405
406
407
408
  
  	strlcat(card->longname, card->shortname, sizeof(card->longname));
  
  	len = strlcat(card->longname, " at ", sizeof(card->longname));
  
  	if (len < sizeof(card->longname))
  		usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
4f4e8f698   Paul Zimmerman   ALSA: usb: USB3 S...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  	switch (snd_usb_get_speed(dev)) {
  	case USB_SPEED_LOW:
  		strlcat(card->longname, ", low speed", sizeof(card->longname));
  		break;
  	case USB_SPEED_FULL:
  		strlcat(card->longname, ", full speed", sizeof(card->longname));
  		break;
  	case USB_SPEED_HIGH:
  		strlcat(card->longname, ", high speed", sizeof(card->longname));
  		break;
  	case USB_SPEED_SUPER:
  		strlcat(card->longname, ", super speed", sizeof(card->longname));
  		break;
  	default:
  		break;
  	}
e5779998b   Daniel Mack   ALSA: usb-audio: ...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
  
  	snd_usb_audio_create_proc(chip);
  
  	*rchip = chip;
  	return 0;
  }
  
  /*
   * probe the active usb device
   *
   * note that this can be called multiple times per a device, when it
   * includes multiple audio control interfaces.
   *
   * thus we check the usb device pointer and creates the card instance
   * only at the first time.  the successive calls of this function will
   * append the pcm interface to the corresponding card.
   */
81b85b6bd   Pavel Roskin   ALSA: usb-audio: ...
442
443
444
445
  static struct snd_usb_audio *
  snd_usb_audio_probe(struct usb_device *dev,
  		    struct usb_interface *intf,
  		    const struct usb_device_id *usb_id)
e5779998b   Daniel Mack   ALSA: usb-audio: ...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
  {
  	const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
  	int i, err;
  	struct snd_usb_audio *chip;
  	struct usb_host_interface *alts;
  	int ifnum;
  	u32 id;
  
  	alts = &intf->altsetting[0];
  	ifnum = get_iface_desc(alts)->bInterfaceNumber;
  	id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
  		    le16_to_cpu(dev->descriptor.idProduct));
  	if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
  		goto __err_val;
  
  	if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)
  		goto __err_val;
  
  	/*
  	 * found a config.  now register to ALSA
  	 */
  
  	/* check whether it's already registered */
  	chip = NULL;
  	mutex_lock(&register_mutex);
  	for (i = 0; i < SNDRV_CARDS; i++) {
  		if (usb_chip[i] && usb_chip[i]->dev == dev) {
  			if (usb_chip[i]->shutdown) {
  				snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance
  ");
  				goto __error;
  			}
  			chip = usb_chip[i];
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
479
  			chip->probing = 1;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  			break;
  		}
  	}
  	if (! chip) {
  		/* it's a fresh one.
  		 * now look for an empty slot and create a new card instance
  		 */
  		for (i = 0; i < SNDRV_CARDS; i++)
  			if (enable[i] && ! usb_chip[i] &&
  			    (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
  			    (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
  				if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
  					goto __error;
  				}
  				snd_card_set_dev(chip->card, &intf->dev);
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
495
  				chip->pm_intf = intf;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
496
497
498
499
500
501
502
503
  				break;
  			}
  		if (!chip) {
  			printk(KERN_ERR "no available usb audio device
  ");
  			goto __error;
  		}
  	}
7b6717e14   Daniel Mack   ALSA: usb-audio: ...
504
505
506
507
508
509
510
  	/*
  	 * For devices with more than one control interface, we assume the
  	 * first contains the audio controls. We might need a more specific
  	 * check here in the future.
  	 */
  	if (!chip->ctrl_intf)
  		chip->ctrl_intf = alts;
79f920fbf   Daniel Mack   ALSA: usb-audio: ...
511

5875c2cb7   Daniel Mack   ALSA: usb-audio: ...
512
513
514
515
516
517
518
  	chip->txfr_quirk = 0;
  	err = 1; /* continue */
  	if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
  		/* need some special handlings */
  		if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)
  			goto __error;
  	}
e5779998b   Daniel Mack   ALSA: usb-audio: ...
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  	if (err > 0) {
  		/* create normal USB audio interfaces */
  		if (snd_usb_create_streams(chip, ifnum) < 0 ||
  		    snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
  			goto __error;
  		}
  	}
  
  	/* we are allowed to call snd_card_register() many times */
  	if (snd_card_register(chip->card) < 0) {
  		goto __error;
  	}
  
  	usb_chip[chip->index] = chip;
  	chip->num_interfaces++;
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
534
  	chip->probing = 0;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
535
536
537
538
  	mutex_unlock(&register_mutex);
  	return chip;
  
   __error:
61a6a108d   Thomas Pfaff   ALSA: usb-audio: ...
539
540
541
542
543
  	if (chip) {
  		if (!chip->num_interfaces)
  			snd_card_free(chip->card);
  		chip->probing = 0;
  	}
e5779998b   Daniel Mack   ALSA: usb-audio: ...
544
545
546
547
548
549
550
551
552
  	mutex_unlock(&register_mutex);
   __err_val:
  	return NULL;
  }
  
  /*
   * we need to take care of counter, since disconnection can be called also
   * many times as well as usb_audio_probe().
   */
81b85b6bd   Pavel Roskin   ALSA: usb-audio: ...
553
554
  static void snd_usb_audio_disconnect(struct usb_device *dev,
  				     struct snd_usb_audio *chip)
e5779998b   Daniel Mack   ALSA: usb-audio: ...
555
  {
e5779998b   Daniel Mack   ALSA: usb-audio: ...
556
557
  	struct snd_card *card;
  	struct list_head *p;
81b85b6bd   Pavel Roskin   ALSA: usb-audio: ...
558
  	if (chip == (void *)-1L)
e5779998b   Daniel Mack   ALSA: usb-audio: ...
559
  		return;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
560
561
  	card = chip->card;
  	mutex_lock(&register_mutex);
382225e62   Takashi Iwai   ALSA: usb-audio: ...
562
  	mutex_lock(&chip->shutdown_mutex);
e5779998b   Daniel Mack   ALSA: usb-audio: ...
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
  	chip->shutdown = 1;
  	chip->num_interfaces--;
  	if (chip->num_interfaces <= 0) {
  		snd_card_disconnect(card);
  		/* release the pcm resources */
  		list_for_each(p, &chip->pcm_list) {
  			snd_usb_stream_disconnect(p);
  		}
  		/* release the midi resources */
  		list_for_each(p, &chip->midi_list) {
  			snd_usbmidi_disconnect(p);
  		}
  		/* release mixer resources */
  		list_for_each(p, &chip->mixer_list) {
  			snd_usb_mixer_disconnect(p);
  		}
  		usb_chip[chip->index] = NULL;
382225e62   Takashi Iwai   ALSA: usb-audio: ...
580
  		mutex_unlock(&chip->shutdown_mutex);
e5779998b   Daniel Mack   ALSA: usb-audio: ...
581
582
583
  		mutex_unlock(&register_mutex);
  		snd_card_free_when_closed(card);
  	} else {
382225e62   Takashi Iwai   ALSA: usb-audio: ...
584
  		mutex_unlock(&chip->shutdown_mutex);
e5779998b   Daniel Mack   ALSA: usb-audio: ...
585
586
587
588
589
590
591
592
593
594
  		mutex_unlock(&register_mutex);
  	}
  }
  
  /*
   * new 2.5 USB kernel API
   */
  static int usb_audio_probe(struct usb_interface *intf,
  			   const struct usb_device_id *id)
  {
81b85b6bd   Pavel Roskin   ALSA: usb-audio: ...
595
  	struct snd_usb_audio *chip;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
  	chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
  	if (chip) {
  		usb_set_intfdata(intf, chip);
  		return 0;
  	} else
  		return -EIO;
  }
  
  static void usb_audio_disconnect(struct usb_interface *intf)
  {
  	snd_usb_audio_disconnect(interface_to_usbdev(intf),
  				 usb_get_intfdata(intf));
  }
  
  #ifdef CONFIG_PM
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
  
  int snd_usb_autoresume(struct snd_usb_audio *chip)
  {
  	int err = -ENODEV;
  
  	if (!chip->shutdown && !chip->probing)
  		err = usb_autopm_get_interface(chip->pm_intf);
  
  	return err;
  }
  
  void snd_usb_autosuspend(struct snd_usb_audio *chip)
  {
  	if (!chip->shutdown && !chip->probing)
  		usb_autopm_put_interface(chip->pm_intf);
  }
e5779998b   Daniel Mack   ALSA: usb-audio: ...
627
628
629
630
631
  static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
  {
  	struct snd_usb_audio *chip = usb_get_intfdata(intf);
  	struct list_head *p;
  	struct snd_usb_stream *as;
edf7de31c   Oliver Neukum   ALSA: usbaudio: f...
632
  	struct usb_mixer_interface *mixer;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
633
634
635
  
  	if (chip == (void *)-1L)
  		return 0;
5b1b0b812   Alan Stern   PM / Runtime: Add...
636
  	if (!PMSG_IS_AUTO(message)) {
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
637
638
639
640
641
642
643
644
645
646
647
648
649
650
  		snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
  		if (!chip->num_suspended_intf++) {
  			list_for_each(p, &chip->pcm_list) {
  				as = list_entry(p, struct snd_usb_stream, list);
  				snd_pcm_suspend_all(as->pcm);
  			}
   		}
  	} else {
  		/*
  		 * otherwise we keep the rest of the system in the dark
  		 * to keep this transparent
  		 */
  		if (!chip->num_suspended_intf++)
  			chip->autosuspended = 1;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
651
  	}
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
652
653
  	list_for_each_entry(mixer, &chip->mixer_list, list)
  		snd_usb_mixer_inactivate(mixer);
e5779998b   Daniel Mack   ALSA: usb-audio: ...
654
655
656
657
658
659
  	return 0;
  }
  
  static int usb_audio_resume(struct usb_interface *intf)
  {
  	struct snd_usb_audio *chip = usb_get_intfdata(intf);
edf7de31c   Oliver Neukum   ALSA: usbaudio: f...
660
  	struct usb_mixer_interface *mixer;
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
661
  	int err = 0;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
662
663
664
665
666
667
668
  
  	if (chip == (void *)-1L)
  		return 0;
  	if (--chip->num_suspended_intf)
  		return 0;
  	/*
  	 * ALSA leaves material resumption to user space
edf7de31c   Oliver Neukum   ALSA: usbaudio: f...
669
  	 * we just notify and restart the mixers
e5779998b   Daniel Mack   ALSA: usb-audio: ...
670
  	 */
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
671
672
673
674
675
  	list_for_each_entry(mixer, &chip->mixer_list, list) {
  		err = snd_usb_mixer_activate(mixer);
  		if (err < 0)
  			goto err_out;
  	}
e5779998b   Daniel Mack   ALSA: usb-audio: ...
676

88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
677
678
679
  	if (!chip->autosuspended)
  		snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
  	chip->autosuspended = 0;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
680

88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
681
682
  err_out:
  	return err;
e5779998b   Daniel Mack   ALSA: usb-audio: ...
683
  }
6407d474e   Randy Dunlap   ALSA: usb: fix us...
684
685
686
  #else
  #define usb_audio_suspend	NULL
  #define usb_audio_resume	NULL
e5779998b   Daniel Mack   ALSA: usb-audio: ...
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
  #endif		/* CONFIG_PM */
  
  static struct usb_device_id usb_audio_ids [] = {
  #include "quirks-table.h"
      { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
        .bInterfaceClass = USB_CLASS_AUDIO,
        .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
      { }						/* Terminating entry */
  };
  
  MODULE_DEVICE_TABLE (usb, usb_audio_ids);
  
  /*
   * entry point for linux usb interface
   */
  
  static struct usb_driver usb_audio_driver = {
  	.name =		"snd-usb-audio",
  	.probe =	usb_audio_probe,
  	.disconnect =	usb_audio_disconnect,
  	.suspend =	usb_audio_suspend,
  	.resume =	usb_audio_resume,
  	.id_table =	usb_audio_ids,
88a8516a2   Oliver Neukum   ALSA: usbaudio: i...
710
  	.supports_autosuspend = 1,
e5779998b   Daniel Mack   ALSA: usb-audio: ...
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
  };
  
  static int __init snd_usb_audio_init(void)
  {
  	if (nrpacks < 1 || nrpacks > MAX_PACKS) {
  		printk(KERN_WARNING "invalid nrpacks value.
  ");
  		return -EINVAL;
  	}
  	return usb_register(&usb_audio_driver);
  }
  
  static void __exit snd_usb_audio_cleanup(void)
  {
  	usb_deregister(&usb_audio_driver);
  }
  
  module_init(snd_usb_audio_init);
  module_exit(snd_usb_audio_cleanup);