diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/clock.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index a694e1c42fdf..ae35e7d22e73 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
@@ -347,6 +347,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
347 | __le32 data; | 347 | __le32 data; |
348 | int err, cur_rate, prev_rate; | 348 | int err, cur_rate, prev_rate; |
349 | int clock; | 349 | int clock; |
350 | bool writeable; | ||
351 | struct uac_clock_source_descriptor *cs_desc; | ||
350 | 352 | ||
351 | clock = snd_usb_clock_find_source(chip, fmt->clock, true); | 353 | clock = snd_usb_clock_find_source(chip, fmt->clock, true); |
352 | if (clock < 0) | 354 | if (clock < 0) |
@@ -354,20 +356,33 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
354 | 356 | ||
355 | prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); | 357 | prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); |
356 | 358 | ||
357 | data = cpu_to_le32(rate); | 359 | cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock); |
358 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | 360 | writeable = uac2_control_is_writeable(cs_desc->bmControls, UAC2_CS_CONTROL_SAM_FREQ - 1); |
359 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 361 | if (writeable) { |
360 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 362 | data = cpu_to_le32(rate); |
361 | snd_usb_ctrl_intf(chip) | (clock << 8), | 363 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, |
362 | &data, sizeof(data))) < 0) { | 364 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, |
363 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2): err %d\n", | 365 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
364 | dev->devnum, iface, fmt->altsetting, rate, err); | 366 | snd_usb_ctrl_intf(chip) | (clock << 8), |
365 | return err; | 367 | &data, sizeof(data)); |
366 | } | 368 | if (err < 0) { |
369 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2): err %d\n", | ||
370 | dev->devnum, iface, fmt->altsetting, rate, err); | ||
371 | return err; | ||
372 | } | ||
367 | 373 | ||
368 | cur_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); | 374 | cur_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); |
375 | } else { | ||
376 | cur_rate = prev_rate; | ||
377 | } | ||
369 | 378 | ||
370 | if (cur_rate != rate) { | 379 | if (cur_rate != rate) { |
380 | if (!writeable) { | ||
381 | snd_printk(KERN_WARNING | ||
382 | "%d:%d:%d: freq mismatch (RO clock): req %d, clock runs @%d\n", | ||
383 | dev->devnum, iface, fmt->altsetting, rate, cur_rate); | ||
384 | return -ENXIO; | ||
385 | } | ||
371 | snd_printd(KERN_WARNING | 386 | snd_printd(KERN_WARNING |
372 | "current rate %d is different from the runtime rate %d\n", | 387 | "current rate %d is different from the runtime rate %d\n", |
373 | cur_rate, rate); | 388 | cur_rate, rate); |