diff options
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r-- | sound/usb/mixer.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 09e59345bb6d..5e4775716607 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 | ||
@@ -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) { |
349 | error: | ||
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; |