diff options
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r-- | sound/usb/mixer.c | 639 |
1 files changed, 559 insertions, 80 deletions
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 |