Hi,
I'm having some trouble with an AD1939 codec. I need my application to work in TDM mode (8 playback streams on a single lane and 4 capture streams on a single lane) and the CPU to be the clock master. I managed to get the codec recognized by the kernel and it playbacks OK. I'm having a hard time getting the capture streams configured.
Here is a snippet of my device tree:
/ {
sound-ad193x {
compatible = "simple-audio-card";
simple-audio-card,name = "ad193x-audio";
simple-audio-card,format = "dsp_a";
simple-audio-card,frame-master = <&cpudai>;
simple-audio-card,bitclock-master = <&cpudai>;
simple-audio-card,mclk-fs = <256>;
cpudai: simple-audio-card,cpu {
sound-dai = <&sai2>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
codecdai:simple-audio-card,codec {
sound-dai = <&codec_audio_analog>;
};
};
};
&ecspi2 {
codec_audio_analog: ad1939_spi@0 {
compatible = "ad1939";
reg = <0>;
spi-max-frequency = <1000000>;
#sound-dai-cells = <0>;
status = "okay";
};
};
&sai2 {
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai2>;
assigned-clocks = <&clk IMX8MP_CLK_SAI2>;
assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
assigned-clock-rates = <12288000>;
clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI2_IPG>, <&clk IMX8MP_CLK_DUMMY>,
<&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI2_MCLK1>, <&clk IMX8MP_CLK_DUMMY>,
<&clk IMX8MP_CLK_DUMMY>;
clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
fsl,dataline = <0 0x1 0x1>;
fsl,sai-mclk-direction-output;
status = "okay";
};
&iomuxc {
pinctrl_sai2: sai2grp {
fsl,pins = <
MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0x000000D6
MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0x00000196
MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0x000000D6
MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0x000000D6
>;
};
};
The configuration sent by the codec driver over the SPI bus looks fine to me. Here is a screenshot of the signals I get:
When I try to record I get just noise. Reproducing the wave file through my logic analyzer looks like the whole 8-slot frame gets "compressed" into 4 frames (muting first channel one and then channel two while recording I see during playback that the most significant bit of channel one got zeroed first then the least significant ones). Another symptom is that if I lunch arecord with a duration flag it records for exactly twice the time!
~# time arecord -fs16 -r48000 -c4 /dev/null --duration 2
Recording WAVE '/dev/null' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
real 0m4.136s
user 0m0.056s
sys 0m0.024s
My theory is the bit clock inside the receiver got somehow halved...
Peeking at the sai registers during the recording I see MSEL in RCR2 is 00, I was expecting it to be 01 as in TCR2.
If I configure the codec to be the clock master all works as expected.
Can anybody please help me?
Thanks
已解决! 转到解答。
Answering myself in case somebody needs a hint on a similar issue.
The problem was I had clocked the SAI peripheral at the same rate my bit clock is. I have 8 32-bit slots at 48 kHz, so my bit clock is 12.288 MHz and in my device tree I had assigned-clock-rates = <12288000>
Running out of ideas I tried to reduce the slot count to 4 (bit clock 6.144 MHz) and all went fine. So I tried to revert to 8 slots and increase assigned-clock-rates to twice the bit clock. Now I can playback and capture w/o any issue.
Answering myself in case somebody needs a hint on a similar issue.
The problem was I had clocked the SAI peripheral at the same rate my bit clock is. I have 8 32-bit slots at 48 kHz, so my bit clock is 12.288 MHz and in my device tree I had assigned-clock-rates = <12288000>
Running out of ideas I tried to reduce the slot count to 4 (bit clock 6.144 MHz) and all went fine. So I tried to revert to 8 slots and increase assigned-clock-rates to twice the bit clock. Now I can playback and capture w/o any issue.