1、确定具体的i2s外部引脚,如图:
我添加的一路是ssi3->int-port7->ext-port5; ext-port5 这路是可以软件上修改的。也就是ext-prot是可以随意搭配的。这样就确定了管脚用的是哪些了。
2、配置dtsi使其能使用对应功能的引脚。
在pinctrl_audmux: audmuxgrp 节点添加对应的管脚。对占用的管脚进行屏蔽。
3、添加imx-mic1388 codec机器层对应的节点。
+ sound-mic {
+ compatible = "fsl,imx6q-sabresd-mic1388",
+ "fsl,imx-audio-mic1388";
+ model = "mic1388-audio";
+ cpu-dai = <&ssi3>; //使用了ssi3 这一路i2s;
+ audio-codec = <&codec_mic1388>;
+ mux-int-port = <7>; //int-port= 7;
+ mux-ext-port = <5>; //ext-port= 5;
+ };
4、添加并配置ssi3 的时钟项
+&ssi3 {
+ assigned-clocks = <&clks IMX6QDL_PLL4_BYPASS_SRC>,
+ <&clks IMX6QDL_CLK_PLL4>,
+ <&clks IMX6QDL_PLL4_BYPASS>,
+ <&clks IMX6QDL_CLK_PLL4_AUDIO>,
+ <&clks IMX6QDL_CLK_PLL4_POST_DIV>,
+ <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>,
+ <&clks IMX6QDL_CLK_SSI3_SEL>,
+ <&clks IMX6QDL_CLK_SSI3_PRED>,
+ <&clks IMX6QDL_CLK_SSI3_PODF>,
+ <&clks IMX6QDL_CLK_SSI3>,
+ <&clks IMX6QDL_CLK_CKO2_SEL>,
+ <&clks IMX6QDL_CLK_CKO2_PODF>,
+ <&clks IMX6QDL_CLK_CKO2>,
+ <&clks IMX6QDL_CLK_CKO>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_OSC>,
+ <&clks IMX6QDL_PLL4_BYPASS_SRC>,
+ <&clks IMX6QDL_CLK_PLL4>,
+ <&clks IMX6QDL_PLL4_BYPASS>,
+ <&clks IMX6QDL_CLK_PLL4_AUDIO>,
+ <&clks IMX6QDL_CLK_PLL4_POST_DIV>,
+ <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>,
+ <&clks IMX6QDL_CLK_SSI3_SEL>,
+ <&clks IMX6QDL_CLK_SSI3_PRED>,
+ <&clks IMX6QDL_CLK_SSI3_PODF>,
+ <&clks IMX6QDL_CLK_SSI3>,
+ <&clks IMX6QDL_CLK_CKO2_SEL>,
+ <&clks IMX6QDL_CLK_CKO2_PODF>,
+ <&clks IMX6QDL_CLK_CKO2>;
+ assigned-clock-rates = <24000000>,
+ <1179648000>,
+ <1179648000>,
+ <1179648000>,
+ <589824000>,
+ <589824000>,
+ <589824000>,
+ <147456000>,
+ <24576000>,
+ <24576000>,
+ <24576000>,
+ <24576000>,
+ <24576000>,
+ <24576000>;
+ fsl,mode = "i2s-master";
+ status = "okay";
+}
5、在kernel_imx/arch/arm/mach-imx/clk-imx6q.c 文件中初始化时钟树
+ imx_clk_set_parent(clk[IMX6QDL_CLK_SSI3_SEL], clk[IMX6QDL_CLK_PLL4_AUDIO_DIV]);//johnli add
+ imx_clk_set_rate(clk[IMX6QDL_CLK_SSI3_PRED], 147456000); //johnli add 48000X512=24576000 22579200
+ imx_clk_set_rate(clk[IMX6QDL_CLK_SSI3_PODF], 24576000); //johnli add 48000X512=24576000 22579200
+ imx_clk_set_rate(clk[IMX6QDL_CLK_SSI3], 24576000); //johnli add 48000X512=24576000 22579200
具体的时钟介绍见audio patch wm8524 文档
6、问题总结:
ssi3-> int-port7-> ext-port5 这个映射配置是在文件imx-mic1833.c 的
265 int_port--;
266 ext_port--;
267 ret = imx_audmux_v2_configure_port(ext_port,
268 IMX_AUDMUX_V2_PTCR_SYN |
269 IMX_AUDMUX_V2_PTCR_TFSEL(int_port) |
270 IMX_AUDMUX_V2_PTCR_TCSEL(int_port) |
271 IMX_AUDMUX_V2_PTCR_TFSDIR |
272 IMX_AUDMUX_V2_PTCR_TCLKDIR |
273 IMX_AUDMUX_V2_PTCR_RFSEL(int_port) |
274 IMX_AUDMUX_V2_PTCR_RCSEL(int_port) |
275 IMX_AUDMUX_V2_PTCR_RFSDIR |
276 IMX_AUDMUX_V2_PTCR_RCLKDIR,
277 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
278 if (ret) {
279 dev_err(&pdev->dev, "audmux internal port setup failed\n");\r
280 return ret;
281 }
282 imx_audmux_v2_configure_port(int_port,
283 IMX_AUDMUX_V2_PTCR_SYN,
284 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
这里写寄存器imx_audmux_v2_configure_port 来配置的。对应的位置在:
我们采用的是normal mode。
如果是capture功能即将ssi2设置成receiver,而ssi2对应的internal-port是2,而external-port假设我们定为4口即需要设置的寄存器是AUDMUX_PDCR2那这时得将RXDSEL[2:0] to 11b(internal-port 2),如果frame(RXFS)和bit clock (RXC)设置成接收外部器件的时钟信号那PTCR4’s RFSEL[3:0] and
RCSEL[3:0] must be set to 011b while PTCR4’s RFSDIR and RCLKDIR set to 0.
PDCR2是Port Data Control Register data相关
PTCR4是Port Timing Control Register clock相关
至于使用请具体查看datasheet相关寄存器的位定义。
7、tinycap 指令
tinycap record_asrc.wav -D 1 -d 0 -c 2 -r 44100 -b 16
capture
这里指定了设备
ll /dev/snd/
drwxr-xr-x 2 root root 80 Jan 1 00:14 by-path/
crw-rw—T 1 root audio 116, 0 Jan 1 00:14 controlC0
crw-rw—T 1 root audio 116, 32 Jan 1 00:14 controlC1
crw-rw—T 1 root audio 116, 24 Jan 1 00:14 pcmC0D0c
crw-rw—T 1 root audio 116, 16 Jan 1 00:14 pcmC0D0p
crw-rw—T 1 root audio 116, 48 Jan 1 00:14 pcmC1D0p
crw-rw—T 1 root audio 116, 33 Jan 1 00:14 timer
这条命令指定的设备是pcmC1D0c
8、采样率48khz 44.1khz是由指令定的。即帧时钟的设定是由上层发的设置指定的。