///////////////////////////////////////////////
// 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
>;
};
Hi Ed_McM
for sai configuration one can look at
"simple-audio-card" example :
https://bootlin.com/blog/eight-channels-audio-on-i-mx7-with-pcm3168/
Best regards
igor
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
Hi Ed
regarding "codec-master" in dts, one can look at imx-wm8962.c sources : "if (!data->is_codec_master.."
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" :
Best regards
igor
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
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
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
Hi Igor,
I will look closer at this and advise on findings.
Thanks,
Ed
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 ?