一、背景概念
在 T5 系列芯片中,内置了一个 AudioHub 模块,使用的 是I2S 接口,都跟 AudioHub 关联在一起,此时外挂的声卡若想正常工作,还需要配置 AudioHub 的路由信息。(AudioHub 是全志 T527 特有的模块,若在全志其他没有 AudioHub 模块的平台上,则不需要考虑配置 AudioHub 的路由信息)。
二、适配步骤
1、确认声卡挂在哪个 I2S 口,哪个 I2C 口
这部分信息可以从原理图看出来,如下图所示,AC107 被挂在 I2C3(TWI3)。
如上图所示,我们可以确认公板的 AC107 挂在 I2S0、I2C3(TWI3),如下步骤将按照公板外挂 AC107 为例进行描述。
2、使能 I2C、I2S 节点,并绑定驱动代码
(1)使能 I2C、I2S 节点
vi longan/device/config/chips/t507/configs/demo2.0/board.dts
twi3: twi@0x05002c00{
status = "okay";
};
ahub_daudio0:ahub_daudio0@0x05097000{
status = "okay";
}
snddaudio0:sound@0{
status = "okay";
};
(2)绑定驱动代码
vi longan/device/config/chips/t507/configs/demo2.0/board.dts
twi3: twi@0x05002c00{
ac107@36 {
compatible = "allwinner,ac107_0"; # 该值请咨询声卡原厂,或者自行去确认声卡驱动代码的 of_match_table 字段
reg = <0x36>; # I2C 地址
};
};
snddaudio0:sound@0{
sunxi,snddaudio-codec = "ac107.3-0036"; # codec name(ac107),3(I2C 口),0036(I2C 地址)
sunxi,snddaudio-codec-dai = "ac107-pcm0"; # 该值请咨询声卡原厂,或者直接去确认声卡驱动代码的 snd_soc_dai_driver 字段
};
3、配置 SDA、SCK、MCLK、LRCK、BCLK、DIN、DOUT 等 GPIO 引脚
(1)配置 SDA、SCK
确认 I2C3 使用哪个 GPIO 口,如下图所示,I2C3 使用 PA10、PA11 口。
vi longan/device/config/chips/t507/configs/demo2.0/board.dts
twi3: twi@0x05002c00{
# 确认 pinctrl 字段
pinctrl-0 = <&twi3_pins_a>;
pinctrl-1 = <&twi3_pins_b>;
};
vi longan/kernel/linux-4.9/arch/arm64/boot/dts/sunxi/sun50iw9p1-pinctrl.dtsi
twi3_pins_a: twi3@0 {
allwinner,pins = "PA10", "PA11";
};
twi3_pins_b: twi3@1 {
allwinner,pins = "PA10", "PA11";
};
(2)配置 MCLK、LRCK、BCLK、DIN、DOUT
确认 I2S0 使用哪个 GPIO 口,如上图所示,I2S0 使用 PA5、PA6、PA7、PA8、PA9口。
# 由于 AC107 只是录音设备,因此不配置 DOUT
ahub_daudio0_pins_a: ahub_daudio0@0 {
allwinner,pins = "PA6", "PA7", "PA8", "PA9";
};
ahub_daudio0_pins_b: ahub_daudio0_sleep@0 {
allwinner,pins = "PA6", "PA7", "PA8", "PA9";
};
4、匹配 I2S 协议参数
由于使用 I2S 通信时需要匹配主从机之间协议,一般是由 T5 端去适配声卡,因此需要向声卡原厂确认如下数据:
- 主从关系
- I2S 格式(若是 PCM 格式,需要说明长短帧)
- LRCK 和 BCLK 的极性
- 是否需要 MCLK 时钟,需要的频率是多少
- 通道数、采样率、位深
按照 AC107,则:
- T5 做主
- I2S 格式,飞利浦格式(标准格式)
- 正常极性
- 需要 MCLK,频率为 3.072M 或者 2.8224M
- 2 通道,位深 16
vi longan/device/config/chips/t507/configs/demo2.0/board.dts
ahub_daudio0:ahub_daudio0@0x05097000{
frametype = <0x00>; # 由于是 I2S 模式,此时不起作用
pcm_lrck_period = <0x20>; # 由于是 I2S 模式,并且只配置 2 通道,一帧数据为 32 * 2 = 64,取其一半为 32
# 假设配置为 4 通道,则一帧数据为 32 * 4 = 128, 取其一半为 64,即 0x40
slot_width_select = <0x20>; # 最大位深为 32 位,即用户使用时,采样位深不得高于 32
tdm_config = <0x01>; # I2S 模式
mclk_div = <0x08>; # MCLK 同步,mclk=pll_audio/8,pll_audio 一般为 24.576M 或者 22.5792M
};
snddaudio0:sound@0{
daudio_master = <0x04>; # T5 做主机
audio_format = <0x01>; # 标准 I2S 格式
signal_inversion = <0x01>; # 信号不翻转
};
配置项 | 含义 | 取值 |
---|---|---|
frametype | 长短帧(仅对 PCM 模式有效,即依赖 tdm_config) | 0:短帧 |
1:长帧 | ||
pcm_lrck_period | 依赖 tdm_config | I2S 模式:一帧数据位数的一半 |
PCM 模式:一帧数据的位数 | ||
一帧数据 = 位深 * 通道 | ||
slot_width_select | 最大采样位深 | 根据实际情况,往小了配以省电 |
tdm_config | I2S 模式还是 PCM 模式 | 0:PCM 模式 |
1:I2S 模式 | ||
mclk_div | mclk 分频系数,mclk=pll_audio/mclk_div | 0:不输出 mclk |
1/2/4…176/192:输出 mclk | ||
daudio_master | T5 做主机还是做从机 | 1:从机 |
4:主机 | ||
audio_format | I2S 协议对齐格式(1/2/3) | 1:标准 I2S |
PCM 协议对齐格式(4/5) | 2:I2S 右对齐 | |
即依赖 tdm_config | 3:I2S 左对齐 | |
4:短帧,标准对齐(DSP MODE A) | ||
5:长帧,左对齐(DSP MODE B) | ||
signal_inversion | 信号的反转 | 1:bclk 正常,lrck 正常 |
2:bclk 正常,lrck 翻转 | ||
3:bclk 翻转,lrck 正常 | ||
4:bclk 翻转,lrck 翻转 |
5、配置 AudioHub 路由参数(在其他非 T5 等平台,如果没有 AudioHub,则可以忽略该步骤)
在 linux 版本下,请直接参考 android/device/softwinner/mercury-common/configs/auto_ahub_paths.xml 配置即可。
比如 I2S2 挂了个录音设备,那么可以使用如下命令配置通路
tinymix -D 1 "I2S2IN Switch" "1"
tinymix -D 1 "APBIF2 Src Select" "I2S2_TXDIF"
比如 I2S3 挂了个播放设备,那么可以使用如下命令配置通路
tinymix -D 1 "I2S3OUT Switch" "1"
tinymix -D 1 "I2S3 Src Select" "APBIF_TXDIF1"
AudioHub 路由:
<mixer>
<!-- These are the initial mixer settings -->
<!-- These are commonly used control sequences -->
<path name="ahub-daudio0-input">
<ctl name="I2S0IN Switch" value="1" />
<ctl name="APBIF0 Src Select" value="I2S0_TXDIF" />
</path>
<path name="ahub-daudio1-output">
<ctl name="I2S1OUT Switch" value="1" />
<ctl name="I2S1 Src Select" value="APBIF_TXDIF0" />
</path>
<path name="ahub-daudio2-input">
<ctl name="I2S2IN Switch" value="1" />
<ctl name="APBIF2 Src Select" value="I2S2_TXDIF" />
</path>
<path name="ahub-daudio2-output">
<ctl name="I2S2OUT Switch" value="1" />
<ctl name="I2S2 Src Select" value="APBIF_TXDIF2" />
</path>
<path name="ahub-daudio3-input">
<ctl name="I2S3IN Switch" value="1" />
<ctl name="APBIF1 Src Select" value="I2S3_TXDIF" />
</path>
<path name="ahub-daudio3-output">
<ctl name="I2S3OUT Switch" value="1" />
<ctl name="I2S3 Src Select" value="APBIF_TXDIF1" />
</path>
<path name="ahub-daudio0-input-close">
<ctl name="I2S0IN Switch" value="0" />
<ctl name="APBIF0 Src Select" value="NONE" />
</path>
<path name="ahub-daudio1-output-close">
<ctl name="I2S1OUT Switch" value="0" />
<ctl name="I2S1 Src Select" value="NONE" />
</path>
<path name="ahub-daudio2-input-close">
<ctl name="I2S2IN Switch" value="0" />
<ctl name="APBIF2 Src Select" value="NONE" />
</path>
<path name="ahub-daudio2-output-close">
<ctl name="I2S2OUT Switch" value="0" />
<ctl name="I2S2 Src Select" value="NONE" />
</path>
<path name="ahub-daudio3-input-close">
<ctl name="I2S3IN Switch" value="0" />
<ctl name="APBIF1 Src Select" value="NONE" />
</path>
<path name="ahub-daudio3-output-close">
<ctl name="I2S3OUT Switch" value="0" />
<ctl name="I2S3 Src Select" value="NONE" />
</path>
<path name="null">
</path>
</mixer>
6、测试
使用 tinyplay/tinyplay_ahub/tinycap/tinycap_ahub/aplay/arecord 进行测试
7、开机适配
若步骤6测试正常,那么接下来需要开机进行自动配置:
- linux:修改 longan/platform/framework/auto/rootfs/etc/init.d/rcS
- android:修改 android/hardware/aw/audio/auto/t507/audio_hw.c
三、常见问题
1. 通过 tinyplay/tinyplay_ahub 等工具进行播放,录音/播放异常。
(1)请先按照本文步骤进行外挂适配
(2)请确认播放/录音命令是否正确
(3)确认驱动层是否正在播放,若节点没有播放信息,则得分析日志,看驱动代码或者应用层代码那部分出了问题。
# cat /proc/asound/card3/pcm0p/sub0/hw_params
access: RW_INTERLEAVED
format: S16_LE
subformat: STD
channels: 2
rate: 48000 (48000/1)
period_size: 1024
buffer_size: 8192
(4)测试内部芯片内部回录
# 声卡挂在哪个 I2S 就把哪个 lookback 开关打开,比如 I2S0
tinymix -D 1 "I2S0 SD0 to SDI0 Loopback Debug" "1"
# 把目标声卡的输入路由以及输出路由都进行配置,比如 I2S0
tinymix -D 1 "I2S0IN Switch" "1"
tinymix -D 1 "APBIF0 Src Select" "I2S0_TXDIF"
tinymix -D 1 "I2S0OUT Switch" "1"
tinymix -D 1 "I2S0 Src Select" "APBIF_TXDIF0"
# 把其他关于 xxx Src Select 的项配置为 0
# 使用 I2S0 播放音乐,后台运行
tinyplay_ahub /etc/test.wav -aD 1 -ad 0 -D card -d device & # card、device 根据实际情况填写
# 使用 I2S0 录制音乐
tinycap_ahub /etc/record.wav -aD 1 -ad 0 -D card -d device -r rate -b byte -c channel # card、device、rate、byte、channel 根据实际情况填写
此时 record.wav 是 test.wav 的一部分片段,此时说明驱动代码是没有问题的,如果 record.wav 不符合预期,说明驱动代码有问题,建议咨询原厂。
(5)测量 MCLK、LRCK、BCLK、DIN、DOUT 信号
- 如果所有信号都正常:
- 再次确认原理图中 DIN、DOUT 所占用的 GPIO 口,其复用的功能是否是 DIN0、DOUT0,如果不是的话,请提单到全志 AService,由 FAE 协助适配。
- 再次确认 MCLK、LRCK、BCLK 是否复合预期。
- 考虑是否是喇叭元器件出现了问题。
- 部分信号不正常:再次确认 GPIO 口配置是否正确。