diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-06-04 05:41:48 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-06-04 05:42:27 -0400 |
commit | cdbc653a04ee692a7105a96e8dd6055d9971d45c (patch) | |
tree | c1282680b3115edfd693a27bc6758208534ac557 /sound/usb | |
parent | 009f8c90f571d87855914dbc20e6c0ea2a3b19ae (diff) | |
parent | ceec4684085a9e4dc60439d84ab47ce260444804 (diff) |
Merge branch 'for-next' into for-linus
4.18-rc1 merge material.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/card.c | 226 | ||||
-rw-r--r-- | sound/usb/clock.c | 27 | ||||
-rw-r--r-- | sound/usb/helper.h | 4 | ||||
-rw-r--r-- | sound/usb/mixer.c | 639 | ||||
-rw-r--r-- | sound/usb/mixer.h | 6 | ||||
-rw-r--r-- | sound/usb/mixer_maps.c | 65 | ||||
-rw-r--r-- | sound/usb/mixer_quirks.c | 39 | ||||
-rw-r--r-- | sound/usb/mixer_quirks.h | 4 | ||||
-rw-r--r-- | sound/usb/mixer_scarlett.c | 6 | ||||
-rw-r--r-- | sound/usb/pcm.c | 270 | ||||
-rw-r--r-- | sound/usb/pcm.h | 1 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 10 | ||||
-rw-r--r-- | sound/usb/quirks.c | 59 | ||||
-rw-r--r-- | sound/usb/stream.c | 693 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 8 |
15 files changed, 1455 insertions, 602 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c index 4a1c6bb3dfa0..a1ed798a1c6b 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -86,6 +86,8 @@ static bool ignore_ctl_error; | |||
86 | static bool autoclock = true; | 86 | static bool autoclock = true; |
87 | static char *quirk_alias[SNDRV_CARDS]; | 87 | static char *quirk_alias[SNDRV_CARDS]; |
88 | 88 | ||
89 | bool snd_usb_use_vmalloc = true; | ||
90 | |||
89 | module_param_array(index, int, NULL, 0444); | 91 | module_param_array(index, int, NULL, 0444); |
90 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); | 92 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); |
91 | module_param_array(id, charp, NULL, 0444); | 93 | module_param_array(id, charp, NULL, 0444); |
@@ -105,6 +107,8 @@ module_param(autoclock, bool, 0444); | |||
105 | MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes)."); | 107 | MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes)."); |
106 | module_param_array(quirk_alias, charp, NULL, 0444); | 108 | module_param_array(quirk_alias, charp, NULL, 0444); |
107 | MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef."); | 109 | MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef."); |
110 | module_param_named(use_vmalloc, snd_usb_use_vmalloc, bool, 0444); | ||
111 | MODULE_PARM_DESC(use_vmalloc, "Use vmalloc for PCM intermediate buffers (default: yes)."); | ||
108 | 112 | ||
109 | /* | 113 | /* |
110 | * we keep the snd_usb_audio_t instances by ourselves for merging | 114 | * we keep the snd_usb_audio_t instances by ourselves for merging |
@@ -221,32 +225,13 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
221 | struct usb_device *dev = chip->dev; | 225 | struct usb_device *dev = chip->dev; |
222 | struct usb_host_interface *host_iface; | 226 | struct usb_host_interface *host_iface; |
223 | struct usb_interface_descriptor *altsd; | 227 | struct usb_interface_descriptor *altsd; |
224 | void *control_header; | ||
225 | int i, protocol; | 228 | int i, protocol; |
226 | int rest_bytes; | ||
227 | 229 | ||
228 | /* find audiocontrol interface */ | 230 | /* find audiocontrol interface */ |
229 | host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; | 231 | host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; |
230 | control_header = snd_usb_find_csint_desc(host_iface->extra, | ||
231 | host_iface->extralen, | ||
232 | NULL, UAC_HEADER); | ||
233 | altsd = get_iface_desc(host_iface); | 232 | altsd = get_iface_desc(host_iface); |
234 | protocol = altsd->bInterfaceProtocol; | 233 | protocol = altsd->bInterfaceProtocol; |
235 | 234 | ||
236 | if (!control_header) { | ||
237 | dev_err(&dev->dev, "cannot find UAC_HEADER\n"); | ||
238 | return -EINVAL; | ||
239 | } | ||
240 | |||
241 | rest_bytes = (void *)(host_iface->extra + host_iface->extralen) - | ||
242 | control_header; | ||
243 | |||
244 | /* just to be sure -- this shouldn't hit at all */ | ||
245 | if (rest_bytes <= 0) { | ||
246 | dev_err(&dev->dev, "invalid control header\n"); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | |||
250 | switch (protocol) { | 235 | switch (protocol) { |
251 | default: | 236 | default: |
252 | dev_warn(&dev->dev, | 237 | dev_warn(&dev->dev, |
@@ -255,7 +240,25 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
255 | /* fall through */ | 240 | /* fall through */ |
256 | 241 | ||
257 | case UAC_VERSION_1: { | 242 | case UAC_VERSION_1: { |
258 | struct uac1_ac_header_descriptor *h1 = control_header; | 243 | struct uac1_ac_header_descriptor *h1; |
244 | int rest_bytes; | ||
245 | |||
246 | h1 = snd_usb_find_csint_desc(host_iface->extra, | ||
247 | host_iface->extralen, | ||
248 | NULL, UAC_HEADER); | ||
249 | if (!h1) { | ||
250 | dev_err(&dev->dev, "cannot find UAC_HEADER\n"); | ||
251 | return -EINVAL; | ||
252 | } | ||
253 | |||
254 | rest_bytes = (void *)(host_iface->extra + | ||
255 | host_iface->extralen) - (void *)h1; | ||
256 | |||
257 | /* just to be sure -- this shouldn't hit at all */ | ||
258 | if (rest_bytes <= 0) { | ||
259 | dev_err(&dev->dev, "invalid control header\n"); | ||
260 | return -EINVAL; | ||
261 | } | ||
259 | 262 | ||
260 | if (rest_bytes < sizeof(*h1)) { | 263 | if (rest_bytes < sizeof(*h1)) { |
261 | dev_err(&dev->dev, "too short v1 buffer descriptor\n"); | 264 | dev_err(&dev->dev, "too short v1 buffer descriptor\n"); |
@@ -308,6 +311,20 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
308 | return -EINVAL; | 311 | return -EINVAL; |
309 | } | 312 | } |
310 | 313 | ||
314 | if (protocol == UAC_VERSION_3) { | ||
315 | int badd = assoc->bFunctionSubClass; | ||
316 | |||
317 | if (badd != UAC3_FUNCTION_SUBCLASS_FULL_ADC_3_0 && | ||
318 | (badd < UAC3_FUNCTION_SUBCLASS_GENERIC_IO || | ||
319 | badd > UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE)) { | ||
320 | dev_err(&dev->dev, | ||
321 | "Unsupported UAC3 BADD profile\n"); | ||
322 | return -EINVAL; | ||
323 | } | ||
324 | |||
325 | chip->badd_profile = badd; | ||
326 | } | ||
327 | |||
311 | for (i = 0; i < assoc->bInterfaceCount; i++) { | 328 | for (i = 0; i < assoc->bInterfaceCount; i++) { |
312 | int intf = assoc->bFirstInterface + i; | 329 | int intf = assoc->bFirstInterface + i; |
313 | 330 | ||
@@ -329,8 +346,9 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
329 | * | 346 | * |
330 | */ | 347 | */ |
331 | 348 | ||
332 | static int snd_usb_audio_free(struct snd_usb_audio *chip) | 349 | static void snd_usb_audio_free(struct snd_card *card) |
333 | { | 350 | { |
351 | struct snd_usb_audio *chip = card->private_data; | ||
334 | struct snd_usb_endpoint *ep, *n; | 352 | struct snd_usb_endpoint *ep, *n; |
335 | 353 | ||
336 | list_for_each_entry_safe(ep, n, &chip->ep_list, list) | 354 | list_for_each_entry_safe(ep, n, &chip->ep_list, list) |
@@ -339,14 +357,90 @@ static int snd_usb_audio_free(struct snd_usb_audio *chip) | |||
339 | mutex_destroy(&chip->mutex); | 357 | mutex_destroy(&chip->mutex); |
340 | if (!atomic_read(&chip->shutdown)) | 358 | if (!atomic_read(&chip->shutdown)) |
341 | dev_set_drvdata(&chip->dev->dev, NULL); | 359 | dev_set_drvdata(&chip->dev->dev, NULL); |
342 | kfree(chip); | ||
343 | return 0; | ||
344 | } | 360 | } |
345 | 361 | ||
346 | static int snd_usb_audio_dev_free(struct snd_device *device) | 362 | static void usb_audio_make_shortname(struct usb_device *dev, |
363 | struct snd_usb_audio *chip, | ||
364 | const struct snd_usb_audio_quirk *quirk) | ||
347 | { | 365 | { |
348 | struct snd_usb_audio *chip = device->device_data; | 366 | struct snd_card *card = chip->card; |
349 | return snd_usb_audio_free(chip); | 367 | |
368 | if (quirk && quirk->product_name && *quirk->product_name) { | ||
369 | strlcpy(card->shortname, quirk->product_name, | ||
370 | sizeof(card->shortname)); | ||
371 | return; | ||
372 | } | ||
373 | |||
374 | /* retrieve the device string as shortname */ | ||
375 | if (!dev->descriptor.iProduct || | ||
376 | usb_string(dev, dev->descriptor.iProduct, | ||
377 | card->shortname, sizeof(card->shortname)) <= 0) { | ||
378 | /* no name available from anywhere, so use ID */ | ||
379 | sprintf(card->shortname, "USB Device %#04x:%#04x", | ||
380 | USB_ID_VENDOR(chip->usb_id), | ||
381 | USB_ID_PRODUCT(chip->usb_id)); | ||
382 | } | ||
383 | |||
384 | strim(card->shortname); | ||
385 | } | ||
386 | |||
387 | static void usb_audio_make_longname(struct usb_device *dev, | ||
388 | struct snd_usb_audio *chip, | ||
389 | const struct snd_usb_audio_quirk *quirk) | ||
390 | { | ||
391 | struct snd_card *card = chip->card; | ||
392 | int len; | ||
393 | |||
394 | /* shortcut - if any pre-defined string is given, use it */ | ||
395 | if (quirk && quirk->profile_name && *quirk->profile_name) { | ||
396 | strlcpy(card->longname, quirk->profile_name, | ||
397 | sizeof(card->longname)); | ||
398 | return; | ||
399 | } | ||
400 | |||
401 | if (quirk && quirk->vendor_name && *quirk->vendor_name) { | ||
402 | len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname)); | ||
403 | } else { | ||
404 | /* retrieve the vendor and device strings as longname */ | ||
405 | if (dev->descriptor.iManufacturer) | ||
406 | len = usb_string(dev, dev->descriptor.iManufacturer, | ||
407 | card->longname, sizeof(card->longname)); | ||
408 | else | ||
409 | len = 0; | ||
410 | /* we don't really care if there isn't any vendor string */ | ||
411 | } | ||
412 | if (len > 0) { | ||
413 | strim(card->longname); | ||
414 | if (*card->longname) | ||
415 | strlcat(card->longname, " ", sizeof(card->longname)); | ||
416 | } | ||
417 | |||
418 | strlcat(card->longname, card->shortname, sizeof(card->longname)); | ||
419 | |||
420 | len = strlcat(card->longname, " at ", sizeof(card->longname)); | ||
421 | |||
422 | if (len < sizeof(card->longname)) | ||
423 | usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); | ||
424 | |||
425 | switch (snd_usb_get_speed(dev)) { | ||
426 | case USB_SPEED_LOW: | ||
427 | strlcat(card->longname, ", low speed", sizeof(card->longname)); | ||
428 | break; | ||
429 | case USB_SPEED_FULL: | ||
430 | strlcat(card->longname, ", full speed", sizeof(card->longname)); | ||
431 | break; | ||
432 | case USB_SPEED_HIGH: | ||
433 | strlcat(card->longname, ", high speed", sizeof(card->longname)); | ||
434 | break; | ||
435 | case USB_SPEED_SUPER: | ||
436 | strlcat(card->longname, ", super speed", sizeof(card->longname)); | ||
437 | break; | ||
438 | case USB_SPEED_SUPER_PLUS: | ||
439 | strlcat(card->longname, ", super speed plus", sizeof(card->longname)); | ||
440 | break; | ||
441 | default: | ||
442 | break; | ||
443 | } | ||
350 | } | 444 | } |
351 | 445 | ||
352 | /* | 446 | /* |
@@ -360,11 +454,8 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
360 | { | 454 | { |
361 | struct snd_card *card; | 455 | struct snd_card *card; |
362 | struct snd_usb_audio *chip; | 456 | struct snd_usb_audio *chip; |
363 | int err, len; | 457 | int err; |
364 | char component[14]; | 458 | char component[14]; |
365 | static struct snd_device_ops ops = { | ||
366 | .dev_free = snd_usb_audio_dev_free, | ||
367 | }; | ||
368 | 459 | ||
369 | *rchip = NULL; | 460 | *rchip = NULL; |
370 | 461 | ||
@@ -382,18 +473,13 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
382 | } | 473 | } |
383 | 474 | ||
384 | err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, | 475 | err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, |
385 | 0, &card); | 476 | sizeof(*chip), &card); |
386 | if (err < 0) { | 477 | if (err < 0) { |
387 | dev_err(&dev->dev, "cannot create card instance %d\n", idx); | 478 | dev_err(&dev->dev, "cannot create card instance %d\n", idx); |
388 | return err; | 479 | return err; |
389 | } | 480 | } |
390 | 481 | ||
391 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 482 | chip = card->private_data; |
392 | if (! chip) { | ||
393 | snd_card_free(card); | ||
394 | return -ENOMEM; | ||
395 | } | ||
396 | |||
397 | mutex_init(&chip->mutex); | 483 | mutex_init(&chip->mutex); |
398 | init_waitqueue_head(&chip->shutdown_wait); | 484 | init_waitqueue_head(&chip->shutdown_wait); |
399 | chip->index = idx; | 485 | chip->index = idx; |
@@ -411,75 +497,15 @@ static int snd_usb_audio_create(struct usb_interface *intf, | |||
411 | INIT_LIST_HEAD(&chip->midi_list); | 497 | INIT_LIST_HEAD(&chip->midi_list); |
412 | INIT_LIST_HEAD(&chip->mixer_list); | 498 | INIT_LIST_HEAD(&chip->mixer_list); |
413 | 499 | ||
414 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | 500 | card->private_free = snd_usb_audio_free; |
415 | snd_usb_audio_free(chip); | ||
416 | snd_card_free(card); | ||
417 | return err; | ||
418 | } | ||
419 | 501 | ||
420 | strcpy(card->driver, "USB-Audio"); | 502 | strcpy(card->driver, "USB-Audio"); |
421 | sprintf(component, "USB%04x:%04x", | 503 | sprintf(component, "USB%04x:%04x", |
422 | USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); | 504 | USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); |
423 | snd_component_add(card, component); | 505 | snd_component_add(card, component); |
424 | 506 | ||
425 | /* retrieve the device string as shortname */ | 507 | usb_audio_make_shortname(dev, chip, quirk); |
426 | if (quirk && quirk->product_name && *quirk->product_name) { | 508 | usb_audio_make_longname(dev, chip, quirk); |
427 | strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname)); | ||
428 | } else { | ||
429 | if (!dev->descriptor.iProduct || | ||
430 | usb_string(dev, dev->descriptor.iProduct, | ||
431 | card->shortname, sizeof(card->shortname)) <= 0) { | ||
432 | /* no name available from anywhere, so use ID */ | ||
433 | sprintf(card->shortname, "USB Device %#04x:%#04x", | ||
434 | USB_ID_VENDOR(chip->usb_id), | ||
435 | USB_ID_PRODUCT(chip->usb_id)); | ||
436 | } | ||
437 | } | ||
438 | strim(card->shortname); | ||
439 | |||
440 | /* retrieve the vendor and device strings as longname */ | ||
441 | if (quirk && quirk->vendor_name && *quirk->vendor_name) { | ||
442 | len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname)); | ||
443 | } else { | ||
444 | if (dev->descriptor.iManufacturer) | ||
445 | len = usb_string(dev, dev->descriptor.iManufacturer, | ||
446 | card->longname, sizeof(card->longname)); | ||
447 | else | ||
448 | len = 0; | ||
449 | /* we don't really care if there isn't any vendor string */ | ||
450 | } | ||
451 | if (len > 0) { | ||
452 | strim(card->longname); | ||
453 | if (*card->longname) | ||
454 | strlcat(card->longname, " ", sizeof(card->longname)); | ||
455 | } | ||
456 | |||
457 | strlcat(card->longname, card->shortname, sizeof(card->longname)); | ||
458 | |||
459 | len = strlcat(card->longname, " at ", sizeof(card->longname)); | ||
460 | |||
461 | if (len < sizeof(card->longname)) | ||
462 | usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); | ||
463 | |||
464 | switch (snd_usb_get_speed(dev)) { | ||
465 | case USB_SPEED_LOW: | ||
466 | strlcat(card->longname, ", low speed", sizeof(card->longname)); | ||
467 | break; | ||
468 | case USB_SPEED_FULL: | ||
469 | strlcat(card->longname, ", full speed", sizeof(card->longname)); | ||
470 | break; | ||
471 | case USB_SPEED_HIGH: | ||
472 | strlcat(card->longname, ", high speed", sizeof(card->longname)); | ||
473 | break; | ||
474 | case USB_SPEED_SUPER: | ||
475 | strlcat(card->longname, ", super speed", sizeof(card->longname)); | ||
476 | break; | ||
477 | case USB_SPEED_SUPER_PLUS: | ||
478 | strlcat(card->longname, ", super speed plus", sizeof(card->longname)); | ||
479 | break; | ||
480 | default: | ||
481 | break; | ||
482 | } | ||
483 | 509 | ||
484 | snd_usb_audio_create_proc(chip); | 510 | snd_usb_audio_create_proc(chip); |
485 | 511 | ||
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 0b030d8fe3fa..c79749613fa6 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
@@ -443,10 +443,11 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | |||
443 | data[0] = rate; | 443 | data[0] = rate; |
444 | data[1] = rate >> 8; | 444 | data[1] = rate >> 8; |
445 | data[2] = rate >> 16; | 445 | data[2] = rate >> 16; |
446 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | 446 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, |
447 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 447 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
448 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | 448 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, |
449 | data, sizeof(data))) < 0) { | 449 | data, sizeof(data)); |
450 | if (err < 0) { | ||
450 | dev_err(&dev->dev, "%d:%d: cannot set freq %d to ep %#x\n", | 451 | dev_err(&dev->dev, "%d:%d: cannot set freq %d to ep %#x\n", |
451 | iface, fmt->altsetting, rate, ep); | 452 | iface, fmt->altsetting, rate, ep); |
452 | return err; | 453 | return err; |
@@ -460,10 +461,11 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | |||
460 | if (chip->sample_rate_read_error > 2) | 461 | if (chip->sample_rate_read_error > 2) |
461 | return 0; | 462 | return 0; |
462 | 463 | ||
463 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, | 464 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, |
464 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, | 465 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, |
465 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | 466 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, |
466 | data, sizeof(data))) < 0) { | 467 | data, sizeof(data)); |
468 | if (err < 0) { | ||
467 | dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n", | 469 | dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n", |
468 | iface, fmt->altsetting, ep); | 470 | iface, fmt->altsetting, ep); |
469 | chip->sample_rate_read_error++; | 471 | chip->sample_rate_read_error++; |
@@ -587,8 +589,15 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | |||
587 | default: | 589 | default: |
588 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); | 590 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); |
589 | 591 | ||
590 | case UAC_VERSION_2: | ||
591 | case UAC_VERSION_3: | 592 | case UAC_VERSION_3: |
593 | if (chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) { | ||
594 | if (rate != UAC3_BADD_SAMPLING_RATE) | ||
595 | return -ENXIO; | ||
596 | else | ||
597 | return 0; | ||
598 | } | ||
599 | /* fall through */ | ||
600 | case UAC_VERSION_2: | ||
592 | return set_sample_rate_v2v3(chip, iface, alts, fmt, rate); | 601 | return set_sample_rate_v2v3(chip, iface, alts, fmt, rate); |
593 | } | 602 | } |
594 | } | 603 | } |
diff --git a/sound/usb/helper.h b/sound/usb/helper.h index 4463e6d6dcb3..d338bd0e0ca6 100644 --- a/sound/usb/helper.h +++ b/sound/usb/helper.h | |||
@@ -18,16 +18,12 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, | |||
18 | * retrieve usb_interface descriptor from the host interface | 18 | * retrieve usb_interface descriptor from the host interface |
19 | * (conditional for compatibility with the older API) | 19 | * (conditional for compatibility with the older API) |
20 | */ | 20 | */ |
21 | #ifndef get_iface_desc | ||
22 | #define get_iface_desc(iface) (&(iface)->desc) | 21 | #define get_iface_desc(iface) (&(iface)->desc) |
23 | #define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc) | 22 | #define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc) |
24 | #define get_ep_desc(ep) (&(ep)->desc) | 23 | #define get_ep_desc(ep) (&(ep)->desc) |
25 | #define get_cfg_desc(cfg) (&(cfg)->desc) | 24 | #define get_cfg_desc(cfg) (&(cfg)->desc) |
26 | #endif | ||
27 | 25 | ||
28 | #ifndef snd_usb_get_speed | ||
29 | #define snd_usb_get_speed(dev) ((dev)->speed) | 26 | #define snd_usb_get_speed(dev) ((dev)->speed) |
30 | #endif | ||
31 | 27 | ||
32 | static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip) | 28 | static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip) |
33 | { | 29 | { |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index bb5ab7a7dfa5..898afd3001ea 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -112,14 +112,12 @@ enum { | |||
112 | #include "mixer_maps.c" | 112 | #include "mixer_maps.c" |
113 | 113 | ||
114 | static const struct usbmix_name_map * | 114 | static const struct usbmix_name_map * |
115 | find_map(struct mixer_build *state, int unitid, int control) | 115 | find_map(const struct usbmix_name_map *p, int unitid, int control) |
116 | { | 116 | { |
117 | const struct usbmix_name_map *p = state->map; | ||
118 | |||
119 | if (!p) | 117 | if (!p) |
120 | return NULL; | 118 | return NULL; |
121 | 119 | ||
122 | for (p = state->map; p->id; p++) { | 120 | for (; p->id; p++) { |
123 | if (p->id == unitid && | 121 | if (p->id == unitid && |
124 | (!control || !p->control || control == p->control)) | 122 | (!control || !p->control || control == p->control)) |
125 | return p; | 123 | return p; |
@@ -201,10 +199,10 @@ static void *find_audio_control_unit(struct mixer_build *state, | |||
201 | /* | 199 | /* |
202 | * copy a string with the given id | 200 | * copy a string with the given id |
203 | */ | 201 | */ |
204 | static int snd_usb_copy_string_desc(struct mixer_build *state, | 202 | static int snd_usb_copy_string_desc(struct snd_usb_audio *chip, |
205 | int index, char *buf, int maxlen) | 203 | int index, char *buf, int maxlen) |
206 | { | 204 | { |
207 | int len = usb_string(state->chip->dev, index, buf, maxlen - 1); | 205 | int len = usb_string(chip->dev, index, buf, maxlen - 1); |
208 | 206 | ||
209 | if (len < 0) | 207 | if (len < 0) |
210 | return 0; | 208 | return 0; |
@@ -600,7 +598,8 @@ int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list, | |||
600 | 598 | ||
601 | while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) | 599 | while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) |
602 | kctl->id.index++; | 600 | kctl->id.index++; |
603 | if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) { | 601 | err = snd_ctl_add(mixer->chip->card, kctl); |
602 | if (err < 0) { | ||
604 | usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n", | 603 | usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n", |
605 | err); | 604 | err); |
606 | return err; | 605 | return err; |
@@ -658,14 +657,14 @@ static struct iterm_name_combo { | |||
658 | { 0 }, | 657 | { 0 }, |
659 | }; | 658 | }; |
660 | 659 | ||
661 | static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm, | 660 | static int get_term_name(struct snd_usb_audio *chip, struct usb_audio_term *iterm, |
662 | unsigned char *name, int maxlen, int term_only) | 661 | unsigned char *name, int maxlen, int term_only) |
663 | { | 662 | { |
664 | struct iterm_name_combo *names; | 663 | struct iterm_name_combo *names; |
665 | int len; | 664 | int len; |
666 | 665 | ||
667 | if (iterm->name) { | 666 | if (iterm->name) { |
668 | len = snd_usb_copy_string_desc(state, iterm->name, | 667 | len = snd_usb_copy_string_desc(chip, iterm->name, |
669 | name, maxlen); | 668 | name, maxlen); |
670 | if (len) | 669 | if (len) |
671 | return len; | 670 | return len; |
@@ -719,6 +718,66 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
719 | } | 718 | } |
720 | 719 | ||
721 | /* | 720 | /* |
721 | * Get logical cluster information for UAC3 devices. | ||
722 | */ | ||
723 | static int get_cluster_channels_v3(struct mixer_build *state, unsigned int cluster_id) | ||
724 | { | ||
725 | struct uac3_cluster_header_descriptor c_header; | ||
726 | int err; | ||
727 | |||
728 | err = snd_usb_ctl_msg(state->chip->dev, | ||
729 | usb_rcvctrlpipe(state->chip->dev, 0), | ||
730 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
731 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
732 | cluster_id, | ||
733 | snd_usb_ctrl_intf(state->chip), | ||
734 | &c_header, sizeof(c_header)); | ||
735 | if (err < 0) | ||
736 | goto error; | ||
737 | if (err != sizeof(c_header)) { | ||
738 | err = -EIO; | ||
739 | goto error; | ||
740 | } | ||
741 | |||
742 | return c_header.bNrChannels; | ||
743 | |||
744 | error: | ||
745 | usb_audio_err(state->chip, "cannot request logical cluster ID: %d (err: %d)\n", cluster_id, err); | ||
746 | return err; | ||
747 | } | ||
748 | |||
749 | /* | ||
750 | * Get number of channels for a Mixer Unit. | ||
751 | */ | ||
752 | static int uac_mixer_unit_get_channels(struct mixer_build *state, | ||
753 | struct uac_mixer_unit_descriptor *desc) | ||
754 | { | ||
755 | int mu_channels; | ||
756 | |||
757 | if (desc->bLength < 11) | ||
758 | return -EINVAL; | ||
759 | if (!desc->bNrInPins) | ||
760 | return -EINVAL; | ||
761 | |||
762 | switch (state->mixer->protocol) { | ||
763 | case UAC_VERSION_1: | ||
764 | case UAC_VERSION_2: | ||
765 | default: | ||
766 | mu_channels = uac_mixer_unit_bNrChannels(desc); | ||
767 | break; | ||
768 | case UAC_VERSION_3: | ||
769 | mu_channels = get_cluster_channels_v3(state, | ||
770 | uac3_mixer_unit_wClusterDescrID(desc)); | ||
771 | break; | ||
772 | } | ||
773 | |||
774 | if (!mu_channels) | ||
775 | return -EINVAL; | ||
776 | |||
777 | return mu_channels; | ||
778 | } | ||
779 | |||
780 | /* | ||
722 | * parse the source unit recursively until it reaches to a terminal | 781 | * parse the source unit recursively until it reaches to a terminal |
723 | * or a branched unit. | 782 | * or a branched unit. |
724 | */ | 783 | */ |
@@ -844,8 +903,12 @@ static int check_input_term(struct mixer_build *state, int id, | |||
844 | term->id = id; | 903 | term->id = id; |
845 | term->type = le16_to_cpu(d->wTerminalType); | 904 | term->type = le16_to_cpu(d->wTerminalType); |
846 | 905 | ||
847 | /* REVISIT: UAC3 IT doesn't have channels/cfg */ | 906 | err = get_cluster_channels_v3(state, le16_to_cpu(d->wClusterDescrID)); |
848 | term->channels = 0; | 907 | if (err < 0) |
908 | return err; | ||
909 | term->channels = err; | ||
910 | |||
911 | /* REVISIT: UAC3 IT doesn't have channels cfg */ | ||
849 | term->chconfig = 0; | 912 | term->chconfig = 0; |
850 | 913 | ||
851 | term->name = le16_to_cpu(d->wTerminalDescrStr); | 914 | term->name = le16_to_cpu(d->wTerminalDescrStr); |
@@ -865,6 +928,18 @@ static int check_input_term(struct mixer_build *state, int id, | |||
865 | term->name = le16_to_cpu(d->wClockSourceStr); | 928 | term->name = le16_to_cpu(d->wClockSourceStr); |
866 | return 0; | 929 | return 0; |
867 | } | 930 | } |
931 | case UAC3_MIXER_UNIT: { | ||
932 | struct uac_mixer_unit_descriptor *d = p1; | ||
933 | |||
934 | err = uac_mixer_unit_get_channels(state, d); | ||
935 | if (err < 0) | ||
936 | return err; | ||
937 | |||
938 | term->channels = err; | ||
939 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
940 | |||
941 | return 0; | ||
942 | } | ||
868 | default: | 943 | default: |
869 | return -ENODEV; | 944 | return -ENODEV; |
870 | } | 945 | } |
@@ -1258,6 +1333,51 @@ static int mixer_ctl_master_bool_get(struct snd_kcontrol *kcontrol, | |||
1258 | return 0; | 1333 | return 0; |
1259 | } | 1334 | } |
1260 | 1335 | ||
1336 | /* get the connectors status and report it as boolean type */ | ||
1337 | static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol, | ||
1338 | struct snd_ctl_elem_value *ucontrol) | ||
1339 | { | ||
1340 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | ||
1341 | struct snd_usb_audio *chip = cval->head.mixer->chip; | ||
1342 | int idx = 0, validx, ret, val; | ||
1343 | |||
1344 | validx = cval->control << 8 | 0; | ||
1345 | |||
1346 | ret = snd_usb_lock_shutdown(chip) ? -EIO : 0; | ||
1347 | if (ret) | ||
1348 | goto error; | ||
1349 | |||
1350 | idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); | ||
1351 | if (cval->head.mixer->protocol == UAC_VERSION_2) { | ||
1352 | struct uac2_connectors_ctl_blk uac2_conn; | ||
1353 | |||
1354 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR, | ||
1355 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
1356 | validx, idx, &uac2_conn, sizeof(uac2_conn)); | ||
1357 | val = !!uac2_conn.bNrChannels; | ||
1358 | } else { /* UAC_VERSION_3 */ | ||
1359 | struct uac3_insertion_ctl_blk uac3_conn; | ||
1360 | |||
1361 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR, | ||
1362 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
1363 | validx, idx, &uac3_conn, sizeof(uac3_conn)); | ||
1364 | val = !!uac3_conn.bmConInserted; | ||
1365 | } | ||
1366 | |||
1367 | snd_usb_unlock_shutdown(chip); | ||
1368 | |||
1369 | if (ret < 0) { | ||
1370 | error: | ||
1371 | usb_audio_err(chip, | ||
1372 | "cannot get connectors status: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", | ||
1373 | UAC_GET_CUR, validx, idx, cval->val_type); | ||
1374 | return ret; | ||
1375 | } | ||
1376 | |||
1377 | ucontrol->value.integer.value[0] = val; | ||
1378 | return 0; | ||
1379 | } | ||
1380 | |||
1261 | static struct snd_kcontrol_new usb_feature_unit_ctl = { | 1381 | static struct snd_kcontrol_new usb_feature_unit_ctl = { |
1262 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1382 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1263 | .name = "", /* will be filled later manually */ | 1383 | .name = "", /* will be filled later manually */ |
@@ -1288,6 +1408,15 @@ static struct snd_kcontrol_new usb_bool_master_control_ctl_ro = { | |||
1288 | .put = NULL, | 1408 | .put = NULL, |
1289 | }; | 1409 | }; |
1290 | 1410 | ||
1411 | static const struct snd_kcontrol_new usb_connector_ctl_ro = { | ||
1412 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1413 | .name = "", /* will be filled later manually */ | ||
1414 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | ||
1415 | .info = snd_ctl_boolean_mono_info, | ||
1416 | .get = mixer_ctl_connector_get, | ||
1417 | .put = NULL, | ||
1418 | }; | ||
1419 | |||
1291 | /* | 1420 | /* |
1292 | * This symbol is exported in order to allow the mixer quirks to | 1421 | * This symbol is exported in order to allow the mixer quirks to |
1293 | * hook up to the standard feature unit control mechanism | 1422 | * hook up to the standard feature unit control mechanism |
@@ -1341,16 +1470,16 @@ static struct usb_feature_control_info *get_feature_control_info(int control) | |||
1341 | return NULL; | 1470 | return NULL; |
1342 | } | 1471 | } |
1343 | 1472 | ||
1344 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | 1473 | static void __build_feature_ctl(struct usb_mixer_interface *mixer, |
1345 | unsigned int ctl_mask, int control, | 1474 | const struct usbmix_name_map *imap, |
1346 | struct usb_audio_term *iterm, int unitid, | 1475 | unsigned int ctl_mask, int control, |
1347 | int readonly_mask) | 1476 | struct usb_audio_term *iterm, |
1477 | struct usb_audio_term *oterm, | ||
1478 | int unitid, int nameid, int readonly_mask) | ||
1348 | { | 1479 | { |
1349 | struct uac_feature_unit_descriptor *desc = raw_desc; | ||
1350 | struct usb_feature_control_info *ctl_info; | 1480 | struct usb_feature_control_info *ctl_info; |
1351 | unsigned int len = 0; | 1481 | unsigned int len = 0; |
1352 | int mapped_name = 0; | 1482 | int mapped_name = 0; |
1353 | int nameid = uac_feature_unit_iFeature(desc); | ||
1354 | struct snd_kcontrol *kctl; | 1483 | struct snd_kcontrol *kctl; |
1355 | struct usb_mixer_elem_info *cval; | 1484 | struct usb_mixer_elem_info *cval; |
1356 | const struct usbmix_name_map *map; | 1485 | const struct usbmix_name_map *map; |
@@ -1361,14 +1490,14 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1361 | return; | 1490 | return; |
1362 | } | 1491 | } |
1363 | 1492 | ||
1364 | map = find_map(state, unitid, control); | 1493 | map = find_map(imap, unitid, control); |
1365 | if (check_ignored_ctl(map)) | 1494 | if (check_ignored_ctl(map)) |
1366 | return; | 1495 | return; |
1367 | 1496 | ||
1368 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1497 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
1369 | if (!cval) | 1498 | if (!cval) |
1370 | return; | 1499 | return; |
1371 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); | 1500 | snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid); |
1372 | cval->control = control; | 1501 | cval->control = control; |
1373 | cval->cmask = ctl_mask; | 1502 | cval->cmask = ctl_mask; |
1374 | 1503 | ||
@@ -1377,7 +1506,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1377 | kfree(cval); | 1506 | kfree(cval); |
1378 | return; | 1507 | return; |
1379 | } | 1508 | } |
1380 | if (state->mixer->protocol == UAC_VERSION_1) | 1509 | if (mixer->protocol == UAC_VERSION_1) |
1381 | cval->val_type = ctl_info->type; | 1510 | cval->val_type = ctl_info->type; |
1382 | else /* UAC_VERSION_2 */ | 1511 | else /* UAC_VERSION_2 */ |
1383 | cval->val_type = ctl_info->type_uac2 >= 0 ? | 1512 | cval->val_type = ctl_info->type_uac2 >= 0 ? |
@@ -1406,7 +1535,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1406 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); | 1535 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); |
1407 | 1536 | ||
1408 | if (!kctl) { | 1537 | if (!kctl) { |
1409 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | 1538 | usb_audio_err(mixer->chip, "cannot malloc kcontrol\n"); |
1410 | kfree(cval); | 1539 | kfree(cval); |
1411 | return; | 1540 | return; |
1412 | } | 1541 | } |
@@ -1415,7 +1544,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1415 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); | 1544 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
1416 | mapped_name = len != 0; | 1545 | mapped_name = len != 0; |
1417 | if (!len && nameid) | 1546 | if (!len && nameid) |
1418 | len = snd_usb_copy_string_desc(state, nameid, | 1547 | len = snd_usb_copy_string_desc(mixer->chip, nameid, |
1419 | kctl->id.name, sizeof(kctl->id.name)); | 1548 | kctl->id.name, sizeof(kctl->id.name)); |
1420 | 1549 | ||
1421 | switch (control) { | 1550 | switch (control) { |
@@ -1430,10 +1559,12 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1430 | * - otherwise, anonymous name. | 1559 | * - otherwise, anonymous name. |
1431 | */ | 1560 | */ |
1432 | if (!len) { | 1561 | if (!len) { |
1433 | len = get_term_name(state, iterm, kctl->id.name, | 1562 | if (iterm) |
1434 | sizeof(kctl->id.name), 1); | 1563 | len = get_term_name(mixer->chip, iterm, |
1435 | if (!len) | 1564 | kctl->id.name, |
1436 | len = get_term_name(state, &state->oterm, | 1565 | sizeof(kctl->id.name), 1); |
1566 | if (!len && oterm) | ||
1567 | len = get_term_name(mixer->chip, oterm, | ||
1437 | kctl->id.name, | 1568 | kctl->id.name, |
1438 | sizeof(kctl->id.name), 1); | 1569 | sizeof(kctl->id.name), 1); |
1439 | if (!len) | 1570 | if (!len) |
@@ -1442,15 +1573,15 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1442 | } | 1573 | } |
1443 | 1574 | ||
1444 | if (!mapped_name) | 1575 | if (!mapped_name) |
1445 | check_no_speaker_on_headset(kctl, state->mixer->chip->card); | 1576 | check_no_speaker_on_headset(kctl, mixer->chip->card); |
1446 | 1577 | ||
1447 | /* | 1578 | /* |
1448 | * determine the stream direction: | 1579 | * determine the stream direction: |
1449 | * if the connected output is USB stream, then it's likely a | 1580 | * if the connected output is USB stream, then it's likely a |
1450 | * capture stream. otherwise it should be playback (hopefully :) | 1581 | * capture stream. otherwise it should be playback (hopefully :) |
1451 | */ | 1582 | */ |
1452 | if (!mapped_name && !(state->oterm.type >> 16)) { | 1583 | if (!mapped_name && oterm && !(oterm->type >> 16)) { |
1453 | if ((state->oterm.type & 0xff00) == 0x0100) | 1584 | if ((oterm->type & 0xff00) == 0x0100) |
1454 | append_ctl_name(kctl, " Capture"); | 1585 | append_ctl_name(kctl, " Capture"); |
1455 | else | 1586 | else |
1456 | append_ctl_name(kctl, " Playback"); | 1587 | append_ctl_name(kctl, " Playback"); |
@@ -1478,7 +1609,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1478 | } | 1609 | } |
1479 | } | 1610 | } |
1480 | 1611 | ||
1481 | snd_usb_mixer_fu_apply_quirk(state->mixer, cval, unitid, kctl); | 1612 | snd_usb_mixer_fu_apply_quirk(mixer, cval, unitid, kctl); |
1482 | 1613 | ||
1483 | range = (cval->max - cval->min) / cval->res; | 1614 | range = (cval->max - cval->min) / cval->res; |
1484 | /* | 1615 | /* |
@@ -1487,26 +1618,46 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1487 | * devices. It will definitively catch all buggy Logitech devices. | 1618 | * devices. It will definitively catch all buggy Logitech devices. |
1488 | */ | 1619 | */ |
1489 | if (range > 384) { | 1620 | if (range > 384) { |
1490 | usb_audio_warn(state->chip, | 1621 | usb_audio_warn(mixer->chip, |
1491 | "Warning! Unlikely big volume range (=%u), cval->res is probably wrong.", | 1622 | "Warning! Unlikely big volume range (=%u), cval->res is probably wrong.", |
1492 | range); | 1623 | range); |
1493 | usb_audio_warn(state->chip, | 1624 | usb_audio_warn(mixer->chip, |
1494 | "[%d] FU [%s] ch = %d, val = %d/%d/%d", | 1625 | "[%d] FU [%s] ch = %d, val = %d/%d/%d", |
1495 | cval->head.id, kctl->id.name, cval->channels, | 1626 | cval->head.id, kctl->id.name, cval->channels, |
1496 | cval->min, cval->max, cval->res); | 1627 | cval->min, cval->max, cval->res); |
1497 | } | 1628 | } |
1498 | 1629 | ||
1499 | usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", | 1630 | usb_audio_dbg(mixer->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", |
1500 | cval->head.id, kctl->id.name, cval->channels, | 1631 | cval->head.id, kctl->id.name, cval->channels, |
1501 | cval->min, cval->max, cval->res); | 1632 | cval->min, cval->max, cval->res); |
1502 | snd_usb_mixer_add_control(&cval->head, kctl); | 1633 | snd_usb_mixer_add_control(&cval->head, kctl); |
1503 | } | 1634 | } |
1504 | 1635 | ||
1636 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | ||
1637 | unsigned int ctl_mask, int control, | ||
1638 | struct usb_audio_term *iterm, int unitid, | ||
1639 | int readonly_mask) | ||
1640 | { | ||
1641 | struct uac_feature_unit_descriptor *desc = raw_desc; | ||
1642 | int nameid = uac_feature_unit_iFeature(desc); | ||
1643 | |||
1644 | __build_feature_ctl(state->mixer, state->map, ctl_mask, control, | ||
1645 | iterm, &state->oterm, unitid, nameid, readonly_mask); | ||
1646 | } | ||
1647 | |||
1648 | static void build_feature_ctl_badd(struct usb_mixer_interface *mixer, | ||
1649 | unsigned int ctl_mask, int control, int unitid, | ||
1650 | const struct usbmix_name_map *badd_map) | ||
1651 | { | ||
1652 | __build_feature_ctl(mixer, badd_map, ctl_mask, control, | ||
1653 | NULL, NULL, unitid, 0, 0); | ||
1654 | } | ||
1655 | |||
1505 | static void get_connector_control_name(struct mixer_build *state, | 1656 | static void get_connector_control_name(struct mixer_build *state, |
1506 | struct usb_audio_term *term, | 1657 | struct usb_audio_term *term, |
1507 | bool is_input, char *name, int name_size) | 1658 | bool is_input, char *name, int name_size) |
1508 | { | 1659 | { |
1509 | int name_len = get_term_name(state, term, name, name_size, 0); | 1660 | int name_len = get_term_name(state->chip, term, name, name_size, 0); |
1510 | 1661 | ||
1511 | if (name_len == 0) | 1662 | if (name_len == 0) |
1512 | strlcpy(name, "Unknown", name_size); | 1663 | strlcpy(name, "Unknown", name_size); |
@@ -1534,17 +1685,25 @@ static void build_connector_control(struct mixer_build *state, | |||
1534 | return; | 1685 | return; |
1535 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id); | 1686 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id); |
1536 | /* | 1687 | /* |
1537 | * The first byte from reading the UAC2_TE_CONNECTOR control returns the | 1688 | * UAC2: The first byte from reading the UAC2_TE_CONNECTOR control returns the |
1538 | * number of channels connected. This boolean ctl will simply report | 1689 | * number of channels connected. |
1539 | * if any channels are connected or not. | 1690 | * |
1540 | * (Audio20_final.pdf Table 5-10: Connector Control CUR Parameter Block) | 1691 | * UAC3: The first byte specifies size of bitmap for the inserted controls. The |
1692 | * following byte(s) specifies which connectors are inserted. | ||
1693 | * | ||
1694 | * This boolean ctl will simply report if any channels are connected | ||
1695 | * or not. | ||
1541 | */ | 1696 | */ |
1542 | cval->control = UAC2_TE_CONNECTOR; | 1697 | if (state->mixer->protocol == UAC_VERSION_2) |
1698 | cval->control = UAC2_TE_CONNECTOR; | ||
1699 | else /* UAC_VERSION_3 */ | ||
1700 | cval->control = UAC3_TE_INSERTION; | ||
1701 | |||
1543 | cval->val_type = USB_MIXER_BOOLEAN; | 1702 | cval->val_type = USB_MIXER_BOOLEAN; |
1544 | cval->channels = 1; /* report true if any channel is connected */ | 1703 | cval->channels = 1; /* report true if any channel is connected */ |
1545 | cval->min = 0; | 1704 | cval->min = 0; |
1546 | cval->max = 1; | 1705 | cval->max = 1; |
1547 | kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval); | 1706 | kctl = snd_ctl_new1(&usb_connector_ctl_ro, cval); |
1548 | if (!kctl) { | 1707 | if (!kctl) { |
1549 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | 1708 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); |
1550 | kfree(cval); | 1709 | kfree(cval); |
@@ -1605,7 +1764,7 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid, | |||
1605 | } | 1764 | } |
1606 | 1765 | ||
1607 | kctl->private_free = snd_usb_mixer_elem_free; | 1766 | kctl->private_free = snd_usb_mixer_elem_free; |
1608 | ret = snd_usb_copy_string_desc(state, hdr->iClockSource, | 1767 | ret = snd_usb_copy_string_desc(state->chip, hdr->iClockSource, |
1609 | name, sizeof(name)); | 1768 | name, sizeof(name)); |
1610 | if (ret > 0) | 1769 | if (ret > 0) |
1611 | snprintf(kctl->id.name, sizeof(kctl->id.name), | 1770 | snprintf(kctl->id.name, sizeof(kctl->id.name), |
@@ -1692,7 +1851,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1692 | } | 1851 | } |
1693 | 1852 | ||
1694 | /* parse the source unit */ | 1853 | /* parse the source unit */ |
1695 | if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0) | 1854 | err = parse_audio_unit(state, hdr->bSourceID); |
1855 | if (err < 0) | ||
1696 | return err; | 1856 | return err; |
1697 | 1857 | ||
1698 | /* determine the input source type and name */ | 1858 | /* determine the input source type and name */ |
@@ -1806,16 +1966,15 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1806 | */ | 1966 | */ |
1807 | static void build_mixer_unit_ctl(struct mixer_build *state, | 1967 | static void build_mixer_unit_ctl(struct mixer_build *state, |
1808 | struct uac_mixer_unit_descriptor *desc, | 1968 | struct uac_mixer_unit_descriptor *desc, |
1809 | int in_pin, int in_ch, int unitid, | 1969 | int in_pin, int in_ch, int num_outs, |
1810 | struct usb_audio_term *iterm) | 1970 | int unitid, struct usb_audio_term *iterm) |
1811 | { | 1971 | { |
1812 | struct usb_mixer_elem_info *cval; | 1972 | struct usb_mixer_elem_info *cval; |
1813 | unsigned int num_outs = uac_mixer_unit_bNrChannels(desc); | ||
1814 | unsigned int i, len; | 1973 | unsigned int i, len; |
1815 | struct snd_kcontrol *kctl; | 1974 | struct snd_kcontrol *kctl; |
1816 | const struct usbmix_name_map *map; | 1975 | const struct usbmix_name_map *map; |
1817 | 1976 | ||
1818 | map = find_map(state, unitid, 0); | 1977 | map = find_map(state->map, unitid, 0); |
1819 | if (check_ignored_ctl(map)) | 1978 | if (check_ignored_ctl(map)) |
1820 | return; | 1979 | return; |
1821 | 1980 | ||
@@ -1848,7 +2007,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1848 | 2007 | ||
1849 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); | 2008 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
1850 | if (!len) | 2009 | if (!len) |
1851 | len = get_term_name(state, iterm, kctl->id.name, | 2010 | len = get_term_name(state->chip, iterm, kctl->id.name, |
1852 | sizeof(kctl->id.name), 0); | 2011 | sizeof(kctl->id.name), 0); |
1853 | if (!len) | 2012 | if (!len) |
1854 | len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1); | 2013 | len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1); |
@@ -1863,16 +2022,28 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid, | |||
1863 | void *raw_desc) | 2022 | void *raw_desc) |
1864 | { | 2023 | { |
1865 | struct usb_audio_term iterm; | 2024 | struct usb_audio_term iterm; |
1866 | struct uac2_input_terminal_descriptor *d = raw_desc; | 2025 | unsigned int control, bmctls, term_id; |
1867 | 2026 | ||
1868 | check_input_term(state, d->bTerminalID, &iterm); | ||
1869 | if (state->mixer->protocol == UAC_VERSION_2) { | 2027 | if (state->mixer->protocol == UAC_VERSION_2) { |
1870 | /* Check for jack detection. */ | 2028 | struct uac2_input_terminal_descriptor *d_v2 = raw_desc; |
1871 | if (uac_v2v3_control_is_readable(le16_to_cpu(d->bmControls), | 2029 | control = UAC2_TE_CONNECTOR; |
1872 | UAC2_TE_CONNECTOR)) { | 2030 | term_id = d_v2->bTerminalID; |
1873 | build_connector_control(state, &iterm, true); | 2031 | bmctls = le16_to_cpu(d_v2->bmControls); |
1874 | } | 2032 | } else if (state->mixer->protocol == UAC_VERSION_3) { |
2033 | struct uac3_input_terminal_descriptor *d_v3 = raw_desc; | ||
2034 | control = UAC3_TE_INSERTION; | ||
2035 | term_id = d_v3->bTerminalID; | ||
2036 | bmctls = le32_to_cpu(d_v3->bmControls); | ||
2037 | } else { | ||
2038 | return 0; /* UAC1. No Insertion control */ | ||
1875 | } | 2039 | } |
2040 | |||
2041 | check_input_term(state, term_id, &iterm); | ||
2042 | |||
2043 | /* Check for jack detection. */ | ||
2044 | if (uac_v2v3_control_is_readable(bmctls, control)) | ||
2045 | build_connector_control(state, &iterm, true); | ||
2046 | |||
1876 | return 0; | 2047 | return 0; |
1877 | } | 2048 | } |
1878 | 2049 | ||
@@ -1887,14 +2058,17 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, | |||
1887 | int input_pins, num_ins, num_outs; | 2058 | int input_pins, num_ins, num_outs; |
1888 | int pin, ich, err; | 2059 | int pin, ich, err; |
1889 | 2060 | ||
1890 | if (desc->bLength < 11 || !(input_pins = desc->bNrInPins) || | 2061 | err = uac_mixer_unit_get_channels(state, desc); |
1891 | !(num_outs = uac_mixer_unit_bNrChannels(desc))) { | 2062 | if (err < 0) { |
1892 | usb_audio_err(state->chip, | 2063 | usb_audio_err(state->chip, |
1893 | "invalid MIXER UNIT descriptor %d\n", | 2064 | "invalid MIXER UNIT descriptor %d\n", |
1894 | unitid); | 2065 | unitid); |
1895 | return -EINVAL; | 2066 | return err; |
1896 | } | 2067 | } |
1897 | 2068 | ||
2069 | num_outs = err; | ||
2070 | input_pins = desc->bNrInPins; | ||
2071 | |||
1898 | num_ins = 0; | 2072 | num_ins = 0; |
1899 | ich = 0; | 2073 | ich = 0; |
1900 | for (pin = 0; pin < input_pins; pin++) { | 2074 | for (pin = 0; pin < input_pins; pin++) { |
@@ -1921,7 +2095,7 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, | |||
1921 | } | 2095 | } |
1922 | } | 2096 | } |
1923 | if (ich_has_controls) | 2097 | if (ich_has_controls) |
1924 | build_mixer_unit_ctl(state, desc, pin, ich, | 2098 | build_mixer_unit_ctl(state, desc, pin, ich, num_outs, |
1925 | unitid, &iterm); | 2099 | unitid, &iterm); |
1926 | } | 2100 | } |
1927 | } | 2101 | } |
@@ -2098,7 +2272,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, | |||
2098 | } | 2272 | } |
2099 | 2273 | ||
2100 | for (i = 0; i < num_ins; i++) { | 2274 | for (i = 0; i < num_ins; i++) { |
2101 | if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0) | 2275 | err = parse_audio_unit(state, desc->baSourceID[i]); |
2276 | if (err < 0) | ||
2102 | return err; | 2277 | return err; |
2103 | } | 2278 | } |
2104 | 2279 | ||
@@ -2114,7 +2289,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, | |||
2114 | 2289 | ||
2115 | if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1)))) | 2290 | if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1)))) |
2116 | continue; | 2291 | continue; |
2117 | map = find_map(state, unitid, valinfo->control); | 2292 | map = find_map(state->map, unitid, valinfo->control); |
2118 | if (check_ignored_ctl(map)) | 2293 | if (check_ignored_ctl(map)) |
2119 | continue; | 2294 | continue; |
2120 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 2295 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
@@ -2162,7 +2337,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, | |||
2162 | nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol); | 2337 | nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol); |
2163 | len = 0; | 2338 | len = 0; |
2164 | if (nameid) | 2339 | if (nameid) |
2165 | len = snd_usb_copy_string_desc(state, nameid, | 2340 | len = snd_usb_copy_string_desc(state->chip, |
2341 | nameid, | ||
2166 | kctl->id.name, | 2342 | kctl->id.name, |
2167 | sizeof(kctl->id.name)); | 2343 | sizeof(kctl->id.name)); |
2168 | if (!len) | 2344 | if (!len) |
@@ -2310,14 +2486,15 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, | |||
2310 | } | 2486 | } |
2311 | 2487 | ||
2312 | for (i = 0; i < desc->bNrInPins; i++) { | 2488 | for (i = 0; i < desc->bNrInPins; i++) { |
2313 | if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0) | 2489 | err = parse_audio_unit(state, desc->baSourceID[i]); |
2490 | if (err < 0) | ||
2314 | return err; | 2491 | return err; |
2315 | } | 2492 | } |
2316 | 2493 | ||
2317 | if (desc->bNrInPins == 1) /* only one ? nonsense! */ | 2494 | if (desc->bNrInPins == 1) /* only one ? nonsense! */ |
2318 | return 0; | 2495 | return 0; |
2319 | 2496 | ||
2320 | map = find_map(state, unitid, 0); | 2497 | map = find_map(state->map, unitid, 0); |
2321 | if (check_ignored_ctl(map)) | 2498 | if (check_ignored_ctl(map)) |
2322 | return 0; | 2499 | return 0; |
2323 | 2500 | ||
@@ -2358,7 +2535,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, | |||
2358 | len = check_mapped_selector_name(state, unitid, i, namelist[i], | 2535 | len = check_mapped_selector_name(state, unitid, i, namelist[i], |
2359 | MAX_ITEM_NAME_LEN); | 2536 | MAX_ITEM_NAME_LEN); |
2360 | if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0) | 2537 | if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0) |
2361 | len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); | 2538 | len = get_term_name(state->chip, &iterm, namelist[i], |
2539 | MAX_ITEM_NAME_LEN, 0); | ||
2362 | if (! len) | 2540 | if (! len) |
2363 | sprintf(namelist[i], "Input %u", i); | 2541 | sprintf(namelist[i], "Input %u", i); |
2364 | } | 2542 | } |
@@ -2380,12 +2558,12 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, | |||
2380 | /* if iSelector is given, use it */ | 2558 | /* if iSelector is given, use it */ |
2381 | nameid = uac_selector_unit_iSelector(desc); | 2559 | nameid = uac_selector_unit_iSelector(desc); |
2382 | if (nameid) | 2560 | if (nameid) |
2383 | len = snd_usb_copy_string_desc(state, nameid, | 2561 | len = snd_usb_copy_string_desc(state->chip, nameid, |
2384 | kctl->id.name, | 2562 | kctl->id.name, |
2385 | sizeof(kctl->id.name)); | 2563 | sizeof(kctl->id.name)); |
2386 | /* ... or pick up the terminal name at next */ | 2564 | /* ... or pick up the terminal name at next */ |
2387 | if (!len) | 2565 | if (!len) |
2388 | len = get_term_name(state, &state->oterm, | 2566 | len = get_term_name(state->chip, &state->oterm, |
2389 | kctl->id.name, sizeof(kctl->id.name), 0); | 2567 | kctl->id.name, sizeof(kctl->id.name), 0); |
2390 | /* ... or use the fixed string "USB" as the last resort */ | 2568 | /* ... or use the fixed string "USB" as the last resort */ |
2391 | if (!len) | 2569 | if (!len) |
@@ -2458,7 +2636,7 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) | |||
2458 | } else { /* UAC_VERSION_3 */ | 2636 | } else { /* UAC_VERSION_3 */ |
2459 | switch (p1[2]) { | 2637 | switch (p1[2]) { |
2460 | case UAC_INPUT_TERMINAL: | 2638 | case UAC_INPUT_TERMINAL: |
2461 | return 0; /* NOP */ | 2639 | return parse_audio_input_terminal(state, unitid, p1); |
2462 | case UAC3_MIXER_UNIT: | 2640 | case UAC3_MIXER_UNIT: |
2463 | return parse_audio_mixer_unit(state, unitid, p1); | 2641 | return parse_audio_mixer_unit(state, unitid, p1); |
2464 | case UAC3_CLOCK_SOURCE: | 2642 | case UAC3_CLOCK_SOURCE: |
@@ -2503,6 +2681,246 @@ static int snd_usb_mixer_dev_free(struct snd_device *device) | |||
2503 | return 0; | 2681 | return 0; |
2504 | } | 2682 | } |
2505 | 2683 | ||
2684 | /* UAC3 predefined channels configuration */ | ||
2685 | struct uac3_badd_profile { | ||
2686 | int subclass; | ||
2687 | const char *name; | ||
2688 | int c_chmask; /* capture channels mask */ | ||
2689 | int p_chmask; /* playback channels mask */ | ||
2690 | int st_chmask; /* side tone mixing channel mask */ | ||
2691 | }; | ||
2692 | |||
2693 | static struct uac3_badd_profile uac3_badd_profiles[] = { | ||
2694 | { | ||
2695 | /* | ||
2696 | * BAIF, BAOF or combination of both | ||
2697 | * IN: Mono or Stereo cfg, Mono alt possible | ||
2698 | * OUT: Mono or Stereo cfg, Mono alt possible | ||
2699 | */ | ||
2700 | .subclass = UAC3_FUNCTION_SUBCLASS_GENERIC_IO, | ||
2701 | .name = "GENERIC IO", | ||
2702 | .c_chmask = -1, /* dynamic channels */ | ||
2703 | .p_chmask = -1, /* dynamic channels */ | ||
2704 | }, | ||
2705 | { | ||
2706 | /* BAOF; Stereo only cfg, Mono alt possible */ | ||
2707 | .subclass = UAC3_FUNCTION_SUBCLASS_HEADPHONE, | ||
2708 | .name = "HEADPHONE", | ||
2709 | .p_chmask = 3, | ||
2710 | }, | ||
2711 | { | ||
2712 | /* BAOF; Mono or Stereo cfg, Mono alt possible */ | ||
2713 | .subclass = UAC3_FUNCTION_SUBCLASS_SPEAKER, | ||
2714 | .name = "SPEAKER", | ||
2715 | .p_chmask = -1, /* dynamic channels */ | ||
2716 | }, | ||
2717 | { | ||
2718 | /* BAIF; Mono or Stereo cfg, Mono alt possible */ | ||
2719 | .subclass = UAC3_FUNCTION_SUBCLASS_MICROPHONE, | ||
2720 | .name = "MICROPHONE", | ||
2721 | .c_chmask = -1, /* dynamic channels */ | ||
2722 | }, | ||
2723 | { | ||
2724 | /* | ||
2725 | * BAIOF topology | ||
2726 | * IN: Mono only | ||
2727 | * OUT: Mono or Stereo cfg, Mono alt possible | ||
2728 | */ | ||
2729 | .subclass = UAC3_FUNCTION_SUBCLASS_HEADSET, | ||
2730 | .name = "HEADSET", | ||
2731 | .c_chmask = 1, | ||
2732 | .p_chmask = -1, /* dynamic channels */ | ||
2733 | .st_chmask = 1, | ||
2734 | }, | ||
2735 | { | ||
2736 | /* BAIOF; IN: Mono only; OUT: Stereo only, Mono alt possible */ | ||
2737 | .subclass = UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER, | ||
2738 | .name = "HEADSET ADAPTER", | ||
2739 | .c_chmask = 1, | ||
2740 | .p_chmask = 3, | ||
2741 | .st_chmask = 1, | ||
2742 | }, | ||
2743 | { | ||
2744 | /* BAIF + BAOF; IN: Mono only; OUT: Mono only */ | ||
2745 | .subclass = UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE, | ||
2746 | .name = "SPEAKERPHONE", | ||
2747 | .c_chmask = 1, | ||
2748 | .p_chmask = 1, | ||
2749 | }, | ||
2750 | { 0 } /* terminator */ | ||
2751 | }; | ||
2752 | |||
2753 | static bool uac3_badd_func_has_valid_channels(struct usb_mixer_interface *mixer, | ||
2754 | struct uac3_badd_profile *f, | ||
2755 | int c_chmask, int p_chmask) | ||
2756 | { | ||
2757 | /* | ||
2758 | * If both playback/capture channels are dynamic, make sure | ||
2759 | * at least one channel is present | ||
2760 | */ | ||
2761 | if (f->c_chmask < 0 && f->p_chmask < 0) { | ||
2762 | if (!c_chmask && !p_chmask) { | ||
2763 | usb_audio_warn(mixer->chip, "BAAD %s: no channels?", | ||
2764 | f->name); | ||
2765 | return false; | ||
2766 | } | ||
2767 | return true; | ||
2768 | } | ||
2769 | |||
2770 | if ((f->c_chmask < 0 && !c_chmask) || | ||
2771 | (f->c_chmask >= 0 && f->c_chmask != c_chmask)) { | ||
2772 | usb_audio_warn(mixer->chip, "BAAD %s c_chmask mismatch", | ||
2773 | f->name); | ||
2774 | return false; | ||
2775 | } | ||
2776 | if ((f->p_chmask < 0 && !p_chmask) || | ||
2777 | (f->p_chmask >= 0 && f->p_chmask != p_chmask)) { | ||
2778 | usb_audio_warn(mixer->chip, "BAAD %s p_chmask mismatch", | ||
2779 | f->name); | ||
2780 | return false; | ||
2781 | } | ||
2782 | return true; | ||
2783 | } | ||
2784 | |||
2785 | /* | ||
2786 | * create mixer controls for UAC3 BADD profiles | ||
2787 | * | ||
2788 | * UAC3 BADD device doesn't contain CS descriptors thus we will guess everything | ||
2789 | * | ||
2790 | * BADD device may contain Mixer Unit, which doesn't have any controls, skip it | ||
2791 | */ | ||
2792 | static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer, | ||
2793 | int ctrlif) | ||
2794 | { | ||
2795 | struct usb_device *dev = mixer->chip->dev; | ||
2796 | struct usb_interface_assoc_descriptor *assoc; | ||
2797 | int badd_profile = mixer->chip->badd_profile; | ||
2798 | struct uac3_badd_profile *f; | ||
2799 | const struct usbmix_ctl_map *map; | ||
2800 | int p_chmask = 0, c_chmask = 0, st_chmask = 0; | ||
2801 | int i; | ||
2802 | |||
2803 | assoc = usb_ifnum_to_if(dev, ctrlif)->intf_assoc; | ||
2804 | |||
2805 | /* Detect BADD capture/playback channels from AS EP descriptors */ | ||
2806 | for (i = 0; i < assoc->bInterfaceCount; i++) { | ||
2807 | int intf = assoc->bFirstInterface + i; | ||
2808 | |||
2809 | struct usb_interface *iface; | ||
2810 | struct usb_host_interface *alts; | ||
2811 | struct usb_interface_descriptor *altsd; | ||
2812 | unsigned int maxpacksize; | ||
2813 | char dir_in; | ||
2814 | int chmask, num; | ||
2815 | |||
2816 | if (intf == ctrlif) | ||
2817 | continue; | ||
2818 | |||
2819 | iface = usb_ifnum_to_if(dev, intf); | ||
2820 | num = iface->num_altsetting; | ||
2821 | |||
2822 | if (num < 2) | ||
2823 | return -EINVAL; | ||
2824 | |||
2825 | /* | ||
2826 | * The number of Channels in an AudioStreaming interface | ||
2827 | * and the audio sample bit resolution (16 bits or 24 | ||
2828 | * bits) can be derived from the wMaxPacketSize field in | ||
2829 | * the Standard AS Audio Data Endpoint descriptor in | ||
2830 | * Alternate Setting 1 | ||
2831 | */ | ||
2832 | alts = &iface->altsetting[1]; | ||
2833 | altsd = get_iface_desc(alts); | ||
2834 | |||
2835 | if (altsd->bNumEndpoints < 1) | ||
2836 | return -EINVAL; | ||
2837 | |||
2838 | /* check direction */ | ||
2839 | dir_in = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN); | ||
2840 | maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
2841 | |||
2842 | switch (maxpacksize) { | ||
2843 | default: | ||
2844 | usb_audio_err(mixer->chip, | ||
2845 | "incorrect wMaxPacketSize 0x%x for BADD profile\n", | ||
2846 | maxpacksize); | ||
2847 | return -EINVAL; | ||
2848 | case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16: | ||
2849 | case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16: | ||
2850 | case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24: | ||
2851 | case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24: | ||
2852 | chmask = 1; | ||
2853 | break; | ||
2854 | case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16: | ||
2855 | case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16: | ||
2856 | case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24: | ||
2857 | case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24: | ||
2858 | chmask = 3; | ||
2859 | break; | ||
2860 | } | ||
2861 | |||
2862 | if (dir_in) | ||
2863 | c_chmask = chmask; | ||
2864 | else | ||
2865 | p_chmask = chmask; | ||
2866 | } | ||
2867 | |||
2868 | usb_audio_dbg(mixer->chip, | ||
2869 | "UAC3 BADD profile 0x%x: detected c_chmask=%d p_chmask=%d\n", | ||
2870 | badd_profile, c_chmask, p_chmask); | ||
2871 | |||
2872 | /* check the mapping table */ | ||
2873 | for (map = uac3_badd_usbmix_ctl_maps; map->id; map++) { | ||
2874 | if (map->id == badd_profile) | ||
2875 | break; | ||
2876 | } | ||
2877 | |||
2878 | if (!map->id) | ||
2879 | return -EINVAL; | ||
2880 | |||
2881 | for (f = uac3_badd_profiles; f->name; f++) { | ||
2882 | if (badd_profile == f->subclass) | ||
2883 | break; | ||
2884 | } | ||
2885 | if (!f->name) | ||
2886 | return -EINVAL; | ||
2887 | if (!uac3_badd_func_has_valid_channels(mixer, f, c_chmask, p_chmask)) | ||
2888 | return -EINVAL; | ||
2889 | st_chmask = f->st_chmask; | ||
2890 | |||
2891 | /* Playback */ | ||
2892 | if (p_chmask) { | ||
2893 | /* Master channel, always writable */ | ||
2894 | build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE, | ||
2895 | UAC3_BADD_FU_ID2, map->map); | ||
2896 | /* Mono/Stereo volume channels, always writable */ | ||
2897 | build_feature_ctl_badd(mixer, p_chmask, UAC_FU_VOLUME, | ||
2898 | UAC3_BADD_FU_ID2, map->map); | ||
2899 | } | ||
2900 | |||
2901 | /* Capture */ | ||
2902 | if (c_chmask) { | ||
2903 | /* Master channel, always writable */ | ||
2904 | build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE, | ||
2905 | UAC3_BADD_FU_ID5, map->map); | ||
2906 | /* Mono/Stereo volume channels, always writable */ | ||
2907 | build_feature_ctl_badd(mixer, c_chmask, UAC_FU_VOLUME, | ||
2908 | UAC3_BADD_FU_ID5, map->map); | ||
2909 | } | ||
2910 | |||
2911 | /* Side tone-mixing */ | ||
2912 | if (st_chmask) { | ||
2913 | /* Master channel, always writable */ | ||
2914 | build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE, | ||
2915 | UAC3_BADD_FU_ID7, map->map); | ||
2916 | /* Mono volume channel, always writable */ | ||
2917 | build_feature_ctl_badd(mixer, 1, UAC_FU_VOLUME, | ||
2918 | UAC3_BADD_FU_ID7, map->map); | ||
2919 | } | ||
2920 | |||
2921 | return 0; | ||
2922 | } | ||
2923 | |||
2506 | /* | 2924 | /* |
2507 | * create mixer controls | 2925 | * create mixer controls |
2508 | * | 2926 | * |
@@ -2596,6 +3014,12 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2596 | err = parse_audio_unit(&state, desc->bCSourceID); | 3014 | err = parse_audio_unit(&state, desc->bCSourceID); |
2597 | if (err < 0 && err != -EINVAL) | 3015 | if (err < 0 && err != -EINVAL) |
2598 | return err; | 3016 | return err; |
3017 | |||
3018 | if (uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls), | ||
3019 | UAC3_TE_INSERTION)) { | ||
3020 | build_connector_control(&state, &state.oterm, | ||
3021 | false); | ||
3022 | } | ||
2599 | } | 3023 | } |
2600 | } | 3024 | } |
2601 | 3025 | ||
@@ -2606,9 +3030,9 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid) | |||
2606 | { | 3030 | { |
2607 | struct usb_mixer_elem_list *list; | 3031 | struct usb_mixer_elem_list *list; |
2608 | 3032 | ||
2609 | for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) { | 3033 | for_each_mixer_elem(list, mixer, unitid) { |
2610 | struct usb_mixer_elem_info *info = | 3034 | struct usb_mixer_elem_info *info = |
2611 | (struct usb_mixer_elem_info *)list; | 3035 | mixer_elem_list_to_info(list); |
2612 | /* invalidate cache, so the value is read from the device */ | 3036 | /* invalidate cache, so the value is read from the device */ |
2613 | info->cached = 0; | 3037 | info->cached = 0; |
2614 | snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, | 3038 | snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, |
@@ -2619,7 +3043,7 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid) | |||
2619 | static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, | 3043 | static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, |
2620 | struct usb_mixer_elem_list *list) | 3044 | struct usb_mixer_elem_list *list) |
2621 | { | 3045 | { |
2622 | struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list; | 3046 | struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list); |
2623 | static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN", | 3047 | static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN", |
2624 | "S8", "U8", "S16", "U16"}; | 3048 | "S8", "U8", "S16", "U16"}; |
2625 | snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, " | 3049 | snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, " |
@@ -2645,8 +3069,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, | |||
2645 | mixer->ignore_ctl_error); | 3069 | mixer->ignore_ctl_error); |
2646 | snd_iprintf(buffer, "Card: %s\n", chip->card->longname); | 3070 | snd_iprintf(buffer, "Card: %s\n", chip->card->longname); |
2647 | for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { | 3071 | for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { |
2648 | for (list = mixer->id_elems[unitid]; list; | 3072 | for_each_mixer_elem(list, mixer, unitid) { |
2649 | list = list->next_id_elem) { | ||
2650 | snd_iprintf(buffer, " Unit: %i\n", list->id); | 3073 | snd_iprintf(buffer, " Unit: %i\n", list->id); |
2651 | if (list->kctl) | 3074 | if (list->kctl) |
2652 | snd_iprintf(buffer, | 3075 | snd_iprintf(buffer, |
@@ -2676,19 +3099,19 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer, | |||
2676 | return; | 3099 | return; |
2677 | } | 3100 | } |
2678 | 3101 | ||
2679 | for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) | 3102 | for_each_mixer_elem(list, mixer, unitid) |
2680 | count++; | 3103 | count++; |
2681 | 3104 | ||
2682 | if (count == 0) | 3105 | if (count == 0) |
2683 | return; | 3106 | return; |
2684 | 3107 | ||
2685 | for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) { | 3108 | for_each_mixer_elem(list, mixer, unitid) { |
2686 | struct usb_mixer_elem_info *info; | 3109 | struct usb_mixer_elem_info *info; |
2687 | 3110 | ||
2688 | if (!list->kctl) | 3111 | if (!list->kctl) |
2689 | continue; | 3112 | continue; |
2690 | 3113 | ||
2691 | info = (struct usb_mixer_elem_info *)list; | 3114 | info = mixer_elem_list_to_info(list); |
2692 | if (count > 1 && info->control != control) | 3115 | if (count > 1 && info->control != control) |
2693 | continue; | 3116 | continue; |
2694 | 3117 | ||
@@ -2809,6 +3232,48 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) | |||
2809 | return 0; | 3232 | return 0; |
2810 | } | 3233 | } |
2811 | 3234 | ||
3235 | static int keep_iface_ctl_get(struct snd_kcontrol *kcontrol, | ||
3236 | struct snd_ctl_elem_value *ucontrol) | ||
3237 | { | ||
3238 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | ||
3239 | |||
3240 | ucontrol->value.integer.value[0] = mixer->chip->keep_iface; | ||
3241 | return 0; | ||
3242 | } | ||
3243 | |||
3244 | static int keep_iface_ctl_put(struct snd_kcontrol *kcontrol, | ||
3245 | struct snd_ctl_elem_value *ucontrol) | ||
3246 | { | ||
3247 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | ||
3248 | bool keep_iface = !!ucontrol->value.integer.value[0]; | ||
3249 | |||
3250 | if (mixer->chip->keep_iface == keep_iface) | ||
3251 | return 0; | ||
3252 | mixer->chip->keep_iface = keep_iface; | ||
3253 | return 1; | ||
3254 | } | ||
3255 | |||
3256 | static const struct snd_kcontrol_new keep_iface_ctl = { | ||
3257 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
3258 | .name = "Keep Interface", | ||
3259 | .info = snd_ctl_boolean_mono_info, | ||
3260 | .get = keep_iface_ctl_get, | ||
3261 | .put = keep_iface_ctl_put, | ||
3262 | }; | ||
3263 | |||
3264 | static int create_keep_iface_ctl(struct usb_mixer_interface *mixer) | ||
3265 | { | ||
3266 | struct snd_kcontrol *kctl = snd_ctl_new1(&keep_iface_ctl, mixer); | ||
3267 | |||
3268 | /* need only one control per card */ | ||
3269 | if (snd_ctl_find_id(mixer->chip->card, &kctl->id)) { | ||
3270 | snd_ctl_free_one(kctl); | ||
3271 | return 0; | ||
3272 | } | ||
3273 | |||
3274 | return snd_ctl_add(mixer->chip->card, kctl); | ||
3275 | } | ||
3276 | |||
2812 | int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | 3277 | int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, |
2813 | int ignore_error) | 3278 | int ignore_error) |
2814 | { | 3279 | { |
@@ -2847,8 +3312,21 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2847 | break; | 3312 | break; |
2848 | } | 3313 | } |
2849 | 3314 | ||
2850 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || | 3315 | if (mixer->protocol == UAC_VERSION_3 && |
2851 | (err = snd_usb_mixer_status_create(mixer)) < 0) | 3316 | chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) { |
3317 | err = snd_usb_mixer_controls_badd(mixer, ctrlif); | ||
3318 | if (err < 0) | ||
3319 | goto _error; | ||
3320 | } else { | ||
3321 | err = snd_usb_mixer_controls(mixer); | ||
3322 | if (err < 0) | ||
3323 | goto _error; | ||
3324 | err = snd_usb_mixer_status_create(mixer); | ||
3325 | if (err < 0) | ||
3326 | goto _error; | ||
3327 | } | ||
3328 | err = create_keep_iface_ctl(mixer); | ||
3329 | if (err < 0) | ||
2852 | goto _error; | 3330 | goto _error; |
2853 | 3331 | ||
2854 | snd_usb_mixer_apply_create_quirk(mixer); | 3332 | snd_usb_mixer_apply_create_quirk(mixer); |
@@ -2909,7 +3387,7 @@ int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer) | |||
2909 | 3387 | ||
2910 | static int restore_mixer_value(struct usb_mixer_elem_list *list) | 3388 | static int restore_mixer_value(struct usb_mixer_elem_list *list) |
2911 | { | 3389 | { |
2912 | struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list; | 3390 | struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list); |
2913 | int c, err, idx; | 3391 | int c, err, idx; |
2914 | 3392 | ||
2915 | if (cval->cmask) { | 3393 | if (cval->cmask) { |
@@ -2945,8 +3423,7 @@ int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume) | |||
2945 | if (reset_resume) { | 3423 | if (reset_resume) { |
2946 | /* restore cached mixer values */ | 3424 | /* restore cached mixer values */ |
2947 | for (id = 0; id < MAX_ID_ELEMS; id++) { | 3425 | for (id = 0; id < MAX_ID_ELEMS; id++) { |
2948 | for (list = mixer->id_elems[id]; list; | 3426 | for_each_mixer_elem(list, mixer, id) { |
2949 | list = list->next_id_elem) { | ||
2950 | if (list->resume) { | 3427 | if (list->resume) { |
2951 | err = list->resume(list); | 3428 | err = list->resume(list); |
2952 | if (err < 0) | 3429 | if (err < 0) |
@@ -2956,6 +3433,8 @@ int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume) | |||
2956 | } | 3433 | } |
2957 | } | 3434 | } |
2958 | 3435 | ||
3436 | snd_usb_mixer_resume_quirk(mixer); | ||
3437 | |||
2959 | return snd_usb_mixer_activate(mixer); | 3438 | return snd_usb_mixer_activate(mixer); |
2960 | } | 3439 | } |
2961 | #endif | 3440 | #endif |
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index ba27f7ade670..e02653465e29 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h | |||
@@ -53,6 +53,12 @@ struct usb_mixer_elem_list { | |||
53 | usb_mixer_elem_resume_func_t resume; | 53 | usb_mixer_elem_resume_func_t resume; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | /* iterate over mixer element list of the given unit id */ | ||
57 | #define for_each_mixer_elem(list, mixer, id) \ | ||
58 | for ((list) = (mixer)->id_elems[id]; (list); (list) = (list)->next_id_elem) | ||
59 | #define mixer_elem_list_to_info(list) \ | ||
60 | container_of(list, struct usb_mixer_elem_info, head) | ||
61 | |||
56 | struct usb_mixer_elem_info { | 62 | struct usb_mixer_elem_info { |
57 | struct usb_mixer_elem_list head; | 63 | struct usb_mixer_elem_list head; |
58 | unsigned int control; /* CS or ICN (high byte) */ | 64 | unsigned int control; /* CS or ICN (high byte) */ |
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index eaa03acd4686..71069e110897 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c | |||
@@ -485,3 +485,68 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { | |||
485 | { 0 } /* terminator */ | 485 | { 0 } /* terminator */ |
486 | }; | 486 | }; |
487 | 487 | ||
488 | /* | ||
489 | * Control map entries for UAC3 BADD profiles | ||
490 | */ | ||
491 | |||
492 | static struct usbmix_name_map uac3_badd_generic_io_map[] = { | ||
493 | { UAC3_BADD_FU_ID2, "Generic Out Playback" }, | ||
494 | { UAC3_BADD_FU_ID5, "Generic In Capture" }, | ||
495 | { 0 } /* terminator */ | ||
496 | }; | ||
497 | static struct usbmix_name_map uac3_badd_headphone_map[] = { | ||
498 | { UAC3_BADD_FU_ID2, "Headphone Playback" }, | ||
499 | { 0 } /* terminator */ | ||
500 | }; | ||
501 | static struct usbmix_name_map uac3_badd_speaker_map[] = { | ||
502 | { UAC3_BADD_FU_ID2, "Speaker Playback" }, | ||
503 | { 0 } /* terminator */ | ||
504 | }; | ||
505 | static struct usbmix_name_map uac3_badd_microphone_map[] = { | ||
506 | { UAC3_BADD_FU_ID5, "Mic Capture" }, | ||
507 | { 0 } /* terminator */ | ||
508 | }; | ||
509 | /* Covers also 'headset adapter' profile */ | ||
510 | static struct usbmix_name_map uac3_badd_headset_map[] = { | ||
511 | { UAC3_BADD_FU_ID2, "Headset Playback" }, | ||
512 | { UAC3_BADD_FU_ID5, "Headset Capture" }, | ||
513 | { UAC3_BADD_FU_ID7, "Sidetone Mixing" }, | ||
514 | { 0 } /* terminator */ | ||
515 | }; | ||
516 | static struct usbmix_name_map uac3_badd_speakerphone_map[] = { | ||
517 | { UAC3_BADD_FU_ID2, "Speaker Playback" }, | ||
518 | { UAC3_BADD_FU_ID5, "Mic Capture" }, | ||
519 | { 0 } /* terminator */ | ||
520 | }; | ||
521 | |||
522 | static struct usbmix_ctl_map uac3_badd_usbmix_ctl_maps[] = { | ||
523 | { | ||
524 | .id = UAC3_FUNCTION_SUBCLASS_GENERIC_IO, | ||
525 | .map = uac3_badd_generic_io_map, | ||
526 | }, | ||
527 | { | ||
528 | .id = UAC3_FUNCTION_SUBCLASS_HEADPHONE, | ||
529 | .map = uac3_badd_headphone_map, | ||
530 | }, | ||
531 | { | ||
532 | .id = UAC3_FUNCTION_SUBCLASS_SPEAKER, | ||
533 | .map = uac3_badd_speaker_map, | ||
534 | }, | ||
535 | { | ||
536 | .id = UAC3_FUNCTION_SUBCLASS_MICROPHONE, | ||
537 | .map = uac3_badd_microphone_map, | ||
538 | }, | ||
539 | { | ||
540 | .id = UAC3_FUNCTION_SUBCLASS_HEADSET, | ||
541 | .map = uac3_badd_headset_map, | ||
542 | }, | ||
543 | { | ||
544 | .id = UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER, | ||
545 | .map = uac3_badd_headset_map, | ||
546 | }, | ||
547 | { | ||
548 | .id = UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE, | ||
549 | .map = uac3_badd_speakerphone_map, | ||
550 | }, | ||
551 | { 0 } /* terminator */ | ||
552 | }; | ||
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 56537a156580..4149543f613e 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -1172,7 +1172,7 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | |||
1172 | int unitid = 12; /* SamleRate ExtensionUnit ID */ | 1172 | int unitid = 12; /* SamleRate ExtensionUnit ID */ |
1173 | 1173 | ||
1174 | list_for_each_entry(mixer, &chip->mixer_list, list) { | 1174 | list_for_each_entry(mixer, &chip->mixer_list, list) { |
1175 | cval = (struct usb_mixer_elem_info *)mixer->id_elems[unitid]; | 1175 | cval = mixer_elem_list_to_info(mixer->id_elems[unitid]); |
1176 | if (cval) { | 1176 | if (cval) { |
1177 | snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, | 1177 | snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, |
1178 | cval->control << 8, | 1178 | cval->control << 8, |
@@ -1799,12 +1799,33 @@ static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer) | |||
1799 | NULL); | 1799 | NULL); |
1800 | } | 1800 | } |
1801 | 1801 | ||
1802 | static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id) | ||
1803 | { | ||
1804 | u16 buf = 0; | ||
1805 | |||
1806 | snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, | ||
1807 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | ||
1808 | ch, snd_usb_ctrl_intf(chip) | (id << 8), | ||
1809 | &buf, 2); | ||
1810 | } | ||
1811 | |||
1812 | static int dell_dock_mixer_init(struct usb_mixer_interface *mixer) | ||
1813 | { | ||
1814 | /* fix to 0dB playback volumes */ | ||
1815 | dell_dock_init_vol(mixer->chip, 1, 16); | ||
1816 | dell_dock_init_vol(mixer->chip, 2, 16); | ||
1817 | dell_dock_init_vol(mixer->chip, 1, 19); | ||
1818 | dell_dock_init_vol(mixer->chip, 2, 19); | ||
1819 | return 0; | ||
1820 | } | ||
1821 | |||
1802 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | 1822 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) |
1803 | { | 1823 | { |
1804 | int err = 0; | 1824 | int err = 0; |
1805 | struct snd_info_entry *entry; | 1825 | struct snd_info_entry *entry; |
1806 | 1826 | ||
1807 | if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) | 1827 | err = snd_usb_soundblaster_remote_init(mixer); |
1828 | if (err < 0) | ||
1808 | return err; | 1829 | return err; |
1809 | 1830 | ||
1810 | switch (mixer->chip->usb_id) { | 1831 | switch (mixer->chip->usb_id) { |
@@ -1884,11 +1905,25 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
1884 | case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */ | 1905 | case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */ |
1885 | err = snd_soundblaster_e1_switch_create(mixer); | 1906 | err = snd_soundblaster_e1_switch_create(mixer); |
1886 | break; | 1907 | break; |
1908 | case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */ | ||
1909 | err = dell_dock_mixer_init(mixer); | ||
1910 | break; | ||
1887 | } | 1911 | } |
1888 | 1912 | ||
1889 | return err; | 1913 | return err; |
1890 | } | 1914 | } |
1891 | 1915 | ||
1916 | #ifdef CONFIG_PM | ||
1917 | void snd_usb_mixer_resume_quirk(struct usb_mixer_interface *mixer) | ||
1918 | { | ||
1919 | switch (mixer->chip->usb_id) { | ||
1920 | case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */ | ||
1921 | dell_dock_mixer_init(mixer); | ||
1922 | break; | ||
1923 | } | ||
1924 | } | ||
1925 | #endif | ||
1926 | |||
1892 | void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, | 1927 | void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, |
1893 | int unitid) | 1928 | int unitid) |
1894 | { | 1929 | { |
diff --git a/sound/usb/mixer_quirks.h b/sound/usb/mixer_quirks.h index b5abd328a361..52be26db558f 100644 --- a/sound/usb/mixer_quirks.h +++ b/sound/usb/mixer_quirks.h | |||
@@ -14,5 +14,9 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, | |||
14 | struct usb_mixer_elem_info *cval, int unitid, | 14 | struct usb_mixer_elem_info *cval, int unitid, |
15 | struct snd_kcontrol *kctl); | 15 | struct snd_kcontrol *kctl); |
16 | 16 | ||
17 | #ifdef CONFIG_PM | ||
18 | void snd_usb_mixer_resume_quirk(struct usb_mixer_interface *mixer); | ||
19 | #endif | ||
20 | |||
17 | #endif /* SND_USB_MIXER_QUIRKS_H */ | 21 | #endif /* SND_USB_MIXER_QUIRKS_H */ |
18 | 22 | ||
diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c index c33e2378089d..4aeb9488a0c9 100644 --- a/sound/usb/mixer_scarlett.c +++ b/sound/usb/mixer_scarlett.c | |||
@@ -287,8 +287,7 @@ static int scarlett_ctl_switch_put(struct snd_kcontrol *kctl, | |||
287 | 287 | ||
288 | static int scarlett_ctl_resume(struct usb_mixer_elem_list *list) | 288 | static int scarlett_ctl_resume(struct usb_mixer_elem_list *list) |
289 | { | 289 | { |
290 | struct usb_mixer_elem_info *elem = | 290 | struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list); |
291 | container_of(list, struct usb_mixer_elem_info, head); | ||
292 | int i; | 291 | int i; |
293 | 292 | ||
294 | for (i = 0; i < elem->channels; i++) | 293 | for (i = 0; i < elem->channels; i++) |
@@ -447,8 +446,7 @@ static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl, | |||
447 | 446 | ||
448 | static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list) | 447 | static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list) |
449 | { | 448 | { |
450 | struct usb_mixer_elem_info *elem = | 449 | struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list); |
451 | container_of(list, struct usb_mixer_elem_info, head); | ||
452 | 450 | ||
453 | if (elem->cached) | 451 | if (elem->cached) |
454 | snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val); | 452 | snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val); |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 3cbfae6604f9..78d1cad08a0a 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -76,10 +76,9 @@ snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs, | |||
76 | */ | 76 | */ |
77 | static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream) | 77 | static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream) |
78 | { | 78 | { |
79 | struct snd_usb_substream *subs; | 79 | struct snd_usb_substream *subs = substream->runtime->private_data; |
80 | unsigned int hwptr_done; | 80 | unsigned int hwptr_done; |
81 | 81 | ||
82 | subs = (struct snd_usb_substream *)substream->runtime->private_data; | ||
83 | if (atomic_read(&subs->stream->chip->shutdown)) | 82 | if (atomic_read(&subs->stream->chip->shutdown)) |
84 | return SNDRV_PCM_POS_XRUN; | 83 | return SNDRV_PCM_POS_XRUN; |
85 | spin_lock(&subs->lock); | 84 | spin_lock(&subs->lock); |
@@ -164,10 +163,11 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface, | |||
164 | ep = get_endpoint(alts, 0)->bEndpointAddress; | 163 | ep = get_endpoint(alts, 0)->bEndpointAddress; |
165 | 164 | ||
166 | data[0] = 1; | 165 | data[0] = 1; |
167 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | 166 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, |
168 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, | 167 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, |
169 | UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, | 168 | UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, |
170 | data, sizeof(data))) < 0) { | 169 | data, sizeof(data)); |
170 | if (err < 0) { | ||
171 | usb_audio_err(chip, "%d:%d: cannot set enable PITCH\n", | 171 | usb_audio_err(chip, "%d:%d: cannot set enable PITCH\n", |
172 | iface, ep); | 172 | iface, ep); |
173 | return err; | 173 | return err; |
@@ -185,10 +185,11 @@ static int init_pitch_v2(struct snd_usb_audio *chip, int iface, | |||
185 | int err; | 185 | int err; |
186 | 186 | ||
187 | data[0] = 1; | 187 | data[0] = 1; |
188 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | 188 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, |
189 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 189 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
190 | UAC2_EP_CS_PITCH << 8, 0, | 190 | UAC2_EP_CS_PITCH << 8, 0, |
191 | data, sizeof(data))) < 0) { | 191 | data, sizeof(data)); |
192 | if (err < 0) { | ||
192 | usb_audio_err(chip, "%d:%d: cannot set enable PITCH (v2)\n", | 193 | usb_audio_err(chip, "%d:%d: cannot set enable PITCH (v2)\n", |
193 | iface, fmt->altsetting); | 194 | iface, fmt->altsetting); |
194 | return err; | 195 | return err; |
@@ -321,6 +322,7 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs, | |||
321 | struct usb_host_interface *alts; | 322 | struct usb_host_interface *alts; |
322 | struct usb_interface *iface; | 323 | struct usb_interface *iface; |
323 | unsigned int ep; | 324 | unsigned int ep; |
325 | unsigned int ifnum; | ||
324 | 326 | ||
325 | /* Implicit feedback sync EPs consumers are always playback EPs */ | 327 | /* Implicit feedback sync EPs consumers are always playback EPs */ |
326 | if (subs->direction != SNDRV_PCM_STREAM_PLAYBACK) | 328 | if (subs->direction != SNDRV_PCM_STREAM_PLAYBACK) |
@@ -330,44 +332,27 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs, | |||
330 | case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ | 332 | case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ |
331 | case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */ | 333 | case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */ |
332 | ep = 0x81; | 334 | ep = 0x81; |
333 | iface = usb_ifnum_to_if(dev, 3); | 335 | ifnum = 3; |
334 | 336 | goto add_sync_ep_from_ifnum; | |
335 | if (!iface || iface->num_altsetting == 0) | ||
336 | return -EINVAL; | ||
337 | |||
338 | alts = &iface->altsetting[1]; | ||
339 | goto add_sync_ep; | ||
340 | break; | ||
341 | case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */ | 337 | case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */ |
342 | case USB_ID(0x0763, 0x2081): | 338 | case USB_ID(0x0763, 0x2081): |
343 | ep = 0x81; | 339 | ep = 0x81; |
344 | iface = usb_ifnum_to_if(dev, 2); | 340 | ifnum = 2; |
345 | 341 | goto add_sync_ep_from_ifnum; | |
346 | if (!iface || iface->num_altsetting == 0) | 342 | case USB_ID(0x2466, 0x8003): /* Fractal Audio Axe-Fx II */ |
347 | return -EINVAL; | ||
348 | |||
349 | alts = &iface->altsetting[1]; | ||
350 | goto add_sync_ep; | ||
351 | case USB_ID(0x2466, 0x8003): | ||
352 | ep = 0x86; | 343 | ep = 0x86; |
353 | iface = usb_ifnum_to_if(dev, 2); | 344 | ifnum = 2; |
354 | 345 | goto add_sync_ep_from_ifnum; | |
355 | if (!iface || iface->num_altsetting == 0) | 346 | case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx III */ |
356 | return -EINVAL; | ||
357 | |||
358 | alts = &iface->altsetting[1]; | ||
359 | goto add_sync_ep; | ||
360 | case USB_ID(0x1397, 0x0002): | ||
361 | ep = 0x81; | 347 | ep = 0x81; |
362 | iface = usb_ifnum_to_if(dev, 1); | 348 | ifnum = 2; |
363 | 349 | goto add_sync_ep_from_ifnum; | |
364 | if (!iface || iface->num_altsetting == 0) | 350 | case USB_ID(0x1397, 0x0002): /* Behringer UFX1204 */ |
365 | return -EINVAL; | 351 | ep = 0x81; |
366 | 352 | ifnum = 1; | |
367 | alts = &iface->altsetting[1]; | 353 | goto add_sync_ep_from_ifnum; |
368 | goto add_sync_ep; | ||
369 | |||
370 | } | 354 | } |
355 | |||
371 | if (attr == USB_ENDPOINT_SYNC_ASYNC && | 356 | if (attr == USB_ENDPOINT_SYNC_ASYNC && |
372 | altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && | 357 | altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && |
373 | altsd->bInterfaceProtocol == 2 && | 358 | altsd->bInterfaceProtocol == 2 && |
@@ -382,6 +367,14 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs, | |||
382 | /* No quirk */ | 367 | /* No quirk */ |
383 | return 0; | 368 | return 0; |
384 | 369 | ||
370 | add_sync_ep_from_ifnum: | ||
371 | iface = usb_ifnum_to_if(dev, ifnum); | ||
372 | |||
373 | if (!iface || iface->num_altsetting == 0) | ||
374 | return -EINVAL; | ||
375 | |||
376 | alts = &iface->altsetting[1]; | ||
377 | |||
385 | add_sync_ep: | 378 | add_sync_ep: |
386 | subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip, | 379 | subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip, |
387 | alts, ep, !subs->direction, | 380 | alts, ep, !subs->direction, |
@@ -507,7 +500,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
507 | iface = usb_ifnum_to_if(dev, fmt->iface); | 500 | iface = usb_ifnum_to_if(dev, fmt->iface); |
508 | if (WARN_ON(!iface)) | 501 | if (WARN_ON(!iface)) |
509 | return -EINVAL; | 502 | return -EINVAL; |
510 | alts = &iface->altsetting[fmt->altset_idx]; | 503 | alts = usb_altnum_to_altsetting(iface, fmt->altsetting); |
511 | altsd = get_iface_desc(alts); | 504 | altsd = get_iface_desc(alts); |
512 | if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting)) | 505 | if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting)) |
513 | return -EINVAL; | 506 | return -EINVAL; |
@@ -517,21 +510,21 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
517 | 510 | ||
518 | /* close the old interface */ | 511 | /* close the old interface */ |
519 | if (subs->interface >= 0 && subs->interface != fmt->iface) { | 512 | if (subs->interface >= 0 && subs->interface != fmt->iface) { |
520 | err = usb_set_interface(subs->dev, subs->interface, 0); | 513 | if (!subs->stream->chip->keep_iface) { |
521 | if (err < 0) { | 514 | err = usb_set_interface(subs->dev, subs->interface, 0); |
522 | dev_err(&dev->dev, | 515 | if (err < 0) { |
523 | "%d:%d: return to setting 0 failed (%d)\n", | 516 | dev_err(&dev->dev, |
524 | fmt->iface, fmt->altsetting, err); | 517 | "%d:%d: return to setting 0 failed (%d)\n", |
525 | return -EIO; | 518 | fmt->iface, fmt->altsetting, err); |
519 | return -EIO; | ||
520 | } | ||
526 | } | 521 | } |
527 | subs->interface = -1; | 522 | subs->interface = -1; |
528 | subs->altset_idx = 0; | 523 | subs->altset_idx = 0; |
529 | } | 524 | } |
530 | 525 | ||
531 | /* set interface */ | 526 | /* set interface */ |
532 | if (subs->interface != fmt->iface || | 527 | if (iface->cur_altsetting != alts) { |
533 | subs->altset_idx != fmt->altset_idx) { | ||
534 | |||
535 | err = snd_usb_select_mode_quirk(subs, fmt); | 528 | err = snd_usb_select_mode_quirk(subs, fmt); |
536 | if (err < 0) | 529 | if (err < 0) |
537 | return -EIO; | 530 | return -EIO; |
@@ -545,12 +538,11 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
545 | } | 538 | } |
546 | dev_dbg(&dev->dev, "setting usb interface %d:%d\n", | 539 | dev_dbg(&dev->dev, "setting usb interface %d:%d\n", |
547 | fmt->iface, fmt->altsetting); | 540 | fmt->iface, fmt->altsetting); |
548 | subs->interface = fmt->iface; | ||
549 | subs->altset_idx = fmt->altset_idx; | ||
550 | |||
551 | snd_usb_set_interface_quirk(dev); | 541 | snd_usb_set_interface_quirk(dev); |
552 | } | 542 | } |
553 | 543 | ||
544 | subs->interface = fmt->iface; | ||
545 | subs->altset_idx = fmt->altset_idx; | ||
554 | subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, | 546 | subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, |
555 | alts, fmt->endpoint, subs->direction, | 547 | alts, fmt->endpoint, subs->direction, |
556 | SND_USB_ENDPOINT_TYPE_DATA); | 548 | SND_USB_ENDPOINT_TYPE_DATA); |
@@ -736,7 +728,11 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
736 | struct audioformat *fmt; | 728 | struct audioformat *fmt; |
737 | int ret; | 729 | int ret; |
738 | 730 | ||
739 | ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, | 731 | if (snd_usb_use_vmalloc) |
732 | ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
733 | params_buffer_bytes(hw_params)); | ||
734 | else | ||
735 | ret = snd_pcm_lib_malloc_pages(substream, | ||
740 | params_buffer_bytes(hw_params)); | 736 | params_buffer_bytes(hw_params)); |
741 | if (ret < 0) | 737 | if (ret < 0) |
742 | return ret; | 738 | return ret; |
@@ -789,7 +785,11 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) | |||
789 | snd_usb_endpoint_deactivate(subs->data_endpoint); | 785 | snd_usb_endpoint_deactivate(subs->data_endpoint); |
790 | snd_usb_unlock_shutdown(subs->stream->chip); | 786 | snd_usb_unlock_shutdown(subs->stream->chip); |
791 | } | 787 | } |
792 | return snd_pcm_lib_free_vmalloc_buffer(substream); | 788 | |
789 | if (snd_usb_use_vmalloc) | ||
790 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
791 | else | ||
792 | return snd_pcm_lib_free_pages(substream); | ||
793 | } | 793 | } |
794 | 794 | ||
795 | /* | 795 | /* |
@@ -1181,9 +1181,6 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
1181 | pt = 125 * (1 << fp->datainterval); | 1181 | pt = 125 * (1 << fp->datainterval); |
1182 | ptmin = min(ptmin, pt); | 1182 | ptmin = min(ptmin, pt); |
1183 | } | 1183 | } |
1184 | err = snd_usb_autoresume(subs->stream->chip); | ||
1185 | if (err < 0) | ||
1186 | return err; | ||
1187 | 1184 | ||
1188 | param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; | 1185 | param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; |
1189 | if (subs->speed == USB_SPEED_FULL) | 1186 | if (subs->speed == USB_SPEED_FULL) |
@@ -1192,30 +1189,37 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
1192 | if (ptmin == 1000) | 1189 | if (ptmin == 1000) |
1193 | /* if period time doesn't go below 1 ms, no rules needed */ | 1190 | /* if period time doesn't go below 1 ms, no rules needed */ |
1194 | param_period_time_if_needed = -1; | 1191 | param_period_time_if_needed = -1; |
1195 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, | 1192 | |
1196 | ptmin, UINT_MAX); | 1193 | err = snd_pcm_hw_constraint_minmax(runtime, |
1197 | 1194 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | |
1198 | if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 1195 | ptmin, UINT_MAX); |
1199 | hw_rule_rate, subs, | 1196 | if (err < 0) |
1200 | SNDRV_PCM_HW_PARAM_FORMAT, | 1197 | return err; |
1201 | SNDRV_PCM_HW_PARAM_CHANNELS, | 1198 | |
1202 | param_period_time_if_needed, | 1199 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
1203 | -1)) < 0) | 1200 | hw_rule_rate, subs, |
1204 | goto rep_err; | 1201 | SNDRV_PCM_HW_PARAM_FORMAT, |
1205 | if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 1202 | SNDRV_PCM_HW_PARAM_CHANNELS, |
1206 | hw_rule_channels, subs, | 1203 | param_period_time_if_needed, |
1207 | SNDRV_PCM_HW_PARAM_FORMAT, | 1204 | -1); |
1208 | SNDRV_PCM_HW_PARAM_RATE, | 1205 | if (err < 0) |
1209 | param_period_time_if_needed, | 1206 | return err; |
1210 | -1)) < 0) | 1207 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
1211 | goto rep_err; | 1208 | hw_rule_channels, subs, |
1212 | if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, | 1209 | SNDRV_PCM_HW_PARAM_FORMAT, |
1213 | hw_rule_format, subs, | 1210 | SNDRV_PCM_HW_PARAM_RATE, |
1214 | SNDRV_PCM_HW_PARAM_RATE, | 1211 | param_period_time_if_needed, |
1215 | SNDRV_PCM_HW_PARAM_CHANNELS, | 1212 | -1); |
1216 | param_period_time_if_needed, | 1213 | if (err < 0) |
1217 | -1)) < 0) | 1214 | return err; |
1218 | goto rep_err; | 1215 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, |
1216 | hw_rule_format, subs, | ||
1217 | SNDRV_PCM_HW_PARAM_RATE, | ||
1218 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
1219 | param_period_time_if_needed, | ||
1220 | -1); | ||
1221 | if (err < 0) | ||
1222 | return err; | ||
1219 | if (param_period_time_if_needed >= 0) { | 1223 | if (param_period_time_if_needed >= 0) { |
1220 | err = snd_pcm_hw_rule_add(runtime, 0, | 1224 | err = snd_pcm_hw_rule_add(runtime, 0, |
1221 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | 1225 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, |
@@ -1225,19 +1229,18 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
1225 | SNDRV_PCM_HW_PARAM_RATE, | 1229 | SNDRV_PCM_HW_PARAM_RATE, |
1226 | -1); | 1230 | -1); |
1227 | if (err < 0) | 1231 | if (err < 0) |
1228 | goto rep_err; | 1232 | return err; |
1229 | } | 1233 | } |
1230 | if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0) | 1234 | err = snd_usb_pcm_check_knot(runtime, subs); |
1231 | goto rep_err; | 1235 | if (err < 0) |
1232 | return 0; | 1236 | return err; |
1233 | 1237 | ||
1234 | rep_err: | 1238 | return snd_usb_autoresume(subs->stream->chip); |
1235 | snd_usb_autosuspend(subs->stream->chip); | ||
1236 | return err; | ||
1237 | } | 1239 | } |
1238 | 1240 | ||
1239 | static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) | 1241 | static int snd_usb_pcm_open(struct snd_pcm_substream *substream) |
1240 | { | 1242 | { |
1243 | int direction = substream->stream; | ||
1241 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); | 1244 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); |
1242 | struct snd_pcm_runtime *runtime = substream->runtime; | 1245 | struct snd_pcm_runtime *runtime = substream->runtime; |
1243 | struct snd_usb_substream *subs = &as->substream[direction]; | 1246 | struct snd_usb_substream *subs = &as->substream[direction]; |
@@ -1257,14 +1260,16 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) | |||
1257 | return setup_hw_info(runtime, subs); | 1260 | return setup_hw_info(runtime, subs); |
1258 | } | 1261 | } |
1259 | 1262 | ||
1260 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) | 1263 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream) |
1261 | { | 1264 | { |
1265 | int direction = substream->stream; | ||
1262 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); | 1266 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); |
1263 | struct snd_usb_substream *subs = &as->substream[direction]; | 1267 | struct snd_usb_substream *subs = &as->substream[direction]; |
1264 | 1268 | ||
1265 | stop_endpoints(subs, true); | 1269 | stop_endpoints(subs, true); |
1266 | 1270 | ||
1267 | if (subs->interface >= 0 && | 1271 | if (!as->chip->keep_iface && |
1272 | subs->interface >= 0 && | ||
1268 | !snd_usb_lock_shutdown(subs->stream->chip)) { | 1273 | !snd_usb_lock_shutdown(subs->stream->chip)) { |
1269 | usb_set_interface(subs->dev, subs->interface, 0); | 1274 | usb_set_interface(subs->dev, subs->interface, 0); |
1270 | subs->interface = -1; | 1275 | subs->interface = -1; |
@@ -1311,7 +1316,7 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1311 | if (bytes % (runtime->sample_bits >> 3) != 0) { | 1316 | if (bytes % (runtime->sample_bits >> 3) != 0) { |
1312 | int oldbytes = bytes; | 1317 | int oldbytes = bytes; |
1313 | bytes = frames * stride; | 1318 | bytes = frames * stride; |
1314 | dev_warn(&subs->dev->dev, | 1319 | dev_warn_ratelimited(&subs->dev->dev, |
1315 | "Corrected urb data len. %d->%d\n", | 1320 | "Corrected urb data len. %d->%d\n", |
1316 | oldbytes, bytes); | 1321 | oldbytes, bytes); |
1317 | } | 1322 | } |
@@ -1619,26 +1624,6 @@ static void retire_playback_urb(struct snd_usb_substream *subs, | |||
1619 | spin_unlock_irqrestore(&subs->lock, flags); | 1624 | spin_unlock_irqrestore(&subs->lock, flags); |
1620 | } | 1625 | } |
1621 | 1626 | ||
1622 | static int snd_usb_playback_open(struct snd_pcm_substream *substream) | ||
1623 | { | ||
1624 | return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK); | ||
1625 | } | ||
1626 | |||
1627 | static int snd_usb_playback_close(struct snd_pcm_substream *substream) | ||
1628 | { | ||
1629 | return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK); | ||
1630 | } | ||
1631 | |||
1632 | static int snd_usb_capture_open(struct snd_pcm_substream *substream) | ||
1633 | { | ||
1634 | return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE); | ||
1635 | } | ||
1636 | |||
1637 | static int snd_usb_capture_close(struct snd_pcm_substream *substream) | ||
1638 | { | ||
1639 | return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE); | ||
1640 | } | ||
1641 | |||
1642 | static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, | 1627 | static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, |
1643 | int cmd) | 1628 | int cmd) |
1644 | { | 1629 | { |
@@ -1700,8 +1685,8 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream | |||
1700 | } | 1685 | } |
1701 | 1686 | ||
1702 | static const struct snd_pcm_ops snd_usb_playback_ops = { | 1687 | static const struct snd_pcm_ops snd_usb_playback_ops = { |
1703 | .open = snd_usb_playback_open, | 1688 | .open = snd_usb_pcm_open, |
1704 | .close = snd_usb_playback_close, | 1689 | .close = snd_usb_pcm_close, |
1705 | .ioctl = snd_pcm_lib_ioctl, | 1690 | .ioctl = snd_pcm_lib_ioctl, |
1706 | .hw_params = snd_usb_hw_params, | 1691 | .hw_params = snd_usb_hw_params, |
1707 | .hw_free = snd_usb_hw_free, | 1692 | .hw_free = snd_usb_hw_free, |
@@ -1713,8 +1698,8 @@ static const struct snd_pcm_ops snd_usb_playback_ops = { | |||
1713 | }; | 1698 | }; |
1714 | 1699 | ||
1715 | static const struct snd_pcm_ops snd_usb_capture_ops = { | 1700 | static const struct snd_pcm_ops snd_usb_capture_ops = { |
1716 | .open = snd_usb_capture_open, | 1701 | .open = snd_usb_pcm_open, |
1717 | .close = snd_usb_capture_close, | 1702 | .close = snd_usb_pcm_close, |
1718 | .ioctl = snd_pcm_lib_ioctl, | 1703 | .ioctl = snd_pcm_lib_ioctl, |
1719 | .hw_params = snd_usb_hw_params, | 1704 | .hw_params = snd_usb_hw_params, |
1720 | .hw_free = snd_usb_hw_free, | 1705 | .hw_free = snd_usb_hw_free, |
@@ -1725,9 +1710,50 @@ static const struct snd_pcm_ops snd_usb_capture_ops = { | |||
1725 | .mmap = snd_pcm_lib_mmap_vmalloc, | 1710 | .mmap = snd_pcm_lib_mmap_vmalloc, |
1726 | }; | 1711 | }; |
1727 | 1712 | ||
1713 | static const struct snd_pcm_ops snd_usb_playback_dev_ops = { | ||
1714 | .open = snd_usb_pcm_open, | ||
1715 | .close = snd_usb_pcm_close, | ||
1716 | .ioctl = snd_pcm_lib_ioctl, | ||
1717 | .hw_params = snd_usb_hw_params, | ||
1718 | .hw_free = snd_usb_hw_free, | ||
1719 | .prepare = snd_usb_pcm_prepare, | ||
1720 | .trigger = snd_usb_substream_playback_trigger, | ||
1721 | .pointer = snd_usb_pcm_pointer, | ||
1722 | .page = snd_pcm_sgbuf_ops_page, | ||
1723 | }; | ||
1724 | |||
1725 | static const struct snd_pcm_ops snd_usb_capture_dev_ops = { | ||
1726 | .open = snd_usb_pcm_open, | ||
1727 | .close = snd_usb_pcm_close, | ||
1728 | .ioctl = snd_pcm_lib_ioctl, | ||
1729 | .hw_params = snd_usb_hw_params, | ||
1730 | .hw_free = snd_usb_hw_free, | ||
1731 | .prepare = snd_usb_pcm_prepare, | ||
1732 | .trigger = snd_usb_substream_capture_trigger, | ||
1733 | .pointer = snd_usb_pcm_pointer, | ||
1734 | .page = snd_pcm_sgbuf_ops_page, | ||
1735 | }; | ||
1736 | |||
1728 | void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream) | 1737 | void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream) |
1729 | { | 1738 | { |
1730 | snd_pcm_set_ops(pcm, stream, | 1739 | const struct snd_pcm_ops *ops; |
1731 | stream == SNDRV_PCM_STREAM_PLAYBACK ? | 1740 | |
1732 | &snd_usb_playback_ops : &snd_usb_capture_ops); | 1741 | if (snd_usb_use_vmalloc) |
1742 | ops = stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
1743 | &snd_usb_playback_ops : &snd_usb_capture_ops; | ||
1744 | else | ||
1745 | ops = stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
1746 | &snd_usb_playback_dev_ops : &snd_usb_capture_dev_ops; | ||
1747 | snd_pcm_set_ops(pcm, stream, ops); | ||
1748 | } | ||
1749 | |||
1750 | void snd_usb_preallocate_buffer(struct snd_usb_substream *subs) | ||
1751 | { | ||
1752 | struct snd_pcm *pcm = subs->stream->pcm; | ||
1753 | struct snd_pcm_substream *s = pcm->streams[subs->direction].substream; | ||
1754 | struct device *dev = subs->dev->bus->controller; | ||
1755 | |||
1756 | if (!snd_usb_use_vmalloc) | ||
1757 | snd_pcm_lib_preallocate_pages(s, SNDRV_DMA_TYPE_DEV_SG, | ||
1758 | dev, 64*1024, 512*1024); | ||
1733 | } | 1759 | } |
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h index 35740d5ef268..f77ec58bf1a1 100644 --- a/sound/usb/pcm.h +++ b/sound/usb/pcm.h | |||
@@ -10,6 +10,7 @@ void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream); | |||
10 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | 10 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, |
11 | struct usb_host_interface *alts, | 11 | struct usb_host_interface *alts, |
12 | struct audioformat *fmt); | 12 | struct audioformat *fmt); |
13 | void snd_usb_preallocate_buffer(struct snd_usb_substream *subs); | ||
13 | 14 | ||
14 | 15 | ||
15 | #endif /* __USBAUDIO_PCM_H */ | 16 | #endif /* __USBAUDIO_PCM_H */ |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 754e632a27bd..0e37e358ca97 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -3371,5 +3371,15 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), | |||
3371 | } | 3371 | } |
3372 | } | 3372 | } |
3373 | }, | 3373 | }, |
3374 | /* Dell WD15 Dock */ | ||
3375 | { | ||
3376 | USB_DEVICE(0x0bda, 0x4014), | ||
3377 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
3378 | .vendor_name = "Dell", | ||
3379 | .product_name = "WD15 Dock", | ||
3380 | .profile_name = "Dell-WD15-Dock", | ||
3381 | .ifnum = QUIRK_NO_INTERFACE | ||
3382 | } | ||
3383 | }, | ||
3374 | 3384 | ||
3375 | #undef USB_DEVICE_VENDOR_SPEC | 3385 | #undef USB_DEVICE_VENDOR_SPEC |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index acbeb52f6fd6..f4b69173682c 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -851,6 +851,36 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) | |||
851 | return 0; /* Successful boot */ | 851 | return 0; /* Successful boot */ |
852 | } | 852 | } |
853 | 853 | ||
854 | static int snd_usb_axefx3_boot_quirk(struct usb_device *dev) | ||
855 | { | ||
856 | int err; | ||
857 | |||
858 | dev_dbg(&dev->dev, "Waiting for Axe-Fx III to boot up...\n"); | ||
859 | |||
860 | /* If the Axe-Fx III has not fully booted, it will timeout when trying | ||
861 | * to enable the audio streaming interface. A more generous timeout is | ||
862 | * used here to detect when the Axe-Fx III has finished booting as the | ||
863 | * set interface message will be acked once it has | ||
864 | */ | ||
865 | err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
866 | USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, | ||
867 | 1, 1, NULL, 0, 120000); | ||
868 | if (err < 0) { | ||
869 | dev_err(&dev->dev, | ||
870 | "failed waiting for Axe-Fx III to boot: %d\n", err); | ||
871 | return err; | ||
872 | } | ||
873 | |||
874 | dev_dbg(&dev->dev, "Axe-Fx III is now ready\n"); | ||
875 | |||
876 | err = usb_set_interface(dev, 1, 0); | ||
877 | if (err < 0) | ||
878 | dev_dbg(&dev->dev, | ||
879 | "error stopping Axe-Fx III interface: %d\n", err); | ||
880 | |||
881 | return 0; | ||
882 | } | ||
883 | |||
854 | /* | 884 | /* |
855 | * Setup quirks | 885 | * Setup quirks |
856 | */ | 886 | */ |
@@ -1026,6 +1056,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, | |||
1026 | return snd_usb_fasttrackpro_boot_quirk(dev); | 1056 | return snd_usb_fasttrackpro_boot_quirk(dev); |
1027 | case USB_ID(0x047f, 0xc010): /* Plantronics Gamecom 780 */ | 1057 | case USB_ID(0x047f, 0xc010): /* Plantronics Gamecom 780 */ |
1028 | return snd_usb_gamecon780_boot_quirk(dev); | 1058 | return snd_usb_gamecon780_boot_quirk(dev); |
1059 | case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx 3 */ | ||
1060 | return snd_usb_axefx3_boot_quirk(dev); | ||
1029 | } | 1061 | } |
1030 | 1062 | ||
1031 | return 0; | 1063 | return 0; |
@@ -1327,20 +1359,47 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | |||
1327 | 1359 | ||
1328 | /* XMOS based USB DACs */ | 1360 | /* XMOS based USB DACs */ |
1329 | switch (chip->usb_id) { | 1361 | switch (chip->usb_id) { |
1362 | case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */ | ||
1363 | case USB_ID(0x20b1, 0x0002): /* Wyred 4 Sound DAC-2 DSD */ | ||
1364 | case USB_ID(0x20b1, 0x2004): /* Matrix Audio X-SPDIF 2 */ | ||
1330 | case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */ | 1365 | case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */ |
1331 | case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ | 1366 | case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ |
1332 | case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ | 1367 | case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ |
1333 | case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */ | 1368 | case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */ |
1369 | case USB_ID(0x22d9, 0x0436): /* OPPO Sonica */ | ||
1370 | case USB_ID(0x22d9, 0x0461): /* OPPO UDP-205 */ | ||
1371 | case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */ | ||
1372 | case USB_ID(0x25ce, 0x001f): /* Mytek Brooklyn DAC */ | ||
1373 | case USB_ID(0x25ce, 0x0021): /* Mytek Manhattan DAC */ | ||
1374 | case USB_ID(0x25ce, 0x8025): /* Mytek Brooklyn DAC+ */ | ||
1334 | case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ | 1375 | case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ |
1335 | if (fp->altsetting == 2) | 1376 | if (fp->altsetting == 2) |
1336 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; | 1377 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; |
1337 | break; | 1378 | break; |
1338 | 1379 | ||
1380 | case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ | ||
1381 | case USB_ID(0x16b0, 0x06b2): /* NuPrime DAC-10 */ | ||
1382 | case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */ | ||
1383 | case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ | ||
1384 | case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */ | ||
1339 | case USB_ID(0x20b1, 0x000a): /* Gustard DAC-X20U */ | 1385 | case USB_ID(0x20b1, 0x000a): /* Gustard DAC-X20U */ |
1386 | case USB_ID(0x20b1, 0x2005): /* Denafrips Ares DAC */ | ||
1340 | case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */ | 1387 | case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */ |
1341 | case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */ | 1388 | case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */ |
1389 | case USB_ID(0x20b1, 0x3021): /* Eastern El. MiniMax Tube DAC Supreme */ | ||
1342 | case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */ | 1390 | case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */ |
1391 | case USB_ID(0x20b1, 0x302d): /* Unison Research Unico CD Due */ | ||
1392 | case USB_ID(0x20b1, 0x3036): /* Holo Springs Level 3 R2R DAC */ | ||
1393 | case USB_ID(0x20b1, 0x307b): /* CH Precision C1 DAC */ | ||
1394 | case USB_ID(0x20b1, 0x3086): /* Singxer F-1 converter board */ | ||
1395 | case USB_ID(0x22d9, 0x0426): /* OPPO HA-2 */ | ||
1396 | case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */ | ||
1397 | case USB_ID(0x249c, 0x9326): /* M2Tech Young MkIII */ | ||
1343 | case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */ | 1398 | case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */ |
1399 | case USB_ID(0x2622, 0x0041): /* Audiolab M-DAC+ */ | ||
1400 | case USB_ID(0x27f7, 0x3002): /* W4S DAC-2v2SE */ | ||
1401 | case USB_ID(0x29a2, 0x0086): /* Mutec MC3+ USB */ | ||
1402 | case USB_ID(0x6b42, 0x0042): /* MSB Technology */ | ||
1344 | if (fp->altsetting == 3) | 1403 | if (fp->altsetting == 3) |
1345 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; | 1404 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; |
1346 | break; | 1405 | break; |
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 5ed334575fc7..729afd808cc4 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c | |||
@@ -106,6 +106,8 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, | |||
106 | subs->ep_num = fp->endpoint; | 106 | subs->ep_num = fp->endpoint; |
107 | if (fp->channels > subs->channels_max) | 107 | if (fp->channels > subs->channels_max) |
108 | subs->channels_max = fp->channels; | 108 | subs->channels_max = fp->channels; |
109 | |||
110 | snd_usb_preallocate_buffer(subs); | ||
109 | } | 111 | } |
110 | 112 | ||
111 | /* kctl callbacks for usb-audio channel maps */ | 113 | /* kctl callbacks for usb-audio channel maps */ |
@@ -633,6 +635,395 @@ snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, | |||
633 | return NULL; | 635 | return NULL; |
634 | } | 636 | } |
635 | 637 | ||
638 | static struct audioformat * | ||
639 | audio_format_alloc_init(struct snd_usb_audio *chip, | ||
640 | struct usb_host_interface *alts, | ||
641 | int protocol, int iface_no, int altset_idx, | ||
642 | int altno, int num_channels, int clock) | ||
643 | { | ||
644 | struct audioformat *fp; | ||
645 | |||
646 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | ||
647 | if (!fp) | ||
648 | return NULL; | ||
649 | |||
650 | fp->iface = iface_no; | ||
651 | fp->altsetting = altno; | ||
652 | fp->altset_idx = altset_idx; | ||
653 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | ||
654 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | ||
655 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); | ||
656 | fp->protocol = protocol; | ||
657 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
658 | fp->channels = num_channels; | ||
659 | if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH) | ||
660 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | ||
661 | * (fp->maxpacksize & 0x7ff); | ||
662 | fp->clock = clock; | ||
663 | INIT_LIST_HEAD(&fp->list); | ||
664 | |||
665 | return fp; | ||
666 | } | ||
667 | |||
668 | static struct audioformat * | ||
669 | snd_usb_get_audioformat_uac12(struct snd_usb_audio *chip, | ||
670 | struct usb_host_interface *alts, | ||
671 | int protocol, int iface_no, int altset_idx, | ||
672 | int altno, int stream, int bm_quirk) | ||
673 | { | ||
674 | struct usb_device *dev = chip->dev; | ||
675 | struct uac_format_type_i_continuous_descriptor *fmt; | ||
676 | unsigned int num_channels = 0, chconfig = 0; | ||
677 | struct audioformat *fp; | ||
678 | int clock = 0; | ||
679 | u64 format; | ||
680 | |||
681 | /* get audio formats */ | ||
682 | if (protocol == UAC_VERSION_1) { | ||
683 | struct uac1_as_header_descriptor *as = | ||
684 | snd_usb_find_csint_desc(alts->extra, alts->extralen, | ||
685 | NULL, UAC_AS_GENERAL); | ||
686 | struct uac_input_terminal_descriptor *iterm; | ||
687 | |||
688 | if (!as) { | ||
689 | dev_err(&dev->dev, | ||
690 | "%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
691 | iface_no, altno); | ||
692 | return NULL; | ||
693 | } | ||
694 | |||
695 | if (as->bLength < sizeof(*as)) { | ||
696 | dev_err(&dev->dev, | ||
697 | "%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
698 | iface_no, altno); | ||
699 | return NULL; | ||
700 | } | ||
701 | |||
702 | format = le16_to_cpu(as->wFormatTag); /* remember the format value */ | ||
703 | |||
704 | iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
705 | as->bTerminalLink); | ||
706 | if (iterm) { | ||
707 | num_channels = iterm->bNrChannels; | ||
708 | chconfig = le16_to_cpu(iterm->wChannelConfig); | ||
709 | } | ||
710 | } else { /* UAC_VERSION_2 */ | ||
711 | struct uac2_input_terminal_descriptor *input_term; | ||
712 | struct uac2_output_terminal_descriptor *output_term; | ||
713 | struct uac2_as_header_descriptor *as = | ||
714 | snd_usb_find_csint_desc(alts->extra, alts->extralen, | ||
715 | NULL, UAC_AS_GENERAL); | ||
716 | |||
717 | if (!as) { | ||
718 | dev_err(&dev->dev, | ||
719 | "%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
720 | iface_no, altno); | ||
721 | return NULL; | ||
722 | } | ||
723 | |||
724 | if (as->bLength < sizeof(*as)) { | ||
725 | dev_err(&dev->dev, | ||
726 | "%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
727 | iface_no, altno); | ||
728 | return NULL; | ||
729 | } | ||
730 | |||
731 | num_channels = as->bNrChannels; | ||
732 | format = le32_to_cpu(as->bmFormats); | ||
733 | chconfig = le32_to_cpu(as->bmChannelConfig); | ||
734 | |||
735 | /* | ||
736 | * lookup the terminal associated to this interface | ||
737 | * to extract the clock | ||
738 | */ | ||
739 | input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
740 | as->bTerminalLink); | ||
741 | if (input_term) { | ||
742 | clock = input_term->bCSourceID; | ||
743 | if (!chconfig && (num_channels == input_term->bNrChannels)) | ||
744 | chconfig = le32_to_cpu(input_term->bmChannelConfig); | ||
745 | goto found_clock; | ||
746 | } | ||
747 | |||
748 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
749 | as->bTerminalLink); | ||
750 | if (output_term) { | ||
751 | clock = output_term->bCSourceID; | ||
752 | goto found_clock; | ||
753 | } | ||
754 | |||
755 | dev_err(&dev->dev, | ||
756 | "%u:%d : bogus bTerminalLink %d\n", | ||
757 | iface_no, altno, as->bTerminalLink); | ||
758 | return NULL; | ||
759 | } | ||
760 | |||
761 | found_clock: | ||
762 | /* get format type */ | ||
763 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, | ||
764 | NULL, UAC_FORMAT_TYPE); | ||
765 | if (!fmt) { | ||
766 | dev_err(&dev->dev, | ||
767 | "%u:%d : no UAC_FORMAT_TYPE desc\n", | ||
768 | iface_no, altno); | ||
769 | return NULL; | ||
770 | } | ||
771 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) | ||
772 | || ((protocol == UAC_VERSION_2) && | ||
773 | (fmt->bLength < 6))) { | ||
774 | dev_err(&dev->dev, | ||
775 | "%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
776 | iface_no, altno); | ||
777 | return NULL; | ||
778 | } | ||
779 | |||
780 | /* | ||
781 | * Blue Microphones workaround: The last altsetting is | ||
782 | * identical with the previous one, except for a larger | ||
783 | * packet size, but is actually a mislabeled two-channel | ||
784 | * setting; ignore it. | ||
785 | * | ||
786 | * Part 2: analyze quirk flag and format | ||
787 | */ | ||
788 | if (bm_quirk && fmt->bNrChannels == 1 && fmt->bSubframeSize == 2) | ||
789 | return NULL; | ||
790 | |||
791 | fp = audio_format_alloc_init(chip, alts, protocol, iface_no, | ||
792 | altset_idx, altno, num_channels, clock); | ||
793 | if (!fp) | ||
794 | return ERR_PTR(-ENOMEM); | ||
795 | |||
796 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, | ||
797 | iface_no); | ||
798 | |||
799 | /* some quirks for attributes here */ | ||
800 | snd_usb_audioformat_attributes_quirk(chip, fp, stream); | ||
801 | |||
802 | /* ok, let's parse further... */ | ||
803 | if (snd_usb_parse_audio_format(chip, fp, format, | ||
804 | fmt, stream) < 0) { | ||
805 | kfree(fp->rate_table); | ||
806 | kfree(fp); | ||
807 | return NULL; | ||
808 | } | ||
809 | |||
810 | /* Create chmap */ | ||
811 | if (fp->channels != num_channels) | ||
812 | chconfig = 0; | ||
813 | |||
814 | fp->chmap = convert_chmap(fp->channels, chconfig, protocol); | ||
815 | |||
816 | return fp; | ||
817 | } | ||
818 | |||
819 | static struct audioformat * | ||
820 | snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, | ||
821 | struct usb_host_interface *alts, | ||
822 | int iface_no, int altset_idx, | ||
823 | int altno, int stream) | ||
824 | { | ||
825 | struct usb_device *dev = chip->dev; | ||
826 | struct uac3_input_terminal_descriptor *input_term; | ||
827 | struct uac3_output_terminal_descriptor *output_term; | ||
828 | struct uac3_cluster_header_descriptor *cluster; | ||
829 | struct uac3_as_header_descriptor *as = NULL; | ||
830 | struct uac3_hc_descriptor_header hc_header; | ||
831 | struct snd_pcm_chmap_elem *chmap; | ||
832 | unsigned char badd_profile; | ||
833 | u64 badd_formats = 0; | ||
834 | unsigned int num_channels; | ||
835 | struct audioformat *fp; | ||
836 | u16 cluster_id, wLength; | ||
837 | int clock = 0; | ||
838 | int err; | ||
839 | |||
840 | badd_profile = chip->badd_profile; | ||
841 | |||
842 | if (badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) { | ||
843 | unsigned int maxpacksize = | ||
844 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
845 | |||
846 | switch (maxpacksize) { | ||
847 | default: | ||
848 | dev_err(&dev->dev, | ||
849 | "%u:%d : incorrect wMaxPacketSize for BADD profile\n", | ||
850 | iface_no, altno); | ||
851 | return NULL; | ||
852 | case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16: | ||
853 | case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16: | ||
854 | badd_formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
855 | num_channels = 1; | ||
856 | break; | ||
857 | case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24: | ||
858 | case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24: | ||
859 | badd_formats = SNDRV_PCM_FMTBIT_S24_3LE; | ||
860 | num_channels = 1; | ||
861 | break; | ||
862 | case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16: | ||
863 | case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16: | ||
864 | badd_formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
865 | num_channels = 2; | ||
866 | break; | ||
867 | case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24: | ||
868 | case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24: | ||
869 | badd_formats = SNDRV_PCM_FMTBIT_S24_3LE; | ||
870 | num_channels = 2; | ||
871 | break; | ||
872 | } | ||
873 | |||
874 | chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); | ||
875 | if (!chmap) | ||
876 | return ERR_PTR(-ENOMEM); | ||
877 | |||
878 | if (num_channels == 1) { | ||
879 | chmap->map[0] = SNDRV_CHMAP_MONO; | ||
880 | } else { | ||
881 | chmap->map[0] = SNDRV_CHMAP_FL; | ||
882 | chmap->map[1] = SNDRV_CHMAP_FR; | ||
883 | } | ||
884 | |||
885 | chmap->channels = num_channels; | ||
886 | clock = UAC3_BADD_CS_ID9; | ||
887 | goto found_clock; | ||
888 | } | ||
889 | |||
890 | as = snd_usb_find_csint_desc(alts->extra, alts->extralen, | ||
891 | NULL, UAC_AS_GENERAL); | ||
892 | if (!as) { | ||
893 | dev_err(&dev->dev, | ||
894 | "%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
895 | iface_no, altno); | ||
896 | return NULL; | ||
897 | } | ||
898 | |||
899 | if (as->bLength < sizeof(*as)) { | ||
900 | dev_err(&dev->dev, | ||
901 | "%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
902 | iface_no, altno); | ||
903 | return NULL; | ||
904 | } | ||
905 | |||
906 | cluster_id = le16_to_cpu(as->wClusterDescrID); | ||
907 | if (!cluster_id) { | ||
908 | dev_err(&dev->dev, | ||
909 | "%u:%d : no cluster descriptor\n", | ||
910 | iface_no, altno); | ||
911 | return NULL; | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * Get number of channels and channel map through | ||
916 | * High Capability Cluster Descriptor | ||
917 | * | ||
918 | * First step: get High Capability header and | ||
919 | * read size of Cluster Descriptor | ||
920 | */ | ||
921 | err = snd_usb_ctl_msg(chip->dev, | ||
922 | usb_rcvctrlpipe(chip->dev, 0), | ||
923 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
924 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
925 | cluster_id, | ||
926 | snd_usb_ctrl_intf(chip), | ||
927 | &hc_header, sizeof(hc_header)); | ||
928 | if (err < 0) | ||
929 | return ERR_PTR(err); | ||
930 | else if (err != sizeof(hc_header)) { | ||
931 | dev_err(&dev->dev, | ||
932 | "%u:%d : can't get High Capability descriptor\n", | ||
933 | iface_no, altno); | ||
934 | return ERR_PTR(-EIO); | ||
935 | } | ||
936 | |||
937 | /* | ||
938 | * Second step: allocate needed amount of memory | ||
939 | * and request Cluster Descriptor | ||
940 | */ | ||
941 | wLength = le16_to_cpu(hc_header.wLength); | ||
942 | cluster = kzalloc(wLength, GFP_KERNEL); | ||
943 | if (!cluster) | ||
944 | return ERR_PTR(-ENOMEM); | ||
945 | err = snd_usb_ctl_msg(chip->dev, | ||
946 | usb_rcvctrlpipe(chip->dev, 0), | ||
947 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
948 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
949 | cluster_id, | ||
950 | snd_usb_ctrl_intf(chip), | ||
951 | cluster, wLength); | ||
952 | if (err < 0) { | ||
953 | kfree(cluster); | ||
954 | return ERR_PTR(err); | ||
955 | } else if (err != wLength) { | ||
956 | dev_err(&dev->dev, | ||
957 | "%u:%d : can't get Cluster Descriptor\n", | ||
958 | iface_no, altno); | ||
959 | kfree(cluster); | ||
960 | return ERR_PTR(-EIO); | ||
961 | } | ||
962 | |||
963 | num_channels = cluster->bNrChannels; | ||
964 | chmap = convert_chmap_v3(cluster); | ||
965 | kfree(cluster); | ||
966 | |||
967 | /* | ||
968 | * lookup the terminal associated to this interface | ||
969 | * to extract the clock | ||
970 | */ | ||
971 | input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
972 | as->bTerminalLink); | ||
973 | if (input_term) { | ||
974 | clock = input_term->bCSourceID; | ||
975 | goto found_clock; | ||
976 | } | ||
977 | |||
978 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
979 | as->bTerminalLink); | ||
980 | if (output_term) { | ||
981 | clock = output_term->bCSourceID; | ||
982 | goto found_clock; | ||
983 | } | ||
984 | |||
985 | dev_err(&dev->dev, "%u:%d : bogus bTerminalLink %d\n", | ||
986 | iface_no, altno, as->bTerminalLink); | ||
987 | kfree(chmap); | ||
988 | return NULL; | ||
989 | |||
990 | found_clock: | ||
991 | fp = audio_format_alloc_init(chip, alts, UAC_VERSION_3, iface_no, | ||
992 | altset_idx, altno, num_channels, clock); | ||
993 | if (!fp) { | ||
994 | kfree(chmap); | ||
995 | return ERR_PTR(-ENOMEM); | ||
996 | } | ||
997 | |||
998 | fp->chmap = chmap; | ||
999 | |||
1000 | if (badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) { | ||
1001 | fp->attributes = 0; /* No attributes */ | ||
1002 | |||
1003 | fp->fmt_type = UAC_FORMAT_TYPE_I; | ||
1004 | fp->formats = badd_formats; | ||
1005 | |||
1006 | fp->nr_rates = 0; /* SNDRV_PCM_RATE_CONTINUOUS */ | ||
1007 | fp->rate_min = UAC3_BADD_SAMPLING_RATE; | ||
1008 | fp->rate_max = UAC3_BADD_SAMPLING_RATE; | ||
1009 | fp->rates = SNDRV_PCM_RATE_CONTINUOUS; | ||
1010 | |||
1011 | } else { | ||
1012 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, | ||
1013 | UAC_VERSION_3, | ||
1014 | iface_no); | ||
1015 | /* ok, let's parse further... */ | ||
1016 | if (snd_usb_parse_audio_format_v3(chip, fp, as, stream) < 0) { | ||
1017 | kfree(fp->chmap); | ||
1018 | kfree(fp->rate_table); | ||
1019 | kfree(fp); | ||
1020 | return NULL; | ||
1021 | } | ||
1022 | } | ||
1023 | |||
1024 | return fp; | ||
1025 | } | ||
1026 | |||
636 | int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | 1027 | int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) |
637 | { | 1028 | { |
638 | struct usb_device *dev; | 1029 | struct usb_device *dev; |
@@ -640,13 +1031,8 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
640 | struct usb_host_interface *alts; | 1031 | struct usb_host_interface *alts; |
641 | struct usb_interface_descriptor *altsd; | 1032 | struct usb_interface_descriptor *altsd; |
642 | int i, altno, err, stream; | 1033 | int i, altno, err, stream; |
643 | u64 format = 0; | ||
644 | unsigned int num_channels = 0; | ||
645 | struct audioformat *fp = NULL; | 1034 | struct audioformat *fp = NULL; |
646 | int num, protocol, clock = 0; | 1035 | int num, protocol; |
647 | struct uac_format_type_i_continuous_descriptor *fmt = NULL; | ||
648 | struct snd_pcm_chmap_elem *chmap_v3 = NULL; | ||
649 | unsigned int chconfig; | ||
650 | 1036 | ||
651 | dev = chip->dev; | 1037 | dev = chip->dev; |
652 | 1038 | ||
@@ -695,303 +1081,48 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
695 | protocol <= 2) | 1081 | protocol <= 2) |
696 | protocol = UAC_VERSION_1; | 1082 | protocol = UAC_VERSION_1; |
697 | 1083 | ||
698 | chconfig = 0; | ||
699 | /* get audio formats */ | ||
700 | switch (protocol) { | 1084 | switch (protocol) { |
701 | default: | 1085 | default: |
702 | dev_dbg(&dev->dev, "%u:%d: unknown interface protocol %#02x, assuming v1\n", | 1086 | dev_dbg(&dev->dev, "%u:%d: unknown interface protocol %#02x, assuming v1\n", |
703 | iface_no, altno, protocol); | 1087 | iface_no, altno, protocol); |
704 | protocol = UAC_VERSION_1; | 1088 | protocol = UAC_VERSION_1; |
705 | /* fall through */ | 1089 | /* fall through */ |
706 | 1090 | case UAC_VERSION_1: | |
707 | case UAC_VERSION_1: { | 1091 | /* fall through */ |
708 | struct uac1_as_header_descriptor *as = | ||
709 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | ||
710 | struct uac_input_terminal_descriptor *iterm; | ||
711 | |||
712 | if (!as) { | ||
713 | dev_err(&dev->dev, | ||
714 | "%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
715 | iface_no, altno); | ||
716 | continue; | ||
717 | } | ||
718 | |||
719 | if (as->bLength < sizeof(*as)) { | ||
720 | dev_err(&dev->dev, | ||
721 | "%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
722 | iface_no, altno); | ||
723 | continue; | ||
724 | } | ||
725 | |||
726 | format = le16_to_cpu(as->wFormatTag); /* remember the format value */ | ||
727 | |||
728 | iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
729 | as->bTerminalLink); | ||
730 | if (iterm) { | ||
731 | num_channels = iterm->bNrChannels; | ||
732 | chconfig = le16_to_cpu(iterm->wChannelConfig); | ||
733 | } | ||
734 | |||
735 | break; | ||
736 | } | ||
737 | |||
738 | case UAC_VERSION_2: { | 1092 | case UAC_VERSION_2: { |
739 | struct uac2_input_terminal_descriptor *input_term; | 1093 | int bm_quirk = 0; |
740 | struct uac2_output_terminal_descriptor *output_term; | ||
741 | struct uac2_as_header_descriptor *as = | ||
742 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | ||
743 | |||
744 | if (!as) { | ||
745 | dev_err(&dev->dev, | ||
746 | "%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
747 | iface_no, altno); | ||
748 | continue; | ||
749 | } | ||
750 | |||
751 | if (as->bLength < sizeof(*as)) { | ||
752 | dev_err(&dev->dev, | ||
753 | "%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
754 | iface_no, altno); | ||
755 | continue; | ||
756 | } | ||
757 | |||
758 | num_channels = as->bNrChannels; | ||
759 | format = le32_to_cpu(as->bmFormats); | ||
760 | chconfig = le32_to_cpu(as->bmChannelConfig); | ||
761 | |||
762 | /* lookup the terminal associated to this interface | ||
763 | * to extract the clock */ | ||
764 | input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
765 | as->bTerminalLink); | ||
766 | if (input_term) { | ||
767 | clock = input_term->bCSourceID; | ||
768 | if (!chconfig && (num_channels == input_term->bNrChannels)) | ||
769 | chconfig = le32_to_cpu(input_term->bmChannelConfig); | ||
770 | break; | ||
771 | } | ||
772 | |||
773 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
774 | as->bTerminalLink); | ||
775 | if (output_term) { | ||
776 | clock = output_term->bCSourceID; | ||
777 | break; | ||
778 | } | ||
779 | |||
780 | dev_err(&dev->dev, | ||
781 | "%u:%d : bogus bTerminalLink %d\n", | ||
782 | iface_no, altno, as->bTerminalLink); | ||
783 | continue; | ||
784 | } | ||
785 | |||
786 | case UAC_VERSION_3: { | ||
787 | struct uac3_input_terminal_descriptor *input_term; | ||
788 | struct uac3_output_terminal_descriptor *output_term; | ||
789 | struct uac3_as_header_descriptor *as; | ||
790 | struct uac3_cluster_header_descriptor *cluster; | ||
791 | struct uac3_hc_descriptor_header hc_header; | ||
792 | u16 cluster_id, wLength; | ||
793 | |||
794 | as = snd_usb_find_csint_desc(alts->extra, | ||
795 | alts->extralen, | ||
796 | NULL, UAC_AS_GENERAL); | ||
797 | |||
798 | if (!as) { | ||
799 | dev_err(&dev->dev, | ||
800 | "%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
801 | iface_no, altno); | ||
802 | continue; | ||
803 | } | ||
804 | |||
805 | if (as->bLength < sizeof(*as)) { | ||
806 | dev_err(&dev->dev, | ||
807 | "%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
808 | iface_no, altno); | ||
809 | continue; | ||
810 | } | ||
811 | |||
812 | cluster_id = le16_to_cpu(as->wClusterDescrID); | ||
813 | if (!cluster_id) { | ||
814 | dev_err(&dev->dev, | ||
815 | "%u:%d : no cluster descriptor\n", | ||
816 | iface_no, altno); | ||
817 | continue; | ||
818 | } | ||
819 | |||
820 | /* | ||
821 | * Get number of channels and channel map through | ||
822 | * High Capability Cluster Descriptor | ||
823 | * | ||
824 | * First step: get High Capability header and | ||
825 | * read size of Cluster Descriptor | ||
826 | */ | ||
827 | err = snd_usb_ctl_msg(chip->dev, | ||
828 | usb_rcvctrlpipe(chip->dev, 0), | ||
829 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
830 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
831 | cluster_id, | ||
832 | snd_usb_ctrl_intf(chip), | ||
833 | &hc_header, sizeof(hc_header)); | ||
834 | if (err < 0) | ||
835 | return err; | ||
836 | else if (err != sizeof(hc_header)) { | ||
837 | dev_err(&dev->dev, | ||
838 | "%u:%d : can't get High Capability descriptor\n", | ||
839 | iface_no, altno); | ||
840 | return -EIO; | ||
841 | } | ||
842 | |||
843 | /* | ||
844 | * Second step: allocate needed amount of memory | ||
845 | * and request Cluster Descriptor | ||
846 | */ | ||
847 | wLength = le16_to_cpu(hc_header.wLength); | ||
848 | cluster = kzalloc(wLength, GFP_KERNEL); | ||
849 | if (!cluster) | ||
850 | return -ENOMEM; | ||
851 | err = snd_usb_ctl_msg(chip->dev, | ||
852 | usb_rcvctrlpipe(chip->dev, 0), | ||
853 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
854 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
855 | cluster_id, | ||
856 | snd_usb_ctrl_intf(chip), | ||
857 | cluster, wLength); | ||
858 | if (err < 0) { | ||
859 | kfree(cluster); | ||
860 | return err; | ||
861 | } else if (err != wLength) { | ||
862 | dev_err(&dev->dev, | ||
863 | "%u:%d : can't get Cluster Descriptor\n", | ||
864 | iface_no, altno); | ||
865 | kfree(cluster); | ||
866 | return -EIO; | ||
867 | } | ||
868 | |||
869 | num_channels = cluster->bNrChannels; | ||
870 | chmap_v3 = convert_chmap_v3(cluster); | ||
871 | |||
872 | kfree(cluster); | ||
873 | |||
874 | format = le64_to_cpu(as->bmFormats); | ||
875 | |||
876 | /* lookup the terminal associated to this interface | ||
877 | * to extract the clock */ | ||
878 | input_term = snd_usb_find_input_terminal_descriptor( | ||
879 | chip->ctrl_intf, | ||
880 | as->bTerminalLink); | ||
881 | |||
882 | if (input_term) { | ||
883 | clock = input_term->bCSourceID; | ||
884 | break; | ||
885 | } | ||
886 | |||
887 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
888 | as->bTerminalLink); | ||
889 | if (output_term) { | ||
890 | clock = output_term->bCSourceID; | ||
891 | break; | ||
892 | } | ||
893 | |||
894 | dev_err(&dev->dev, | ||
895 | "%u:%d : bogus bTerminalLink %d\n", | ||
896 | iface_no, altno, as->bTerminalLink); | ||
897 | continue; | ||
898 | } | ||
899 | } | ||
900 | |||
901 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { | ||
902 | /* get format type */ | ||
903 | fmt = snd_usb_find_csint_desc(alts->extra, | ||
904 | alts->extralen, | ||
905 | NULL, UAC_FORMAT_TYPE); | ||
906 | if (!fmt) { | ||
907 | dev_err(&dev->dev, | ||
908 | "%u:%d : no UAC_FORMAT_TYPE desc\n", | ||
909 | iface_no, altno); | ||
910 | continue; | ||
911 | } | ||
912 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) | ||
913 | || ((protocol == UAC_VERSION_2) && | ||
914 | (fmt->bLength < 6))) { | ||
915 | dev_err(&dev->dev, | ||
916 | "%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
917 | iface_no, altno); | ||
918 | continue; | ||
919 | } | ||
920 | 1094 | ||
921 | /* | 1095 | /* |
922 | * Blue Microphones workaround: The last altsetting is | 1096 | * Blue Microphones workaround: The last altsetting is |
923 | * identical with the previous one, except for a larger | 1097 | * identical with the previous one, except for a larger |
924 | * packet size, but is actually a mislabeled two-channel | 1098 | * packet size, but is actually a mislabeled two-channel |
925 | * setting; ignore it. | 1099 | * setting; ignore it. |
1100 | * | ||
1101 | * Part 1: prepare quirk flag | ||
926 | */ | 1102 | */ |
927 | if (fmt->bNrChannels == 1 && | 1103 | if (altno == 2 && num == 3 && |
928 | fmt->bSubframeSize == 2 && | ||
929 | altno == 2 && num == 3 && | ||
930 | fp && fp->altsetting == 1 && fp->channels == 1 && | 1104 | fp && fp->altsetting == 1 && fp->channels == 1 && |
931 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | 1105 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && |
932 | protocol == UAC_VERSION_1 && | 1106 | protocol == UAC_VERSION_1 && |
933 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | 1107 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == |
934 | fp->maxpacksize * 2) | 1108 | fp->maxpacksize * 2) |
935 | continue; | 1109 | bm_quirk = 1; |
936 | } | ||
937 | |||
938 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | ||
939 | if (!fp) | ||
940 | return -ENOMEM; | ||
941 | 1110 | ||
942 | fp->iface = iface_no; | 1111 | fp = snd_usb_get_audioformat_uac12(chip, alts, protocol, |
943 | fp->altsetting = altno; | 1112 | iface_no, i, altno, |
944 | fp->altset_idx = i; | 1113 | stream, bm_quirk); |
945 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | 1114 | break; |
946 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | 1115 | } |
947 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); | 1116 | case UAC_VERSION_3: |
948 | fp->protocol = protocol; | 1117 | fp = snd_usb_get_audioformat_uac3(chip, alts, |
949 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | 1118 | iface_no, i, altno, stream); |
950 | fp->channels = num_channels; | 1119 | break; |
951 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | ||
952 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | ||
953 | * (fp->maxpacksize & 0x7ff); | ||
954 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); | ||
955 | fp->clock = clock; | ||
956 | INIT_LIST_HEAD(&fp->list); | ||
957 | |||
958 | /* some quirks for attributes here */ | ||
959 | snd_usb_audioformat_attributes_quirk(chip, fp, stream); | ||
960 | |||
961 | /* ok, let's parse further... */ | ||
962 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { | ||
963 | if (snd_usb_parse_audio_format(chip, fp, format, | ||
964 | fmt, stream) < 0) { | ||
965 | kfree(fp->rate_table); | ||
966 | kfree(fp); | ||
967 | fp = NULL; | ||
968 | continue; | ||
969 | } | ||
970 | } else { | ||
971 | struct uac3_as_header_descriptor *as; | ||
972 | |||
973 | as = snd_usb_find_csint_desc(alts->extra, | ||
974 | alts->extralen, | ||
975 | NULL, UAC_AS_GENERAL); | ||
976 | |||
977 | if (snd_usb_parse_audio_format_v3(chip, fp, as, | ||
978 | stream) < 0) { | ||
979 | kfree(fp->rate_table); | ||
980 | kfree(fp); | ||
981 | fp = NULL; | ||
982 | continue; | ||
983 | } | ||
984 | } | 1120 | } |
985 | 1121 | ||
986 | /* Create chmap */ | 1122 | if (!fp) |
987 | if (fp->channels != num_channels) | 1123 | continue; |
988 | chconfig = 0; | 1124 | else if (IS_ERR(fp)) |
989 | 1125 | return PTR_ERR(fp); | |
990 | if (protocol == UAC_VERSION_3) | ||
991 | fp->chmap = chmap_v3; | ||
992 | else | ||
993 | fp->chmap = convert_chmap(fp->channels, chconfig, | ||
994 | protocol); | ||
995 | 1126 | ||
996 | dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); | 1127 | dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); |
997 | err = snd_usb_add_audio_stream(chip, stream, fp); | 1128 | err = snd_usb_add_audio_stream(chip, stream, fp); |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 4d5c89a7ba2b..b9faeca645fd 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -49,6 +49,8 @@ struct snd_usb_audio { | |||
49 | int num_suspended_intf; | 49 | int num_suspended_intf; |
50 | int sample_rate_read_error; | 50 | int sample_rate_read_error; |
51 | 51 | ||
52 | int badd_profile; /* UAC3 BADD profile */ | ||
53 | |||
52 | struct list_head pcm_list; /* list of pcm streams */ | 54 | struct list_head pcm_list; /* list of pcm streams */ |
53 | struct list_head ep_list; /* list of audio-related endpoints */ | 55 | struct list_head ep_list; /* list of audio-related endpoints */ |
54 | int pcm_devs; | 56 | int pcm_devs; |
@@ -59,6 +61,9 @@ struct snd_usb_audio { | |||
59 | 61 | ||
60 | int setup; /* from the 'device_setup' module param */ | 62 | int setup; /* from the 'device_setup' module param */ |
61 | bool autoclock; /* from the 'autoclock' module param */ | 63 | bool autoclock; /* from the 'autoclock' module param */ |
64 | bool keep_iface; /* keep interface/altset after closing | ||
65 | * or parameter change | ||
66 | */ | ||
62 | 67 | ||
63 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ | 68 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ |
64 | }; | 69 | }; |
@@ -109,6 +114,7 @@ enum quirk_type { | |||
109 | struct snd_usb_audio_quirk { | 114 | struct snd_usb_audio_quirk { |
110 | const char *vendor_name; | 115 | const char *vendor_name; |
111 | const char *product_name; | 116 | const char *product_name; |
117 | const char *profile_name; /* override the card->longname */ | ||
112 | int16_t ifnum; | 118 | int16_t ifnum; |
113 | uint16_t type; | 119 | uint16_t type; |
114 | const void *data; | 120 | const void *data; |
@@ -121,4 +127,6 @@ struct snd_usb_audio_quirk { | |||
121 | int snd_usb_lock_shutdown(struct snd_usb_audio *chip); | 127 | int snd_usb_lock_shutdown(struct snd_usb_audio *chip); |
122 | void snd_usb_unlock_shutdown(struct snd_usb_audio *chip); | 128 | void snd_usb_unlock_shutdown(struct snd_usb_audio *chip); |
123 | 129 | ||
130 | extern bool snd_usb_use_vmalloc; | ||
131 | |||
124 | #endif /* __USBAUDIO_H */ | 132 | #endif /* __USBAUDIO_H */ |