Platform: ROCKCHIP
Chip: RK3288
OS: Android7.1.2
Kernel: 4.4.143
背景:
之前平台用的RT5640, 由于此IC将要停产,所以需要替换为ES8396,RT5640和ES8396在硬件上兼容,只是芯片换了。
音频开发指南
一个声卡包含cpu_dai, codec_dai, 以及dai_link组成,分别对应cpu dai的dirver,比如I2S driver, spdif driver;codec driver, 比如rt5640 codec driver;dai_link driver,也就是machine driver, 比如sound/soc/rockchip/rockchip_rt5640.c。
4.4的内核中支持两种方式创建声卡,一种是通用的simple-card framework,一种是传统的编写自定义的machine driver来创建
硬件原理图
数据走I2S0通道
控制走I2C2通道
输出走HPLOUT/HPROUT SPKROUTP/SPKLOUTP
打开对应的宏
/kernel/arch/arm/configs/rockchip_defconfig
+CONFIG_SND_SOC_ES8396=y
修改dts文件
/kernel/arch/arm/boot/dts/rk3288-android.dtsi
原本的是rt5640,修改后的是es8396
+#if 0
+ hdmi_analog_sound: hdmi-analog-sound {
+ status = "okay";
+ compatible = "rockchip,rk3288-hdmi-analog",
+ "rockchip,rk3368-hdmi-analog";
+ rockchip,model = "rockchip,rt5640-codec";
+ rockchip,cpu = <&i2s>;
+ rockchip,codec = <&rt5640>, <&hdmi>;
+ rockchip,widgets =
+ "Microphone", "Microphone Jack",
+ "Headphone", "Headphone Jack";
+ rockchip,routing =
+ "MIC1", "Microphone Jack",
+ "MIC2", "Microphone Jack",
+ "Microphone Jack", "micbias1",
+ "Headphone Jack", "HPOL",
+ "Headphone Jack", "HPOR";
+ };
+#else
+ hdmi_analog_sound: hdmi-analog-sound {
+ status = "okay";
+ compatible = "rockchip,rk3288-hdmi-analog",
+ "rockchip,rk3368-hdmi-analog";
+ rockchip,model = "rockchip,es8396-codec";
+ rockchip,cpu = <&i2s>;
+ rockchip,codec = <&es8396>, <&hdmi>;
+ rockchip,widgets =
+ "Microphone", "Microphone Jack",
+ "Line", "Microphone Headset",
+ "Headphone", "Headphone Jack";
+ rockchip,routing =
+ "MIC", "Microphone Jack",
+ "DMIC", "Microphone Headset",
+ "Headphone Jack", "LOUTP",
+ "Headphone Jack", "ROUTN";
+ };
+#endif
/kernel/arch/arm/boot/dts/rk3288-evb.dtsi
+#if 0
+ sound: sound {
+ status = "disabled";
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "rockchip,rt5640-codec";
+ simple-audio-card,mclk-fs = <512>;
+ simple-audio-card,widgets =
+ "Microphone", "Microphone Jack",
+ "Headphone", "Headphone Jack";
+ simple-audio-card,routing =
+ "MIC1", "Microphone Jack",
+ "MIC2", "Microphone Jack",
+ "Microphone Jack", "micbias1",
+ "Headphone Jack", "HPOL",
+ "Headphone Jack", "HPOR";
+
+ simple-audio-card,dai-link@0 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&i2s>;
+ };
+
+ codec {
+ sound-dai = <&rt5640>;
+ };
};
+
+ simple-audio-card,dai-link@1 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&i2s>;
+ };
+
+ codec {
+ sound-dai = <&hdmi>;
+ };
};
+ }
+#else
+ es8396-sound {
+ status = "okay";
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "rockchip,es8396-codec";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,widgets =
+ "Microphone", "Microphone Jack",
+ "Line", "Microphone Headset",
+ "Headphone", "Headphone Jack";
+
+ simple-audio-card,routing =
+ "MIC", "Microphone Jack",
+ "DMIC", "Microphone Headset",
+ "Headphone Jack", "LOUTP",
+ "Headphone Jack", "ROUTN";
+
+ simple-audio-card,dai-link@0 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&i2s>;
+ };
+
+ codec {
+ sound-dai = <&es8396>;
+ };
};
+ simple-audio-card,dai-link@1 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&i2s>;
+ };
+
+ codec {
+ sound-dai = <&hdmi>;
+ };
};
+
};
+#endif
&i2c2 {
status = "okay";
+ /*i2c-scl-rising-time-ns = <460>;
+ i2c-scl-falling-time-ns = <15>;*/
+#if 0
rt5640: rt5640@1c {
#sound-dai-cells = <0>;
compatible = "realtek,rt5640";
@@ -307,8 +351,24 @@
pinctrl-names = "default";
pinctrl-0 = <&i2s0_mclk>;
};
+#else
+ es8396: es8396@10 {
+ status = "okay";
+ #sound-dai-cells = <0>;
+ compatible = "es8396";
+ reg = <0x10>;
+ clocks = <&cru SCLK_I2S0_OUT>;
+ clock-names = "mclk";
+ spk-con-gpio = <&gpio6 RK_PA7 GPIO_ACTIVE_HIGH>;
+ //lineout-con-gpio = <&gpio6 RK_PA7 GPIO_ACTIVE_HIGH>
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_mclk>;
+ };
+
+#endif
};
+
编译烧录
确定声卡注册成功:cat /proc/asound/cards
开机日志
现象:播放音乐:hp出声正常,但是喇叭不出声,用i2ctransfer按下列配置寄存器来配置,喇叭能出声
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x75 0x41
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x1a 0x00
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x66 0x00
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x26 0x99
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x08 0x00
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3a 0x65
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x6e 0x00
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3a 0x21
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3c 0x13
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3d 0x10
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x26 0x88
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3b 0xff
将此配置写入/kernel/sound/soc/codecs/es8396.c的es8396_pcm_startup函数中
+ //use SPK
+ snd_soc_write(tron_codec, 0x75, 0x41);
+ snd_soc_write(tron_codec, 0x1A, 0x00);
+ snd_soc_write(tron_codec, 0x66, 0x00);
+ snd_soc_write(tron_codec, 0x26, 0x99);
+ snd_soc_write(tron_codec, 0x08, 0x00);
+ snd_soc_write(tron_codec, 0x3A, 0x65);
+ snd_soc_write(tron_codec, 0x6E, 0x00);
+ snd_soc_write(tron_codec, 0x3A, 0x21);
+ snd_soc_write(tron_codec, 0x3C, 0x13);
+ snd_soc_write(tron_codec, 0x3D, 0x10);
+ snd_soc_write(tron_codec, 0x26, 0x88);
+ snd_soc_write(tron_codec, 0x3B, 0xff);
return 0;
}
最后编译烧录,喇叭正常
声卡播放状态:cat proc/asound/card0/pcm0p/sub0/status
声卡配置信息:cat proc/asound/card0/pcm0p/sub0/hw_params
Platform: ROCKCHIP
Chip: RK3288
OS: Android7.1.2
Kernel: 4.4.143
背景:
之前平台用的RT5640, 由于此IC将要停产,所以需要替换为ES8396,RT5640和ES8396在硬件上兼容,只是芯片换了。
音频开发指南
一个声卡包含cpu_dai, codec_dai, 以及dai_link组成,分别对应cpu dai的dirver,比如I2S driver, spdif driver;codec driver, 比如rt5640 codec driver;dai_link driver,也就是machine driver, 比如sound/soc/rockchip/rockchip_rt5640.c。
4.4的内核中支持两种方式创建声卡,一种是通用的simple-card framework,一种是传统的编写自定义的machine driver来创建
硬件原理图
数据走I2S0通道
控制走I2C2通道
输出走HPLOUT/HPROUT SPKROUTP/SPKLOUTP
打开对应的宏
/kernel/arch/arm/configs/rockchip_defconfig
+CONFIG_SND_SOC_ES8396=y
修改dts文件
/kernel/arch/arm/boot/dts/rk3288-android.dtsi
原本的是rt5640,修改后的是es8396
+#if 0
+ hdmi_analog_sound: hdmi-analog-sound {
+ status = "okay";
+ compatible = "rockchip,rk3288-hdmi-analog",
+ "rockchip,rk3368-hdmi-analog";
+ rockchip,model = "rockchip,rt5640-codec";
+ rockchip,cpu = <&i2s>;
+ rockchip,codec = <&rt5640>, <&hdmi>;
+ rockchip,widgets =
+ "Microphone", "Microphone Jack",
+ "Headphone", "Headphone Jack";
+ rockchip,routing =
+ "MIC1", "Microphone Jack",
+ "MIC2", "Microphone Jack",
+ "Microphone Jack", "micbias1",
+ "Headphone Jack", "HPOL",
+ "Headphone Jack", "HPOR";
+ };
+#else
+ hdmi_analog_sound: hdmi-analog-sound {
+ status = "okay";
+ compatible = "rockchip,rk3288-hdmi-analog",
+ "rockchip,rk3368-hdmi-analog";
+ rockchip,model = "rockchip,es8396-codec";
+ rockchip,cpu = <&i2s>;
+ rockchip,codec = <&es8396>, <&hdmi>;
+ rockchip,widgets =
+ "Microphone", "Microphone Jack",
+ "Line", "Microphone Headset",
+ "Headphone", "Headphone Jack";
+ rockchip,routing =
+ "MIC", "Microphone Jack",
+ "DMIC", "Microphone Headset",
+ "Headphone Jack", "LOUTP",
+ "Headphone Jack", "ROUTN";
+ };
+#endif
/kernel/arch/arm/boot/dts/rk3288-evb.dtsi
+#if 0
+ sound: sound {
+ status = "disabled";
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "rockchip,rt5640-codec";
+ simple-audio-card,mclk-fs = <512>;
+ simple-audio-card,widgets =
+ "Microphone", "Microphone Jack",
+ "Headphone", "Headphone Jack";
+ simple-audio-card,routing =
+ "MIC1", "Microphone Jack",
+ "MIC2", "Microphone Jack",
+ "Microphone Jack", "micbias1",
+ "Headphone Jack", "HPOL",
+ "Headphone Jack", "HPOR";
+
+ simple-audio-card,dai-link@0 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&i2s>;
+ };
+
+ codec {
+ sound-dai = <&rt5640>;
+ };
};
+
+ simple-audio-card,dai-link@1 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&i2s>;
+ };
+
+ codec {
+ sound-dai = <&hdmi>;
+ };
};
+ }
+#else
+ es8396-sound {
+ status = "okay";
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "rockchip,es8396-codec";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,widgets =
+ "Microphone", "Microphone Jack",
+ "Line", "Microphone Headset",
+ "Headphone", "Headphone Jack";
+
+ simple-audio-card,routing =
+ "MIC", "Microphone Jack",
+ "DMIC", "Microphone Headset",
+ "Headphone Jack", "LOUTP",
+ "Headphone Jack", "ROUTN";
+
+ simple-audio-card,dai-link@0 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&i2s>;
+ };
+
+ codec {
+ sound-dai = <&es8396>;
+ };
};
+ simple-audio-card,dai-link@1 {
+ format = "i2s";
+ cpu {
+ sound-dai = <&i2s>;
+ };
+
+ codec {
+ sound-dai = <&hdmi>;
+ };
};
+
};
+#endif
&i2c2 {
status = "okay";
+ /*i2c-scl-rising-time-ns = <460>;
+ i2c-scl-falling-time-ns = <15>;*/
+#if 0
rt5640: rt5640@1c {
#sound-dai-cells = <0>;
compatible = "realtek,rt5640";
@@ -307,8 +351,24 @@
pinctrl-names = "default";
pinctrl-0 = <&i2s0_mclk>;
};
+#else
+ es8396: es8396@10 {
+ status = "okay";
+ #sound-dai-cells = <0>;
+ compatible = "es8396";
+ reg = <0x10>;
+ clocks = <&cru SCLK_I2S0_OUT>;
+ clock-names = "mclk";
+ spk-con-gpio = <&gpio6 RK_PA7 GPIO_ACTIVE_HIGH>;
+ //lineout-con-gpio = <&gpio6 RK_PA7 GPIO_ACTIVE_HIGH>
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_mclk>;
+ };
+
+#endif
};
+
编译烧录
确定声卡注册成功:cat /proc/asound/cards
开机日志
现象:播放音乐:hp出声正常,但是喇叭不出声,用i2ctransfer按下列配置寄存器来配置,喇叭能出声
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x75 0x41
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x1a 0x00
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x66 0x00
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x26 0x99
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x08 0x00
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3a 0x65
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x6e 0x00
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3a 0x21
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3c 0x13
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3d 0x10
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x26 0x88
Z20:/data # ./i2ctransfer -f -y 2 w2@0x10 0x3b 0xff
将此配置写入/kernel/sound/soc/codecs/es8396.c的es8396_pcm_startup函数中
+ //use SPK
+ snd_soc_write(tron_codec, 0x75, 0x41);
+ snd_soc_write(tron_codec, 0x1A, 0x00);
+ snd_soc_write(tron_codec, 0x66, 0x00);
+ snd_soc_write(tron_codec, 0x26, 0x99);
+ snd_soc_write(tron_codec, 0x08, 0x00);
+ snd_soc_write(tron_codec, 0x3A, 0x65);
+ snd_soc_write(tron_codec, 0x6E, 0x00);
+ snd_soc_write(tron_codec, 0x3A, 0x21);
+ snd_soc_write(tron_codec, 0x3C, 0x13);
+ snd_soc_write(tron_codec, 0x3D, 0x10);
+ snd_soc_write(tron_codec, 0x26, 0x88);
+ snd_soc_write(tron_codec, 0x3B, 0xff);
return 0;
}
最后编译烧录,喇叭正常
声卡播放状态:cat proc/asound/card0/pcm0p/sub0/status
声卡配置信息:cat proc/asound/card0/pcm0p/sub0/hw_params
举报