Skip to content

Commit 5fadc94

Browse files
committed
ALSA: usb-audio: Fix init call orders for UAC1
There have been reports of USB-audio driver spewing errors at the probe time on a few devices like Jabra and Logitech. The suggested fix there couldn't be applied as is, unfortunately, because it'll likely break other devices. But, the patch suggested an interesting point: looking at the current init code in stream.c, one may notice that it does initialize differently from the device setup in endpoint.c. Namely, for UAC1, we should call snd_usb_init_pitch() and snd_usb_init_sample_rate() after setting the interface, while the init sequence at parsing calls them before setting the interface blindly. This patch changes the init sequence at parsing for UAC1 (and other devices that need a similar behavior) to be aligned with the rest of the code, setting the interface at first. And, this fixes the long-standing problems on a few UAC1 devices like Jabra / Logitech, as reported, too. Reported-and-tested-by: Joakim Tjernlund <joakim.tjernlund@infinera.com> Closes: https://lore.kernel.org/r/202bbbc0f51522e8545783c4c5577d12a8e2d56d.camel@infinera.com Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20230821111857.28926-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent f286620 commit 5fadc94

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

sound/usb/stream.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,7 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
10931093
int i, altno, err, stream;
10941094
struct audioformat *fp = NULL;
10951095
struct snd_usb_power_domain *pd = NULL;
1096+
bool set_iface_first;
10961097
int num, protocol;
10971098

10981099
dev = chip->dev;
@@ -1223,11 +1224,19 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
12231224
return err;
12241225
}
12251226

1227+
set_iface_first = false;
1228+
if (protocol == UAC_VERSION_1 ||
1229+
(chip->quirk_flags & QUIRK_FLAG_SET_IFACE_FIRST))
1230+
set_iface_first = true;
1231+
12261232
/* try to set the interface... */
12271233
usb_set_interface(chip->dev, iface_no, 0);
1234+
if (set_iface_first)
1235+
usb_set_interface(chip->dev, iface_no, altno);
12281236
snd_usb_init_pitch(chip, fp);
12291237
snd_usb_init_sample_rate(chip, fp, fp->rate_max);
1230-
usb_set_interface(chip->dev, iface_no, altno);
1238+
if (!set_iface_first)
1239+
usb_set_interface(chip->dev, iface_no, altno);
12311240
}
12321241
return 0;
12331242
}

0 commit comments

Comments
 (0)