Linux音频驱动设备树与I2S接口配置详解 - 第1节

1.1 数字音频基础概念

数字音频的本质是将连续变化的模拟声波信号,通过采样、量化和编码三个步骤,转换为离散的数字序列。理解以下三个核心参数是掌握音频驱动的基础。

参数 定义 常见值 对音质的影响
采样率 (Sample Rate) 每秒对模拟信号采样的次数,单位 Hz (kHz) 8k, 16k, 44.1k, 48k, 96k, 192k 决定频率上限(奈奎斯特频率 = 采样率/2)
位深 (Bit Depth) 每个采样点用多少比特表示幅度 8, 16, 20, 24, 32 决定动态范围(信噪比 ≈ 6.02 × 位深 + 1.76 dB)
声道数 (Channels) 独立音频信号的数量 1 (Mono), 2 (Stereo), 5.1, 7.1 决定空间感和沉浸度
关键公式: 未压缩 PCM 数据速率 = 采样率 × 位深 × 声道数。例如:CD 音质 (44.1kHz × 16bit × 2ch) = 1,411.2 kbps。

1.1.1 采样与量化过程

下图展示了模拟信号到数字 PCM 数据的转换流程。采样保持电路在固定时间点捕获电压,量化器将其映射到最接近的离散电平。

模拟信号 → 采样 → 量化 → 编码 (PCM) 模拟信号 量化电平 量化后阶梯波 采样脉冲 采样率决定频率上限,位深决定动态范围,两者共同决定数字音频质量

1.2 PCM 数据流

PCM(Pulse Code Modulation,脉冲编码调制)是数字音频最基础的未压缩格式。在 Linux 音频子系统中,PCM 数据流是驱动层与用户空间交互的核心载体。

1.2.1 PCM 数据在内存中的排列

对于多声道数据,常见的排列方式有两种:交错(Interleaved)和非交错(Non-interleaved)。

  • 交错模式: 声道数据按帧连续排列:L0 R0 L1 R1 L2 R2 ... 适用于大多数消费类音频设备。
  • 非交错模式: 每个声道的数据独立成块:L0 L1 L2 ... R0 R1 R2 ... 适用于多声道录音或专业音频处理。
驱动开发提示: 在 ALSA 驱动中,snd_pcm_hardware 结构体的 formats 字段定义了硬件支持的 PCM 格式。常见格式包括 S16_LE(16位有符号小端)、S24_LE(24位有符号小端)、S32_LE(32位有符号小端)。

1.2.2 PCM 数据流生命周期

从应用程序写入数据到扬声器发声,PCM 数据流经过以下关键路径:

  1. 用户空间: 应用程序通过 ALSA lib 调用 snd_pcm_writei() 写入 PCM 数据。
  2. 内核 ALSA 核心层: 数据进入 DMA 缓冲区,触发 snd_pcm_ops::copy 或 snd_pcm_ops::fill_silence 回调。
  3. DMA 控制器: 将 PCM 数据从内存搬运到 I2S 发送 FIFO。
  4. I2S 控制器: 按位时钟将 FIFO 中的数据串行化,通过 I2S 总线发送给 Codec。
  5. Codec: 接收 I2S 数据,进行 D/A 转换,输出模拟信号驱动扬声器。
PCM 数据流路径 用户应用 ALSA 核心层 DMA 控制器 I2S 控制器 Codec DMA 负责数据搬运,I2S 负责串行化传输,Codec 负责数模转换

1.3 I2S 总线在音频系统中的角色

I2S(Inter-IC Sound,集成电路内置音频总线)是飞利浦公司制定的串行总线标准,专门用于连接数字音频设备(如 SoC 的 I2S 控制器与外部 Codec)。它是嵌入式 Linux 音频驱动中最核心的硬件接口之一。

1.3.1 I2S 总线信号定义

信号线 名称 方向 功能描述
BCLK 位时钟 (Bit Clock) 主机 → 从机 每个脉冲对应一个数据位的传输,频率 = 采样率 × 位深 × 声道数
LRCK 左右声道时钟 (Left/Right Clock) 主机 → 从机 高电平表示左声道,低电平表示右声道(或相反),频率 = 采样率
SD 串行数据 (Serial Data) 双向 传输 PCM 数据,可以是 SDI(输入)或 SDO(输出)
MCLK 主时钟 (Master Clock) 主机 → 从机 可选信号,为 Codec 提供高精度时钟源,频率通常为 256×fs 或 384×fs

1.3.2 I2S 数据格式与时序

标准的 I2S 协议规定:数据在 BCLK 的下降沿变化,在上升沿采样;LRCK 在数据发送前一个 BCLK 周期切换;数据从 MSB(最高有效位)开始传输,MSB 在 LRCK 切换后的第二个 BCLK 周期开始发送。

I2S 总线时序图 (标准模式, 16位数据) LRCK 左声道 (高) 右声道 (低) BCLK SD MSB 左声道数据 (16位) MSB 右声道数据 (16位) 数据在 BCLK 上升沿采样,MSB 在 LRCK 切换后的第二个 BCLK 周期开始

1.3.3 I2S 在音频子系统中的位置

在 Linux 音频驱动架构中,I2S 总线位于 CPU 侧 DAI(Digital Audio Interface) 与 Codec 侧 DAI 之间。DAI 是数字音频接口的抽象,I2S 是其中最常用的物理层协议之一。

I2S 总线在音频子系统中的位置 CPU 侧 DAI (I2S 控制器) SoC 内部 I2S 总线 BCLK / LRCK / SD / MCLK Codec 侧 DAI (音频编解码器) 外部芯片 I2S 总线是 CPU 与 Codec 之间的数字音频桥梁,驱动配置的核心在于 DAI 链路 驱动栈中的对应关系 CPU DAI 驱动 → I2S 控制器驱动 (如 DesignWare I2S, Samsung I2S) Codec DAI 驱动 → Codec 驱动 (如 WM8960, MAX98090, ES8316)

1.4 本章小结

  • 数字音频三要素: 采样率、位深、声道数,三者共同决定 PCM 数据速率和音质。
  • PCM 数据流: 从用户空间到 Codec 的完整路径涉及 ALSA 核心层、DMA 控制器和 I2S 控制器。
  • I2S 总线: 使用 BCLK、LRCK、SD 三线(可选 MCLK)传输数字音频,是 CPU DAI 与 Codec DAI 之间的标准接口。
  • 驱动开发视角: 理解 I2S 时序和 PCM 数据格式是配置设备树中 sound-dai、format、mclk-fs 等属性的前提。
常见误区: 初学者容易混淆 I2S 的 BCLK 频率计算。BCLK = 采样率 × 位深 × 声道数。例如 48kHz/24bit/2ch 的 BCLK = 48,000 × 24 × 2 = 2.304 MHz。如果 Codec 要求 64 个 BCLK 周期每帧(即 32 位槽每声道),则实际 BCLK = 48,000 × 64 = 3.072 MHz。务必查阅 Codec 数据手册确认槽宽配置。