Rockchip RK3399 - Platform驱动(DMA&i2s0)

发布时间 2023-07-30 14:40:34作者: 大奥特曼打小怪兽

Platfrom driver提供了配置/使能SoC音频接口的能力;Plaftrom驱动分为两个部分:snd_soc_platform_driver、snd_soc_dai_driver。

  • snd_soc_platform_driver:负责管理音频数据,把音频数据通过DMA或其他操作传送至CPU DAI中;
  • snd_soc_dai_driver:负责完成SoC一侧的DAI参数配置,同时也会通过一定的路径把必要的DMA等参数与snd_soc_platform_driver进行交互;

驱动代码位于sound/soc/rockchip/rockchip_i2s.c文件。

一、设备节点

1.1 设备节点i2s0

设备节点i2s0定义在arch/arm64/boot/dts/rockchip/rk3399.dts文件:

i2s0: i2s@ff880000 {
        compatible = "rockchip,rk3399-i2s", "rockchip,rk3066-i2s";
        reg = <0x0 0xff880000 0x0 0x1000>;
        rockchip,grf = <&grf>;
        interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH 0>;
        dmas = <&dmac_bus 0>, <&dmac_bus 1>;
        dma-names = "tx", "rx";
        clock-names = "i2s_clk", "i2s_hclk";
        clocks = <&cru SCLK_I2S0_8CH>, <&cru HCLK_I2S0_8CH>;
        pinctrl-names = "bclk_on", "bclk_off";
        pinctrl-0 = <&i2s0_8ch_bus>;
        pinctrl-1 = <&i2s0_8ch_bus_bclk_off>;
        power-domains = <&power RK3399_PD_SDIOAUDIO>;
        #sound-dai-cells = <0>;
        status = "disabled";
};

这是 Rockchip RK3399 SoC中I2S0设备节点描述。它包括以下属性:

  • compatible: 指定设备驱动程序的兼容性,即告诉内核该设备可以被哪些驱动程序所使用;
  • reg: 指定I2S0控制器的基地址和地址空间大小,从 0xff880000 到 0xff881000 共有 0x1000 个字节的寄存器空间,其中0xff880000 为I2S0寄存器基地址;
  • rockchip,grf:设置为grf设备节点,用于定位并访问与I2S0控制器相关的GRF寄存器;
  • interrupts: 指定I2S控制器的中断号为GIC_SPI 39,并且取值方式为IRQ_TYPE_LEVEL_HIGH,意味着中断信号为高电平触发;
  • dmas: 指定数据传输时使用的DMA控制器,第一个表示TX数据使用的DMA控制器,第二个表示 RX 数据使用的 DMA 控制器;
  • dma-names: 分别对应 "tx" 和 "rx" 的 DMA 名称;
  • clock-names: 指定I2S0时钟名称,"i2s_clk"表示I2S0控制器时钟,"i2s_hclk" 表示I2S0 BUS时钟;
  • clocks: 指定I2S0控制器时钟使用SCLK_I2S0_8CH,BUS时钟使用 HCLK_I2S0_8CH;
  • pinctrl-names: 指定设备pinctrl配置集合;
  • pinctrl-0: 设置bclk_on状态对应的引脚配置为i2s0_8ch_bus,这里主要配置I2S0相关引脚复用为I2S功能;
  • pinctrl-1: 设置bclk_off状态对应的引脚配置为i2s0_8ch_bus_bclk_off,这里主要配置I2S0相关引脚复用为I2S功能,但是SCLK被设置为了GPIO,因此此时I2S0功能是禁用的;
  • power-domains: 指定设备隶属于的电源域,这里是 RK3399_PD_SDIOAUDIO;
  • #sound-dai-cells: 表示定义这个节点的sound DAI数据单元格的数量,这里为0表示没有单元格;
  • status: 表示设备状态,这里 "disabled" 表示该设备当前是禁用状态;

