[alsa-devel] [PATCH] ALSA: usb-audio: fix PCM device order
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@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; +} +
Ping? This patch never got any feedback, and yesterday another user complained on PulseAudio bug tracker that Audinst HUD-mx2 doesn't work out of the box, because by default hw:x,0 is used when hw:x,1 is the pcm that works.
-- Tanu
On Fri, 2017-08-11 at 02:36 +0300, Alexander Tsoy wrote:
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:
- Parse altsettings with PCM formats.
- Parse altsettings with non-PCM formats.
This fixes at least following cards:
- Audinst HUD-mx2
- Audinst HUD-mini
Signed-off-by: Alexander Tsoy alexander@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)
if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { dev_err(&dev->dev,continue;
@@ -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;
+}
On Sat, 27 Jul 2019 10:09:08 +0200, Tanu Kaskinen wrote:
Ping? This patch never got any feedback, and yesterday another user complained on PulseAudio bug tracker that Audinst HUD-mx2 doesn't work out of the box, because by default hw:x,0 is used when hw:x,1 is the pcm that works.
Oohoo, it's a ping with so large latency. This must have been simply overlooked, or I was off at that time.
In anyway the patch can't be applied to the latest code as of today, so I rewrote with a cleanup patch.
The patchset will be submitted, so please give it a try.
thanks,
Takashi
-- Tanu
On Fri, 2017-08-11 at 02:36 +0300, Alexander Tsoy wrote:
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:
- Parse altsettings with PCM formats.
- Parse altsettings with non-PCM formats.
This fixes at least following cards:
- Audinst HUD-mx2
- Audinst HUD-mini
Signed-off-by: Alexander Tsoy alexander@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)
if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { dev_err(&dev->dev,continue;
@@ -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;
+}
Alsa-devel mailing list Alsa-devel@alsa-project.org https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
participants (3)
-
Alexander Tsoy
-
Takashi Iwai
-
Tanu Kaskinen