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 模式不能混用,否则会导致数据移位或声道错乱。
I2S 总线时序与信号连接 SoC CPU DAI (主控端) Codec 芯片 (从设备) BCLK(位时钟) LRCLK(帧同步) SDATA_OUT(SoC→Codec) SDATA_IN(Codec→SoC) I2S 时序示意(左声道 16-bit 数据) BCLK LRCLK SDATA ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐ └───────高电平(左声道)──────────┴───────低电平(右声道)────── └─ MSB ─┘ └─ 数据位 14~1 ─┘ └─ LSB ─┘

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 / 中断寄存器:用于插拔检测、按键检测、状态输出。
典型 Codec 寄存器模型与驱动映射 复位 & ID 0x00 ~ 0x0F 电源管理 0x10 ~ 0x2F 音频接口 0x30 ~ 0x4F 采样率 & PLL 0x50 ~ 0x6F 混音器路由 0x70 ~ 0x8F 增益 / 音量 0x90 ~ 0xAF GPIO / 中断 0xB0 ~ 0xCF 保留 / 测试 0xD0 ~ 0xFF ALSA Codec 驱动层(snd_soc_codec_driver) regmap 读写 → 控件(kcontrol)→ DAPM 路由 → 事件回调 I2C / SPI 总线 → Codec 硬件寄存器

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 驱动集成。