SAI3 on imx6ull with sgtl5000

Hi,

I’m trying to make a devicetree overlay for the sai3 interface on a Colibri imx6ull module (emmc version).
I’ve made the following overlay:

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/imx6ul-clock.h>
#include <dt-bindings/pinctrl/imx6ul-pinfunc.h>


&{/} {
    compatible = "toradex,colibri-imx6ull-emmc";

    sound {
        compatible = "toradex,colibri-imx6ull-emmc",
                     "simple-audio-card";
        simple-audio-card,name="sgtl5000-audio";
        simple-audio-card,format = "i2s";
        simple-audio-card,bitclock-master = <&dailink_master_cpu>;
        simple-audio-card,frame-master = <&dailink_master_cpu>;
        simple-audio-card,widgets =
                "Microphone", "Mic Jack",
                "Line", "Line In",
                "Line", "Line Out",
                "Headphone", "Headphone Jack";
        simple-audio-card,routing =
                "MIC_IN", "Mick Jack",
                "Mic Jack", "Mic Bias",
                "Headphone Jack", "HP_OUT";

        simple-audio-card,codec {
                sound-dai = <&codec_ext>;
        };

        dailink_master_cpu: simple-audio-card,cpu {
                sound-dai = <&sai3>;
        };

    };
};

&lcdif {
        status="disabled";
};

&backlight {
        status="disabled";
};

&i2c1 {
        codec_ext: sgtl5000@a {
                compatible = "fsl,sgtl5000";
                reg = <0xa>;
                #sound-dai-cells = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_sai3_mclk>;
                clocks = <&clks IMX6UL_CLK_SAI3>;
                clk-names = "mclk";
                VDDA-supply = <&reg_module_3v3_avdd>;
                VDDIO-supply = <&reg_module_3v3>;
                VDDD-supply = <&reg_module_3v3>;
                status="okay";
        };
};

&sai3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sai3>;
        assigned-clocks = <&clks IMX6UL_CLK_SAI3_SEL>,
                          <&clks IMX6UL_CLK_SAI3>, <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
        assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
        assigned-clock-rates = <2>, <24576000>, <786432000>;
        fsl,sai-asynchronous;
        //fsl,sai-mclk-direction-output;
        status = "okay";
};

&iomuxc {
                pinctrl_sai3: sai3grp {
                        fsl,pins = <
                                MX6UL_PAD_LCD_DATA13__SAI3_TX_BCLK      0x1F089
                                MX6UL_PAD_LCD_DATA12__SAI3_TX_SYNC      0x17088
                                MX6UL_PAD_LCD_DATA15__SAI3_TX_DATA      0x11088
                                MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA      0x11088
                                MX6UL_PAD_LCD_DATA09__SAI3_MCLK         0x17088
                        >;
                };
                pinctrl_sai3_mclk: sai3grp_mclk {
                        fsl,pins = <
                                MX6UL_PAD_LCD_DATA09__SAI3_MCLK         0x17088
                        >;
                };
};

After boot I get:

Applying Overlay: audio_sgtl5000.dtbo
3281 bytes read in 33 ms (96.7 KiB/s)
8040960 bytes read in 207 ms (37 MiB/s)
8053158 bytes read in 210 ms (36.6 MiB/s)
Kernel image @ 0x81000000 [ 0x000000 - 0x7ab200 ]
## Flattened Device Tree blob at 82100000
   Booting using the fdt blob at 0x82100000
   Loading Ramdisk to 8f851000, end 8ffff1a6 ... OK
   Loading Device Tree to 8f822000, end 8f850fff ... OK
   Updating MTD partitions...

Starting kernel ...

[    0.074375] debugfs: Directory 'dummy-iomuxc-gpr@20e4000' with parent 'regmap' already present!
[    3.411226] fec 20b4000.ethernet: fec clock (0) too fast to get right mii speed
[    4.795515] sgtl5000 0-000a: Error reading chip id -110
Starting version 244.5+

TorizonCore Upstream 5.7.0+build.17 colibri-imx6ull-emmc-07201239 ttymxc0

colibri-imx6ull-emmc-07201239 login:

So for some reason I don’t get a mclk on pin 48 (MX6UL_PAD_LCD_DATA09__SAI3_MCLK).
I’m not sure if the clock configuration is correct. The sgtl5000 needs a MCLK so the Error reading chip error is obvious.

