aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2010-03-11 15:13:24 -0500
committerTakashi Iwai <tiwai@suse.de>2010-03-12 06:21:12 -0500
commit99fc86450c439039d2ef88d06b222fd51a779176 (patch)
treede18f564ac09bc36f40b4ea4f88ab71c48ce290c
parentf0b5e634ff25e02a64676022ee13284a9c810879 (diff)
ALSA: usb-mixer: parse descriptors with structs
Introduce a number of new structs for mixer, selector, feature and processing units and some static inline helpers to access fields which have dynamic offsets. Use them in mixer.c to parse the descriptors. This is necessary for the upcoming audio v2 parsers. Signed-off-by: Daniel Mack <daniel@caiaq.de> Cc: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/linux/usb/audio.h129
-rw-r--r--sound/usb/mixer.c87
2 files changed, 166 insertions, 50 deletions
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h
index cdad728543ae..bc78a83d0f48 100644
--- a/include/linux/usb/audio.h
+++ b/include/linux/usb/audio.h
@@ -181,6 +181,125 @@ struct uac_feature_unit_descriptor_##ch { \
181 __u8 iFeature; \ 181 __u8 iFeature; \
182} __attribute__ ((packed)) 182} __attribute__ ((packed))
183 183
184/* 4.3.2.3 Mixer Unit Descriptor */
185struct uac_mixer_unit_descriptor {
186 __u8 bLength;
187 __u8 bDescriptorType;
188 __u8 bDescriptorSubtype;
189 __u8 bUnitID;
190 __u8 bNrInPins;
191 __u8 baSourceID[];
192} __attribute__ ((packed));
193
194static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc)
195{
196 return desc->baSourceID[desc->bNrInPins];
197}
198
199static inline __u16 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc)
200{
201 return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
202 desc->baSourceID[desc->bNrInPins + 1];
203}
204
205static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc)
206{
207 return desc->baSourceID[desc->bNrInPins + 3];
208}
209
210static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc)
211{
212 return &desc->baSourceID[desc->bNrInPins + 4];
213}
214
215static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
216{
217 __u8 *raw = (__u8 *) desc;
218 return raw[desc->bLength - 1];
219}
220
221/* 4.3.2.4 Selector Unit Descriptor */
222struct uac_selector_unit_descriptor {
223 __u8 bLength;
224 __u8 bDescriptorType;
225 __u8 bDescriptorSubtype;
226 __u8 bUintID;
227 __u8 bNrInPins;
228 __u8 baSourceID[];
229} __attribute__ ((packed));
230
231static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
232{
233 __u8 *raw = (__u8 *) desc;
234 return raw[desc->bLength - 1];
235}
236
237/* 4.3.2.5 Feature Unit Descriptor */
238struct uac_feature_unit_descriptor {
239 __u8 bLength;
240 __u8 bDescriptorType;
241 __u8 bDescriptorSubtype;
242 __u8 bUnitID;
243 __u8 bSourceID;
244 __u8 bControlSize;
245 __u8 bmaControls[0]; /* variable length */
246} __attribute__((packed));
247
248static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc)
249{
250 __u8 *raw = (__u8 *) desc;
251 return raw[desc->bLength - 1];
252}
253
254/* 4.3.2.6 Processing Unit Descriptors */
255struct uac_processing_unit_descriptor {
256 __u8 bLength;
257 __u8 bDescriptorType;
258 __u8 bDescriptorSubtype;
259 __u8 bUnitID;
260 __u16 wProcessType;
261 __u8 bNrInPins;
262 __u8 baSourceID[];
263} __attribute__ ((packed));
264
265static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc)
266{
267 return desc->baSourceID[desc->bNrInPins];
268}
269
270static inline __u16 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc)
271{
272 return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
273 desc->baSourceID[desc->bNrInPins + 1];
274}
275
276static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc)
277{
278 return desc->baSourceID[desc->bNrInPins + 3];
279}
280
281static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc)
282{
283 return desc->baSourceID[desc->bNrInPins + 4];
284}
285
286static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc)
287{
288 return &desc->baSourceID[desc->bNrInPins + 5];
289}
290
291static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc)
292{
293 __u8 control_size = uac_processing_unit_bControlSize(desc);
294 return desc->baSourceID[desc->bNrInPins + control_size];
295}
296
297static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc)
298{
299 __u8 control_size = uac_processing_unit_bControlSize(desc);
300 return &desc->baSourceID[desc->bNrInPins + control_size + 1];
301}
302
184/* 4.5.2 Class-Specific AS Interface Descriptor */ 303/* 4.5.2 Class-Specific AS Interface Descriptor */
185struct uac_as_header_descriptor_v1 { 304struct uac_as_header_descriptor_v1 {
186 __u8 bLength; /* in bytes: 7 */ 305 __u8 bLength; /* in bytes: 7 */
@@ -315,16 +434,6 @@ struct uac_iso_endpoint_descriptor {
315 434
316/* A.10.2 Feature Unit Control Selectors */ 435/* A.10.2 Feature Unit Control Selectors */
317 436
318struct uac_feature_unit_descriptor {
319 __u8 bLength;
320 __u8 bDescriptorType;
321 __u8 bDescriptorSubtype;
322 __u8 bUnitID;
323 __u8 bSourceID;
324 __u8 bControlSize;
325 __u8 controls[0]; /* variable length */
326} __attribute__((packed));
327
328#define UAC_FU_CONTROL_UNDEFINED 0x00 437#define UAC_FU_CONTROL_UNDEFINED 0x00
329#define UAC_MUTE_CONTROL 0x01 438#define UAC_MUTE_CONTROL 0x01
330#define UAC_VOLUME_CONTROL 0x02 439#define UAC_VOLUME_CONTROL 0x02
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