Several audio devices in one USB card

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I am developing a product, where in a single USB card there are two audio
(UAC1) devices. The general structure reflected in the USB Configuration
Descriptor is:

IAD0
  IF0 - Audio Control 0
  IF1 - Audio Streaming Downstream 0
  IF2 - Audio Streaming Upstream 0
IAD1
  IF3 - Audio Control 1
  IF4 - Audio Streaming Upstream 1

(IADx = Interface Associacion Descriptor as per the USB2.0 IAD ECN; IFx =
interface - there's no need to go deeper in the desriptors' structure for
this post). 

The reason why there are two devices (separated by IADs) is, that in this
way both devices are simple devices which are nicely parsed and mapped by
the class drivers of Windows and OsX (as opposed to the case when all
three streaming interface are grouped under one control interface); and
they also map straighforwardly to two physical sound source/sinks: one
CODEC and one ADC. There is no interaction between these two, not in
hardware, nor in firmware, and it's desired that they behave completely
independently in the host, too.

However, when plugged into Linux machine, ALSA incorrectly sends
min/max/cur/set requests for controls of the device 1 into IF0, rather
than IF3 as it should. The reason is very straigforward and even
documented in the comment in [linux-4.19]\sound\usb\card.c,
usb_audio_probe() :

  /*
   * For devices with more than one control interface, we assume the
   * first contains the audio controls. We might need a more specific
   * check here in the future.
   */
  if (!chip->ctrl_intf)
    chip->ctrl_intf = alts; 

and later this single interface is used as a target for all class-specific
interface requests on this card, regardless of which device i.e. control
interface the given streaming interface corresponds to, e.g. in mixer.c
get_ctl_value_v1():
    idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); 

where from helper.h

static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip)
{
	return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber;
} 


I am not versed in alsa/linux development so cannot submit a patch;
however, I believe that similarly structured USB cards are fully
legitimate and class-compliant, thus deserve to be supported natively.

Thanks,

Jan Waclawek



_______________________________________________
Alsa-user mailing list
Alsa-user@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-user



[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux