IMX7d SAI setup for clock master

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IMX7d SAI setup for clock master

3,061 Views
Ed_McM
Contributor I
Hello,
We are trying to get SAI working on the IMX7d under Linux 4.14.98. The SAI must be the master. 
It will use an internal clock as mclk, and from that generate the frame sync and bclk.
 
I have been able to register the soundcard, but have not had any success transmitting audio data. 
I've attached relevant DTB input pieces below, along with some kernel data and command line tests.
Any advice on what might be configured incorrectly OR any area to look at, is appreciated.
 

 

///////////////////////////////////////////////
// DTS nodes for sound card, dai and codec
///////////////////////////////////////////////

     codec_dummy: codec_dummy {
         compatible = "linux,snd-soc-dummy";
         #sound-dai-cells = <0>;

         clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
         assigned-clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_SRC>,
         <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
         assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
         assigned-clock-rates = <0>, <24576000>;
         status = "okay";
     };

     sound {
         	compatible = "simple-audio-card";
         	simple-audio-card,name = "test_dummy";
         	simple-audio-card,format="i2s";
         	simple-audio-card,bitclock-master = <&dailink_master>;
         	simple-audio-card,frame-master = <&dailink_master>;
                //simple-audio-card,mclk-fs = <512>;

                dailink_master: simple-audio-card,codec {
                        sound-dai = <&codec_dummy>;
		        clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
                };
		simple-audio-card,cpu {
			sound-dai = <&sai1>;
		};
     };

/////////////////////
// DTS notes for SAI
/////////////////////
&sai1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_sai1>;
	assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>,
			  <&clks IMX7D_SAI1_ROOT_CLK>;
	assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
	assigned-clock-rates = <0>, <24576000>;
        fsl,sai-mclk-direction-output;
        fsl,sai-synchronous-rx;
	status = "okay";
};
sai1: sai@308a0000 {
	#sound-dai-cells = <0>;
	compatible = "fsl,imx7d-sai", "fsl,imx6sx-sai";
	reg = <0x308a0000 0x10000>;
	interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&clks IMX7D_SAI1_IPG_CLK>,
		 <&clks IMX7D_CLK_DUMMY>,
		 <&clks IMX7D_SAI1_ROOT_CLK>,
		 <&clks IMX7D_CLK_DUMMY>,
		 <&clks IMX7D_CLK_DUMMY>;
		 clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
		 dma-names = "rx", "tx";
		 dmas = <&sdma 8 24 0>, <&sdma 9 24 0>;
		 status = "disabled";
};
pinctrl_sai1: sai1grp {
	fsl,pins = <
		MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK	0x1f
		MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC	0x1f
		MX7D_PAD_ENET1_COL__SAI1_TX_DATA0	0x30
		MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0	0x1f
	>;
};

 

 

//////////////////////
// Kernel data
//////////////////////
root@pico-imx7:/# aplay -L
...
    sysdefault:CARD=test_dummy
    test_dummy,
    Default Audio Device

root@pico-imx7:/# aplay -l
    card0: test_dummy [test_dummy], device 0: 308a0000.sai-snd-soc-dummy-dai snd-soc-dummy-dai-0
 
root@pico-imx7:/# cat /proc/asound/cards
    0 [test_dummy    ]: test_dummy - test_dummy
    test_dummy
 
root@pico-imx7:/# dmesg | grep dummy
    asoc-simple-card sound: snd-soc-dummy-dai <-> 308a0000.sai mapping ok
 
root@pico-imx7:/# cat /sys/kernel/debug/asoc/dais
    308b0000.sai
    308a0000.sai
    snd-soc-dummy-dai
    snd-soc-dummy-dai
 
///////////////////////////////////////
// Test Results (cmdline)
//////////////////////////////////////
root@pico-imx7:/#  aplay -D sysdefault:test_dummy -d 5 -r 44100 audiotest.wav
     Playing WAVE 'audiotest.wav' ..
     aplay: pcm_write:2051: write error: Input/output error
 
root@pico-imx7:/#  speaker-test -Dsysdefault:test_dummy -c2 -twav
...
     0 - Front Left
     Write error: -5, Input/output error
     Xrun_recovery failed: -5 Input/output error
     Transfer failed: Input/Output error
0 Kudos
9 Replies

3,047 Views
igorpadykov
NXP Employee
NXP Employee
0 Kudos

3,041 Views
Ed_McM
Contributor I

Hi Igor,

Thanks for the response. 