From /sys/kernel/debug/clk/clk_summary I get:

    pll4                              0        0        0   786432000          0     0  50000
       pll4_bypass                    0        0        0   786432000          0     0  50000
          pll4_audio                  0        0        0   786432000          0     0  50000
             pll4_post_div            0        0        0   786432000          0     0  50000
                pll4_audio_div        0        0        0   786432000          0     0  50000
                   sai3_sel           0        0        0   786432000          0     0  50000
                      sai3_pred       0        0        0   393216000          0     0  50000
                         sai3_podf       0        0        0    24576000          0     0  50000
                            sai3       0        0        0    24576000          0     0  50000

Not sure if this is correct? At least to get some clock going on pin 48?

Pinmux settings from /sys/kernel/debug/pinctrl/20e0000.iomuxc/pinmux-pins:

pin 79 (MX6UL_PAD_LCD_DATA09): 2030000.sai (GPIO UNCLAIMED) function iomuxc group sai3grp
pin 80 (MX6UL_PAD_LCD_DATA10): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 81 (MX6UL_PAD_LCD_DATA11): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 82 (MX6UL_PAD_LCD_DATA12): 2030000.sai (GPIO UNCLAIMED) function iomuxc group sai3grp
pin 83 (MX6UL_PAD_LCD_DATA13): 2030000.sai (GPIO UNCLAIMED) function iomuxc group sai3grp
pin 84 (MX6UL_PAD_LCD_DATA14): 2030000.sai (GPIO UNCLAIMED) function iomuxc group sai3grp
pin 85 (MX6UL_PAD_LCD_DATA15): 2030000.sai (GPIO UNCLAIMED) function iomuxc group sai3grp

I also don’t understand why I get this error:

[ 3.408154] fec 20b4000.ethernet: fec clock (0) too fast to get right mii speed

If I remove the overlay this error is also gone. With this error the ethernet interface is not working anymore.

So the question is what’s wrong with this overlay. Any help would really be would be greatly appreciated.

Kind regards,

Chris

Having another look at this… I’ve noticed PLL4 is disabled. How can I enable it?

Regards,

Chris

Hi @sirhc ,

On first look there doesn’t seem to be any obvious mistake on your overlay.

On this solved topic: Device tree configuration for SGTL5000 audio codec someone had a very similar issue with SAI on iMX6ULL with SGTL5000. Can you try the proposed solution and see if it works for you?

Best regards,
Lucas Akira

Hi Lucas,

Thanks for your reply. I’ve seen this post. He was using an external clock as master clock.
The last comment of your colleague was it should also work with an internal clock, but unfortunately there was no follup-up.

Regards,

Chris

Hi @sirhc ,

I did some investigation on my side and it looks like fsl,sai-mclk-direction-output should be present in your sai3 node in order to enable the SAI internal master clock.

With this property enabled the SAI driver should enable bit 21 of register IOMUXC_GPR_GPR1.

One thing to note is that according to the i.MX6ULL Reference Manual from NXP this bit enables the MCLK from pad LCD_CLK; it doesn’t mention pin LCD_DATA09, the one you’ve set as SAI3 MCLK.

I suggest you enable the property mentioned above, and if that doesn’t work, try using pad LCD_CLK as MCLK and try again.

Best regards,
Lucas Akira

Hi @sirhc !

About your codec_ext node:

Taking a look at the imx6qdl-colibri.dtsi « dts « boot « arm « arch - linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules device tree (line 585), we can see that there is no pinctrl for the codec labeled node. You can also take a look at this file regarding other device tree setup done in Colibri iMX6DL for the codec. It will most certainly help you to setup it up for Colibri iMX6ULL.

Also, you are assigning the same pin (MX6UL_PAD_LCD_DATA09) to two different nodes. This should not occur.

Please take a look at the articles below to learn more about Device Trees:

Also, this nice Application Note from NXP about Device Trees:

Best regards,

Hi @henrique.tx and @lucas_a.tx ,

I tried both your suggestions without any luck. Ofcourse you should not have 2 the same different nodes assigned with the same pin. I already noticed that I just forgot to comment out one of the two.
I also tried using the LCD_CLK pin as suggested.
Also the imx6 is different compared to an imx6ull. It does not have this audmux interface. So I use the normal sgtl5000 driver.

At this moment I have the following device tree:

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/imx6ul-clock.h>
#include "../dts-arm32/imx6ul-pinfunc.h"


