[PATCH 6.18 016/314] ALSA: usb-audio: Add QUIRK_FLAG_SKIP_IFACE_SETUP

Sasha Levin
2026-03-10T11:20:50Z

From: "Geoffrey D. Bennett" <g@b4.vu>

[ Upstream commit 38c322068a26a01d7ff64da92179e68cdde9860b ]

Add a quirk flag to skip the usb_set_interface(),
snd_usb_init_pitch(), and snd_usb_init_sample_rate() calls in
__snd_usb_parse_audio_interface(). These are redundant with
snd_usb_endpoint_prepare() at stream-open time.

Enable the quirk for Focusrite devices, as init_sample_rate(rate_max)
sets 192kHz during probing, which disables the internal mixer and Air
and Safe modes.

Fixes: 16f1f838442d ("Revert "ALSA: usb-audio: Drop superfluous interface setup at parsing"")
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/65a7909b15f9feb76c2a6f4f8814c240ddc50737.1771594828.git.g@b4.vu
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/quirks.c | 3 ++-
sound/usb/stream.c | 3 +++
sound/usb/usbaudio.h | 6 ++++++
3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index ea5de072c36a1..c411005cd4d87 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2421,7 +2421,7 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
VENDOR_FLG(0x07fd, /* MOTU */
QUIRK_FLAG_VALIDATE_RATES),
VENDOR_FLG(0x1235, /* Focusrite Novation */
- 0),
+ QUIRK_FLAG_SKIP_IFACE_SETUP),
VENDOR_FLG(0x1511, /* AURALiC */
QUIRK_FLAG_DSD_RAW),
VENDOR_FLG(0x152a, /* Thesycon devices */
@@ -2503,6 +2503,7 @@ static const char *const snd_usb_audio_quirk_flag_names[] = {
QUIRK_STRING_ENTRY(MIC_RES_384),
QUIRK_STRING_ENTRY(MIXER_PLAYBACK_MIN_MUTE),
QUIRK_STRING_ENTRY(MIXER_CAPTURE_MIN_MUTE),
+ QUIRK_STRING_ENTRY(SKIP_IFACE_SETUP),
NULL
};

diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 5c235a5ba7e1b..3b2526964e4b4 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -1261,6 +1261,9 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
set_iface_first = true;

/* try to set the interface... */
+ if (chip->quirk_flags & QUIRK_FLAG_SKIP_IFACE_SETUP)
+ continue;
+
usb_set_interface(chip->dev, iface_no, 0);
if (set_iface_first)
usb_set_interface(chip->dev, iface_no, altno);
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 79978cae9799c..085530cf62d92 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -224,6 +224,10 @@ extern bool snd_usb_skip_validation;
* playback value represents muted state instead of minimum audible volume
* QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE
* Similar to QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE, but for capture streams
+ * QUIRK_FLAG_SKIP_IFACE_SETUP
+ * Skip the probe-time interface setup (usb_set_interface,
+ * init_pitch, init_sample_rate); redundant with
+ * snd_usb_endpoint_prepare() at stream-open time
*/

enum {
@@ -253,6 +257,7 @@ enum {
QUIRK_TYPE_MIC_RES_384 = 23,
QUIRK_TYPE_MIXER_PLAYBACK_MIN_MUTE = 24,
QUIRK_TYPE_MIXER_CAPTURE_MIN_MUTE = 25,
+ QUIRK_TYPE_SKIP_IFACE_SETUP = 26,
/* Please also edit snd_usb_audio_quirk_flag_names */
};

@@ -284,5 +289,6 @@ enum {
#define QUIRK_FLAG_MIC_RES_384 QUIRK_FLAG(MIC_RES_384)
#define QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE QUIRK_FLAG(MIXER_PLAYBACK_MIN_MUTE)
#define QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE QUIRK_FLAG(MIXER_CAPTURE_MIN_MUTE)
+#define QUIRK_FLAG_SKIP_IFACE_SETUP QUIRK_FLAG(SKIP_IFACE_SETUP)

#endif /* __USBAUDIO_H */
--
2.51.0