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 [ Adapted to 5.3 kernel by tiwai ] Signed-off-by: Alexander Tsoy <alexander@tsoy.me> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
c1ae5e7f05
commit
f7f5301814
@ -1077,7 +1077,9 @@ found_clock:
|
|||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_device *dev;
|
||||||
struct usb_interface *iface;
|
struct usb_interface *iface;
|
||||||
@ -1178,6 +1180,16 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
|
|||||||
else if (IS_ERR(fp))
|
else if (IS_ERR(fp))
|
||||||
return PTR_ERR(fp);
|
return PTR_ERR(fp);
|
||||||
|
|
||||||
|
if (fp->fmt_type != UAC_FORMAT_TYPE_I)
|
||||||
|
*has_non_pcm = true;
|
||||||
|
if ((fp->fmt_type == UAC_FORMAT_TYPE_I) == non_pcm) {
|
||||||
|
audioformat_free(fp);
|
||||||
|
kfree(pd);
|
||||||
|
fp = NULL;
|
||||||
|
pd = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);
|
dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);
|
||||||
if (protocol == UAC_VERSION_3)
|
if (protocol == UAC_VERSION_3)
|
||||||
err = snd_usb_add_audio_stream_v3(chip, stream, fp, pd);
|
err = snd_usb_add_audio_stream_v3(chip, stream, fp, pd);
|
||||||
@ -1197,3 +1209,23 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
|
|||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user