summaryrefslogtreecommitdiffstats
path: root/sound/usb/mixer.c
diff options
context:
space:
mode:
authorRuslan Bilovol <ruslan.bilovol@gmail.com>2018-05-03 21:24:04 -0400
committerTakashi Iwai <tiwai@suse.de>2018-05-13 02:54:35 -0400
commit17156f23e93c0f59e06dd2aaffd06221341caaee (patch)
treef7eac9dcff74c160bc43f1a032b5d15647fbe1d8 /sound/usb/mixer.c
parent10aa7cad37d330dbff6a285af56dc4a7153a8f00 (diff)
ALSA: usb: add UAC3 BADD profiles support
Recently released USB Audio Class 3.0 specification contains BADD (Basic Audio Device Definition) document which describes pre-defined UAC3 configurations. BADD support is mandatory for UAC3 devices, it should be implemented as a separate USB device configuration. As per BADD document, class-specific descriptors shall not be included in the Device’s Configuration descriptor ("inferred"), but host can guess them from BADD profile number, number of endpoints and their max packed sizes. This patch adds support of all BADD profiles from the spec Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com> Tested-by: Jorge Sanjuan <jorge.sanjuan@codethink.co.uk> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r--sound/usb/mixer.c327
1 files changed, 296 insertions, 31 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 76417943ff85..4987982250d5 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
114static const struct usbmix_name_map * 114static const struct usbmix_name_map *
115find_map(struct mixer_build *state, int unitid, int control) 115find_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;
@@ -1333,16 +1331,16 @@ static struct usb_feature_control_info *get_feature_control_info(int control)
1333 return NULL; 1331 return NULL;
1334} 1332}
1335 1333
1336static void build_feature_ctl(struct mixer_build *state, void *raw_desc, 1334static void __build_feature_ctl(struct usb_mixer_interface *mixer,
1337 unsigned int ctl_mask, int control, 1335 const struct usbmix_name_map *imap,
1338 struct usb_audio_term *iterm, int unitid, 1336 unsigned int ctl_mask, int control,
1339 int readonly_mask) 1337 struct usb_audio_term *iterm,
1338 struct usb_audio_term *oterm,
1339 int unitid, int nameid, int readonly_mask)
1340{ 1340{
1341 struct uac_feature_unit_descriptor *desc = raw_desc;
1342 struct usb_feature_control_info *ctl_info; 1341 struct usb_feature_control_info *ctl_info;
1343 unsigned int len = 0; 1342 unsigned int len = 0;
1344 int mapped_name = 0; 1343 int mapped_name = 0;
1345 int nameid = uac_feature_unit_iFeature(desc);
1346 struct snd_kcontrol *kctl; 1344 struct snd_kcontrol *kctl;
1347 struct usb_mixer_elem_info *cval; 1345 struct usb_mixer_elem_info *cval;
1348 const struct usbmix_name_map *map; 1346 const struct usbmix_name_map *map;
@@ -1353,14 +1351,14 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1353 return; 1351 return;
1354 } 1352 }
1355 1353
1356 map = find_map(state, unitid, control); 1354 map = find_map(imap, unitid, control);
1357 if (check_ignored_ctl(map)) 1355 if (check_ignored_ctl(map))
1358 return; 1356 return;
1359 1357
1360 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1358 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
1361 if (!cval) 1359 if (!cval)
1362 return; 1360 return;
1363 snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); 1361 snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid);
1364 cval->control = control; 1362 cval->control = control;
1365 cval->cmask = ctl_mask; 1363 cval->cmask = ctl_mask;
1366 1364
@@ -1369,7 +1367,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1369 kfree(cval); 1367 kfree(cval);
1370 return; 1368 return;
1371 } 1369 }
1372 if (state->mixer->protocol == UAC_VERSION_1) 1370 if (mixer->protocol == UAC_VERSION_1)
1373 cval->val_type = ctl_info->type; 1371 cval->val_type = ctl_info->type;
1374 else /* UAC_VERSION_2 */ 1372 else /* UAC_VERSION_2 */
1375 cval->val_type = ctl_info->type_uac2 >= 0 ? 1373 cval->val_type = ctl_info->type_uac2 >= 0 ?
@@ -1398,7 +1396,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1398 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); 1396 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
1399 1397
1400 if (!kctl) { 1398 if (!kctl) {
1401 usb_audio_err(state->chip, "cannot malloc kcontrol\n"); 1399 usb_audio_err(mixer->chip, "cannot malloc kcontrol\n");
1402 kfree(cval); 1400 kfree(cval);
1403 return; 1401 return;
1404 } 1402 }
@@ -1407,7 +1405,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1407 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); 1405 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1408 mapped_name = len != 0; 1406 mapped_name = len != 0;
1409 if (!len && nameid) 1407 if (!len && nameid)
1410 len = snd_usb_copy_string_desc(state->chip, nameid, 1408 len = snd_usb_copy_string_desc(mixer->chip, nameid,
1411 kctl->id.name, sizeof(kctl->id.name)); 1409 kctl->id.name, sizeof(kctl->id.name));
1412 1410
1413 switch (control) { 1411 switch (control) {
@@ -1422,10 +1420,12 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1422 * - otherwise, anonymous name. 1420 * - otherwise, anonymous name.
1423 */ 1421 */
1424 if (!len) { 1422 if (!len) {
1425 len = get_term_name(state->chip, iterm, kctl->id.name, 1423 if (iterm)
1426 sizeof(kctl->id.name), 1); 1424 len = get_term_name(mixer->chip, iterm,
1427 if (!len) 1425 kctl->id.name,
1428 len = get_term_name(state->chip, &state->oterm, 1426 sizeof(kctl->id.name), 1);
1427 if (!len && oterm)
1428 len = get_term_name(mixer->chip, oterm,
1429 kctl->id.name, 1429 kctl->id.name,
1430 sizeof(kctl->id.name), 1); 1430 sizeof(kctl->id.name), 1);
1431 if (!len) 1431 if (!len)
@@ -1434,15 +1434,15 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1434 } 1434 }
1435 1435
1436 if (!mapped_name) 1436 if (!mapped_name)
1437 check_no_speaker_on_headset(kctl, state->mixer->chip->card); 1437 check_no_speaker_on_headset(kctl, mixer->chip->card);
1438 1438
1439 /* 1439 /*
1440 * determine the stream direction: 1440 * determine the stream direction:
1441 * if the connected output is USB stream, then it's likely a 1441 * if the connected output is USB stream, then it's likely a
1442 * capture stream. otherwise it should be playback (hopefully :) 1442 * capture stream. otherwise it should be playback (hopefully :)
1443 */ 1443 */
1444 if (!mapped_name && !(state->oterm.type >> 16)) { 1444 if (!mapped_name && oterm && !(oterm->type >> 16)) {
1445 if ((state->oterm.type & 0xff00) == 0x0100) 1445 if ((oterm->type & 0xff00) == 0x0100)
1446 append_ctl_name(kctl, " Capture"); 1446 append_ctl_name(kctl, " Capture");
1447 else 1447 else
1448 append_ctl_name(kctl, " Playback"); 1448 append_ctl_name(kctl, " Playback");
@@ -1470,7 +1470,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1470 } 1470 }
1471 } 1471 }
1472 1472
1473 snd_usb_mixer_fu_apply_quirk(state->mixer, cval, unitid, kctl); 1473 snd_usb_mixer_fu_apply_quirk(mixer, cval, unitid, kctl);
1474 1474
1475 range = (cval->max - cval->min) / cval->res; 1475 range = (cval->max - cval->min) / cval->res;
1476 /* 1476 /*
@@ -1479,21 +1479,41 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1479 * devices. It will definitively catch all buggy Logitech devices. 1479 * devices. It will definitively catch all buggy Logitech devices.
1480 */ 1480 */
1481 if (range > 384) { 1481 if (range > 384) {
1482 usb_audio_warn(state->chip, 1482 usb_audio_warn(mixer->chip,
1483 "Warning! Unlikely big volume range (=%u), cval->res is probably wrong.", 1483 "Warning! Unlikely big volume range (=%u), cval->res is probably wrong.",
1484 range); 1484 range);
1485 usb_audio_warn(state->chip, 1485 usb_audio_warn(mixer->chip,
1486 "[%d] FU [%s] ch = %d, val = %d/%d/%d", 1486 "[%d] FU [%s] ch = %d, val = %d/%d/%d",
1487 cval->head.id, kctl->id.name, cval->channels, 1487 cval->head.id, kctl->id.name, cval->channels,
1488 cval->min, cval->max, cval->res); 1488 cval->min, cval->max, cval->res);
1489 } 1489 }
1490 1490
1491 usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", 1491 usb_audio_dbg(mixer->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
1492 cval->head.id, kctl->id.name, cval->channels, 1492 cval->head.id, kctl->id.name, cval->channels,
1493 cval->min, cval->max, cval->res); 1493 cval->min, cval->max, cval->res);
1494 snd_usb_mixer_add_control(&cval->head, kctl); 1494 snd_usb_mixer_add_control(&cval->head, kctl);
1495} 1495}
1496 1496
1497static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1498 unsigned int ctl_mask, int control,
1499 struct usb_audio_term *iterm, int unitid,
1500 int readonly_mask)
1501{
1502 struct uac_feature_unit_descriptor *desc = raw_desc;
1503 int nameid = uac_feature_unit_iFeature(desc);
1504
1505 __build_feature_ctl(state->mixer, state->map, ctl_mask, control,
1506 iterm, &state->oterm, unitid, nameid, readonly_mask);
1507}
1508
1509static void build_feature_ctl_badd(struct usb_mixer_interface *mixer,
1510 unsigned int ctl_mask, int control, int unitid,
1511 const struct usbmix_name_map *badd_map)
1512{
1513 __build_feature_ctl(mixer, badd_map, ctl_mask, control,
1514 NULL, NULL, unitid, 0, 0);
1515}
1516
1497static void get_connector_control_name(struct mixer_build *state, 1517static void get_connector_control_name(struct mixer_build *state,
1498 struct usb_audio_term *term, 1518 struct usb_audio_term *term,
1499 bool is_input, char *name, int name_size) 1519 bool is_input, char *name, int name_size)
@@ -1807,7 +1827,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
1807 struct snd_kcontrol *kctl; 1827 struct snd_kcontrol *kctl;
1808 const struct usbmix_name_map *map; 1828 const struct usbmix_name_map *map;
1809 1829
1810 map = find_map(state, unitid, 0); 1830 map = find_map(state->map, unitid, 0);
1811 if (check_ignored_ctl(map)) 1831 if (check_ignored_ctl(map))
1812 return; 1832 return;
1813 1833
@@ -2106,7 +2126,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
2106 2126
2107 if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1)))) 2127 if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
2108 continue; 2128 continue;
2109 map = find_map(state, unitid, valinfo->control); 2129 map = find_map(state->map, unitid, valinfo->control);
2110 if (check_ignored_ctl(map)) 2130 if (check_ignored_ctl(map))
2111 continue; 2131 continue;
2112 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 2132 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -2310,7 +2330,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
2310 if (desc->bNrInPins == 1) /* only one ? nonsense! */ 2330 if (desc->bNrInPins == 1) /* only one ? nonsense! */
2311 return 0; 2331 return 0;
2312 2332
2313 map = find_map(state, unitid, 0); 2333 map = find_map(state->map, unitid, 0);
2314 if (check_ignored_ctl(map)) 2334 if (check_ignored_ctl(map))
2315 return 0; 2335 return 0;
2316 2336
@@ -2497,6 +2517,246 @@ static int snd_usb_mixer_dev_free(struct snd_device *device)
2497 return 0; 2517 return 0;
2498} 2518}
2499 2519
2520/* UAC3 predefined channels configuration */
2521struct uac3_badd_profile {
2522 int subclass;
2523 const char *name;
2524 int c_chmask; /* capture channels mask */
2525 int p_chmask; /* playback channels mask */
2526 int st_chmask; /* side tone mixing channel mask */
2527};
2528
2529static struct uac3_badd_profile uac3_badd_profiles[] = {
2530 {
2531 /*
2532 * BAIF, BAOF or combination of both
2533 * IN: Mono or Stereo cfg, Mono alt possible
2534 * OUT: Mono or Stereo cfg, Mono alt possible
2535 */
2536 .subclass = UAC3_FUNCTION_SUBCLASS_GENERIC_IO,
2537 .name = "GENERIC IO",
2538 .c_chmask = -1, /* dynamic channels */
2539 .p_chmask = -1, /* dynamic channels */
2540 },
2541 {
2542 /* BAOF; Stereo only cfg, Mono alt possible */
2543 .subclass = UAC3_FUNCTION_SUBCLASS_HEADPHONE,
2544 .name = "HEADPHONE",
2545 .p_chmask = 3,
2546 },
2547 {
2548 /* BAOF; Mono or Stereo cfg, Mono alt possible */
2549 .subclass = UAC3_FUNCTION_SUBCLASS_SPEAKER,
2550 .name = "SPEAKER",
2551 .p_chmask = -1, /* dynamic channels */
2552 },
2553 {
2554 /* BAIF; Mono or Stereo cfg, Mono alt possible */
2555 .subclass = UAC3_FUNCTION_SUBCLASS_MICROPHONE,
2556 .name = "MICROPHONE",
2557 .c_chmask = -1, /* dynamic channels */
2558 },
2559 {
2560 /*
2561 * BAIOF topology
2562 * IN: Mono only
2563 * OUT: Mono or Stereo cfg, Mono alt possible
2564 */
2565 .subclass = UAC3_FUNCTION_SUBCLASS_HEADSET,
2566 .name = "HEADSET",
2567 .c_chmask = 1,
2568 .p_chmask = -1, /* dynamic channels */
2569 .st_chmask = 1,
2570 },
2571 {
2572 /* BAIOF; IN: Mono only; OUT: Stereo only, Mono alt possible */
2573 .subclass = UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER,
2574 .name = "HEADSET ADAPTER",
2575 .c_chmask = 1,
2576 .p_chmask = 3,
2577 .st_chmask = 1,
2578 },
2579 {
2580 /* BAIF + BAOF; IN: Mono only; OUT: Mono only */
2581 .subclass = UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE,
2582 .name = "SPEAKERPHONE",
2583 .c_chmask = 1,
2584 .p_chmask = 1,
2585 },
2586 { 0 } /* terminator */
2587};
2588
2589static bool uac3_badd_func_has_valid_channels(struct usb_mixer_interface *mixer,
2590 struct uac3_badd_profile *f,
2591 int c_chmask, int p_chmask)
2592{
2593 /*
2594 * If both playback/capture channels are dynamic, make sure
2595 * at least one channel is present
2596 */
2597 if (f->c_chmask < 0 && f->p_chmask < 0) {
2598 if (!c_chmask && !p_chmask) {
2599 usb_audio_warn(mixer->chip, "BAAD %s: no channels?",
2600 f->name);
2601 return false;
2602 }
2603 return true;
2604 }
2605
2606 if ((f->c_chmask < 0 && !c_chmask) ||
2607 (f->c_chmask >= 0 && f->c_chmask != c_chmask)) {
2608 usb_audio_warn(mixer->chip, "BAAD %s c_chmask mismatch",
2609 f->name);
2610 return false;
2611 }
2612 if ((f->p_chmask < 0 && !p_chmask) ||
2613 (f->p_chmask >= 0 && f->p_chmask != p_chmask)) {
2614 usb_audio_warn(mixer->chip, "BAAD %s p_chmask mismatch",
2615 f->name);
2616 return false;
2617 }
2618 return true;
2619}
2620
2621/*
2622 * create mixer controls for UAC3 BADD profiles
2623 *
2624 * UAC3 BADD device doesn't contain CS descriptors thus we will guess everything
2625 *
2626 * BADD device may contain Mixer Unit, which doesn't have any controls, skip it
2627 */
2628static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,
2629 int ctrlif)
2630{
2631 struct usb_device *dev = mixer->chip->dev;
2632 struct usb_interface_assoc_descriptor *assoc;
2633 int badd_profile = mixer->chip->badd_profile;
2634 struct uac3_badd_profile *f;
2635 const struct usbmix_ctl_map *map;
2636 int p_chmask = 0, c_chmask = 0, st_chmask = 0;
2637 int i;
2638
2639 assoc = usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
2640
2641 /* Detect BADD capture/playback channels from AS EP descriptors */
2642 for (i = 0; i < assoc->bInterfaceCount; i++) {
2643 int intf = assoc->bFirstInterface + i;
2644
2645 struct usb_interface *iface;
2646 struct usb_host_interface *alts;
2647 struct usb_interface_descriptor *altsd;
2648 unsigned int maxpacksize;
2649 char dir_in;
2650 int chmask, num;
2651
2652 if (intf == ctrlif)
2653 continue;
2654
2655 iface = usb_ifnum_to_if(dev, intf);
2656 num = iface->num_altsetting;
2657
2658 if (num < 2)
2659 return -EINVAL;
2660
2661 /*
2662 * The number of Channels in an AudioStreaming interface
2663 * and the audio sample bit resolution (16 bits or 24
2664 * bits) can be derived from the wMaxPacketSize field in
2665 * the Standard AS Audio Data Endpoint descriptor in
2666 * Alternate Setting 1
2667 */
2668 alts = &iface->altsetting[1];
2669 altsd = get_iface_desc(alts);
2670
2671 if (altsd->bNumEndpoints < 1)
2672 return -EINVAL;
2673
2674 /* check direction */
2675 dir_in = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN);
2676 maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
2677
2678 switch (maxpacksize) {
2679 default:
2680 usb_audio_err(mixer->chip,
2681 "incorrect wMaxPacketSize 0x%x for BADD profile\n",
2682 maxpacksize);
2683 return -EINVAL;
2684 case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16:
2685 case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16:
2686 case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24:
2687 case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24:
2688 chmask = 1;
2689 break;
2690 case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16:
2691 case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16:
2692 case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24:
2693 case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24:
2694 chmask = 3;
2695 break;
2696 }
2697
2698 if (dir_in)
2699 c_chmask = chmask;
2700 else
2701 p_chmask = chmask;
2702 }
2703
2704 usb_audio_dbg(mixer->chip,
2705 "UAC3 BADD profile 0x%x: detected c_chmask=%d p_chmask=%d\n",
2706 badd_profile, c_chmask, p_chmask);
2707
2708 /* check the mapping table */
2709 for (map = uac3_badd_usbmix_ctl_maps; map->id; map++) {
2710 if (map->id == badd_profile)
2711 break;
2712 }
2713
2714 if (!map->id)
2715 return -EINVAL;
2716
2717 for (f = uac3_badd_profiles; f->name; f++) {
2718 if (badd_profile == f->subclass)
2719 break;
2720 }
2721 if (!f->name)
2722 return -EINVAL;
2723 if (!uac3_badd_func_has_valid_channels(mixer, f, c_chmask, p_chmask))
2724 return -EINVAL;
2725 st_chmask = f->st_chmask;
2726
2727 /* Playback */
2728 if (p_chmask) {
2729 /* Master channel, always writable */
2730 build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE,
2731 UAC3_BADD_FU_ID2, map->map);
2732 /* Mono/Stereo volume channels, always writable */
2733 build_feature_ctl_badd(mixer, p_chmask, UAC_FU_VOLUME,
2734 UAC3_BADD_FU_ID2, map->map);
2735 }
2736
2737 /* Capture */
2738 if (c_chmask) {
2739 /* Master channel, always writable */
2740 build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE,
2741 UAC3_BADD_FU_ID5, map->map);
2742 /* Mono/Stereo volume channels, always writable */
2743 build_feature_ctl_badd(mixer, c_chmask, UAC_FU_VOLUME,
2744 UAC3_BADD_FU_ID5, map->map);
2745 }
2746
2747 /* Side tone-mixing */
2748 if (st_chmask) {
2749 /* Master channel, always writable */
2750 build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE,
2751 UAC3_BADD_FU_ID7, map->map);
2752 /* Mono volume channel, always writable */
2753 build_feature_ctl_badd(mixer, 1, UAC_FU_VOLUME,
2754 UAC3_BADD_FU_ID7, map->map);
2755 }
2756
2757 return 0;
2758}
2759
2500/* 2760/*
2501 * create mixer controls 2761 * create mixer controls
2502 * 2762 *
@@ -2882,9 +3142,14 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2882 break; 3142 break;
2883 } 3143 }
2884 3144
2885 if ((err = snd_usb_mixer_controls(mixer)) < 0 || 3145 if (mixer->protocol == UAC_VERSION_3 &&
2886 (err = snd_usb_mixer_status_create(mixer)) < 0) 3146 chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {
3147 if ((err = snd_usb_mixer_controls_badd(mixer, ctrlif)) < 0)
3148 goto _error;
3149 } else if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
3150 (err = snd_usb_mixer_status_create(mixer)) < 0) {
2887 goto _error; 3151 goto _error;
3152 }
2888 err = create_keep_iface_ctl(mixer); 3153 err = create_keep_iface_ctl(mixer);
2889 if (err < 0) 3154 if (err < 0)
2890 goto _error; 3155 goto _error;