diff options
-rw-r--r-- | sound/usb/usbmixer.c | 21 | ||||
-rw-r--r-- | sound/usb/usbmixer_maps.c | 54 |
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 | ||
75 | struct usb_mixer_elem_info { | 76 | struct 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 */ | ||
192 | static 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 | ||
29 | struct usbmix_selector_map { | ||
30 | int id; | ||
31 | int count; | ||
32 | const char **names; | ||
33 | }; | ||
34 | |||
29 | struct usbmix_ctl_map { | 35 | struct 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 | ||
172 | static 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 */ |
166 | static struct usbmix_name_map linex_map[] = { | 192 | static 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 | ||
200 | static struct usbmix_ctl_map usbmix_ctl_maps[] = { | 226 | static 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 | ||