ALSA: usb-audio: Improve Focusrite sample rate filtering

Replace the bLength == 10 max_rate check in
focusrite_valid_sample_rate() with filtering that also examines the
bmControls VAL_ALT_SETTINGS bit.

When VAL_ALT_SETTINGS is readable, the device uses strict
per-altsetting rate filtering (only the highest rate pair for that
altsetting is valid). When it is not readable, all rates up to
max_rate are valid.

For devices without the bLength == 10 Format Type descriptor extension
but with VAL_ALT_SETTINGS readable and multiple altsettings (only seen
in Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.

This produces correct rate tables for all tested Focusrite devices
(all Scarlett 2nd, 3rd, and 4th Gen, Clarett+, and Vocaster) using
only USB descriptors, allowing QUIRK_FLAG_VALIDATE_RATES to be removed
for Focusrite in the next commit.

Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/7e18c1f393a6ecb6fc75dd867a2c4dbe135e3e22.1771594828.git.g@b4.vu
This commit is contained in:
Geoffrey D. Bennett 2026-02-21 02:33:45 +10:30 committed by Takashi Iwai
parent 9fb16a5c5f
commit 24d2d3c5f9

View file

@ -305,17 +305,48 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp,
}
/*
* 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.
* Focusrite devices use rate pairs: 44100/48000, 88200/96000, and
* 176400/192000. Return true if rate is in the pair for max_rate.
*/
static bool focusrite_rate_pair(unsigned int rate,
unsigned int max_rate)
{
switch (max_rate) {
case 48000: return rate == 44100 || rate == 48000;
case 96000: return rate == 88200 || rate == 96000;
case 192000: return rate == 176400 || rate == 192000;
default: return true;
}
}
/*
* Focusrite devices report all supported rates in a single clock
* source but only a subset is valid per altsetting.
*
* Detection uses two descriptor features:
*
* 1. Format Type descriptor bLength == 10: non-standard extension
* with max sample rate in bytes 6..9.
*
* 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device
* only supports the highest rate pair for that altsetting, and when
* clear, all rates up to max_rate are valid.
*
* For devices without the bLength == 10 extension but with
* VAL_ALT_SETTINGS readable and multiple altsettings (only seen in
* Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
* convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
*/
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;
struct uac2_as_header_descriptor *as;
unsigned char *fmt;
unsigned int max_rate;
bool val_alt;
alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting);
if (!alts)
@ -326,9 +357,21 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
if (!fmt)
return true;
as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
NULL, UAC_AS_GENERAL);
if (!as)
return true;
val_alt = uac_v2v3_control_is_readable(as->bmControls,
UAC2_AS_VAL_ALT_SETTINGS);
if (fmt[0] == 10) { /* bLength */
max_rate = combine_quad(&fmt[6]);
if (val_alt)
return focusrite_rate_pair(rate, max_rate);
/* No val_alt: rates fall through from higher */
switch (max_rate) {
case 192000:
if (rate == 176400 || rate == 192000)
@ -344,12 +387,29 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
usb_audio_info(chip,
"%u:%d : unexpected max rate: %u\n",
fp->iface, fp->altsetting, max_rate);
return true;
}
}
return true;
if (!val_alt)
return true;
/* Multi-altsetting device with val_alt but no max_rate
* in the format descriptor. Use Focusrite convention:
* alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
*/
iface = usb_ifnum_to_if(chip->dev, fp->iface);
if (!iface || iface->num_altsetting <= 2)
return true;
switch (fp->altsetting) {
case 1: max_rate = 48000; break;
case 2: max_rate = 96000; break;
case 3: max_rate = 192000; break;
default: return true;
}
return focusrite_rate_pair(rate, max_rate);
}
/*