1 问题
播放文件无声输出,采集声音数据全为0。
2 定位过程
2.1 查看pinctrl无i2s
查询指令:
go
cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins |grep i2s
发现无i2s的相关管脚定义,修改设备树,增加pinctrl,代码如下:

同时i2s0_pins也要修改,如下:
修改完后,pinctrl正确:
如果还不对,估计是有和别的功能的管脚定义冲突了,需要再检查设备树。
2.2 示波器抓无MCLK信号
此时问题依然,抓i2s的信号。
下图逻辑分析仪抓的,实际上MCLK使用示波器抓有波形的,但是幅值只有不到100mv,正常的应该是3.3V。
针对无MCLK的问题,通过redmine和官方沟通给出一个指令,devmem 0xff000004 32,显示确实是MCLK没有使能,图示如下:
手动配置使能:devmem 0xff000004 32 0xffff2220(具体定义官方文档需要申请,这里不纠结了)
配置后MCLK有输出,示波器测量电压也是3.3v,波形如下:

2.3 ES8388无输出
此时依然是问题依旧。
不经意间发现,rv1106的SDO是接在es8388的SDO上的:
Es8388手册中明确pin6为输入,pin8为输出:
硬件飞线,使得sdo对sdi,sdi对sdo,文件播放正常,录音正常。
3 设备树的要点
3.1 pinctrl
go
i2s0 {
/omit-if-no-ref/
i2s0_pins: i2s0-pins {
rockchip,pins =
/* i2s0_lrck */
<2 RK_PA1 2 &pcfg_pull_none>,
/* i2s0_mclk */
<2 RK_PA2 2 &pcfg_pull_none>,
/* i2s0_sclk */
<2 RK_PA0 2 &pcfg_pull_none>,
/* i2s0_sdi0 */
<2 RK_PA5 2 &pcfg_pull_none>,
/* i2s0_sdo0 */
<2 RK_PA4 2 &pcfg_pull_none>;
/* i2s0_sdo1_sdi3 */
//<2 RK_PA7 2 &pcfg_pull_none>,
/* i2s0_sdo2_sdi2 */
//<2 RK_PA6 2 &pcfg_pull_none>,
/* i2s0_sdo3_sdi1 */
//<2 RK_PA3 2 &pcfg_pull_none>;
};
};
go
&i2s0_8ch {
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0_pins>;
status = "okay";
};
3.2 8388驱动
go
&i2c3 {
status = "okay";
es8388: es8388@10 {
status = "okay";
compatible = "everest,es8388", "everest,es8323";
reg = <0x10>;
clocks = <&cru I2S0_8CH_MCLKOUT>;
clock-names = "mclk";
assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
assigned-clock-rates = <12288000>;
#sound-dai-cells = <0>;
};
};
3.3 8388声卡驱动
go
es8388_sound: es8388-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "Erockchip,es8388-codec";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = <&es8388>;
};
};
//关闭rv1106的原有声卡定义
go
acodec_sound: acodec-sound {
status = "disable";
compatible = "simple-audio-card";
simple-audio-card,name = "rv1106-acodec";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = <&acodec>;
};
};
4 基本调试指令
go
cat /proc/asound/cards //查看声卡
cat /sys/kernel/debug/regmap/3-0010/registers //查看8388的寄存器
cat /sys/kernel/debug/clk/clk_summary | grep i2s0_8ch_mclkout // 查看mclk的频率
cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins |grep i2s //查看管脚映射
go
rk_mpi_amix_test --list_contents //查看指令,具体的在sdk的文档中也有介绍
rk_mpi_ai_test --sound_card_name=hw:0,0 --device_rate=16000 --device_ch=2 --out_rate=16000 --out_ch=2 --output=/tmp
rk_mpi_ao_test -i /tmp/test.pcm --input_rate=48000 --input_ch=2 --device_rate=48000 --device_ch=2 --bit=16 --sound_card_name=hw:0,0
rk_mpi_ao_test -i /tmp/cap_out.pcm --input_rate=16000 --input_ch=2 --device_rate=16000 --device_ch=2 --bit=16 --sound_card_name=hw:0,0
go
i2cdetect -y 3 //查看iic总线
//输出增益
i2cget -f -y 3 0x10 0x2e //L out1 vol 0x1e = 0
i2cget -f -y 3 0x10 0x2f //R out1 vol
i2cget -f -y 3 0x10 0x30 //L out2 vol
i2cget -f -y 3 0x10 0x31 //R out2 vol
i2cset -f -y 3 0x10 0x2e 0x1e
i2cset -f -y 3 0x10 0x2f 0x1e
i2cset -f -y 3 0x10 0x30 0x1e
i2cset -f -y 3 0x10 0x31 0x1e
5 MCLK使能配置
上边已经找到了MCLK无输出的原因,所以要加到代码中,添加代码到es8388的probe或者i2s的probe。
我这边加到了es8388的probe中,具体代码如下:
go
void __iomem *reg_addr;
int val = 0 ;
printk("-------------------mclk out enable set\n");
reg_addr = ioremap(0xff000004, 4);
if (reg_addr) {
writel(0xffff2220, reg_addr);
val = readl(reg_addr);
printk("-------------------val = 0x%x\n",val);
iounmap(reg_addr);
} else {
printk("-------------------Failed to map CPU config register\n");
}
6 MCLK的疑问
原则上这个mclk应该是可以随着设备树的配置一起工作的,因为sclk、lrclk、dat都是正常。
可能还是设备树的配置问题,官方给了一个设备树配置的方法,但是依然不行,所以索性就直接在代码中使能,待以后有时间再找原因。