Commit 24d2d3c5 authored by Geoffrey D. Bennett's avatar Geoffrey D. Bennett Committed by Takashi Iwai
Browse files

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: default avatarGeoffrey D. Bennett <g@b4.vu>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/7e18c1f393a6ecb6fc75dd867a2c4dbe135e3e22.1771594828.git.g@b4.vu
parent 9fb16a5c
Loading
Loading
Loading
Loading
+65 −5
Original line number Diff line number Diff line
@@ -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;
		}
	}

	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);
}

/*