Both of those examples are showing the codec as the "clock master".   Could you point me to the documentation, or to a device tree example of the SAI being setup as the "clock master" ? 

I haven't been able to find any examples on successfully setting-up the SAI to generate the frame clock and the bit clock, using an internal master clock.

Thanks,

Ed

 

0 Kudos

3,034 Views
igorpadykov
NXP Employee
NXP Employee

Hi Ed

 

regarding "codec-master" in dts, one can look at imx-wm8962.c sources : "if (!data->is_codec_master.."

https://source.codeaurora.org/external/imx/linux-imx/tree/sound/soc/fsl/imx-wm8962.c?h=imx_4.14.98_2...

so commenting "codec-master" should cause wm8962 driver to work in slave mode,

look at i.MX6UL example :

https://community.nxp.com/t5/i-MX-Processors/iMX6UL-define-sai1-as-master/m-p/707120

also one can debug it in sai driver, look for "sai->slave_mode" :

https://source.codeaurora.org/external/imx/linux-imx/tree/sound/soc/fsl/fsl_sai.c?h=imx_4.14.98_2.3....

 

Best regards
igor

 

0 Kudos

2,995 Views
Ed_McM
Contributor I

Hi Ivan,

Thank-you for the examples. In these examples, I can see very clearly how the device tree is used to setup various hardware parameters. But I still can't see any way to use the device tree to setup the Frame sync and Bit clock direction in the SAI Transmit configuration registers TCR2/4 ( to make the SAI the I2S master).

I see the code in the fsl_sai.c driver where these configuration registers are set, but I don't see how to connect to that code from the device tree (without modifying the driver code).


1: Does the fsl_sai.c driver file have to be modified to configure the SAI as I2S master?
2: If not, what are the specific line(s) to add to device tree file, to configure these registers?


Thanks,
Ed

0 Kudos

2,991 Views
igorpadykov
NXP Employee
NXP Employee

dts adjustable settings are provided by "of_property_read.." in driver code,

like sai->is_lsb_first = of_property_read_bool(np, "lsb-first");

https://source.codeaurora.org/external/imx/linux-imx/tree/sound/soc/fsl/fsl_sai.c?h=imx_5.4.24_2.1.0

other settings which are not configurable in such way should be set changing driver code

 

Best regards
igor

 

 

 

0 Kudos

2,984 Views
Ed_McM
Contributor I

Hi Ivan,

Thanks for the examples. I can see clearly how parameters are described in the device
tree bindings and used in the device tree files. Then how they are used in the driver
files to setup configuration registers. Simple example:

 

// DEVICE TREE (imx7d-sdb.dts)
	sound {
		compatible = "fsl,imx7d-evk-wm8960",
			     "fsl,imx-audio-wm8960";
		model = "wm8960-audio";
		cpu-dai = <&sai1>;
		audio-codec = <&codec>;
		codec-master;
		...

// DEVICE DRIVER (fsl_sai.c)
if (of_property_read_bool(pdev->dev.of_node, "codec-master"))
	"set registers"

 

But I still can't see how to setup the FSL SAI as I2S Master. I can see in fsl_sai.c driver code,
where the frame_clock and bit_clock registers are set in configuration registers 2 and 4.

 

val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
val_cr4 |= FSL_SAI_CR4_FSD_MSTR;

 

But I can't see how to use the device tree, to connect to that driver code and set  these registers.

(1) Is it required to modify the FSL SAI driver, in order to use the device tree files to setup
those registers and establish the SAI as I2S MASTER?

(2) If not, can you please advise on the specific line(s) of code in the Device Tree that will set these registers and make the SAI the I2S master?

Thanks,

Ed

0 Kudos

3,024 Views
Ed_McM
Contributor I

Hi Igor,

I will look closer at this and advise on findings.

Thanks,

Ed

0 Kudos

620 Views
YuriyBV
Contributor I
Hi Ed,
Were you able to find any solutions? I'm running into a similar issues.
Thanks
0 Kudos

2,590 Views
medaliyou
Contributor I

Hey, i wonder if you solved your issues.

I'm facing the same problem but with ics43432 MEMS microphone on SAI2.

(SAi1 reserved for the sgtl5000 codec).

 

I can't get the BCLK ( = Fs*bitdepth*channels ) to get derived properly 

Always have a fsl_sai error : can't derive required Rx rate.

 

And my mic works only with Fs = 11025 Hz.

 

I tried all possible MCLK value attribution ... But with no success 

 

Did you solve your issue and changed MCLK value ?

 

 

 

 

 

 

 

0 Kudos