0. 背景
hardware platform:骁龙865
android version:android10
Linux kernel version:msm-4.19
思维导图如下:
1. 遇到的一点坑
由于我没有拿到这个平台的MI2S高通配置文档,所以遇到了一点坑,同步也分享。
这个平台目前还没有具体codec器件的调试需求,但是我想验证下接口,于是找硬件,告诉我可以配置MI2S1,对应上面几个GPIO,然后我寻思,默认pri_mi2s应该是MI2S0,这个MI2S1不就应该是配置sec_mi2s嘛。
(我可真是大聪明,逃…)
/vendor/qcom/proprietary/devicetree-4.19/qcom/kona-pinctrl.dtsi
sec_mi2s_sck {
sec_mi2s_sck_sleep: sec_mi2s_sck_sleep {
mux {
- pins = "gpio142";
+ pins = "gpio152";
function = "gpio";
};
config {
- pins = "gpio142";
+ pins = "gpio152";
drive-strength = <2>; /* 2 mA */
bias-pull-down; /* PULL DOWN */
input-enable;
@@ -1871,12 +1871,12 @@
sec_mi2s_sck_active: sec_mi2s_sck_active {
mux {
- pins = "gpio142";
+ pins = "gpio152";
function = "mi2s1_sck";
};
config {
- pins = "gpio142";
+ pins = "gpio152";
drive-strength = <8>; /* 8 mA */
bias-disable; /* NO PULL */
};
@@ -1886,12 +1886,12 @@
sec_mi2s_ws {
sec_mi2s_ws_sleep: sec_mi2s_ws_sleep {
mux {
- pins = "gpio145";
+ pins = "gpio153";
function = "gpio";
};
config {
- pins = "gpio145";
+ pins = "gpio153";
drive-strength = <2>; /* 2 mA */
bias-pull-down; /* PULL DOWN */
input-enable;
@@ -1900,12 +1900,12 @@
sec_mi2s_ws_active: sec_mi2s_ws_active {
mux {
- pins = "gpio145";
+ pins = "gpio153";
function = "mi2s1_ws";
};
config {
- pins = "gpio145";
+ pins = "gpio153";
drive-strength = <8>; /* 8 mA */
bias-disable; /* NO PULL */
};
@@ -1915,12 +1915,12 @@
sec_mi2s_sd0 {
sec_mi2s_sd0_sleep: sec_mi2s_sd0_sleep {
mux {
- pins = "gpio143";
+ pins = "gpio154";
function = "gpio";
};
config {
- pins = "gpio143";
+ pins = "gpio154";
drive-strength = <2>; /* 2 mA */
bias-pull-down; /* PULL DOWN */
input-enable;
@@ -1929,12 +1929,12 @@
sec_mi2s_sd0_active: sec_mi2s_sd0_active {
mux {
- pins = "gpio143";
+ pins = "gpio154";
function = "mi2s1_data0";
};
config {
- pins = "gpio143";
+ pins = "gpio154";
drive-strength = <8>; /* 8 mA */
bias-disable; /* NO PULL */
};
@@ -1944,12 +1944,12 @@
sec_mi2s_sd1 {
sec_mi2s_sd1_sleep: sec_mi2s_sd1_sleep {
mux {
- pins = "gpio144";
+ pins = "gpio155";
function = "gpio";
};
config {
- pins = "gpio144";
+ pins = "gpio155";
drive-strength = <2>; /* 2 mA */
bias-pull-down; /* PULL DOWN */
input-enable;
@@ -1958,12 +1958,12 @@
sec_mi2s_sd1_active: sec_mi2s_sd1_active {
mux {
- pins = "gpio144";
+ pins = "gpio155";
function = "mi2s1_data1";
};
config {
- pins = "gpio144";
+ pins = "gpio155";
drive-strength = <8>; /* 8 mA */
bias-disable; /* NO PULL */
};
./vendor/qcom/proprietary/devicetree-4.19/qcom/kona-audio-overlay.dtsi
qcom,codec-aux-devs = <&wcd938x_codec>;
+ qcom,sec-mi2s-gpios = <&cdc_sec_mi2s_gpios>;
qcom,msm_audio_ssr_devs = <&audio_apr>, <&q6core>, <&lpi_tlmm>,
<&bolero>;
};
@@ -377,6 +378,17 @@
qcom,lpi-gpios;
qcom,tlmm-gpio = <147>;
};
+ cdc_sec_mi2s_gpios: cdc_sec_mi2s_clk_data_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&sec_mi2s_sck_active &sec_mi2s_ws_active &sec_mi2s_sd0_active
+ &sec_mi2s_sd1_active>;
+ pinctrl-1 = <&sec_mi2s_sck_sleep &sec_mi2s_ws_sleep &sec_mi2s_sd0_sleep
+ &sec_mi2s_sd1_sleep>;
+ qcom,lpi-gpios;
+ qcom,tlmm-gpio = <152 153 154 155>;
+ };
};
然后编译,烧录,adb shell执行tinyalsa命令录音:
tinymix "MultiMedia1 Mixer SEC_MI2S_TX" 1
tinycap /sdcard/rec.wav
发现终端录制不了:
kona:/ # tinymix "MultiMedia1 Mixer SEC_MI2S_TX" 1
p /sdcard/rec.wavkona:/ # tinycap /sdcard/rec.wav
Unable to open PCM device (cannot set hw params: Invalid argument)
Captured 0 frames
然后串口报错log如下:
[ 410.635747] bt_ioctl: BT_CMD_PWR_CTRL pwr_cntrl:1
[ 410.641033] bt_vreg_enable: vreg_en successful for : qca,bt-vdd-aon
[ 410.647820] bt_vreg_init: regulator_get(qca,bt-vdd-dig) failed. rc=-517
[ 410.655571] bluetooth_power: bt_power vdddig config failed
[ 410.661381] bt_vreg_disable: vreg_disable successful for : qca,bt-vdd-aon
[ 412.117603] msm_dai_q6_mi2s_hw_params: dai_data->channels = 1 channel_mode = 0
[ 412.125138] msm-dai-q6-mi2s soc:qcom,msm-dai-mi2s:qcom,msm-dai-q6-mi2s-sec:
ASoC: can't set Secondary MI2S hw params: -22
[ 412.137315] SEC_MI2S_TX: ASoC: hw_params BE failed -22
[ 412.142744] KONA Media1: ASoC: hw_params BE failed -22
[ 412.148442] q6asm_callback: cmd = 0x10bcd returned error = 0x1
[ 412.155280] __q6asm_cmd: DSP returned error[ADSP_EFAILED] opcode 68557
这个报错看起来是平台info里面xml backend配置异常,但是我们当前是用tinyalsa命令抓数据,无须考虑那个info的配置,这里我怀疑是硬件搞错了MI2S GPIO(其实是我搞错了=_=)。
在我的再三请求下,硬件老哥帮我又检查了一遍,说gpio没有问题,我当时感觉自己麻了,没个文档都不知道gpio配的对不对,然后我问他有没有这个平台的PING定义啊,GPIO的那种表格。
(一番沟通之后,俺拿到了表格)
从表格里面拿到了两个重要的信息:这组MI2S是和数字麦克冲突的,gpio152对应LPI GPIO6。
这里说明下,类比已知的高通外部MI2S总线,按顺序依次是:Primary MI2S、Secondary MI2S、Tertiary MI2S、Quaternary MI2S、Quinary MI2S、 Senary MI2S。
其中,和DMIC1以及DMIC2冲突的总线应该是,quin_mi2s。
总之,之前是白捣鼓了,我们可以再看看lpi设备树来佐证想法:当前应该配置quin_mi2s。
./vendor/qcom/proprietary/devicetree-4.19/qcom/kona-lpi.dtsi
如我们所料,这个LPI GPIO6是QUAT总线的下一组MI2S的SCLK,即 QUIN总线的SCLK。
2. 按照上面的思维导图再进行一遍
● 获取到正确信息,明确要配置的MI2S。(已完成,明确是quin总线)
● 对应平台pinctrl dtsi里面添加MI2S相关的GPIO配置。
./vendor/qcom/proprietary/devicetree-4.19/qcom/kona-pinctrl.dtsi
+//add for test QUIN MI2S start
+
+ quin_mi2s_sck {
+ quin_mi2s_sck_sleep: quin_mi2s_sck_sleep {
+ mux {
+ pins = "gpio152";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio152";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ quin_mi2s_sck_active: quin_mi2s_sck_active {
+ mux {
+ pins = "gpio152";
+ function = "mi2s4_sck";
+ };
+
+ config {
+ pins = "gpio152";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ quin_mi2s_ws {
+ quin_mi2s_ws_sleep: quin_mi2s_ws_sleep {
+ mux {
+ pins = "gpio153";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio153";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ quin_mi2s_ws_active: quin_mi2s_ws_active {
+ mux {
+ pins = "gpio153";
+ function = "mi2s4_ws";
+ };
+
+ config {
+ pins = "gpio153";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ quin_mi2s_sd0 {
+ quin_mi2s_sd0_sleep: quin_mi2s_sd0_sleep {
+ mux {
+ pins = "gpio154";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio154";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ quin_mi2s_sd0_active: quin_mi2s_sd0_active {
+ mux {
+ pins = "gpio154";
+ function = "mi2s4_data0";
+ };
+
+ config {
+ pins = "gpio154";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+ quin_mi2s_sd1 {
+ quin_mi2s_sd1_sleep: quin_mi2s_sd1_sleep {
+ mux {
+ pins = "gpio155";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio155";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ input-enable;
+ };
+ };
+
+ quin_mi2s_sd1_active: quin_mi2s_sd1_active {
+ mux {
+ pins = "gpio155";
+ function = "mi2s4_data1";
+ };
+
+ config {
+ pins = "gpio155";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL */
+ };
+ };
+ };
+
+//add for test QUIN MI2S end
● 对应平台主要的audio dtsi 里面添加调用MI2S。
./vendor/qcom/proprietary/devicetree-4.19/qcom/kona-audio-overlay.dtsi
+ qcom,codec-max-aux-devs = <0>;
+ qcom,quin-mi2s-gpios = <&cdc_quin_mi2s_gpios>;
qcom,codec-aux-devs = <&wcd938x_codec>;
qcom,msm_audio_ssr_devs = <&audio_apr>, <&q6core>, <&lpi_tlmm>,
<&bolero>;
};
&q6core {
+
+
+ cdc_quin_mi2s_gpios: cdc_quin_mi2s_clk_data_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&quin_mi2s_sck_active &quin_mi2s_ws_active &quin_mi2s_sd0_active
+ &quin_mi2s_sd1_active>;
+ pinctrl-1 = <&quin_mi2s_sck_sleep &quin_mi2s_ws_sleep &quin_mi2s_sd0_sleep
+ &quin_mi2s_sd1_sleep>;
+ qcom,lpi-gpios;
+ qcom,tlmm-gpio = <152 153 154 155>;
+ };
● 关闭设备树里面可能引起冲突的dtsi配置,正确启用MI2S总线,而不是其他总线,比如TDM总线。
./vendor/qcom/proprietary/devicetree-4.19/qcom/kona-audio-overlay.dtsi
cdc_dmic01_gpios: cdc_dmic01_pinctrl {
+ status = "disabled";
compatible = "qcom,msm-cdc-pinctrl";
pinctrl-names = "aud_active", "aud_sleep";
pinctrl-0 = <&cdc_dmic01_clk_active &cdc_dmic01_data_active>;
@@ -333,6 +349,7 @@
};
cdc_dmic23_gpios: cdc_dmic23_pinctrl {
+ status = "disabled";
compatible = "qcom,msm-cdc-pinctrl";
pinctrl-names = "aud_active", "aud_sleep";
pinctrl-0 = <&cdc_dmic23_clk_active &cdc_dmic23_data_active>;
@@ -341,6 +358,7 @@
};
cdc_dmic45_gpios: cdc_dmic45_pinctrl {
+ status = "disabled";
compatible = "qcom,msm-cdc-pinctrl";
pinctrl-names = "aud_active", "aud_sleep";
pinctrl-0 = <&cdc_dmic45_clk_active &cdc_dmic45_data_active>;
@@ -350,6 +368,7 @@
};
./vendor/qcom/proprietary/devicetree-4.19/qcom/kona-audio.dtsi
qcom,mi2s-audio-intf = <1>;
- qcom,auxpcm-audio-intf = <1>;
- qcom,tdm-audio-intf = <1>;
+ qcom,auxpcm-audio-intf = <0>;
+ qcom,tdm-audio-intf = <0>;
● tinyalsa命令起进程,抓波形。
编译烧录之后,adb root,adb shell,执行以下命令录音:
tinymix "MultiMedia1 Mixer QUIN_MI2S_TX" 1
tinycap /sdcard/rec.wav
波形一动不动=_=。
3. 终章
因为配置个总线就这几个步骤,没啥说的,到这步心里一点不慌(逃…),估计是哪里犯了个小错误。经过排查,发现是
gpio的引用方式不对,原因是检索dmic的配置:
./vendor/qcom/proprietary/devicetree-4.19/qcom/kona-audio-overlay.dtsi
cdc_dmic01_gpios: cdc_dmic01_pinctrl {
status = "disabled";
compatible = "qcom,msm-cdc-pinctrl";
pinctrl-names = "aud_active", "aud_sleep";
pinctrl-0 = <&cdc_dmic01_clk_active &cdc_dmic01_data_active>;
pinctrl-1 = <&cdc_dmic01_clk_sleep &cdc_dmic01_data_sleep>;
qcom,lpi-gpios;
};
grep -nrR “cdc_dmic01_clk_active” ./vendor/qcom/proprietary/devicetree-4.19/qcom/
发现dmic直接引用的平台lpi设备树的节点:kona-lpi.dtsi,那么依次类推,我们准备也直接引用lpi的节点即可。
补充以下修改:
./vendor/qcom/proprietary/devicetree-4.19/qcom/kona-audio-overlay.dtsi
+ //cdc_quin_mi2s_gpios: cdc_quin_mi2s_clk_data_pinctrl {
+ // compatible = "qcom,msm-cdc-pinctrl";
+ // pinctrl-names = "aud_active", "aud_sleep";
+ // pinctrl-0 = <&quin_mi2s_sck_active &quin_mi2s_ws_active &quin_mi2s_sd0_active
+ // &quin_mi2s_sd1_active>;
+ // pinctrl-1 = <&quin_mi2s_sck_sleep &quin_mi2s_ws_sleep &quin_mi2s_sd0_sleep
+ // &quin_mi2s_sd1_sleep>;
+ // qcom,lpi-gpios;
+ // qcom,tlmm-gpio = <152 153 154 155>;
+ //};
+
+ cdc_quin_mi2s_gpios: cdc_quin_mi2s_clk_data_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&lpi_i2s1_sck_active &lpi_i2s1_ws_active &lpi_i2s1_sd0_active
+ &lpi_i2s1_sd1_active>;
+ pinctrl-1 = <&lpi_i2s1_sck_sleep &lpi_i2s1_ws_sleep &lpi_i2s1_sd0_sleep
+ &lpi_i2s1_sd1_sleep>;
+ qcom,lpi-gpios;
+ //qcom,tlmm-gpio = <152 153 154 155>;
+ };
(小细节,SCLK为1.536MHz,那么周期应该为1us左右可以抓到 稳定波形)
这两个图片表明正确获取到了SCLK以及WS的波形,WS是48KHz,由于我没有在machine driver修改sclk,此时sclk应该为默认值1.536MHz :
总线至此配置OK,本文到此结束,篇幅过长,感谢阅读!