aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/usb/usbmixer.c21
-rw-r--r--sound/usb/usbmixer_maps.c54
2 files changed, 69 insertions, 6 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 5f1906915aa6..6ad154aaba1b 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -70,6 +70,7 @@ struct usb_mixer_build {
70 DECLARE_BITMAP(unitbitmap, 32*32); 70 DECLARE_BITMAP(unitbitmap, 32*32);
71 usb_audio_term_t oterm; 71 usb_audio_term_t oterm;
72 const struct usbmix_name_map *map; 72 const struct usbmix_name_map *map;
73 const struct usbmix_selector_map *selector_map;
73}; 74};
74 75
75struct usb_mixer_elem_info { 76struct usb_mixer_elem_info {
@@ -187,6 +188,21 @@ static int check_ignored_ctl(mixer_build_t *state, int unitid, int control)
187 return 0; 188 return 0;
188} 189}
189 190
191/* get the mapped selector source name */
192static int check_mapped_selector_name(mixer_build_t *state, int unitid,
193 int index, char *buf, int buflen)
194{
195 const struct usbmix_selector_map *p;
196
197 if (! state->selector_map)
198 return 0;
199 for (p = state->selector_map; p->id; p++) {
200 if (p->id == unitid && index < p->count)
201 return strlcpy(buf, p->names[index], buflen);
202 }
203 return 0;
204}
205
190/* 206/*
191 * find an audio control unit with the given unit id 207 * find an audio control unit with the given unit id
192 */ 208 */
@@ -1415,7 +1431,9 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned
1415 kfree(cval); 1431 kfree(cval);
1416 return -ENOMEM; 1432 return -ENOMEM;
1417 } 1433 }
1418 if (check_input_term(state, desc[5 + i], &iterm) >= 0) 1434 len = check_mapped_selector_name(state, unitid, i, namelist[i],
1435 MAX_ITEM_NAME_LEN);
1436 if (! len && check_input_term(state, desc[5 + i], &iterm) >= 0)
1419 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); 1437 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
1420 if (! len) 1438 if (! len)
1421 sprintf(namelist[i], "Input %d", i); 1439 sprintf(namelist[i], "Input %d", i);
@@ -1521,6 +1539,7 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
1521 for (map = usbmix_ctl_maps; map->vendor; map++) { 1539 for (map = usbmix_ctl_maps; map->vendor; map++) {
1522 if (map->vendor == state.vendor && map->product == state.product) { 1540 if (map->vendor == state.vendor && map->product == state.product) {
1523 state.map = map->map; 1541 state.map = map->map;
1542 state.selector_map = map->selector_map;
1524 chip->ignore_ctl_error = map->ignore_ctl_error; 1543 chip->ignore_ctl_error = map->ignore_ctl_error;
1525 break; 1544 break;
1526 } 1545 }
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
index 4918a1854223..adb0abb3ee85 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/usbmixer_maps.c
@@ -26,10 +26,17 @@ struct usbmix_name_map {
26 int control; 26 int control;
27}; 27};
28 28
29struct usbmix_selector_map {
30 int id;
31 int count;
32 const char **names;
33};
34
29struct usbmix_ctl_map { 35struct usbmix_ctl_map {
30 int vendor; 36 int vendor;
31 int product; 37 int product;
32 const struct usbmix_name_map *map; 38 const struct usbmix_name_map *map;
39 const struct usbmix_selector_map *selector_map;
33 int ignore_ctl_error; 40 int ignore_ctl_error;
34}; 41};
35 42
@@ -162,6 +169,25 @@ static struct usbmix_name_map audigy2nx_map[] = {
162 { 0 } /* terminator */ 169 { 0 } /* terminator */
163}; 170};
164 171
172static struct usbmix_selector_map audigy2nx_selectors[] = {
173 {
174 .id = 14, /* Capture Source */
175 .count = 3,
176 .names = (const char*[]) {"Line", "Digital In", "What-U-Hear"}
177 },
178 {
179 .id = 29, /* Digital Out Source */
180 .count = 3,
181 .names = (const char*[]) {"Front", "PCM", "Digital In"}
182 },
183 {
184 .id = 31, /* Headphone Source */
185 .count = 2,
186 .names = (const char*[]) {"Front", "Side"}
187 },
188 { 0 } /* terminator */
189};
190
165/* LineX FM Transmitter entry - needed to bypass controls bug */ 191/* LineX FM Transmitter entry - needed to bypass controls bug */
166static struct usbmix_name_map linex_map[] = { 192static struct usbmix_name_map linex_map[] = {
167 /* 1: IT pcm */ 193 /* 1: IT pcm */
@@ -198,11 +224,29 @@ static struct usbmix_name_map justlink_map[] = {
198 */ 224 */
199 225
200static struct usbmix_ctl_map usbmix_ctl_maps[] = { 226static struct usbmix_ctl_map usbmix_ctl_maps[] = {
201 { 0x41e, 0x3000, extigy_map, 1 }, 227 {
202 { 0x41e, 0x3010, mp3plus_map, 0 }, 228 .vendor = 0x41e, .product = 0x3000,
203 { 0x41e, 0x3020, audigy2nx_map, 0 }, 229 .map = extigy_map,
204 { 0x8bb, 0x2702, linex_map, 1 }, 230 .ignore_ctl_error = 1,
205 { 0xc45, 0x1158, justlink_map, 0 }, 231 },
232 {
233 .vendor = 0x41e, .product = 0x3010,
234 .map = mp3plus_map,
235 },
236 {
237 .vendor = 0x41e, .product = 0x3020,
238 .map = audigy2nx_map,
239 .selector_map = audigy2nx_selectors,
240 },
241 {
242 .vendor = 0x8bb, .product = 0x2702,
243 .map = linex_map,
244 .ignore_ctl_error = 1,
245 },
246 {
247 .vendor = 0xc45, .product = 0x1158,
248 .map = justlink_map,
249 },
206 { 0 } /* terminator */ 250 { 0 } /* terminator */
207}; 251};
208 252