aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/mixer.c87
1 files changed, 47 insertions, 40 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 4e7c2fd9e3b4..994b0385235c 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -860,13 +860,14 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
860 return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); 860 return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
861} 861}
862 862
863static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, 863static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
864 unsigned int ctl_mask, int control, 864 unsigned int ctl_mask, int control,
865 struct usb_audio_term *iterm, int unitid) 865 struct usb_audio_term *iterm, int unitid)
866{ 866{
867 struct uac_feature_unit_descriptor *desc = raw_desc;
867 unsigned int len = 0; 868 unsigned int len = 0;
868 int mapped_name = 0; 869 int mapped_name = 0;
869 int nameid = desc[desc[0] - 1]; 870 int nameid = uac_feature_unit_iFeature(desc);
870 struct snd_kcontrol *kctl; 871 struct snd_kcontrol *kctl;
871 struct usb_mixer_elem_info *cval; 872 struct usb_mixer_elem_info *cval;
872 const struct usbmix_name_map *map; 873 const struct usbmix_name_map *map;
@@ -1032,7 +1033,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1032 1033
1033 channels = (ftr->bLength - 7) / csize - 1; 1034 channels = (ftr->bLength - 7) / csize - 1;
1034 1035
1035 master_bits = snd_usb_combine_bytes(ftr->controls, csize); 1036 master_bits = snd_usb_combine_bytes(ftr->bmaControls, csize);
1036 /* master configuration quirks */ 1037 /* master configuration quirks */
1037 switch (state->chip->usb_id) { 1038 switch (state->chip->usb_id) {
1038 case USB_ID(0x08bb, 0x2702): 1039 case USB_ID(0x08bb, 0x2702):
@@ -1043,14 +1044,14 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1043 break; 1044 break;
1044 } 1045 }
1045 if (channels > 0) 1046 if (channels > 0)
1046 first_ch_bits = snd_usb_combine_bytes(ftr->controls + csize, csize); 1047 first_ch_bits = snd_usb_combine_bytes(ftr->bmaControls + csize, csize);
1047 else 1048 else
1048 first_ch_bits = 0; 1049 first_ch_bits = 0;
1049 /* check all control types */ 1050 /* check all control types */
1050 for (i = 0; i < 10; i++) { 1051 for (i = 0; i < 10; i++) {
1051 unsigned int ch_bits = 0; 1052 unsigned int ch_bits = 0;
1052 for (j = 0; j < channels; j++) { 1053 for (j = 0; j < channels; j++) {
1053 unsigned int mask = snd_usb_combine_bytes(ftr->controls + csize * (j+1), csize); 1054 unsigned int mask = snd_usb_combine_bytes(ftr->bmaControls + csize * (j+1), csize);
1054 if (mask & (1 << i)) 1055 if (mask & (1 << i))
1055 ch_bits |= (1 << j); 1056 ch_bits |= (1 << j);
1056 } 1057 }
@@ -1075,13 +1076,13 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1075 * input channel number (zero based) is given in control field instead. 1076 * input channel number (zero based) is given in control field instead.
1076 */ 1077 */
1077 1078
1078static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc, 1079static void build_mixer_unit_ctl(struct mixer_build *state,
1080 struct uac_mixer_unit_descriptor *desc,
1079 int in_pin, int in_ch, int unitid, 1081 int in_pin, int in_ch, int unitid,
1080 struct usb_audio_term *iterm) 1082 struct usb_audio_term *iterm)
1081{ 1083{
1082 struct usb_mixer_elem_info *cval; 1084 struct usb_mixer_elem_info *cval;
1083 unsigned int input_pins = desc[4]; 1085 unsigned int num_outs = uac_mixer_unit_bNrChannels(desc);
1084 unsigned int num_outs = desc[5 + input_pins];
1085 unsigned int i, len; 1086 unsigned int i, len;
1086 struct snd_kcontrol *kctl; 1087 struct snd_kcontrol *kctl;
1087 const struct usbmix_name_map *map; 1088 const struct usbmix_name_map *map;
@@ -1099,7 +1100,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1099 cval->control = in_ch + 1; /* based on 1 */ 1100 cval->control = in_ch + 1; /* based on 1 */
1100 cval->val_type = USB_MIXER_S16; 1101 cval->val_type = USB_MIXER_S16;
1101 for (i = 0; i < num_outs; i++) { 1102 for (i = 0; i < num_outs; i++) {
1102 if (check_matrix_bitmap(desc + 9 + input_pins, in_ch, i, num_outs)) { 1103 if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc), in_ch, i, num_outs)) {
1103 cval->cmask |= (1 << i); 1104 cval->cmask |= (1 << i);
1104 cval->channels++; 1105 cval->channels++;
1105 } 1106 }
@@ -1132,18 +1133,19 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1132/* 1133/*
1133 * parse a mixer unit 1134 * parse a mixer unit
1134 */ 1135 */
1135static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1136static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
1136{ 1137{
1138 struct uac_mixer_unit_descriptor *desc = raw_desc;
1137 struct usb_audio_term iterm; 1139 struct usb_audio_term iterm;
1138 int input_pins, num_ins, num_outs; 1140 int input_pins, num_ins, num_outs;
1139 int pin, ich, err; 1141 int pin, ich, err;
1140 1142
1141 if (desc[0] < 11 || ! (input_pins = desc[4]) || ! (num_outs = desc[5 + input_pins])) { 1143 if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
1142 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid); 1144 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
1143 return -EINVAL; 1145 return -EINVAL;
1144 } 1146 }
1145 /* no bmControls field (e.g. Maya44) -> ignore */ 1147 /* no bmControls field (e.g. Maya44) -> ignore */
1146 if (desc[0] <= 10 + input_pins) { 1148 if (desc->bLength <= 10 + input_pins) {
1147 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid); 1149 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
1148 return 0; 1150 return 0;
1149 } 1151 }
@@ -1151,10 +1153,10 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigne
1151 num_ins = 0; 1153 num_ins = 0;
1152 ich = 0; 1154 ich = 0;
1153 for (pin = 0; pin < input_pins; pin++) { 1155 for (pin = 0; pin < input_pins; pin++) {
1154 err = parse_audio_unit(state, desc[5 + pin]); 1156 err = parse_audio_unit(state, desc->baSourceID[pin]);
1155 if (err < 0) 1157 if (err < 0)
1156 return err; 1158 return err;
1157 err = check_input_term(state, desc[5 + pin], &iterm); 1159 err = check_input_term(state, desc->baSourceID[pin], &iterm);
1158 if (err < 0) 1160 if (err < 0)
1159 return err; 1161 return err;
1160 num_ins += iterm.channels; 1162 num_ins += iterm.channels;
@@ -1162,7 +1164,7 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigne
1162 int och, ich_has_controls = 0; 1164 int och, ich_has_controls = 0;
1163 1165
1164 for (och = 0; och < num_outs; ++och) { 1166 for (och = 0; och < num_outs; ++och) {
1165 if (check_matrix_bitmap(desc + 9 + input_pins, 1167 if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc),
1166 ich, och, num_outs)) { 1168 ich, och, num_outs)) {
1167 ich_has_controls = 1; 1169 ich_has_controls = 1;
1168 break; 1170 break;
@@ -1323,9 +1325,10 @@ static struct procunit_info extunits[] = {
1323/* 1325/*
1324 * build a processing/extension unit 1326 * build a processing/extension unit
1325 */ 1327 */
1326static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned char *dsc, struct procunit_info *list, char *name) 1328static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
1327{ 1329{
1328 int num_ins = dsc[6]; 1330 struct uac_processing_unit_descriptor *desc = raw_desc;
1331 int num_ins = desc->bNrInPins;
1329 struct usb_mixer_elem_info *cval; 1332 struct usb_mixer_elem_info *cval;
1330 struct snd_kcontrol *kctl; 1333 struct snd_kcontrol *kctl;
1331 int i, err, nameid, type, len; 1334 int i, err, nameid, type, len;
@@ -1340,17 +1343,17 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1340 0, NULL, default_value_info 1343 0, NULL, default_value_info
1341 }; 1344 };
1342 1345
1343 if (dsc[0] < 13 || dsc[0] < 13 + num_ins || dsc[0] < num_ins + dsc[11 + num_ins]) { 1346 if (desc->bLength < 13 || desc->bLength < 13 + num_ins || desc->bLength < num_ins + uac_processing_unit_bControlSize(desc)) {
1344 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid); 1347 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid);
1345 return -EINVAL; 1348 return -EINVAL;
1346 } 1349 }
1347 1350
1348 for (i = 0; i < num_ins; i++) { 1351 for (i = 0; i < num_ins; i++) {
1349 if ((err = parse_audio_unit(state, dsc[7 + i])) < 0) 1352 if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
1350 return err; 1353 return err;
1351 } 1354 }
1352 1355
1353 type = combine_word(&dsc[4]); 1356 type = le16_to_cpu(desc->wProcessType);
1354 for (info = list; info && info->type; info++) 1357 for (info = list; info && info->type; info++)
1355 if (info->type == type) 1358 if (info->type == type)
1356 break; 1359 break;
@@ -1358,8 +1361,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1358 info = &default_info; 1361 info = &default_info;
1359 1362
1360 for (valinfo = info->values; valinfo->control; valinfo++) { 1363 for (valinfo = info->values; valinfo->control; valinfo++) {
1361 /* FIXME: bitmap might be longer than 8bit */ 1364 __u8 *controls = uac_processing_unit_bmControls(desc);
1362 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1)))) 1365
1366 if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
1363 continue; 1367 continue;
1364 map = find_map(state, unitid, valinfo->control); 1368 map = find_map(state, unitid, valinfo->control);
1365 if (check_ignored_ctl(map)) 1369 if (check_ignored_ctl(map))
@@ -1377,9 +1381,10 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1377 1381
1378 /* get min/max values */ 1382 /* get min/max values */
1379 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) { 1383 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) {
1384 __u8 *control_spec = uac_processing_unit_specific(desc);
1380 /* FIXME: hard-coded */ 1385 /* FIXME: hard-coded */
1381 cval->min = 1; 1386 cval->min = 1;
1382 cval->max = dsc[15]; 1387 cval->max = control_spec[0];
1383 cval->res = 1; 1388 cval->res = 1;
1384 cval->initialized = 1; 1389 cval->initialized = 1;
1385 } else { 1390 } else {
@@ -1409,7 +1414,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1409 else if (info->name) 1414 else if (info->name)
1410 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); 1415 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
1411 else { 1416 else {
1412 nameid = dsc[12 + num_ins + dsc[11 + num_ins]]; 1417 nameid = uac_processing_unit_iProcessing(desc);
1413 len = 0; 1418 len = 0;
1414 if (nameid) 1419 if (nameid)
1415 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); 1420 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
@@ -1428,14 +1433,16 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1428} 1433}
1429 1434
1430 1435
1431static int parse_audio_processing_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1436static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
1432{ 1437{
1433 return build_audio_procunit(state, unitid, desc, procunits, "Processing Unit"); 1438 return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
1434} 1439}
1435 1440
1436static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1441static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
1437{ 1442{
1438 return build_audio_procunit(state, unitid, desc, extunits, "Extension Unit"); 1443 /* Note that we parse extension units with processing unit descriptors.
1444 * That's ok as the layout is the same */
1445 return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
1439} 1446}
1440 1447
1441 1448
@@ -1537,9 +1544,9 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
1537/* 1544/*
1538 * parse a selector unit 1545 * parse a selector unit
1539 */ 1546 */
1540static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1547static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
1541{ 1548{
1542 unsigned int num_ins = desc[4]; 1549 struct uac_selector_unit_descriptor *desc = raw_desc;
1543 unsigned int i, nameid, len; 1550 unsigned int i, nameid, len;
1544 int err; 1551 int err;
1545 struct usb_mixer_elem_info *cval; 1552 struct usb_mixer_elem_info *cval;
@@ -1547,17 +1554,17 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1547 const struct usbmix_name_map *map; 1554 const struct usbmix_name_map *map;
1548 char **namelist; 1555 char **namelist;
1549 1556
1550 if (! num_ins || desc[0] < 5 + num_ins) { 1557 if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
1551 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid); 1558 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
1552 return -EINVAL; 1559 return -EINVAL;
1553 } 1560 }
1554 1561
1555 for (i = 0; i < num_ins; i++) { 1562 for (i = 0; i < desc->bNrInPins; i++) {
1556 if ((err = parse_audio_unit(state, desc[5 + i])) < 0) 1563 if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
1557 return err; 1564 return err;
1558 } 1565 }
1559 1566
1560 if (num_ins == 1) /* only one ? nonsense! */ 1567 if (desc->bNrInPins == 1) /* only one ? nonsense! */
1561 return 0; 1568 return 0;
1562 1569
1563 map = find_map(state, unitid, 0); 1570 map = find_map(state, unitid, 0);
@@ -1574,18 +1581,18 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1574 cval->val_type = USB_MIXER_U8; 1581 cval->val_type = USB_MIXER_U8;
1575 cval->channels = 1; 1582 cval->channels = 1;
1576 cval->min = 1; 1583 cval->min = 1;
1577 cval->max = num_ins; 1584 cval->max = desc->bNrInPins;
1578 cval->res = 1; 1585 cval->res = 1;
1579 cval->initialized = 1; 1586 cval->initialized = 1;
1580 1587
1581 namelist = kmalloc(sizeof(char *) * num_ins, GFP_KERNEL); 1588 namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
1582 if (! namelist) { 1589 if (! namelist) {
1583 snd_printk(KERN_ERR "cannot malloc\n"); 1590 snd_printk(KERN_ERR "cannot malloc\n");
1584 kfree(cval); 1591 kfree(cval);
1585 return -ENOMEM; 1592 return -ENOMEM;
1586 } 1593 }
1587#define MAX_ITEM_NAME_LEN 64 1594#define MAX_ITEM_NAME_LEN 64
1588 for (i = 0; i < num_ins; i++) { 1595 for (i = 0; i < desc->bNrInPins; i++) {
1589 struct usb_audio_term iterm; 1596 struct usb_audio_term iterm;
1590 len = 0; 1597 len = 0;
1591 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); 1598 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
@@ -1599,7 +1606,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1599 } 1606 }
1600 len = check_mapped_selector_name(state, unitid, i, namelist[i], 1607 len = check_mapped_selector_name(state, unitid, i, namelist[i],
1601 MAX_ITEM_NAME_LEN); 1608 MAX_ITEM_NAME_LEN);
1602 if (! len && check_input_term(state, desc[5 + i], &iterm) >= 0) 1609 if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
1603 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); 1610 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
1604 if (! len) 1611 if (! len)
1605 sprintf(namelist[i], "Input %d", i); 1612 sprintf(namelist[i], "Input %d", i);
@@ -1615,7 +1622,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1615 kctl->private_value = (unsigned long)namelist; 1622 kctl->private_value = (unsigned long)namelist;
1616 kctl->private_free = usb_mixer_selector_elem_free; 1623 kctl->private_free = usb_mixer_selector_elem_free;
1617 1624
1618 nameid = desc[desc[0] - 1]; 1625 nameid = uac_selector_unit_iSelector(desc);
1619 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); 1626 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1620 if (len) 1627 if (len)
1621 ; 1628 ;
@@ -1634,7 +1641,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1634 } 1641 }
1635 1642
1636 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", 1643 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
1637 cval->id, kctl->id.name, num_ins); 1644 cval->id, kctl->id.name, desc->bNrInPins);
1638 if ((err = add_control_to_empty(state, kctl)) < 0) 1645 if ((err = add_control_to_empty(state, kctl)) < 0)
1639 return err; 1646 return err;
1640 1647