lkml.org 
[lkml]   [2020]   [May]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 38/70] ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices
    Date
    From: Alexander Tsoy <alexander@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-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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

    --- a/sound/usb/format.c
    +++ b/sound/usb/format.c
    @@ -223,6 +223,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.
    @@ -258,6 +304,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)
    @@ -272,6 +323,7 @@ static int parse_uac2_sample_rate_range(
    break;
    }

    +skip_rate:
    /* avoid endless loop */
    if (res == 0)
    break;

    \
     
     \ /
      Last update: 2020-05-01 16:01    [W:4.133 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site