&{/} {
    compatible = "toradex,colibri-imx6ull-emmc";

    sound {
        compatible = "simple-audio-card";
        simple-audio-card,name="sgtl5000-audio";
        simple-audio-card,format = "i2s";
        simple-audio-card,bitclock-master = <&dailink_master_cpu>;
        simple-audio-card,frame-master = <&dailink_master_cpu>;
        simple-audio-card,widgets =
                "Microphone", "Mic Jack",
                "Line", "Line In",
                "Line", "Line Out",
                "Headphone", "Headphone Jack";
        simple-audio-card,routing =
                "MIC_IN", "Mick Jack",
                "Mic Jack", "Mic Bias",
                "Headphone Jack", "HP_OUT";

        simple-audio-card,cpu {
                sound-dai = <&sai3>;
        };
        simple-audio-card,codec {
                sound-dai = <&codec_ext>;
        };
        dailink_master_cpu: simple-audio-card-cpu {
                sound-dai = <&sai3>;
        };


    };
};

&lcdif {
        status="disabled";
};

&backlight {
        status="disabled";
};


&sai3 {
        #sound-dai-cells = <0>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sai3>;
        assigned-clocks = <&clks IMX6UL_CLK_SAI3_SEL>,
                          <&clks IMX6UL_CLK_SAI3>, <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
        assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
        assigned-clock-rates = <0>, <24576000>, <786432000>;
        //fsl,sai-asynchronous;
        fsl,sai-mclk-direction-output;
        status = "okay";
};

&i2c1 {

        codec_ext: sgtl5000@a {
                compatible = "fsl,sgtl5000";
                reg = <0xa>;
                #sound-dai-cells = <0>;
                clocks = <&clks IMX6UL_CLK_SAI3>;
                clock-names = "mclk";
                VDDA-supply = <&reg_module_3v3_avdd>;
                VDDIO-supply = <&reg_module_3v3>;
                assigned-clocks = <&clks IMX6UL_CLK_SAI3_SEL>,
                          <&clks IMX6UL_CLK_SAI3>, <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
                assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
                assigned-clock-rates = <2>, <24576000>, <786432000>;
        };
};
&iomuxc {
                pinctrl_sai3: sai3grp {
                        fsl,pins = <
                                MX6UL_PAD_LCD_DATA13__SAI3_TX_BCLK      0x1F089
                                MX6UL_PAD_LCD_DATA12__SAI3_TX_SYNC      0x17088
                                MX6UL_PAD_LCD_DATA15__SAI3_TX_DATA      0x11088
                                /*MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA    0x11088*/
                                /*MX6UL_PAD_LCD_DATA09__SAI3_MCLK       0x17088*/
                                MX6UL_PAD_LCD_CLK__SAI3_MCLK            0x17088
                        >;
                };
};

One thing I still don’t understand why I get that fec clock error:

Starting kernel ...

[    0.074305] debugfs: Directory 'dummy-iomuxc-gpr@20e4000' with parent 'regmap' already present!
[    3.402880] fec 20b4000.ethernet: fec clock (0) too fast to get right mii speed
[    3.557006] sgtl5000 0-000a: Error reading chip id -6
Starting version 244.5+

And why is the PLL not enabled:

 pll4                              0        0        0   786432000          0     0  50000
       pll4_bypass                    0        0        0   786432000          0     0  50000
          pll4_audio                  0        0        0   786432000          0     0  50000
             pll4_post_div            0        0        0   786432000          0     0  50000
                pll4_audio_div        0        0        0   786432000          0     0  50000
                   sai3_sel           0        0        0   786432000          0     0  50000
                      sai3_pred       0        0        0   393216000          0     0  50000
                         sai3_podf       0        0        0    24576000          0     0  50000
                            sai3       0        0        0    24576000          0     0  50000

Regards,

Chris

Hi @sirhc ,

Before continuing to further investigate your issues, including the fec clock and PLL errors, we need to narrow down the possible causes:

Best regards,
Lucas Akira

Hi @lucas_a.tx

  • Did you change the device tree in any way?

No original devicetree. I apply this overlay on imx6ull-colibri-emmc-eval-v3.dtb

  • Is this overlay the only one applied?

Yes I have removed the other ones I have.

  • Can you change the interface to another SAI?

I have tried sai1. Same result.

Well I have applied this overlay to the torizoncore with evaluation containers image for the imx6ull. Before the imx6ull I have used the imx6 and imx8 Colibri modules. I made several overlays for these modules all without any issue. I can try your proposal but I expect the same result.

So to summerize. I did a fresh install of the build environment last week. I use the imx6ull-colibri-emmc-eval-v3.dtb devicetree and have just one overlay applied to it.

Regards,

Chris

