2. I2S 总线协议详解

I2S(Inter-IC Sound)总线是数字音频设备间传输 PCM 音频数据最常用的串行总线标准,由 Philips 公司于 1986 年提出。在 Linux 音频驱动中,I2S 是 CPU 侧 I2S 控制器与外部 Codec 之间音频数据流的主干道。理解 I2S 物理层信号定义、时序关系以及数据对齐格式,是正确配置设备树中 #sound-dai-cells、format 等属性的前提。

学习提示: 本章所有时序图和数据格式对比均基于标准 I2S 规范(Philips 协议)。实际 SoC 可能支持多种变体(如左对齐、右对齐、DSP 模式),但核心信号线定义一致。

2.1 I2S 物理层信号定义

标准 I2S 总线由三条主要信号线组成,所有信号均与位时钟同步。

信号名称 缩写 方向(典型) 功能描述
位时钟 BCLK (Bit Clock) 主设备 → 从设备 每个脉冲对应一个数据位的传输。频率 = 采样率 × 位宽 × 通道数。
帧时钟 / 字选择 LRCLK (Left/Right Clock) 主设备 → 从设备 指示当前数据属于左声道还是右声道。频率 = 采样率。
串行数据 SD (Serial Data) 双向(通常 TX/RX 分离) 承载音频采样数据的串行位流。可以是输入(SDI)或输出(SDO)。
关键参数计算: 对于 48kHz 采样率、24 位深、立体声的音频流,BCLK 频率 = 48000 × 24 × 2 = 2.304 MHz。LRCLK 频率 = 48 kHz。

2.2 标准 I2S 时序图

标准 I2S 协议规定:SD 数据在 BCLK 的下降沿变化,在上升沿被接收端采样。LRCLK 在左声道时为低电平,右声道时为高电平(或相反,取决于具体实现,但标准 Philips 协议为:左声道 LRCLK = 0,右声道 LRCLK = 1)。数据从 LRCLK 跳变后的第二个 BCLK 上升沿开始传输,且 MSB 优先。

下图展示了标准 I2S 模式下传输一个立体声帧(左声道 + 右声道)的时序关系:

标准 I2S 时序图(Philips 协议) BCLK LRCLK 左声道 (L) 右声道 (R) SD MSB LSB MSB LSB 时序要点: 1. LRCLK 在左声道期间为低,右声道期间为高。 2. SD 数据在 LRCLK 跳变后的第 2 个 BCLK 上升沿开始传输 MSB。 3. 数据在 BCLK 下降沿变化,接收端在上升沿采样。

2.3 左对齐与右对齐格式对比

除了标准 I2S 格式,许多 Codec 和 SoC 还支持 左对齐(Left-Justified) 和 右对齐(Right-Justified) 格式。它们的核心区别在于 数据 MSB 相对于 LRCLK 跳变沿的位置。

特性 标准 I2S (Philips) 左对齐 (Left-Justified) 右对齐 (Right-Justified)
MSB 起始位置 LRCLK 跳变后的第 2 个 BCLK LRCLK 跳变后的第 1 个 BCLK LRCLK 跳变后的最后一个 BCLK 周期
数据与帧时钟关系 延迟 1 个 BCLK 与 LRCLK 边沿对齐 与 LRCLK 边沿右对齐
典型应用 Philips 标准 Codec ADI、TI 部分 Codec 部分 DSP 或老旧 Codec
设备树配置 format = "i2s" format = "left_j" format = "right_j"

下图直观对比了这三种格式在一个左声道数据帧内的起始位置差异(以 8 位数据为例,实际通常为 16/24/32 位):

I2S / 左对齐 / 右对齐 格式对比(左声道数据起始位置) BCLK LRCLK 标准 I2S 数据有效(MSB 从第2个BCLK开始) MSB 起始 左对齐 数据有效(MSB 从第1个BCLK开始) MSB 起始 右对齐 数据有效(MSB 在最后一个BCLK周期) MSB 起始
驱动配置陷阱: 在设备树中错误配置 format 属性(例如 Codec 要求左对齐但配置为标准 I2S)会导致音频数据错位,表现为声音严重失真或完全无声。务必查阅 Codec 数据手册确认其支持的格式。

2.4 I2S 数据格式与位宽

除了对齐格式,I2S 还涉及数据位宽和有效位宽的概念。常见配置如下:

  • 数据位宽(Data Width): 每个 BCLK 周期传输的位数,通常为 16、24 或 32 位。
  • 有效位宽(Sample Width): 实际音频采样数据的位数。例如 24 位数据可能放在 32 位槽位中。
  • 槽位宽度(Slot Width): 每个声道占用的 BCLK 周期数。当槽位宽度大于有效位宽时,多余位通常填充 0。

在设备树中,这些参数通过 dai-tdm-slot-width、dai-tdm-slot-num 等属性配置,或由 sound-dai 的 dai-format 隐含决定。

2.5 I2S 主从模式与时钟极性

I2S 总线可以配置为 主机模式(Master) 或 从机模式(Slave):

模式 BCLK / LRCLK 产生者 典型场景
CPU 主模式 CPU I2S 控制器 CPU 作为音频时钟源,Codec 作为从设备
CPU 从模式 外部 Codec 或 PLL Codec 内部 PLL 产生时钟,CPU 同步接收

时钟极性(BCLK 和 LRCLK 的有效边沿)也需匹配。设备树中通过 bitclock-inversion 和 frame-inversion 属性调整。

设备树配置示例(CPU 主模式,标准 I2S,24 位):
&i2s1 {
    status = "okay";
    #sound-dai-cells = <0>;
    pinctrl-names = "default";
    pinctrl-0 = <&i2s1_pins>;
    assigned-clocks = <&clk IMX8MM_CLK_SAI1>;
    assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
    assigned-clock-rates = <24576000>; /* 48kHz * 32 * 2 * 8 */
};

&wm8960 {
    status = "okay";
    #sound-dai-cells = <0>;
    compatible = "wlf,wm8960";
    reg = <0x1a>;
    clocks = <&clk IMX8MM_CLK_SAI1>;
    clock-names = "mclk";
    assigned-clocks = <&clk IMX8MM_CLK_SAI1>;
    assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
    assigned-clock-rates = <24576000>;
};

&sound {
    compatible = "simple-audio-card";
    simple-audio-card,name = "imx8mm-wm8960";
    simple-audio-card,format = "i2s";
    simple-audio-card,bitclock-master = <&cpu_dai>;
    simple-audio-card,frame-master = <&cpu_dai>;
    simple-audio-card,mclk-fs = <512>;

    cpu_dai: simple-audio-card,cpu {
        sound-dai = <&i2s1>;
    };

    codec_dai: simple-audio-card,codec {
        sound-dai = <&wm8960>;
    };
};

2.6 本章小结

  • I2S 总线由 BCLK、LRCLK 和 SD 三条信号线组成,BCLK 频率由采样率、位宽和通道数决定。
  • 标准 I2S 时序中,数据 MSB 在 LRCLK 跳变后的第 2 个 BCLK 开始传输,下降沿变化、上升沿采样。
  • 左对齐 格式 MSB 从第 1 个 BCLK 开始;右对齐 格式 MSB 在帧末尾。设备树中通过 format 属性区分。
  • 主从模式、时钟极性、位宽配置必须在 CPU 和 Codec 之间完全匹配,否则音频无法正常工作。