]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: usb-audio: Improve filtering of sample rates on Focusrite devices
authorAlexander Tsoy <alexander@tsoy.me>
Mon, 30 Jun 2025 01:33:57 +0000 (04:33 +0300)
committerTakashi Iwai <tiwai@suse.de>
Mon, 30 Jun 2025 07:11:39 +0000 (09:11 +0200)
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 <alexander@tsoy.me>
Link: https://patch.msgid.link/20250630013357.1327420-1-alexander@tsoy.me
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/format.c

index 8cd54f7bf33a198278e3071166a29f5f74eab0c6..0ee532acbb6034b4b5f27b4e43ba5fccdbcff914 100644 (file)
@@ -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;