diff options
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r-- | sound/usb/mixer.c | 77 |
1 files changed, 42 insertions, 35 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 736d134cc03c..c166db0057d3 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -26,6 +26,22 @@ | |||
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | /* | ||
30 | * TODOs, for both the mixer and the streaming interfaces: | ||
31 | * | ||
32 | * - support for UAC2 effect units | ||
33 | * - support for graphical equalizers | ||
34 | * - RANGE and MEM set commands (UAC2) | ||
35 | * - RANGE and MEM interrupt dispatchers (UAC2) | ||
36 | * - audio channel clustering (UAC2) | ||
37 | * - audio sample rate converter units (UAC2) | ||
38 | * - proper handling of clock multipliers (UAC2) | ||
39 | * - dispatch clock change notifications (UAC2) | ||
40 | * - stop PCM streams which use a clock that became invalid | ||
41 | * - stop PCM streams which use a clock selector that has changed | ||
42 | * - parse available sample rates again when clock sources changed | ||
43 | */ | ||
44 | |||
29 | #include <linux/bitops.h> | 45 | #include <linux/bitops.h> |
30 | #include <linux/init.h> | 46 | #include <linux/init.h> |
31 | #include <linux/list.h> | 47 | #include <linux/list.h> |
@@ -275,28 +291,28 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val) | |||
275 | 291 | ||
276 | static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 292 | static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) |
277 | { | 293 | { |
294 | struct snd_usb_audio *chip = cval->mixer->chip; | ||
278 | unsigned char buf[2]; | 295 | unsigned char buf[2]; |
279 | int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; | 296 | int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; |
280 | int timeout = 10; | 297 | int timeout = 10; |
281 | 298 | ||
282 | while (timeout-- > 0) { | 299 | while (timeout-- > 0) { |
283 | if (snd_usb_ctl_msg(cval->mixer->chip->dev, | 300 | if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, |
284 | usb_rcvctrlpipe(cval->mixer->chip->dev, 0), | ||
285 | request, | ||
286 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 301 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
287 | validx, cval->mixer->ctrlif | (cval->id << 8), | 302 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
288 | buf, val_len, 100) >= val_len) { | 303 | buf, val_len, 100) >= val_len) { |
289 | *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); | 304 | *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); |
290 | return 0; | 305 | return 0; |
291 | } | 306 | } |
292 | } | 307 | } |
293 | snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", | 308 | snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", |
294 | request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type); | 309 | request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); |
295 | return -EINVAL; | 310 | return -EINVAL; |
296 | } | 311 | } |
297 | 312 | ||
298 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 313 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) |
299 | { | 314 | { |
315 | struct snd_usb_audio *chip = cval->mixer->chip; | ||
300 | unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ | 316 | unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ |
301 | unsigned char *val; | 317 | unsigned char *val; |
302 | int ret, size; | 318 | int ret, size; |
@@ -312,16 +328,14 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v | |||
312 | 328 | ||
313 | memset(buf, 0, sizeof(buf)); | 329 | memset(buf, 0, sizeof(buf)); |
314 | 330 | ||
315 | ret = snd_usb_ctl_msg(cval->mixer->chip->dev, | 331 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, |
316 | usb_rcvctrlpipe(cval->mixer->chip->dev, 0), | ||
317 | bRequest, | ||
318 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 332 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
319 | validx, cval->mixer->ctrlif | (cval->id << 8), | 333 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
320 | buf, size, 1000); | 334 | buf, size, 1000); |
321 | 335 | ||
322 | if (ret < 0) { | 336 | if (ret < 0) { |
323 | snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", | 337 | snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", |
324 | request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type); | 338 | request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); |
325 | return ret; | 339 | return ret; |
326 | } | 340 | } |
327 | 341 | ||
@@ -397,6 +411,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval, | |||
397 | int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | 411 | int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, |
398 | int request, int validx, int value_set) | 412 | int request, int validx, int value_set) |
399 | { | 413 | { |
414 | struct snd_usb_audio *chip = cval->mixer->chip; | ||
400 | unsigned char buf[2]; | 415 | unsigned char buf[2]; |
401 | int val_len, timeout = 10; | 416 | int val_len, timeout = 10; |
402 | 417 | ||
@@ -419,15 +434,14 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
419 | buf[0] = value_set & 0xff; | 434 | buf[0] = value_set & 0xff; |
420 | buf[1] = (value_set >> 8) & 0xff; | 435 | buf[1] = (value_set >> 8) & 0xff; |
421 | while (timeout-- > 0) | 436 | while (timeout-- > 0) |
422 | if (snd_usb_ctl_msg(cval->mixer->chip->dev, | 437 | if (snd_usb_ctl_msg(chip->dev, |
423 | usb_sndctrlpipe(cval->mixer->chip->dev, 0), | 438 | usb_sndctrlpipe(chip->dev, 0), request, |
424 | request, | ||
425 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | 439 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, |
426 | validx, cval->mixer->ctrlif | (cval->id << 8), | 440 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
427 | buf, val_len, 100) >= 0) | 441 | buf, val_len, 100) >= 0) |
428 | return 0; | 442 | return 0; |
429 | snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", | 443 | snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", |
430 | request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]); | 444 | request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); |
431 | return -EINVAL; | 445 | return -EINVAL; |
432 | } | 446 | } |
433 | 447 | ||
@@ -582,9 +596,9 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
582 | switch (iterm->type >> 16) { | 596 | switch (iterm->type >> 16) { |
583 | case UAC_SELECTOR_UNIT: | 597 | case UAC_SELECTOR_UNIT: |
584 | strcpy(name, "Selector"); return 8; | 598 | strcpy(name, "Selector"); return 8; |
585 | case UAC_PROCESSING_UNIT_V1: | 599 | case UAC1_PROCESSING_UNIT: |
586 | strcpy(name, "Process Unit"); return 12; | 600 | strcpy(name, "Process Unit"); return 12; |
587 | case UAC_EXTENSION_UNIT_V1: | 601 | case UAC1_EXTENSION_UNIT: |
588 | strcpy(name, "Ext Unit"); return 8; | 602 | strcpy(name, "Ext Unit"); return 8; |
589 | case UAC_MIXER_UNIT: | 603 | case UAC_MIXER_UNIT: |
590 | strcpy(name, "Mixer"); return 5; | 604 | strcpy(name, "Mixer"); return 5; |
@@ -672,8 +686,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ | |||
672 | term->name = uac_selector_unit_iSelector(d); | 686 | term->name = uac_selector_unit_iSelector(d); |
673 | return 0; | 687 | return 0; |
674 | } | 688 | } |
675 | case UAC_PROCESSING_UNIT_V1: | 689 | case UAC1_PROCESSING_UNIT: |
676 | case UAC_EXTENSION_UNIT_V1: { | 690 | case UAC1_EXTENSION_UNIT: { |
677 | struct uac_processing_unit_descriptor *d = p1; | 691 | struct uac_processing_unit_descriptor *d = p1; |
678 | if (d->bNrInPins) { | 692 | if (d->bNrInPins) { |
679 | id = d->baSourceID[0]; | 693 | id = d->baSourceID[0]; |
@@ -745,6 +759,8 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | |||
745 | */ | 759 | */ |
746 | static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | 760 | static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) |
747 | { | 761 | { |
762 | struct snd_usb_audio *chip = cval->mixer->chip; | ||
763 | |||
748 | /* for failsafe */ | 764 | /* for failsafe */ |
749 | cval->min = default_min; | 765 | cval->min = default_min; |
750 | cval->max = cval->min + 1; | 766 | cval->max = cval->min + 1; |
@@ -767,7 +783,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
767 | if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || | 783 | if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || |
768 | get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { | 784 | get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { |
769 | snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", | 785 | snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", |
770 | cval->id, cval->mixer->ctrlif, cval->control, cval->id); | 786 | cval->id, snd_usb_ctrl_intf(chip), cval->control, cval->id); |
771 | return -EINVAL; | 787 | return -EINVAL; |
772 | } | 788 | } |
773 | if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { | 789 | if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { |
@@ -1199,14 +1215,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1199 | } | 1215 | } |
1200 | } else { /* UAC_VERSION_2 */ | 1216 | } else { /* UAC_VERSION_2 */ |
1201 | for (i = 0; i < 30/2; i++) { | 1217 | for (i = 0; i < 30/2; i++) { |
1202 | /* From the USB Audio spec v2.0: | ||
1203 | bmaControls() is a (ch+1)-element array of 4-byte bitmaps, | ||
1204 | each containing a set of bit pairs. If a Control is present, | ||
1205 | it must be Host readable. If a certain Control is not | ||
1206 | present then the bit pair must be set to 0b00. | ||
1207 | If a Control is present but read-only, the bit pair must be | ||
1208 | set to 0b01. If a Control is also Host programmable, the bit | ||
1209 | pair must be set to 0b11. The value 0b10 is not allowed. */ | ||
1210 | unsigned int ch_bits = 0; | 1218 | unsigned int ch_bits = 0; |
1211 | unsigned int ch_read_only = 0; | 1219 | unsigned int ch_read_only = 0; |
1212 | 1220 | ||
@@ -1855,13 +1863,13 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) | |||
1855 | return parse_audio_selector_unit(state, unitid, p1); | 1863 | return parse_audio_selector_unit(state, unitid, p1); |
1856 | case UAC_FEATURE_UNIT: | 1864 | case UAC_FEATURE_UNIT: |
1857 | return parse_audio_feature_unit(state, unitid, p1); | 1865 | return parse_audio_feature_unit(state, unitid, p1); |
1858 | case UAC_PROCESSING_UNIT_V1: | 1866 | case UAC1_PROCESSING_UNIT: |
1859 | /* UAC2_EFFECT_UNIT has the same value */ | 1867 | /* UAC2_EFFECT_UNIT has the same value */ |
1860 | if (state->mixer->protocol == UAC_VERSION_1) | 1868 | if (state->mixer->protocol == UAC_VERSION_1) |
1861 | return parse_audio_processing_unit(state, unitid, p1); | 1869 | return parse_audio_processing_unit(state, unitid, p1); |
1862 | else | 1870 | else |
1863 | return 0; /* FIXME - effect units not implemented yet */ | 1871 | return 0; /* FIXME - effect units not implemented yet */ |
1864 | case UAC_EXTENSION_UNIT_V1: | 1872 | case UAC1_EXTENSION_UNIT: |
1865 | /* UAC2_PROCESSING_UNIT_V2 has the same value */ | 1873 | /* UAC2_PROCESSING_UNIT_V2 has the same value */ |
1866 | if (state->mixer->protocol == UAC_VERSION_1) | 1874 | if (state->mixer->protocol == UAC_VERSION_1) |
1867 | return parse_audio_extension_unit(state, unitid, p1); | 1875 | return parse_audio_extension_unit(state, unitid, p1); |
@@ -1905,7 +1913,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
1905 | struct usb_host_interface *hostif; | 1913 | struct usb_host_interface *hostif; |
1906 | void *p; | 1914 | void *p; |
1907 | 1915 | ||
1908 | hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; | 1916 | hostif = mixer->chip->ctrl_intf; |
1909 | memset(&state, 0, sizeof(state)); | 1917 | memset(&state, 0, sizeof(state)); |
1910 | state.chip = mixer->chip; | 1918 | state.chip = mixer->chip; |
1911 | state.mixer = mixer; | 1919 | state.mixer = mixer; |
@@ -1925,7 +1933,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
1925 | p = NULL; | 1933 | p = NULL; |
1926 | while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) { | 1934 | while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) { |
1927 | if (mixer->protocol == UAC_VERSION_1) { | 1935 | if (mixer->protocol == UAC_VERSION_1) { |
1928 | struct uac_output_terminal_descriptor_v1 *desc = p; | 1936 | struct uac1_output_terminal_descriptor *desc = p; |
1929 | 1937 | ||
1930 | if (desc->bLength < sizeof(*desc)) | 1938 | if (desc->bLength < sizeof(*desc)) |
1931 | continue; /* invalid descriptor? */ | 1939 | continue; /* invalid descriptor? */ |
@@ -1997,7 +2005,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, | |||
1997 | list_for_each_entry(mixer, &chip->mixer_list, list) { | 2005 | list_for_each_entry(mixer, &chip->mixer_list, list) { |
1998 | snd_iprintf(buffer, | 2006 | snd_iprintf(buffer, |
1999 | "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n", | 2007 | "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n", |
2000 | chip->usb_id, mixer->ctrlif, | 2008 | chip->usb_id, snd_usb_ctrl_intf(chip), |
2001 | mixer->ignore_ctl_error); | 2009 | mixer->ignore_ctl_error); |
2002 | snd_iprintf(buffer, "Card: %s\n", chip->card->longname); | 2010 | snd_iprintf(buffer, "Card: %s\n", chip->card->longname); |
2003 | for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { | 2011 | for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { |
@@ -2115,7 +2123,7 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) | |||
2115 | int buffer_length; | 2123 | int buffer_length; |
2116 | unsigned int epnum; | 2124 | unsigned int epnum; |
2117 | 2125 | ||
2118 | hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; | 2126 | hostif = mixer->chip->ctrl_intf; |
2119 | /* we need one interrupt input endpoint */ | 2127 | /* we need one interrupt input endpoint */ |
2120 | if (get_iface_desc(hostif)->bNumEndpoints < 1) | 2128 | if (get_iface_desc(hostif)->bNumEndpoints < 1) |
2121 | return 0; | 2129 | return 0; |
@@ -2158,7 +2166,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2158 | if (!mixer) | 2166 | if (!mixer) |
2159 | return -ENOMEM; | 2167 | return -ENOMEM; |
2160 | mixer->chip = chip; | 2168 | mixer->chip = chip; |
2161 | mixer->ctrlif = ctrlif; | ||
2162 | mixer->ignore_ctl_error = ignore_error; | 2169 | mixer->ignore_ctl_error = ignore_error; |
2163 | mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems), | 2170 | mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems), |
2164 | GFP_KERNEL); | 2171 | GFP_KERNEL); |