From: Alexander Tsoy <alexan...@tsoy.me>

commit 1c826792586f526a5a5cd21d55aad388f5bb0b23 upstream.

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...@ya.ru>
Signed-off-by: Alexander Tsoy <alexan...@tsoy.me>
Cc: <sta...@vger.kernel.org>
Link: https://lore.kernel.org/r/20200418175815.12211-1-alexan...@tsoy.me
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 sound/usb/format.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -248,6 +248,52 @@ static int parse_audio_format_rates_v1(s
 }
 
 /*
+ * 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
  * the device. The problem is that we need to parse whole array first to
  * get to know how many sample rates we have to expect.
@@ -283,6 +329,11 @@ static int parse_uac2_sample_rate_range(
                }
 
                for (rate = min; rate <= max; rate += res) {
+                       /* 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)
                                fp->rate_table[nr_rates] = rate;
                        if (!fp->rate_min || rate < fp->rate_min)
@@ -297,6 +348,7 @@ static int parse_uac2_sample_rate_range(
                                break;
                        }
 
+skip_rate:
                        /* avoid endless loop */
                        if (res == 0)
                                break;


Reply via email to