1. Overview
ALSA stands for Advanced Linux Sound Architecture, which has become the mainstream audio architecture in Linux.
In the Linux kernel device driver layer, ALSA provides alsa-driver, and in the user space, it provides alsa-lib. Therefore, Linux applications can control the underlying audio hardware by simply calling the API provided by alsa-lib. The software structure of ALSA in the Linux kernel is as follows:

The user-space alsa-lib provides a unified API interface for applications, hiding the actual details of the driver layer and simplifying the implementation difficulty. However, because alsa-lib is also large, tiny-alsa is often used in Android and other systems (detailed description omitted here).
As shown in the figure above, there is a further encapsulation of alsa-driver in the Linux kernel, namely alsa-soc, which enhances some deficiencies of ALSA. This will be introduced in detail in subsequent sections.
2. ALSA Device File Structure
The device file structure seen under a Linux system is as follows:
$ cd /dev/snd
$ ls -l
crw-rw----+ 1 root audio 116, 8 2011-02-23 21:38 controlC0
crw-rw----+ 1 root audio 116, 4 2011-02-23 21:38 midiC0D0
crw-rw----+ 1 root audio 116, 7 2011-02-23 21:39 pcmC0D0c
crw-rw----+ 1 root audio 116, 6 2011-02-23 21:56 pcmC0D0p
crw-rw----+ 1 root audio 116, 5 2011-02-23 21:38 pcmC0D1p
crw-rw----+ 1 root audio 116, 3 2011-02-23 21:38 seq
crw-rw----+ 1 root audio 116, 2 2011-02-23 21:38 timer
From the above, we can see the following device files:
controlC0 --> used for sound card control, such as channel selection, mixer, microphone control, volume up/down, switches, etc.
midiC0D0 --> used for playing MIDI audio
pcmC0D0c --> PCM device for recording
pcmC0D0p --> PCM device for playback
seq --> sequencer
timer --> timer
Here, C0D0 represents device 0 on card 0. The last 'c' in pcmC0D0c stends for capture, and the last 'p' in pcmC0D0p stands for playback. These are naming conventions in alsa-driver. From the list, my sound card has six devices attached. Depending on the actual capabilities of the sound card, the driver can attach more types of devices. In include/sound/core.h, the following device types are defined. Typically, we care more about pcm and control devices. By default, each sound card corresponds to one Control device.
#define SNDRV_DEV_TOPLEVEL ((__force snd_device_type_t) 0)
#define SNDRV_DEV_CONTROL ((__force snd_device_type_t) 1)
#define SNDRV_DEV_LOWLEVEL_PRE ((__force snd_device_type_t) 2)
#define SNDRV_DEV_LOWLEVEL_NORMAL ((__force snd_device_type_t) 0x1000)
#define SNDRV_DEV_PCM ((__force snd_device_type_t) 0x1001)
#define SNDRV_DEV_RAWMIDI ((__force snd_device_type_t) 0x1002)
#define SNDRV_DEV_TIMER ((__force snd_device_type_t) 0x1003)
#define SNDRV_DEV_SEQUENCER ((__force snd_device_type_t) 0x1004)
#define SNDRV_DEV_HWDEP ((__force snd_device_type_t) 0x1005)
#define SNDRV_DEV_INFO ((__force snd_device_type_t) 0x1006)
#define SNDRV_DEV_BUS ((__force snd_device_type_t) 0x1007)
#define SNDRV_DEV_CODEC ((__force snd_device_type_t) 0x1008)
#define SNDRV_DEV_JACK ((__force snd_device_type_t) 0x1009)
#define SNDRV_DEV_COMPRESS ((__force snd_device_type_t) 0x100A)
#define SNDRV_DEV_LOWLEVEL ((__force snd_device_type_t) 0x2000)
3. Linux ALSA Source Code Directory Structure
The ALSA architecture code in the Linux source tree is located under /sound. The directory structure in Linux 5.0 is as follows:

The roles of the main subdirectory are:
core Contains the middle layer of the ALSA driver, the core part of the entire ALSA driver
core/oss Contains modules that emulate the old OSS architecture for PCM and Mixer
core/seq Code related to the sequencer
drivers Contains common code independent of CPU and BUS architecture
i2c ALSA's own I2C control code
pci Top-level directory for PCI sound cards; subdirectories contain code for various PCI sound cards
isa Top-level directory for ISA sound cards; subdirectories contain code for various ISA sound cards
soc Middle layer code for system-on-chip (SoC) architectures
soc/codecs Code for various codecs in SoC architectures, platform-independent
include Public header file directory for ALSA drivers, path is /include/sound. Headers here need to be exported for user-space applications. Usually, private header files for driver modules should not be placed here.
Reference posts:
- Linux ALSA Sound Card Driver Part 1: Introduction to ALSA Architecture
- Linux-alsa Detailed Explanation 1: Basic Knowledge
Encouragement: The Linux ALSA architecture is a tough nut to crack. Keep going! ☺