AnsweredAssumed Answered

iMX8M SAI Master Clock "Skipping"

Question asked by Krisztian Bakos on May 6, 2019
Latest reply on Sep 18, 2019 by Kapil Bhutani



I wrote a codec driver and modified the "fsl-asoc-card.c" driver to work with my system, which went surprisingly well.

My system consists of the following:

iMX8M SAI2 connected to a TLV320ADC3100 with SAI/I2S interface plus I2C3 for register read/write.


The expectation is that the iMX8M provides MCLK out of its pin named:



And based on this, the TLV320ADC3100 will generate BCLK and WCLK (or BCLK and FS, as you wish).

I plan to have 44100Hz sampling rate, so that's what I set up in the I2C driver, which would result in a BCLK frequency of 705.6kHz (fs * bitdepth = 44100 Hz * 16bit)


After playing around with the device tree, I was finally able to get the output on the MCLK pin, but it looks "odd".

Here are the relevant entries:

        pinctrl_sai2: sai2grp {
            fsl,pins = <
                MX8MQ_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC 0xd6
                MX8MQ_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0xd6
                MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6
                MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6
                MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6
                MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6
                MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6
                MX8MQ_IOMUXC_SAI2_TXFS_GPIO4_IO24               0x16


&i2c3 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c3>;
    status = "okay";

    tlv320adc3100: tlv320adc3100@1b {
        #sound-dai-cells = <0>;
        status= "okay";
        compatible = "ti,tlv320adc3100";
        rst-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>;
        //compatible = "linux,snd-soc-dummy";
        reg = <0x1b>;
        clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>;
        clock-names = "mclk";
        assigned-clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>;
        assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
        assigned-clock-rates = <0>, <11289600>;


&sai2 {
    #sound-dai-cells = <0>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_sai2>;
    assigned-clocks = <&clk IMX8MQ_CLK_SAI2_SRC>,
            <&clk IMX8MQ_CLK_SAI2_DIV>;
    assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
    assigned-clock-rates = <0>, <11289600>;
    status = "okay";


    sound-tlv320adc3100 {
        compatible = "fsl,imx-audio-tlv320adc3100";
        model = "imx-tlv320adc3100";
        audio-cpu = <&sai2>;
        audio-codec = <&tlv320adc3100>;
        audio-routing =
            "CPU-Capture", "Capture";
        status = "okay";


With such a setting, the driver gets loaded, maps up to the SAI interface, everything looks sunny.

According to dmesg:

[    3.459784] fsl-asoc-card sound-tlv320adc3100: tlv320adc3100 <-> 308b0000.sai mapping ok


And I'm able to start a recording as a sound card gets registered:

root@b1sample:~# arecord -d 1 --rate=44100 --channels=1 -f S16
Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono
RIFF▒XWAVEfmt D▒▒Xdata▒X


Now it hangs here and my oscilloscope shows the following on pins MCLK and BCLK:


GREEN -> MCLK (from iMX8)

YELLOW -> BCLK (from TLV320ADC3100 codec)

(This is a zoomed oscilloscope view, the unzoomed "preview" is on top, the zoomed part is on the bottom)


As you can see MCLK is around the expected 11.26 MHz (close enough for now...)

BCLK, generated by the CODEC TLV320ADC3100 also seems correct with its 702kHz (again, not perfect, but good for now)


The "odd" behavior is in-between, when it looks like the MCLK goes away, then returns (upper view is unzoomed, in the red rectangle MCLK disappears, then comes back again)


Any idea why this happens and how to fix it would be greatly appreciated!