Audio
1. 概述
1.1 Rockchip 音频特性
本小节描述 RK 平台的音频特性,如表 1-1 所示:
表 1-1 Rockchip Audio 特性
1.2 DAI
本章节主要描述 RK 平台数字音频接口支持情况。
1.2.1 I2S
RK 平台有两种 I2S 控制器:I2S 和 I2S-TDM。I2S 控制器支持 I2S, PCM 协议;I2S-TDM 控制器支持 I2S, PCM, TDM 协议。
1.2.1.1 I2S 控制器 Features
- 支持 8 声道 I2S 协议:standard, left justified, right justified
- 支持 stereo PCM 协议:early, late 1, late 2, late 3
- 支持 master/slave 模式,模式同时应用于 TX/RX 逻辑
- 支持 8k ~ 192k 采样率,384k 采样率
- 支持 16 ~ 32 bits 位宽
- 支持 MSB/LSB 模式
- 支持 时钟相位调整
- 支持 时钟补偿
Note:
384k 采样率需要高精度 clk,可从 MCLK PIN 导入外部高精度 clk 或者采用 slave 模式。
不支持 mono PCM,如有需求,可采用 stereo PCM 传输 mono PCM,有效数据放在 slot 0。
时钟补偿应用于异源系统的时钟补偿,比如 UAC,但有使用条件限制,参考音频时钟补偿章节。
1.2.1.2 I2S-TDM 控制器 Features
除了支持 I2S 控制器的功能之外,I2S-TDM 控制器新增支持如下功能:
- 支持 8 slots TDM PCM 协议:normal, left shift mode[0~3]
- 支持 8 slots TDM I2S 协议:normal, left justified, right justified
- 支持 slot 位宽可配:16 ~ 32 bits
- 支持 data line 全映射,可重映射 data line 与 path 的关系
- 支持 TX/RX 异步模式,独立的时钟,可支持独立的采样率,位宽,协议
- 支持 TX/RX 同步模式,共享时钟
- 支持 PCM FSYNC 宽度可配:[1~7] sclk cycle 或 one channel block
- 支持 I2S FSYNC 宽度可配:half frame / whole frame
Note:
slot 仅支持偶数配置。
TDM I2S 长帧模式下,可支持 16 声道传输。
TDM 协议下,仅使用 path-0,所以物理连接的 PIN 与声道不对应时,请通过 data line 重映射到 path-0。
1.2.1.3 RK 系列芯片 I2S 支持列表
Chip | I2S | I2S-TDM |
---|---|---|
PX30/RK3326 | I2S1_2CH, I2S2_2CH | I2S0_8CH |
RK1808 | I2S1 | I2S0 |
RK3036 | I2S0 | |
RK3066 | I2S0, I2S1, I2S2 | |
RK312X | I2S_8CH, I2S_2CH | |
RK3188 | I2S0 | |
RK3288 | I2S0 | |
RK322X | I2S0, I2S1, I2S2 | |
RK3308 | I2S_2CH_0, I2S_2CH_1 I2S_8CH_0, I2S_8CH_1, I2S_8CH_2, I2S_8CH_3 | |
RK3328 | I2S0, I2S1, I2S2 | |
RK3368 | I2S_8CH, I2S_2CH | |
RK3399 | I2S0, I2S1, I2S2 | |
RK3568/RK3566 | I2S0_8CH, I2S1_8CH, I2S2_2CH, I2S3_2CH | |
RV1108 | I2S0, I2S1, I2S2 | |
RV1126/RV1109 | I2S1_2CH, I2S2_2CH | I2S0_8CH |
1.2.2 PDM
1.2.2.1 PDM 控制器 Features
RK 平台支持 PDM 协议的数字麦或者 ADC,具体 Features 如下:
- 支持 master mode only
- 支持 最大 8 个 MIC 阵列
- 支持 16 ~ 24 bits 位宽
- 支持 8 ~ 48k 采样率
- 支持 声道交换
- 支持 高通滤波:3.79 Hz, 60 Hz, 243 Hz, 493 Hz
- 支持 存储对齐:左对齐, 右对齐
- 支持 data line 全映射
- 支持 时钟相位调整
- 支持 时钟补偿
Note: 存储对齐仅对于位宽大于16 bits 的格式,大于16 bits 的格式,数据按 word 存储,默认低位补0 时钟补偿应用于异源系统的时钟补偿,比如 UAC,但有使用条件限制,参考 音频时钟补偿 章节 data line 全映射功能在 RV1126 及后续推出的芯片才支持: RV1126/RV1109, RK3568/RK3566...
1.2.2.2 RK 系列芯片 PDM 支持列表
Chip | Name | Max Channel | Version |
---|---|---|---|
PX30/RK3326 | PDM | 8 | V2 |
RK1808 | PDM | 8 | V2 |
RK2108 | PDM | 4 | V3 |
RK3308 | PDM_8CH | 8 | V2 |
RK3328 | PDM | 8 | V1 |
RK3568/RK3566 | PDM | 8 | V3 |
RV1126/RV1109 | PDM | 8 | V3 |
版本描述
Version | Description |
---|---|
V1 | 1. 支持标准模式,对应时钟:2.048/2.822/3.072 MHz。 |
V2 | 1. 新增小数分频。 2. 新增存储对齐模式。 |
V3 | BUG FIX: 1. 修正 HPF 使能情况下,输入信号幅度接近 0 db 时,符号位溢出问题。 2. 修正通带内纹波一致性问题,新版本通带纹波小于 0.1 db。 3. 修正混叠问题。 Features: 1. 新增低功耗模式,对应时钟 1.024/1.411/1.536 MHz。 2. 新增高性能模式,对应时钟 4.096/5.644/6.144 MHz。 |
1.2.3 DCODEC
RK 平台支持数字 CODEC 接口,可对接支持该协议的模拟 CODEC,比如 RK812,组合成完整 CODEC。另外,控制器工作于 DSM 模式时,可驱动外部 PA,满足普通音质产品需求,节省成本。
- 支持 3 声道 ADC
- 支持 stereo DAC
- 支持 异步模式:播放和录音采样率可不同。
- 支持 同步模式:播放和录音采样率必须相同。
- 支持 PGA / ALC
- 支持 DSM 输出,直驱 PA
- 支持 高通滤波
1.2.4 VAD
语音活性检测 (Voice Activity Detection),VAD 接收来自 DAI 的数据,处理统计分析,达到预设阈值时,触发中断,唤醒系统。简要数据流图如图 1-1 所示:
图 1-1 RK VAD 数据流
- 系统休眠时,DAI -> VAD -> SRAM 保持工作,VAD 持续的接收数据,滤波,噪声自学习,音频数据存储在 SRAM 循环 Buffer 中。
- VAD 检测到声音超过预设阈值时,产生中断唤醒 CPU,CPU 关闭 VAD,VAD 关闭时,数据流自动切换 DMAC 通路,即:DAI -> DMAC -> DDR -> CPU 标准录音路径。
- CPU 将 SRAM 中的数据无缝填充到录音 Buffer 中,数据处理对用户态透明。
- 唤醒后 ,ASR 程序对录取的数据做分析处理,关键词检测等。
1.2.5 SPDIF
RK 平台支持 SPDIF Transmitter 接口协议,特别的,RK3308 还支持 SPDIF Receiver。
- 支持 16 ~ 24 bits 位宽
- 支持 192k 采样率
- 支持 stereo uncompressed audio,即 LPCM
- 支持 5.1 / 7.1 compressed audio,比如:DD, DD+
- 支持 Optical, Coaxial
Note:
192k 采样率输出的时候,需要配套支持 192k 的 Optical 器件。
1.3 Combo DAI
RK 平台支持任意 DAI 的组合使用,重组 DAI 生成 Combo DAI,如图 1-2 所示:
2. Audio 驱动开发
本章节描述 RK 平台音频支持情况,驱动开发及调试。
2.1 声卡基本构成
本小节介绍声卡的基本构成,如图 2-1 所示:
图 2-1 ALSA 声卡构成
DAI: Digital Audio Interface.
MACHINE: Link dai and codec to be a new sound card.
DMAENGINE: Transfer data between memory and dai's fifo.
通常情况下,基于发布的 SDK 添加一个声卡,仅需要移植或者编写 codec 驱动即可,个别情况下需要添加 machine 驱动,详见 Machine 驱动开发章节。
2.2 代码清单
代码清单及描述如下所示:
kernel/sound/soc/rockchip$ tree -I "*.o|*.h"
.
├── rk3288_hdmi_analog.c
├── rk3399_gru_sound.c
├── rockchip_audio_pwm.c /* low quality audio out by driving pa */
├── rockchip_cdndp.c
├── rockchip_da7219.c
├── rockchip_hdmi_analog.c /* hdmi and codec share the same i2s */
├── rockchip_hdmi_dp.c /* hdmi and dp share the same i2s */
├── rockchip_i2s.c /* old i2s which support i2s/pcm */
├── rockchip_i2s_tdm.c /* new i2s-tdm which support i2s/pcm/tdm */
├── rockchip_max98090.c
├── rockchip_multicodecs.c /* support multi-streaming */
├── rockchip_multi_dais.c /* support combo-dais */
├── rockchip_multi_dais_pcm.c /* co-work with combo-dais */
├── rockchip_pcm.c /* audio data flow and control */
├── rockchip_pdm.c /* pdm dai driver */
├── rockchip_rt5645.c
├── rockchip_rt5651.c
├── rockchip_spdif.c /* spdif tx dai driver */
├── rockchip_spdifrx.c /* spdif rx dai driver */
├── rockchip_vad.c /* voice activity detection driver */
├── vad_preprocess_arm64.S /* vad preprocess algorithm for arm64 */
├── vad_preprocess_arm.S /* vad preprocess algorithm for arm32 */
└── vad_preprocess_thumb.S /* vad preprocess algorithm for thumb */
kernel/sound/soc/codecs$ tree -P "rk*.c|h*.c|d*.c"
.
├── dmic.c /* driver for dmic, e.g. i2s dmics, pdm dmics */
├── dummy-codec.c /* driver for dmic, direct, none-codec */
├── hdac_hdmi.c
├── hdmi-codec.c /* hdmi codec driver */
├── rk1000_codec.c
├── rk312x_codec.c /* internal codec */
├── rk3228_codec.c /* internal codec */
├── rk3308_codec.c /* internal codec 8ch adc */
├── rk3328_codec.c /* internal codec */
├ ── rk817_codec.c /* codec in rk817 pmic ic */
└── rk_codec_digital.c /* link with external analog part, e.g. rk812. */
2.3 DAI 驱动开发
发布的 SDK 里 DAI 的驱动都已经完成,开发者只需要根据应用场景配置属性启用相应功能。
2.3.1 I2S
2.3.1.1 协议格式设置
协议格式设置通过 Machine Driver 解析 DTS,然后调用 set_fmt API 设置控制器的协议格式,Simple Card 请参照 Simple Card 章节。
2.3.1.2 master / slave 设置
master / slave 设置通过 Machine Driver 解析 DTS,然后调用 set_fmt API 设置控制器的协议格式,Simple Card 请参照 Simple Card 章节。
2.3.1.3 时钟相位反相设置
时钟相位反相通过 Machine Driver 解析 DTS,然后调用 set_fmt API 设置控制器的协议格式,Simple Card 请参照 Simple Card 章节。
2.3.1.4 bclk-fs 设置
Property | Value | Description |
---|---|---|
rockchip,bclk-fs | int | 默认情况下,bclk 为采样率的64倍 |
示例:bclk 为采样率的 32 倍
&i2s0 {
rockchip,bclk-fs = <32>;
};
2.3.1.5 高精度时钟设置
Property | Value | Description |
---|---|---|
rockchip,mclk-calibrate | boolean | 支持高精度时钟,且支持时钟补偿,具体使用参照 音频时钟补偿 |
2.3.1.6 其他
Property | Value | Description |
---|---|---|
rockchip,no-dmaengine | boolean | 不绑定 dmaengine,具体使用参照 Combo DAI 驱动开发 |
rockchip,playback-only | boolean | 只支持播放功能,仅注册 TX DMA |
rockchip,capture-only | boolean | 只支持录音功能,仅注册 RX DMA |
更多功能详见内核文档:kernel/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
2.3.2 I2S-TDM
除了支持 I2S 控制器的功能之外,I2S-TDM 控制器新增支持如下功能:
2.3.2.1 TX/RX 时钟共享设置
Property | Value | Description |
---|---|---|
rockchip,clk-trcm | 0 | TX/RX 逻辑独立,使用各自的时钟,IO 上有两组时钟 |
rockchip,clk-trcm | 1 | TX/RX 逻辑同步,共享 TX 的时钟,IO上只有 TX 的时钟 |
rockchip,clk-trcm | 2 | TX/TX/RX 逻辑同步,共享 RX 的时钟, IO 上只有 RX 的时钟 |
示例:设置为共享 TX 时钟模式
&i2s0 {
rockchip,clk-trcm = <1>;
};
2.3.2.2 data line 全映射设置
硬件可接任意 data line,配置对应属性修正声道顺序。
Property | Value | Description |
---|---|---|
rockchip,i2s-tx-route | <int int int int> | 默认为正序:SDO0 SDO1 SDO2 SDO3 |
rockchip,i2s-rx-route | <int int int int> | 默认为正序:SDI0 SDI1 SDI2 SDI3 |
示例:播放声道顺序为 “SDO3 | SDO2 | SDO1 | SDO0" 排列
&i2s0 {
rockchip,i2s-tx-route = <3 2 1 0>;
};
2.3.2.3 TDM 半帧模式设置
Property | Value | Description |
---|---|---|
rockchip,tdm-fsync-half-frame | boolean | TDM I2S 模式下,帧时钟支持半帧和长帧格式,默认长帧 |
示例:半帧格式
&i2s0 {
rockchip,tdm-fsync-half-frame;
};
2.3.2.4 TDM slot 参数设置
驱动已经实现 set_tdm_slot 接口,Machine Driver 解析 DTS 属性,然后调用 set_tdm_slot API 设置控制器对应参数。Simple Card 请参照 Simple Card 章节。
更多功能详见内核文档:kernel/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.txt
2.3.3 PDM
2.3.3.1 data line 全映射设置
硬件可接任意 data line,配置对应属性修正声道顺序。
Property | Value | Description |
---|---|---|
rockchip,path-map | <int int int int> | 默认为正序:SDI0 SDI1 SDI2 SDI3 |
示例:录音声道顺序为 “SDI3 | SDI2 | SDI1 | SDI0" 排列
&i2s0 {
rockchip,i2s-tx-route = <3 2 1 0>;
};
2.3.3.2 高精度时钟设置
Property | Value | Description |
---|---|---|
rockchip,mclk-calibrat | boolean | 支持高精度时钟,且支持时钟补偿,具体使用参照 音频时钟补偿 |
2.3.3.3 其他
Property | Value | Description |
---|---|---|
rockchip,no-dmaengine | boolean | 不绑定 dmaengine,具体使用参照 Combo DAI 驱动开发 |
更多功能详见内核文档:kernel/Documentation/devicetree/bindings/sound/rockchip,pdm.txt
2.3.4 DCODEC
2.3.4.1 时钟同步模式设置
Property | Value | Description |
---|---|---|
rockchip,clk-sync-mode | boolean | 默认为时钟异步模式,即 ADC/DAC 时钟独立 |
示例:设置为时钟同步模式,共享 ADC 时钟
&dig_acodec {
rockchip,clk-sync-mode;
};
2.3.4.2 DSM 输出模式设置
Property | Value | Description |
---|---|---|
rockchip,pwm-output-mode | boolean | 外接 RC,直驱 PA |
示例:设置为 DSM PWM 输出模式,IOMUX 切换为 PWM 差分输出
&dig_acodec {
rockchip,pwm-output-mode;
pinctrl-names = "default";
pinctrl-0 = <&audiopwmoutdiff_pins>;
};
更多功能详见内核文档:kernel/Documentation/devicetree/bindings/sound/rockchip,codec-digital.txt
2.3.5 VAD
2.3.5.1 音频源设置
Property | Value | Description |
---|---|---|
rockchip,audio-src | phandle | 设置用于语音检测的音频源 |
用于语音检测的音频源来自于 DAI,不同的芯片支持的音频源不同,如下表所示:
芯片 | 音频源 |
---|---|
RK1808 | I2S0, I2S1, PDM |
RK3308 | I2S_8CH_0, I2S_8CH_1, I2S_8CH_2, I2S_8CH_3, PDM_8CH |
RK3568/RK3566 | I2S1_8CH, I2S2_2CH, I2S3_2CH |
示例:RK3308 上 VAD 使用 PDM_8CH 阵列麦 作为音频源
&vad {
rockchip,audio-src = <&pdm_8ch>;
};
2.3.5.1 VAD 配置
Property | Value | Description |
---|---|---|
rockchip,det-channel | int | 设置用于检测的声道,默认声道0 |
2.3.5.2 检测声道设置
示例:RK3308 上 VAD 使用阵列麦2作为检测声道
&vad {
rockchip,det-channel = <2>;
};
2.3.5.3 数据存储模式设置
Property | Value | Description |
---|---|---|
rockchip,mode | 0 | VAD 检测到语音信号后才开始缓存音频数据 |
rockchip,mode | 1 | VAD 使能后即开始缓存音频数据 |
rockchip,mode | 2 | VAD 不缓存音频数据 |
示例:RK3308 上 VAD 使用模式1
&vad {
rockchip,mode = <1>;
};
Note:为了确保后级 ASR 应用能得到完整的音频数据,建议使用模式1。缓存的数据存储于 sram 的循环 buffer 中,VAD 唤醒系统后,将 sram 的缓存音频合并入音频流中,该部分数据处理对应用程序透明。
2.3.5.4 缓存大小设置
Property | Value | Description |
---|---|---|
rockchip,buffer-time-ms | int | 设置 VAD 缓存大小,大小等于:采样率 * 位宽 * 声道 * 时间 |
示例:缓存设置为100 ms,16k 16bits 8ch 条件下为 204800 bytes
&vad {
rockchip,buffer-time-ms = <100>;
};
Note:缓存变大,会同等增大后级 ASR 应用的 Latency。且系统 sram 有限,谨慎调整。调整策略为 “保证数据完整性”,即缓存的大小能覆盖 “唤醒-> 应用接管” 时间即可。如果该部分时间过长,请优化该部分时间。
更多功能详见内核文档:kernel/Documentation/devicetree/bindings/sound/rockchip,vad.txt
2.4 Combo DAI 驱动开发
2.4.1 sub dai 设置
Property | Value | Description |
---|---|---|
dais | <phandle>... | sub dai,用于组合成 combo dai。sub dai 需要使用属性 |
“rockchip,no-dmaengine” 移除关联的 dmaengine,统一由 | ||
Combo DAI 框架注册绑定。 |
示例:将 i2s_8ch_2 和 pdm_8ch 组合成 Combo DAI
&i2s_8ch_2 {
status = "okay";
rockchip,no-dmaengine;
};
&pdm_8ch {
status = "okay";
rockchip,no-dmaengine;
};
&multi-dais {
dais = <&i2s_8ch_2>, <&pdm_8ch>;
};
2.4.2 声道映射设置
Property | Value | Description |
---|---|---|
capture,channel-mapping | <int ...> | 每个sub dai 用于组合的录音声道数量 |
playback,channel-mapping | <int ...> | 每个sub dai 用于组合的播放声道数量 |
示例:声卡立体声播放,8声道录音(6声道麦 + 2声道回采)
&multi-dais {
dais = <&i2s_8ch_2>, <&pdm_8ch>;
capture,channel-mapping = <2 0>;
playback,channel-mapping = <2 6>;
};
2.4.3 master / slave 设置
Property | Value | Description |
---|---|---|
bitclock-master | <int ...> | 设置提供位时钟的设备,1表示提供时钟,即 master |
frame-master | <int ...> | 设置提供帧时钟的设备,1表示提供时钟,即 master |
示例1:i2s_8ch_2 和 pdm_8ch 组合成 8 声道录音(回采 + 麦克阵列),i2s_8ch_2 可配置为 master / slave 模式,该例中作为 master,pdm 只有 master 模式。
&multi-dais {
dais = <&i2s_8ch_2>, <&pdm_8ch>;
capture,channel-mapping = <2 6>;
playback,channel-mapping = <2 0>;
bitclock-master = <1 1>;
frame-master = <1 1>;
};
示例2:两个 i2s 组合成 16 ch,一个为 master,一个为 slave,外部硬件连线需要将提供时钟的 dai 连接到各 slave dai。
&multi-dais {
dais = <&i2s_8ch_0>, <&i2s_8ch_1>;
capture,channel-mapping = <8 8>;
playback,channel-mapping = <8 8>;
bitclock-master = <1 0>;
frame-master = <1 0>;
};
示例3:两个 i2s 组合成 16 ch,都为 slave 模式,时钟由 codec 端提供。
&multi-dais {
dais = <&i2s_8ch_0>, <&i2s_8ch_1>;
capture,channel-mapping = <8 8>;
playback,channel-mapping = <8 8>;
bitclock-master = <0 0>;
frame-master = <0 0>;
};
2.4.4 时钟相位反相设置
Property | Value | Description |
---|---|---|
bbitclock-inversion | <int ...> | 1 表示反相 位时钟,即 BCLK |
frame-inversion | <int ...> | 1 反相 帧时钟,即 LRCK |
示例:将 sub dai 的时钟都取反
&multi-dais {
dais = <&i2s_8ch_0>, <&i2s_8ch_1>;
bitclock-inversion = <1 1>;
frame-inversion = <1 1>;
};
Property | Value | Description |
---|---|---|
bitclock-inversion | int | 1 表示反相位时钟,即 BCLK |
frame-inversion | int | 1 反相帧时钟,即 LRCK |
2.4.5 实例
示例1:RK3308 PDM 阵列麦 + 立体声回采 + 立体声放音 + VAD 语音检测
multi_dais: multi-dais {
status = "okay";
compatible = "rockchip,multi-dais";
dais = <&i2s_8ch_2>, <&pdm_8ch>;
capture,channel-mapping = <2 6>;
playback,channel-mapping = <2 0>;
bitclock-master = <1 1>;
frame-master = <1 1>;
bitclock-inversion = <0 0>;
frame-inversion = <0 0>;
rockchip,grf = <&grf>;
};
&i2s_8ch_2 {
status = "okay";
rockchip,no-dmaengine;
};
&pdm_8ch {
status = "okay";
rockchip,no-dmaengine;
};
vad-sound {
status = "okay";
compatible = "rockchip,multicodecs-card";
rockchip,card-name = "rockchip,rk3308-vad";
rockchip,cpu = <&multi_dais>;
rockchip,codec = <&acodec>, <&vad>;
};
示例2:RK3308 SoundBar I2S_8CH_0 + I2S_8CH_1 组合 16 声道输出
&i2s_8ch_0 {
#sound-dai-cells = <0>;
rockchip,no-dmaengine;
};
&i2s_8ch_1 {
#sound-dai-cells = <0>;
rockchip,no-dmaengine;
pinctrl-names = "default";
pinctrl-0 = <&i2s_8ch_1_m0_sdo0
&i2s_8ch_1_m0_sdo1_sdi3
&i2s_8ch_1_m0_sdo2_sdi2
&i2s_8ch_1_m0_sdo3_sdi1
&i2s_8ch_1_m0_sdi0>;
};
i2s_16ch_dais: i2s-16ch-dais {
compatible = "rockchip,rk3308-multi-dais", "rockchip,multi-dais";
dais = <&i2s_8ch_0>, <&i2s_8ch_1>;
capture,channel-mapping = <8 8>;
playback,channel-mapping = <8 8>;
bitclock-master = <1 0>;
frame-master = <1 0>;
rockchip,grf = <&grf>;
};
更多功能详见内核文档:kernel/Documentation/devicetree/bindings/sound/rockchip,multidais.txt
2.5 CODEC 驱动开发
请参考内核音频官方文档:Linux Sound Subsystem Documentation
2.6 Machine 驱动开发
本章节主要结合实例简述声卡添加步骤。
2.6.1 Simple Card
Simple Card 是 ASoC 通用的 machine driver,可支持大部分标准声卡的添加。
2.6.1.1 协议格式设置
Property | Value | Description |
---|---|---|
simple-audio-card,format | string | 设置协议格式 |
Format | Description |
---|---|
i2s | i2s 标准格式 |
right_j | i2s 右对齐格式 |
left_j | i2s 左对齐格式 |
dsp_a | pcm delay 1 bit 格式 |
dsp_b | pcm no delay 格式 |
pdm | pdm 格式 |
示例:设置为 i2s 左对齐格式
audiopwmout_diff: audiopwmout-diff {
compatible = "simple-audio-card";
simple-audio-card,format = "left_j";
simple-audio-card,cpu {
sound-dai = <&i2s3_2ch>;
};
master: simple-audio-card,codec {
sound-dai = <&dig_acodec>;
};
};
2.6.1.2 mclk-fs 设置
Property | Value | Description |
---|---|---|
simple-audio-card,mclk-fs | int | 默认情况下,mclk 为采样率的256倍 |
示例:mclk 为采样率的512倍
audiopwmout_diff: audiopwmout-diff {
compatible = "simple-audio-card";
simple-audio-card,mclk-fs = <512>;
simple-audio-card,cpu {
sound-dai = <&i2s3_2ch>;
};
master: simple-audio-card,codec {
sound-dai = <&dig_acodec>;
};
};
2.6.1.3 master / slave 设置
Property | Value | Description |
---|---|---|
simple-audio-card,bitclock-master | ||
phandle | 设置提供位时钟的设备,默认情况下 DAI 提供 | |
时钟 | ||
simple-audio-card,frame-master | phandle | 设置提供帧时钟的设备,默认情况下 DAI 提供 |
时钟 |
示例:DAI 工作于 slave 模式,CODEC 工作于 master 模式
audiopwmout_diff: audiopwmout-diff {
compatible = "simple-audio-card";
simple-audio-card,bitclock-master = <&master>;
simple-audio-card,frame-master = <&master>;
simple-audio-card,cpu {
sound-dai = <&i2s3_2ch>;
};
master: simple-audio-card,codec {
sound-dai = <&dig_acodec>;
};
};
2.6.1.4 时钟相位反相设置
Property | Value | Description |
---|---|---|
simple-audio-card,bitclock-inversion | boolean | 反相 位时钟,即 BCLK |
simple-audio-card,frame-inversion | boolean 反相 帧时钟,即 LRCK |
示例:bclk,lrck 同时反相
audiopwmout_diff: audiopwmout-diff {
compatible = "simple-audio-card";
simple-audio-card,bitclock-inversion;
simple-audio-card,frame-inversion;
simple-audio-card,cpu {
sound-dai = <&i2s3_2ch>;
};
simple-audio-card,codec {
sound-dai = <&dig_acodec>;
};
};
2.6.1.5 TDM slot 参数设置
Property | Value | Description |
---|---|---|
dai-tdm-slot-num | int | 设置 slot 的个数 |
dai-tdm-slot-width | int | 设置 slot 的位宽 |
示例:slot 位宽为 32 bits,8个 slot
i2s-dmic-array {
compatible = "simple-audio-card";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s_8ch_0>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
simple-audio-card,codec {
sound-dai = <&dummy_codec>;
};
};
Note:mclk-fs 等于 [ slot num ] * [ slot-width ],或为其偶数倍。 更多功能详见内核文档:kernel/Documentation/devicetree/bindings/sound/simple-card.txt
2.6.1.6 声卡添加实例
- 移植或者编写 codec 驱动
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/tas571x.c
sound/soc/codecs/tas571x.h
- 使能 CONFIG
CONFIG_SND_SIMPLE_CARD
CONFIG_SND_SOC_ROCKCHIP_I2S
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM
CONFIG_SND_SOC_TAS571X
- 添加 DTS 声卡节点 根据硬件连接情况,使能对应的 i2s 节点
&i2s_8ch_1 {
status = "okay";
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s_8ch_1_m0_sclktx
&i2s_8ch_1_m0_lrcktx
&i2s_8ch_1_m0_sdo0
&i2s_8ch_1_m0_mclk>;
};
根据硬件连接情况,在对应 i2c 或者 spi 下添加 codec 节点
&i2c1 {
clock-frequency = <400000>;
status = "okay";
tas5731: tas5731@1a {
#sound-dai-cells = <0>;
compatible = "ti,tas5731";
reg = <0x1a>;
clocks = <&cru SCLK_I2S1_8CH_TX_OUT>;
clock-names = "mclk";
pinctrl-names = "default";
pinctrl-0 = <&i2s_8ch_1_m0_mclk>;
pdn-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;
};
};
添加并使能声卡节点
tas5731_sound: tas5731-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "rockchip,tas5731";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s_8ch_1>;
};
simple-audio-card,codec {
sound-dai = <&tas5731>;
};
};
确认声卡创建成功
cat /proc/asound/cards
0 [rockchiptas5731]: rockchip_tas5731 - rockchip,tas5731
Note: mclk 遵循 “谁使用谁申请” 原则。当 codec 需要使用外部 mclk 时,驱动需要申请并管理 mclk。本例中 codec mclk 来自于 RK3308 的 SCLK_I2S1_8CH_TX_OUT。
2.6.2 Multi Codecs Machine Driver
当 Simple Card 不满足需求时,则需要编写对应的 Machine Driver。本小节介绍 RK 的 Multi Codecs Machine Driver。应用于 1个 DAI 对应多个 CODEC,或者 Combo DAI 对应多个 CODEC 的场景。
2.6.2.1 dai / codec 设置
Property | Value | Description |
---|---|---|
rockchip,cpu | phandle | 设置 DAI 设备 |
rockchip,codec | phandle... | 设置关联的 codecs |
示例:i2s0_8ch 同时应用于 codec 和 vad |
&sound {
compatible = "rockchip,multicodecs-card";
rockchip,cpu = <&i2s0_8ch>;
rockchip,codec = <&codec>, <&vad>;
};
2.6.2.2 协议格式设置
Property | Value | Description |
---|---|---|
rockchip,format | string | 设置协议格式 |
Format | Description |
---|---|
i2s i2s | 标准格式 |
right_j | i2s 右对齐格式 |
left_j | i2s 左对齐格式 |
dsp_a | pcm delay 1 bit 格式 |
dsp_b | pcm no delay 格式 |
pdm | pdm 格式 |
示例:设置为 i2s 左对齐格式
&sound {
rockchip,format = "left_j";
};
2.6.2.3 mclk-fs 设置
Property | Value | Description |
---|---|---|
rockchip,mclk-fs | int | 默认情况下,mclk 为采样率的256倍 |
示例:mclk 为采样率的512倍
&sound {
rockchip,mclk-fs = <512>;
};
2.6.2.4 master / slave 设置
Property | Value | Description |
---|---|---|
rockchip,frame-master | phandle | 设置提供位时钟的设备,默认情况下 DAI 提供时钟 |
rockchip,bitclock-master | phandle | 设置提供帧时钟的设备,默认情况下 DAI 提供时钟 |
示例:DAI 工作于 slave 模式,CODEC 工作于 master 模式
&sound {
compatible = "rockchip,multicodecs-card";
rockchip,frame-master = <&codec>;
rockchip,bitclock-master = <&codec>;
rockchip,cpu = <&i2s0_8ch>;
rockchip,codec = <&codec>, <&vad>;
};
2.6.2.5 时钟相位反相设置
Property | Value | Description |
---|---|---|
rockchip,bitclock-inversion | boolean | 反相位时钟,即 BCLK |
rockchip,frame-inversion | boolean | 反相帧时钟,即 LRCK |
示例:bclk,lrck 同时反相
&sound {
compatible = "rockchip,multicodecs-card";
rockchip,bitclock-inversion;
rockchip,frame-inversion;
rockchip,cpu = <&i2s0_8ch>;
rockchip,codec = <&codec>, <&vad>;
};
2.6.2.6 设置wait-card-locked
Property | Value | Description |
---|---|---|
rockchip,wait-card-locked | int | 等待特定soundcard的ID注册后再进行注册,确保当前 |
soundcard的ID排在指定ID之后 |
示例:希望当前bluetooth-sound注册为card1,需要card0注册了之后当前card才注册。
bluetooth_sound: bluetooth-sound {
status = "disabled";
compatible = "rockchip,multicodecs-card";
rockchip,card-name = "rockchip,rk3308-pcm";
rockchip,mclk-fs = <128>;
rockchip,cpu = <&i2s_2ch_0>;
rockchip,codec = <&dummy_codec>;
rockchip,format = "dsp_b";
rockchip,bitclock-inversion = <0>;
rockchip,wait-card-locked = <0>;
};