diff mbox

ALSA: usb-audio: fix PCM device order

Message ID 20170810233614.3184-1-alexander@tsoy.me (mailing list archive)
State New, archived
Headers show

Commit Message

Alexander Tsoy Aug. 10, 2017, 11:36 p.m. UTC
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(-)

Comments

Tanu Kaskinen July 27, 2019, 8:09 a.m. UTC | #1
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:
>  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;
> +}
> +
Takashi Iwai July 27, 2019, 9:26 a.m. UTC | #2
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:
> >  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;
> > +}
> > +
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
diff mbox

Patch

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;
+}
+