From: Alexander Tsoy Date: Mon, 30 Jun 2025 01:33:57 +0000 (+0300) Subject: ALSA: usb-audio: Improve filtering of sample rates on Focusrite devices X-Git-Tag: v6.16-rc6~27^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=05f254a6369ac020fc0382a7cbd3ef64ad997c92;p=thirdparty%2Fkernel%2Flinux.git ALSA: usb-audio: Improve filtering of sample rates on Focusrite devices Previously we were filtering out only upper unsupported sampling rates. This patch adds filtering of the lower unsupported sampling rates. As a result there is 1:1 mapping between altsetting and supported rates. The issue was found on a Scarlett 3rd Gen card (see linked bug), but the same filtering is likely needed for the Scarlett 1st and 2nd Gen as well as the older Clarett cards which lacks Valid Alternate Setting Control. Patch was not tested on a real hardware. Link: https://bugzilla.kernel.org/show_bug.cgi?id=214493 Signed-off-by: Alexander Tsoy Link: https://patch.msgid.link/20250630013357.1327420-1-alexander@tsoy.me Signed-off-by: Takashi Iwai --- diff --git a/sound/usb/format.c b/sound/usb/format.c index 8cd54f7bf33a1..0ee532acbb603 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -310,16 +310,14 @@ 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) + alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting); + if (!alts) return true; - alts = &iface->altsetting[fp->altset_idx]; fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE); if (!fmt) @@ -328,20 +326,20 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, 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) { - + 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: 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;