summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/usb/card.c14
-rw-r--r--sound/usb/clock.c9
-rw-r--r--sound/usb/mixer.c327
-rw-r--r--sound/usb/mixer_maps.c65
-rw-r--r--sound/usb/stream.c83
-rw-r--r--sound/usb/usbaudio.h2
6 files changed, 459 insertions, 41 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 0d7a5d70634e..f6c3c1cd591e 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -307,6 +307,20 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
307 return -EINVAL; 307 return -EINVAL;
308 } 308 }
309 309
310 if (protocol == UAC_VERSION_3) {
311 int badd = assoc->bFunctionSubClass;
312
313 if (badd != UAC3_FUNCTION_SUBCLASS_FULL_ADC_3_0 &&
314 (badd < UAC3_FUNCTION_SUBCLASS_GENERIC_IO ||
315 badd > UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE)) {
316 dev_err(&dev->dev,
317 "Unsupported UAC3 BADD profile\n");
318 return -EINVAL;
319 }
320
321 chip->badd_profile = badd;
322 }
323
310 for (i = 0; i < assoc->bInterfaceCount; i++) { 324 for (i = 0; i < assoc->bInterfaceCount; i++) {
311 int intf = assoc->bFirstInterface + i; 325 int intf = assoc->bFirstInterface + i;
312 326
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 0b030d8fe3fa..17673f37fcc8 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -587,8 +587,15 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
587 default: 587 default:
588 return set_sample_rate_v1(chip, iface, alts, fmt, rate); 588 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
589 589
590 case UAC_VERSION_2:
591 case UAC_VERSION_3: 590 case UAC_VERSION_3:
591 if (chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {
592 if (rate != UAC3_BADD_SAMPLING_RATE)
593 return -ENXIO;
594 else
595 return 0;
596 }
597 /* fall through */
598 case UAC_VERSION_2:
592 return set_sample_rate_v2v3(chip, iface, alts, fmt, rate); 599 return set_sample_rate_v2v3(chip, iface, alts, fmt, rate);
593 } 600 }
594} 601}
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;
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
492static 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};
497static struct usbmix_name_map uac3_badd_headphone_map[] = {
498 { UAC3_BADD_FU_ID2, "Headphone Playback" },
499 { 0 } /* terminator */
500};
501static struct usbmix_name_map uac3_badd_speaker_map[] = {
502 { UAC3_BADD_FU_ID2, "Speaker Playback" },
503 { 0 } /* terminator */
504};
505static 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 */
510static 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};
516static 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
522static 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/stream.c b/sound/usb/stream.c
index 764be07474a8..de8bbb304199 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -817,15 +817,67 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
817 struct uac3_input_terminal_descriptor *input_term; 817 struct uac3_input_terminal_descriptor *input_term;
818 struct uac3_output_terminal_descriptor *output_term; 818 struct uac3_output_terminal_descriptor *output_term;
819 struct uac3_cluster_header_descriptor *cluster; 819 struct uac3_cluster_header_descriptor *cluster;
820 struct uac3_as_header_descriptor *as; 820 struct uac3_as_header_descriptor *as = NULL;
821 struct uac3_hc_descriptor_header hc_header; 821 struct uac3_hc_descriptor_header hc_header;
822 struct snd_pcm_chmap_elem *chmap; 822 struct snd_pcm_chmap_elem *chmap;
823 unsigned char badd_profile;
824 u64 badd_formats = 0;
823 unsigned int num_channels; 825 unsigned int num_channels;
824 struct audioformat *fp; 826 struct audioformat *fp;
825 u16 cluster_id, wLength; 827 u16 cluster_id, wLength;
826 int clock = 0; 828 int clock = 0;
827 int err; 829 int err;
828 830
831 badd_profile = chip->badd_profile;
832
833 if (badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {
834 unsigned int maxpacksize =
835 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
836
837 switch (maxpacksize) {
838 default:
839 dev_err(&dev->dev,
840 "%u:%d : incorrect wMaxPacketSize for BADD profile\n",
841 iface_no, altno);
842 return NULL;
843 case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16:
844 case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16:
845 badd_formats = SNDRV_PCM_FMTBIT_S16_LE;
846 num_channels = 1;
847 break;
848 case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24:
849 case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24:
850 badd_formats = SNDRV_PCM_FMTBIT_S24_3LE;
851 num_channels = 1;
852 break;
853 case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16:
854 case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16:
855 badd_formats = SNDRV_PCM_FMTBIT_S16_LE;
856 num_channels = 2;
857 break;
858 case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24:
859 case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24:
860 badd_formats = SNDRV_PCM_FMTBIT_S24_3LE;
861 num_channels = 2;
862 break;
863 }
864
865 chmap = kzalloc(sizeof(*chmap), GFP_KERNEL);
866 if (!chmap)
867 return ERR_PTR(-ENOMEM);
868
869 if (num_channels == 1) {
870 chmap->map[0] = SNDRV_CHMAP_MONO;
871 } else {
872 chmap->map[0] = SNDRV_CHMAP_FL;
873 chmap->map[1] = SNDRV_CHMAP_FR;
874 }
875
876 chmap->channels = num_channels;
877 clock = UAC3_BADD_CS_ID9;
878 goto found_clock;
879 }
880
829 as = snd_usb_find_csint_desc(alts->extra, alts->extralen, 881 as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
830 NULL, UAC_AS_GENERAL); 882 NULL, UAC_AS_GENERAL);
831 if (!as) { 883 if (!as) {
@@ -931,16 +983,29 @@ found_clock:
931 if (!fp) 983 if (!fp)
932 return ERR_PTR(-ENOMEM); 984 return ERR_PTR(-ENOMEM);
933 985
934 fp->attributes = parse_uac_endpoint_attributes(chip, alts,
935 UAC_VERSION_3,
936 iface_no);
937 fp->chmap = chmap; 986 fp->chmap = chmap;
938 987
939 /* ok, let's parse further... */ 988 if (badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {
940 if (snd_usb_parse_audio_format_v3(chip, fp, as, stream) < 0) { 989 fp->attributes = 0; /* No attributes */
941 kfree(fp->rate_table); 990
942 kfree(fp); 991 fp->fmt_type = UAC_FORMAT_TYPE_I;
943 return NULL; 992 fp->formats = badd_formats;
993
994 fp->nr_rates = 0; /* SNDRV_PCM_RATE_CONTINUOUS */
995 fp->rate_min = UAC3_BADD_SAMPLING_RATE;
996 fp->rate_max = UAC3_BADD_SAMPLING_RATE;
997 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
998
999 } else {
1000 fp->attributes = parse_uac_endpoint_attributes(chip, alts,
1001 UAC_VERSION_3,
1002 iface_no);
1003 /* ok, let's parse further... */
1004 if (snd_usb_parse_audio_format_v3(chip, fp, as, stream) < 0) {
1005 kfree(fp->rate_table);
1006 kfree(fp);
1007 return NULL;
1008 }
944 } 1009 }
945 1010
946 return fp; 1011 return fp;
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 1cb6b3e9483c..7b28cbde22c0 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;