Commit 05f254a6 authored by Alexander Tsoy's avatar Alexander Tsoy Committed by Takashi Iwai
Browse files

ALSA: usb-audio: Improve filtering of sample rates on Focusrite devices

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: default avatarAlexander Tsoy <alexander@tsoy.me>
Link: https://patch.msgid.link/20250630013357.1327420-1-alexander@tsoy.me


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ce174b48
Loading
Loading
Loading
Loading
+10 −12
Original line number Diff line number Diff line
@@ -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;