我们需要在arch/arm64/boot/dts/rockchip/rk3399-evb.dts文件添加如下属性,启用I2S0控制器:

&i2s0 {
        rockchip,playback-channels = <2>;
        rockchip,capture-channels = <2>;
        status = "okay";
};

关于设备节点属性可以参考文档Documentation/devicetree/bindings/sound/rockchip-i2s.yaml。

而RK3399 I2S控制器驱动代码位于sound/soc/rockchip/rockchip_i2s.c文件。

1.2 引脚配置节点i2s0_8ch_bus

引脚配置节点i2s0_8ch_bus和i2s0_8ch_bus_bclk_off定义在pinctrl设备节点下:

i2s0 {
        i2s0_2ch_bus: i2s0-2ch-bus {
                rockchip,pins =
                        <3 RK_PD0 1 &pcfg_pull_none>,
                        <3 RK_PD1 1 &pcfg_pull_none>,
                        <3 RK_PD2 1 &pcfg_pull_none>,
                        <3 RK_PD3 1 &pcfg_pull_none>,
                        <3 RK_PD7 1 &pcfg_pull_none>,
                        <4 RK_PA0 1 &pcfg_pull_none>;
        };

        i2s0_8ch_bus: i2s0-8ch-bus {
                rockchip,pins =
                        <3 RK_PD0 1 &pcfg_pull_none>,
                        <3 RK_PD1 1 &pcfg_pull_none>,
                        <3 RK_PD2 1 &pcfg_pull_none>,
                        <3 RK_PD3 1 &pcfg_pull_none>,
                        <3 RK_PD4 1 &pcfg_pull_none>,
                        <3 RK_PD5 1 &pcfg_pull_none>,
                        <3 RK_PD6 1 &pcfg_pull_none>,
                        <3 RK_PD7 1 &pcfg_pull_none>,
                        <4 RK_PA0 1 &pcfg_pull_none>;
        };

        i2s0_8ch_bus_bclk_off: i2s0-8ch-bus-bclk-off {
                rockchip,pins =
                        <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>,
                        <3 RK_PD1 1 &pcfg_pull_none>,
                        <3 RK_PD2 1 &pcfg_pull_none>,
                        <3 RK_PD3 1 &pcfg_pull_none>,
                        <3 RK_PD4 1 &pcfg_pull_none>,
                        <3 RK_PD5 1 &pcfg_pull_none>,
                        <3 RK_PD6 1 &pcfg_pull_none>,
                        <3 RK_PD7 1 &pcfg_pull_none>,
                        <4 RK_PA0 1 &pcfg_pull_none>;
        };
}; 

这里我们只关注i2s0_8ch_bus引脚配置节点,这里定义了9个引脚,管脚与具体的功能和电气特性如下:

  • GPIO3_PD0:功能复用为I2S0_SCLK,电气特性配置为pcfg_pull_none;
  • GPIO3_PD1:功能复用为I2S0_LRCK_RX,电气特性配置为pcfg_pull_none;
  • GPIO3_PD2:功能复用为I2S0_LRCK_TX,电气特性配置为pcfg_pull_none;
  • GPIO3_PD3:功能复用为I2S0_SDI0,电气特性配置为pcfg_pull_none;
  • GPIO3_PD4:功能复用为I2S0_SDI1/I2S0_SDO3,电气特性配置为pcfg_pull_none;
  • GPIO3_PD5:功能复用为I2S0_SDI2/I2S0_SDO2,电气特性配置为pcfg_pull_none;
  • GPIO3_PD6:功能复用为I2S0_SDI3/I2S0_SDO1,电气特性配置为pcfg_pull_none;
  • GPIO3_PD7:功能复用为I2S0_SDO0,电气特性配置为pcfg_pull_none;
  • GPIO4_PA0:功能复用为I2S0_MCLK,电气特性配置为pcfg_pull_none;

二、I2S控制器驱动

 

 

参考文章

[1] 理解ALSA(三):从零写ASoC驱动