Hi @sirhc !

Are you able to check your codec using i2c-detect?

Also, could you please try using compatible=fsl,imx-audio-sgtl5000 in your sound node instead of compatible=simple-audio-card?

There are some i.MX6UL device trees that use the SGTL5000 in dts « boot « arm « arch - linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules. You can take a look in them to get some inspiration.

Meanwhile, we are doing some tests about the clock. The fact that they seem to be disabled is intriguing indeed.

Best regards,

Hi @sirhc !

Do you have any updates on this topic?

Best regards,

HI @henrique.tx,

Sorry for the delay. I have been busy with some other issues. I don’t think the imx-audio-sgtl5000 will work because the imx6ul does not have this audmux device. I really tried many combinations of the device tree without success. It would be nice if someone could have a look into this because I have to decide which module we will choose for the new project so we can place an order.

Kind regards,

Christian Vossen

Hi @sirhc !

I am still working on this issue of yours.

As far as I understand, you should be able to make the sgtl5000 work with Colibri iMX6ULL.

But I will need more time on this issue to understand what is missing in your device tree.

Best regards,

Hi @sirhc !

Sorry if I missed something, but what was the result of your test using fsl,imx-audio-sgtl5000 instead of the simple-audio-card?

Best regards,

Hi @henrique.tx

If I remember correctly it was something with audmux. The imx6ul does not have this multiplexer.

Best regards,

Chris

Hi @sirhc

I see.

What happened?

The kernel logs still showed the problem reading the IC? E.g.:

Could you please share the full kernel log of the attempt?

Please also share the output of amixer, aplay -l and aplay -L for that attempt.

Best regards,

Hi @henrique.tx ,

Find attached the complete kernel log. For some reason this morning it was working once. The I2C address was detected by the kernel and claimed by the driver.
So there has to be a mclk in order for the i2c of the sgtl5000 to work. This makes me think there is a timing/order of load issue.

The other thing I don’t understand is why is the ethernet device not working with this device tree.

[ 3.409276] fec 20b4000.ethernet: fec clock (0) too fast to get right mii speed
[ 3.417749] fec: probe of 20b4000.ethernet failed with error -22

amixer,aplay etc give no soundcard found as output.

dmesg_1.txt (18.5 KB)

Hi

AUDMUX is optional. iMX7 as well lacks it, but fsl,imx-audio-sgtl5000 works well on iMX7. However it doesn’t make a lot of sense for you to jump to it now. The 1st thing to do should be making SGTL5000 appearing in i2cdetect output. For that you need SGTL5000 SYS_MCLK clock running, at least for as long as it needed for required codec probe I2C transfers.

As I understand, you have SYS_MCLK connected to SAI MCLK output? I see you have set bitclock-master properly set to SAI instead of SGTL, but isn’t fsl-sai driver as most of other drivers unpreparing unused clocks while not playing? Let’s check:

First I enabled iMX6ULL MQS card with MCLK pinmux, MCLK master set to SAI, and fsl,sai-mclk-direction-output present. MCLK seems being enabled as long as sound card is enabled in DT. No way to may MCLK clock working without sound card consuming your SAI instance.
Repeating the same with physically missing SGTL5000 codec. MCLK gets enabled for ~8ms, for as long as it is required for codec probe I2C transfers. If codec would be present, I guess MCLK won’t cease after successful probe. I see I2C transfer on scope while MCLK is present. You need to check it with scope. Compiling codec as module can help repeating probe without reboot. Just rmmod/modprobe it again and again.

Edward

1 Like

Hi @henrique.tx,

I got it working with both the simple audio card driver as the fsl-imx-audio-sgtl5000 driver. The only issue I still have is it’s not working after power up. The i2c driver is loaded first so there’s no MCLK output. When I do a sw reboot the MCLK will stay enabled so the next time the kernel boots the i2c driver is loaded the way it should. Any idea if this can be fixed? So actually the sai driver has to be loaded first so it outputs the MCLK for the i2c driver to be loaded correctly.

Regards,

Chris

Hi

It’s chicken-egg like problem. SAI and sound card drivers don’t know about how your codec is clocked. The best would be to clock codec by other means. You could use one of iMX6ull CKO outputs for this.
Compiling codec driver as module (=m) will definitely make it probed later compared to all other kernel built in (=y) drivers. If you have several =m drivers, you may make one or few of them blacklisted in /etc/modprobe.d, then load those blacklisted modules in particular order in some service, or perhaps in bash script, which is supposed to launch your application.

Edward