diff options
| -rw-r--r-- | sound/usb/clock.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 5e634a2eb282..9e2703a25156 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
| @@ -253,7 +253,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
| 253 | { | 253 | { |
| 254 | struct usb_device *dev = chip->dev; | 254 | struct usb_device *dev = chip->dev; |
| 255 | unsigned char data[4]; | 255 | unsigned char data[4]; |
| 256 | int err, crate; | 256 | int err, cur_rate, prev_rate; |
| 257 | int clock = snd_usb_clock_find_source(chip, fmt->clock); | 257 | int clock = snd_usb_clock_find_source(chip, fmt->clock); |
| 258 | 258 | ||
| 259 | if (clock < 0) | 259 | if (clock < 0) |
| @@ -266,6 +266,19 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
| 266 | return -ENXIO; | 266 | return -ENXIO; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | ||
| 270 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
| 271 | UAC2_CS_CONTROL_SAM_FREQ << 8, | ||
| 272 | snd_usb_ctrl_intf(chip) | (clock << 8), | ||
| 273 | data, sizeof(data)); | ||
| 274 | if (err < 0) { | ||
| 275 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", | ||
| 276 | dev->devnum, iface, fmt->altsetting); | ||
| 277 | prev_rate = 0; | ||
| 278 | } else { | ||
| 279 | prev_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | ||
| 280 | } | ||
| 281 | |||
| 269 | data[0] = rate; | 282 | data[0] = rate; |
| 270 | data[1] = rate >> 8; | 283 | data[1] = rate >> 8; |
| 271 | data[2] = rate >> 16; | 284 | data[2] = rate >> 16; |
| @@ -280,19 +293,31 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
| 280 | return err; | 293 | return err; |
| 281 | } | 294 | } |
| 282 | 295 | ||
| 283 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | 296 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, |
| 284 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 297 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
| 285 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 298 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
| 286 | snd_usb_ctrl_intf(chip) | (clock << 8), | 299 | snd_usb_ctrl_intf(chip) | (clock << 8), |
| 287 | data, sizeof(data))) < 0) { | 300 | data, sizeof(data)); |
| 301 | if (err < 0) { | ||
| 288 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", | 302 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", |
| 289 | dev->devnum, iface, fmt->altsetting); | 303 | dev->devnum, iface, fmt->altsetting); |
| 290 | return err; | 304 | cur_rate = 0; |
| 305 | } else { | ||
| 306 | cur_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | ||
| 291 | } | 307 | } |
| 292 | 308 | ||
| 293 | crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | 309 | if (cur_rate != rate) { |
| 294 | if (crate != rate) | 310 | snd_printd(KERN_WARNING |
| 295 | snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); | 311 | "current rate %d is different from the runtime rate %d\n", |
| 312 | cur_rate, rate); | ||
| 313 | } | ||
| 314 | |||
| 315 | /* Some devices doesn't respond to sample rate changes while the | ||
| 316 | * interface is active. */ | ||
| 317 | if (rate != prev_rate) { | ||
| 318 | usb_set_interface(dev, iface, 0); | ||
| 319 | usb_set_interface(dev, iface, fmt->altsetting); | ||
| 320 | } | ||
| 296 | 321 | ||
| 297 | return 0; | 322 | return 0; |
| 298 | } | 323 | } |
