ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices
Many Focusrite devices supports a limited set of sample rates per altsetting. These includes audio interfaces with ADAT ports: - Scarlett 18i6, 18i8 1st gen, 18i20 1st gen; - Scarlett 18i8 2nd gen, 18i20 2nd gen; - Scarlett 18i8 3rd gen, 18i20 3rd gen; - Clarett 2Pre USB, 4Pre USB, 8Pre USB. Maximum rate is exposed in the last 4 bytes of Format Type descriptor which has a non-standard bLength = 10. Tested-by: Alexey Skobkin <skobkin-ru@ya.ru> Signed-off-by: Alexander Tsoy <alexander@tsoy.me> Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20200418175815.12211-1-alexander@tsoy.me Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
b392350ec3
commit
1c82679258
|
@ -277,6 +277,52 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Many Focusrite devices supports a limited set of sampling rates per
|
||||||
|
* altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
|
||||||
|
* descriptor which has a non-standard bLength = 10.
|
||||||
|
*/
|
||||||
|
static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
|
||||||
|
struct audioformat *fp,
|
||||||
|
unsigned int rate)
|
||||||
|
{
|
||||||
|
struct usb_interface *iface;
|
||||||
|
struct usb_host_interface *alts;
|
||||||
|
unsigned char *fmt;
|
||||||
|
unsigned int max_rate;
|
||||||
|
|
||||||
|
iface = usb_ifnum_to_if(chip->dev, fp->iface);
|
||||||
|
if (!iface)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
alts = &iface->altsetting[fp->altset_idx];
|
||||||
|
fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen,
|
||||||
|
NULL, UAC_FORMAT_TYPE);
|
||||||
|
if (!fmt)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (fmt[0] == 10) { /* bLength */
|
||||||
|
max_rate = combine_quad(&fmt[6]);
|
||||||
|
|
||||||
|
/* Validate max rate */
|
||||||
|
if (max_rate != 48000 &&
|
||||||
|
max_rate != 96000 &&
|
||||||
|
max_rate != 192000 &&
|
||||||
|
max_rate != 384000) {
|
||||||
|
|
||||||
|
usb_audio_info(chip,
|
||||||
|
"%u:%d : unexpected max rate: %u\n",
|
||||||
|
fp->iface, fp->altsetting, max_rate);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rate <= max_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function to walk the array of sample rate triplets reported by
|
* Helper function to walk the array of sample rate triplets reported by
|
||||||
* the device. The problem is that we need to parse whole array first to
|
* the device. The problem is that we need to parse whole array first to
|
||||||
|
@ -319,6 +365,11 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,
|
||||||
!s1810c_valid_sample_rate(fp, rate))
|
!s1810c_valid_sample_rate(fp, rate))
|
||||||
goto skip_rate;
|
goto skip_rate;
|
||||||
|
|
||||||
|
/* Filter out invalid rates on Focusrite devices */
|
||||||
|
if (USB_ID_VENDOR(chip->usb_id) == 0x1235 &&
|
||||||
|
!focusrite_valid_sample_rate(chip, fp, rate))
|
||||||
|
goto skip_rate;
|
||||||
|
|
||||||
if (fp->rate_table)
|
if (fp->rate_table)
|
||||||
fp->rate_table[nr_rates] = rate;
|
fp->rate_table[nr_rates] = rate;
|
||||||
if (!fp->rate_min || rate < fp->rate_min)
|
if (!fp->rate_min || rate < fp->rate_min)
|
||||||
|
|
Loading…
Reference in New Issue