Audio routing on a smartphone is incredibly complex. A device might be playing Spotify out of the bottom speaker, routing a phone call to the top earpiece, and listening for "Hey Google" via the bottom microphone, all simultaneously.
To handle this massive matrix of routing and mixing, the Android kernel relies entirely on the ALSA (Advanced Linux Sound Architecture) and specifically the ASoC (ALSA System on Chip) framework.
The ALSA Subsystem
ALSA provides the core audio and MIDI functionality to the Linux operating system. It exposes hardware devices to user-space via character device nodes located in /dev/snd/.
# You can view the available ALSA sound cards and PCM devices on Android
adb shell ls -l /dev/snd
# You can also read the ALSA configuration directly
adb shell cat /proc/asound/cards
The Android user-space (specifically the Audio HAL and AudioFlinger) opens these /dev/snd/pcmC0D0p nodes to write raw PCM audio data directly to the hardware.
The ASoC Framework
Standard ALSA was designed for desktop PCs, where a single PCI sound card handles everything. Smartphones use embedded SoCs, where the audio processing is heavily fragmented.
To solve this, ASoC splits the audio driver into three distinct, reusable components:
- The Machine Driver: This is the top-level driver specific to the actual phone model (e.g., Pixel 8). It acts as the glue, telling the kernel, "Wire the Qualcomm audio interface to the Cirrus Logic amplifier chip."
- The Platform Driver: This driver handles the SoC-specific audio DMA (Direct Memory Access) engines. It is responsible for shoveling the PCM audio bytes from RAM into the hardware FIFOs.
- The Codec Driver: This driver controls the actual hardware chip (the DAC/ADC) that converts digital bytes into physical analog sound waves. It is highly reusable; the same Cirrus Logic codec driver can be used across 50 different phone models.
DPCM (Dynamic PCM)
Mobile audio requires extreme flexibility. If you plug in a USB-C headset while listening to music, the audio must instantly reroute from the speaker codec to the USB interface without the music player app crashing.
ASoC achieves this using DPCM (Dynamic PCM).
DPCM separates the "Frontend" (the virtual PCM device the Android AudioFlinger is writing to) from the "Backend" (the actual physical codec).
When you plug in the headset, the DPCM framework dynamically unlinks the frontend from the speaker backend and links it to the USB backend on-the-fly, completely seamlessly.
// Conceptual ASoC Machine Driver mapping
static struct snd_soc_dai_link my_phone_dai_links[] = {
{
.name = "Primary Audio",
.stream_name = "Playback/Capture",
.cpu_dai_name = "soc-audio-interface", // Platform DMA
.codec_dai_name = "cs35l41-amp", // Codec Chip
.platform_name = "soc-audio-platform",
},
};