aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r--sound/usb/mixer.c82
1 files changed, 66 insertions, 16 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index f2d74d654b3c..6ec33b62e6cf 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -61,6 +61,7 @@
61#include "mixer.h" 61#include "mixer.h"
62#include "helper.h" 62#include "helper.h"
63#include "mixer_quirks.h" 63#include "mixer_quirks.h"
64#include "power.h"
64 65
65#define MAX_ID_ELEMS 256 66#define MAX_ID_ELEMS 256
66 67
@@ -95,7 +96,7 @@ enum {
95}; 96};
96 97
97 98
98/*E-mu 0202(0404) eXtension Unit(XU) control*/ 99/*E-mu 0202/0404/0204 eXtension Unit(XU) control*/
99enum { 100enum {
100 USB_XU_CLOCK_RATE = 0xe301, 101 USB_XU_CLOCK_RATE = 0xe301,
101 USB_XU_CLOCK_SOURCE = 0xe302, 102 USB_XU_CLOCK_SOURCE = 0xe302,
@@ -295,16 +296,22 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
295 unsigned char buf[2]; 296 unsigned char buf[2];
296 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 297 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
297 int timeout = 10; 298 int timeout = 10;
299 int err;
298 300
301 err = snd_usb_autoresume(cval->mixer->chip);
302 if (err < 0)
303 return -EIO;
299 while (timeout-- > 0) { 304 while (timeout-- > 0) {
300 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, 305 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
301 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 306 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
302 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 307 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
303 buf, val_len, 100) >= val_len) { 308 buf, val_len, 100) >= val_len) {
304 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); 309 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
310 snd_usb_autosuspend(cval->mixer->chip);
305 return 0; 311 return 0;
306 } 312 }
307 } 313 }
314 snd_usb_autosuspend(cval->mixer->chip);
308 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 315 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
309 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); 316 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
310 return -EINVAL; 317 return -EINVAL;
@@ -328,12 +335,18 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
328 335
329 memset(buf, 0, sizeof(buf)); 336 memset(buf, 0, sizeof(buf));
330 337
338 ret = snd_usb_autoresume(chip) ? -EIO : 0;
339 if (ret)
340 goto error;
341
331 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, 342 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
332 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 343 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
333 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 344 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
334 buf, size, 1000); 345 buf, size, 1000);
346 snd_usb_autosuspend(chip);
335 347
336 if (ret < 0) { 348 if (ret < 0) {
349error:
337 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 350 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
338 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); 351 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
339 return ret; 352 return ret;
@@ -413,7 +426,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
413{ 426{
414 struct snd_usb_audio *chip = cval->mixer->chip; 427 struct snd_usb_audio *chip = cval->mixer->chip;
415 unsigned char buf[2]; 428 unsigned char buf[2];
416 int val_len, timeout = 10; 429 int val_len, err, timeout = 10;
417 430
418 if (cval->mixer->protocol == UAC_VERSION_1) { 431 if (cval->mixer->protocol == UAC_VERSION_1) {
419 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 432 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -433,13 +446,19 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
433 value_set = convert_bytes_value(cval, value_set); 446 value_set = convert_bytes_value(cval, value_set);
434 buf[0] = value_set & 0xff; 447 buf[0] = value_set & 0xff;
435 buf[1] = (value_set >> 8) & 0xff; 448 buf[1] = (value_set >> 8) & 0xff;
449 err = snd_usb_autoresume(chip);
450 if (err < 0)
451 return -EIO;
436 while (timeout-- > 0) 452 while (timeout-- > 0)
437 if (snd_usb_ctl_msg(chip->dev, 453 if (snd_usb_ctl_msg(chip->dev,
438 usb_sndctrlpipe(chip->dev, 0), request, 454 usb_sndctrlpipe(chip->dev, 0), request,
439 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 455 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
440 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 456 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
441 buf, val_len, 100) >= 0) 457 buf, val_len, 100) >= 0) {
458 snd_usb_autosuspend(chip);
442 return 0; 459 return 0;
460 }
461 snd_usb_autosuspend(chip);
443 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", 462 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
444 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); 463 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
445 return -EINVAL; 464 return -EINVAL;
@@ -987,6 +1006,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
987 struct snd_kcontrol *kctl; 1006 struct snd_kcontrol *kctl;
988 struct usb_mixer_elem_info *cval; 1007 struct usb_mixer_elem_info *cval;
989 const struct usbmix_name_map *map; 1008 const struct usbmix_name_map *map;
1009 unsigned int range;
990 1010
991 control++; /* change from zero-based to 1-based value */ 1011 control++; /* change from zero-based to 1-based value */
992 1012
@@ -1121,6 +1141,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1121 } 1141 }
1122 break; 1142 break;
1123 1143
1144 case USB_ID(0x046d, 0x0808):
1124 case USB_ID(0x046d, 0x0809): 1145 case USB_ID(0x046d, 0x0809):
1125 case USB_ID(0x046d, 0x0991): 1146 case USB_ID(0x046d, 0x0991):
1126 /* Most audio usb devices lie about volume resolution. 1147 /* Most audio usb devices lie about volume resolution.
@@ -1136,6 +1157,21 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1136 1157
1137 } 1158 }
1138 1159
1160 range = (cval->max - cval->min) / cval->res;
1161 /* Are there devices with volume range more than 255? I use a bit more
1162 * to be sure. 384 is a resolution magic number found on Logitech
1163 * devices. It will definitively catch all buggy Logitech devices.
1164 */
1165 if (range > 384) {
1166 snd_printk(KERN_WARNING "usb_audio: Warning! Unlikely big "
1167 "volume range (=%u), cval->res is probably wrong.",
1168 range);
1169 snd_printk(KERN_WARNING "usb_audio: [%d] FU [%s] ch = %d, "
1170 "val = %d/%d/%d", cval->id,
1171 kctl->id.name, cval->channels,
1172 cval->min, cval->max, cval->res);
1173 }
1174
1139 snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", 1175 snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
1140 cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); 1176 cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
1141 add_control_to_empty(state, kctl); 1177 add_control_to_empty(state, kctl);
@@ -1146,7 +1182,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1146/* 1182/*
1147 * parse a feature unit 1183 * parse a feature unit
1148 * 1184 *
1149 * most of controlls are defined here. 1185 * most of controls are defined here.
1150 */ 1186 */
1151static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr) 1187static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
1152{ 1188{
@@ -1566,7 +1602,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw
1566 cval->initialized = 1; 1602 cval->initialized = 1;
1567 } else { 1603 } else {
1568 if (type == USB_XU_CLOCK_RATE) { 1604 if (type == USB_XU_CLOCK_RATE) {
1569 /* E-Mu USB 0404/0202/TrackerPre 1605 /* E-Mu USB 0404/0202/TrackerPre/0204
1570 * samplerate control quirk 1606 * samplerate control quirk
1571 */ 1607 */
1572 cval->min = 0; 1608 cval->min = 0;
@@ -1633,18 +1669,11 @@ static int parse_audio_extension_unit(struct mixer_build *state, int unitid, voi
1633static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1669static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1634{ 1670{
1635 struct usb_mixer_elem_info *cval = kcontrol->private_data; 1671 struct usb_mixer_elem_info *cval = kcontrol->private_data;
1636 char **itemlist = (char **)kcontrol->private_value; 1672 const char **itemlist = (const char **)kcontrol->private_value;
1637 1673
1638 if (snd_BUG_ON(!itemlist)) 1674 if (snd_BUG_ON(!itemlist))
1639 return -EINVAL; 1675 return -EINVAL;
1640 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1676 return snd_ctl_enum_info(uinfo, 1, cval->max, itemlist);
1641 uinfo->count = 1;
1642 uinfo->value.enumerated.items = cval->max;
1643 if (uinfo->value.enumerated.item >= cval->max)
1644 uinfo->value.enumerated.item = cval->max - 1;
1645 strlcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item],
1646 sizeof(uinfo->value.enumerated.name));
1647 return 0;
1648} 1677}
1649 1678
1650/* get callback for selector unit */ 1679/* get callback for selector unit */
@@ -2065,8 +2094,9 @@ static void snd_usb_mixer_interrupt(struct urb *urb)
2065{ 2094{
2066 struct usb_mixer_interface *mixer = urb->context; 2095 struct usb_mixer_interface *mixer = urb->context;
2067 int len = urb->actual_length; 2096 int len = urb->actual_length;
2097 int ustatus = urb->status;
2068 2098
2069 if (urb->status != 0) 2099 if (ustatus != 0)
2070 goto requeue; 2100 goto requeue;
2071 2101
2072 if (mixer->protocol == UAC_VERSION_1) { 2102 if (mixer->protocol == UAC_VERSION_1) {
@@ -2107,12 +2137,32 @@ static void snd_usb_mixer_interrupt(struct urb *urb)
2107 } 2137 }
2108 2138
2109requeue: 2139requeue:
2110 if (urb->status != -ENOENT && urb->status != -ECONNRESET) { 2140 if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) {
2111 urb->dev = mixer->chip->dev; 2141 urb->dev = mixer->chip->dev;
2112 usb_submit_urb(urb, GFP_ATOMIC); 2142 usb_submit_urb(urb, GFP_ATOMIC);
2113 } 2143 }
2114} 2144}
2115 2145
2146/* stop any bus activity of a mixer */
2147void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
2148{
2149 usb_kill_urb(mixer->urb);
2150 usb_kill_urb(mixer->rc_urb);
2151}
2152
2153int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
2154{
2155 int err;
2156
2157 if (mixer->urb) {
2158 err = usb_submit_urb(mixer->urb, GFP_NOIO);
2159 if (err < 0)
2160 return err;
2161 }
2162
2163 return 0;
2164}
2165
2116/* create the handler for the optional status interrupt endpoint */ 2166/* create the handler for the optional status interrupt endpoint */
2117static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) 2167static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
2118{ 2168{