2. Codec 驱动基础:Codec 芯片的作用、I2S/PCM 接口、I2C/SPI 控制接口、Codec 寄存器模型
2.1 Codec 芯片在音频链路中的核心作用
Codec(Coder-Decoder)芯片是嵌入式音频子系统的模拟-数字混合边界。它在数字域与模拟域之间完成双向转换,并承担信号调理、增益控制、路由切换等任务。在 ALSA 驱动架构中,Codec 驱动位于 Machine 驱动 与 CPU DAI 驱动 之间,是音频数据流的最终执行者。
关键职责:
- ADC/DAC 转换:将麦克风/线路输入的模拟信号转为 PCM 数字流,或将数字流还原为耳机/扬声器驱动信号。
- 采样率与位深转换:支持 8 kHz ~ 192 kHz 采样率,16/24/32 位精度。
- 混音与路由:内部多路模拟/数字混音器,实现播放与录音路径的灵活切换。
- 增益与静音控制:通过寄存器控制 PGA(可编程增益放大器)、数字音量、静音开关。
- 电源管理:支持多级省电模式,动态关闭未使用的模拟模块。
2.2 I2S / PCM 数字音频接口
I2S(Inter-IC Sound)与 PCM(Pulse Code Modulation)是 Codec 与 SoC CPU DAI 之间传输数字音频数据的同步串行总线。两者物理层兼容,但时序与帧结构存在差异。
| 特性 | I2S(Philips 标准) | PCM(DSP 模式) |
|---|---|---|
| 帧同步信号 | LRCLK(左右声道选择),高电平=左声道 | FSYNC(帧同步),通常为 8/16 kHz 脉冲 |
| 数据对齐 | 数据在 LRCLK 跳变后延迟 1 个 BCLK 开始 | 数据与 FSYNC 对齐,无延迟 |
| 时隙数量 | 固定 2 个时隙(左/右) | 可配置 2/4/8/16 个时隙(TDM) |
| 典型应用 | 立体声耳机、麦克风 | 多通道阵列、语音通信 |
| ALSA 格式标识 | SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_DSP_A / DSP_B |
ALSA 驱动提示: 在
snd_soc_dai_link 的 dai_fmt 字段中设置格式。I2S 与 PCM 模式不能混用,否则会导致数据移位或声道错乱。
2.3 I2C / SPI 控制接口
Codec 的寄存器读写通过低速控制总线完成,主流方案为 I2C 或 SPI。ALSA 的 regmap 框架统一抽象这两种总线,驱动开发者只需提供 regmap_config 结构体。
| 特性 | I2C | SPI |
|---|---|---|
| 引脚数量 | 2 线(SCL, SDA) | 4 线(SCLK, MOSI, MISO, CS) |
| 最大速率 | 标准 100 kHz / 快速 400 kHz | 通常 1~10 MHz |
| 寻址方式 | 7-bit 或 10-bit 设备地址 | 片选信号 CS 选择设备 |
| 典型 Codec 示例 | WM8960, ES8316, NAU88C22 | TLV320AIC3104, ADAU1361 |
| ALSA 注册方式 | i2c_new_client_device + devm_regmap_init_i2c |
spi_new_device + devm_regmap_init_spi |
常见陷阱: I2C 地址的 7-bit 值与 8-bit 值容易混淆。Codec 数据手册通常给出 7-bit 地址(如 0x1A),ALSA 驱动中应左移 1 位写入
i2c_client.addr。SPI 模式下需注意 CPOL/CPHA 极性配置,错误极性会导致寄存器读写全为 0xFF。
2.4 Codec 寄存器模型
Codec 内部功能通过寄存器映射暴露给驱动。典型的寄存器模型包含以下类别:
- 复位寄存器(Reset):写入特定值使芯片恢复默认状态。
- 电源管理寄存器(Power Management):控制 ADC、DAC、MICBIAS、HPOUT 等模块的供电开关。
- 音频接口寄存器(Audio Interface):配置 I2S/PCM 格式、位宽、主从模式。
- 采样率控制寄存器(Sample Rate Control):设置内部 PLL 分频、MCLK/LRCLK 比率。
- 混音器寄存器(Mixer):选择输入源、控制混音比例、旁路路径。
- 增益寄存器(Gain/Volume):PGA 增益、数字音量、静音位。
- GPIO / 中断寄存器:用于插拔检测、按键检测、状态输出。
2.5 寄存器读写与 ALSA 控件映射
ALSA 驱动通过 snd_kcontrol_new 将寄存器位域暴露为用户空间控件。典型的映射关系如下:
/* 示例:WM8960 左声道耳机音量寄存器 0x02,位 0~6 */
static const struct snd_kcontrol_new wm8960_hp_l_control =
SOC_DOUBLE_R_TLV("Headphone Playback Volume",
WM8960_LOUT1_VOLUME, /* 左声道寄存器地址 */
WM8960_ROUT1_VOLUME, /* 右声道寄存器地址 */
0, /* 寄存器位偏移 */
127, /* 最大值 */
0, /* 是否反转 */
hp_tlv); /* TLV 增益表 */
TLV(音量和线性值)表: 用于将寄存器数值映射为 dB 增益。ALSA 的
DECLARE_TLV_DB_SCALE 宏可快速生成线性或对数刻度表。例如 DECLARE_TLV_DB_SCALE(hp_tlv, -7300, 100, 0) 表示范围 -73 dB ~ 0 dB,步进 1 dB。
2.6 本章小结
- Codec 是音频模拟域与数字域的桥梁,负责 ADC/DAC、混音、增益、电源管理。
- I2S/PCM 接口传输音频数据,I2C/SPI 接口传输控制命令,两者物理分离。
- 寄存器模型按功能分区:复位、电源、接口、采样率、混音器、增益、GPIO。
- ALSA 驱动通过 regmap 统一访问寄存器,通过 kcontrol 暴露用户空间控件。
- 理解寄存器模型是编写跨平台 Codec 驱动的第一步,后续章节将基于此展开 DAPM 与 Machine 驱动集成。