mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
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:
parent
9fb16a5c5f
commit
24d2d3c5f9
1 changed files with 65 additions and 5 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue