Linux and USB Audio Class 3 - Ruslan Bilovo [FOSDEM 2019]

USB has defined a new specification for Audio, USB Audio Class 3.0. It was supported by Linux even before devices existed.

USB was first released in 1996. USB Audio Class 1.0 was added together with USB 1.1 in 1998. USB 2.0 was released in 2000, Audio Class 2.0 in 2006. USB 3.0 was released in 2008, 3.1 in 2013, but no Audio Class 3.0 release until 2016. In 2017 we had USB 3.2, we’ll see if there is any new audio specification after that.

Audio Class 1.0 already has MIDI. There is a Basic Audio specification (profile) that vendors can standardise to. It models the pipeline between inputs and output, where the USB device is one of the IOs.

Audio Class 2.0 mainly added clock improvements and more audio controls, mostly for professional use. Of course also High Speed support. It is incompatible with UAC1.0. Also, there is no power management.

Audio Class 3.0 adds Super Speed support. It adds power domains. It adds descriptors for the connectors. It adds burst modes for more efficient throughput. There is a special backward compatible mode for hosts that don’t support it yet. Linux support existed before any device existed. Initial support in 4.17, BADD profile in 4.18, connectors in 4.18, power domains in 4.19, configuration switching in 4.20. Gadget driver is being worked on.

UAC3 mandates the BADD (Basic Audio Device Definition) support. A device must always support this specification so it can work with simple hosts. It has 3 possible topologies: one input, one output, or both. It just has mono or stereo, and a few sample rates.

Power domains specify parts of the topology that can be shut down when not in use. E.g. the microphone amp when you’re listening to music.

Backward compatibility and the BADD profile are supported by multiple configurations. UAC1 or 2 is configuration 1. BADD is configuration 2. Full features is configuration 3. An old host will just use configuration 1. A limited UAC3 host will always choose configuration 2. Linux will use configuration 3. However, normally the kernel doesn’t do mode switching… Still, for this, in-kernel switching was accepted by the USB maintainers.

Unfortunately, the USB documentation has a lot of wholes and mistakes. They are being fixed by the working group, but that is not public.

Writing a driver was challenging when there was no hardware yet. So Ruslan first wrote the gadget driver and tested in qemu with dummy_hcd.ko, and later on BBB with alsaloop to the actual audio output. Of course that is not ideal because it’s likely that the same bug happens on both sides.

Since there was no hardware yet, it was difficult to get reviews and testing. Fortunately someone who was working on a UAC3 device picked up the patch and used it to test his hardware, thereby testing the patch as well.