[alsa-devel] [PATCH] ALSA: usb-audio: fix PCM device order

Alexander Tsoy alexander at tsoy.me
Fri Aug 11 01:36:14 CEST 2017


Some cards have alternate setting with non-PCM format as the first
altsetting in the interface descriptors. This confuses userspace, since
alsa-lib uses device 0 by default. So lets parse interfaces in two steps:
 1. Parse altsettings with PCM formats.
 2. Parse altsettings with non-PCM formats.

This fixes at least following cards:
 - Audinst HUD-mx2
 - Audinst HUD-mini

Signed-off-by: Alexander Tsoy <alexander at tsoy.me>
---
 sound/usb/stream.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 8e9548bc1f1a..b2ebeae91396 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -477,7 +477,8 @@ static struct uac2_output_terminal_descriptor *
 	return NULL;
 }
 
-int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
+static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no,
+				           bool *has_non_pcm, bool non_pcm)
 {
 	struct usb_device *dev;
 	struct usb_interface *iface;
@@ -634,6 +635,10 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
 				iface_no, altno);
 			continue;
 		}
+		if (fmt->bFormatType != UAC_FORMAT_TYPE_I)
+			*has_non_pcm = true;
+		if ((fmt->bFormatType == UAC_FORMAT_TYPE_I) == non_pcm)
+			continue;
 		if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
 		    ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) {
 			dev_err(&dev->dev,
@@ -740,3 +745,23 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
 	return 0;
 }
 
+int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
+{
+	int err;
+	bool has_non_pcm = false;
+
+	/* parse PCM formats */
+	err = __snd_usb_parse_audio_interface(chip, iface_no, &has_non_pcm, false);
+	if (err < 0)
+		return err;
+
+	if (has_non_pcm) {
+		/* parse non-PCM formats */
+		err = __snd_usb_parse_audio_interface(chip, iface_no, &has_non_pcm, true);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
-- 
2.13.0



More information about the Alsa-devel mailing list