i.MX6 and MA98357a with simple-audio-card

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

i.MX6 and MA98357a with simple-audio-card

Jump to solution
7,565 Views
lynix
Contributor II

We're trying to hook up a MAX98357a Amp/Codec to an i.MX 6Solo using the 'simple-audio-card' device tree abstraction. We see no errors in dmesg and the ALSA device is visible, we can play audio files using 'aplay' but speakers remain silent.

Using a scope we see that data is transmitted over the I2S interface but clock lines remain silent. We also tried the solution using 'imx-pt10ex' driver instead of simple-audio-card, as suggested in #384918, but this yielded the opposite behaviour: clocks turn on and off but not data transmitted.

The Amp/Codec is hooked up as I2S slave on Port 3. We're using the following DTS (only relevant parts):

codec: max98357a@0 {
    compatible = "maxim,max98357a";
    #sound-dai-cells = <0>;
};

sound {
    compatible = "simple-audio-card";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_audmux>;
    simple-audio-card,name = "TI3 Audio";
    simple-audio-card,format = "i2s";
    simple-audio-card,widgets = "Speaker", "Speakers";
    simple-audio-card,routing = "Speakers", "Speaker";
    simple-audio-card,bitclock-master = <&cpu_dai>;
    simple-audio-card,frame-master = <&cpu_dai>;
    cpu_dai: simple-audio-card,cpu {
        sound-dai = <&ssi1 0>;
    };
    codec_dai: simple-audio-card,codec {
        sound-dai = <&codec>;
    };
};

&audmux {
    status = "okay";

    ssi0 {
        fsl,audmux-port = <MX31_AUDMUX_PORT1_SSI0>;
        fsl,port-config = <
                (IMX_AUDMUX_V2_PTCR_SYN |
                IMX_AUDMUX_V2_PTCR_TFSDIR |
                IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT3_SSI_PINS_3) |
                IMX_AUDMUX_V2_PTCR_TCLKDIR |
                IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT3_SSI_PINS_3))
                IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT3_SSI_PINS_3)
            >;
    };

    aud3 {
        fsl,audmux-port = <MX31_AUDMUX_PORT3_SSI_PINS_3>;
        fsl,port-config = <
                IMX_AUDMUX_V2_PTCR_SYN
                IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0)
            >;
    };
};

&ssi1 {
    fsl,mode = "i2s-master";
    status = "okay";
};

(I know 'ssi0' in audmux and 'ssi1' look inconsistent, however we had a different codec running fine with these definitions so we just kept them.)

Any ideas or advice what might be wrong? Thanks in advance!

Labels (4)
0 Kudos
1 Solution
4,573 Views
lynix
Contributor II

Thanks for the hint regarding SSI clock generation.

Well, I got it basically working now, with the following device tree entries:

codec: max98357a@0 {
    compatible = "maxim,max98357a";
    #sound-dai-cells = <0>;
};

sound {
    compatible = "simple-audio-card";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_audmux>;
    simple-audio-card,name = "TI3 Audio";
    simple-audio-card,format = "i2s";
    simple-audio-card,widgets = "Speaker", "Speakers";
    simple-audio-card,routing = "Speakers", "Speaker";
    simple-audio-card,bitclock-master = <&cpu_dai>;
    simple-audio-card,frame-master = <&cpu_dai>;
    cpu_dai: simple-audio-card,cpu {
        sound-dai = <&ssi1>;
        system-clock-frequency = <883200>;
        dai-tdm-slot-num = <2>;
        dai-tdm-slot-width = <16>;
    };
    codec_dai: simple-audio-card,codec {
        sound-dai = <&codec>;
    };
};

&audmux {
    status = "okay";

    // Note: 'ssi1' (node of first SSI) corresponds to '_SSI0' below.

    ssi1 {
        fsl,audmux-port = <MX31_AUDMUX_PORT1_SSI0>;
        fsl,port-config = <
            0x00000000
            IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT3_SSI_PINS_3)
        >;
    };

    aud3 {
        fsl,audmux-port = <MX31_AUDMUX_PORT3_SSI_PINS_3>;
        fsl,port-config = <
            (IMX_AUDMUX_V2_PTCR_TFSDIR |
             IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT1_SSI0) |
             IMX_AUDMUX_V2_PTCR_TCLKDIR |
             IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT1_SSI0))
             IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0)
            >;
    };
};

&ssi1 {
    fsl,mode = "i2s-master";
    assigned-clocks = <&clks IMX6QDL_CLK_SSI1_SEL>, <&clks IMX6QDL_CLK_SSI1>;
    assigned-clock-parents = <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <0>, <49152000>; // 48kHz on SSI1 clock
    status = "okay";
};

The only thing that I don't understand about this is why I need to set the system clock of the CPU DAI to <883200> in order to get an LRCLK of 48 kHz.

View solution in original post

0 Kudos
4 Replies
4,574 Views
brobin
Contributor I

I had some trouble getting the sound card (MA98357a codec with the simple-audio-card) to work with a recent revision of the imx6q (i.MX 6 Quad), so I am sharing my solution, posted here: linux device driver - Audio issue with IMX6 board (max98357a codec) - Stack Overflow 

0 Kudos
4,574 Views
lynix
Contributor II

Thanks for the hint regarding SSI clock generation.

Well, I got it basically working now, with the following device tree entries:

codec: max98357a@0 {
    compatible = "maxim,max98357a";
    #sound-dai-cells = <0>;
};

sound {
    compatible = "simple-audio-card";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_audmux>;
    simple-audio-card,name = "TI3 Audio";
    simple-audio-card,format = "i2s";
    simple-audio-card,widgets = "Speaker", "Speakers";
    simple-audio-card,routing = "Speakers", "Speaker";
    simple-audio-card,bitclock-master = <&cpu_dai>;
    simple-audio-card,frame-master = <&cpu_dai>;
    cpu_dai: simple-audio-card,cpu {
        sound-dai = <&ssi1>;
        system-clock-frequency = <883200>;
        dai-tdm-slot-num = <2>;
        dai-tdm-slot-width = <16>;
    };
    codec_dai: simple-audio-card,codec {
        sound-dai = <&codec>;
    };
};

&audmux {
    status = "okay";

    // Note: 'ssi1' (node of first SSI) corresponds to '_SSI0' below.

    ssi1 {
        fsl,audmux-port = <MX31_AUDMUX_PORT1_SSI0>;
        fsl,port-config = <
            0x00000000
            IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT3_SSI_PINS_3)
        >;
    };

    aud3 {
        fsl,audmux-port = <MX31_AUDMUX_PORT3_SSI_PINS_3>;
        fsl,port-config = <
            (IMX_AUDMUX_V2_PTCR_TFSDIR |
             IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT1_SSI0) |
             IMX_AUDMUX_V2_PTCR_TCLKDIR |
             IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT1_SSI0))
             IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0)
            >;
    };
};

&ssi1 {
    fsl,mode = "i2s-master";
    assigned-clocks = <&clks IMX6QDL_CLK_SSI1_SEL>, <&clks IMX6QDL_CLK_SSI1>;
    assigned-clock-parents = <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <0>, <49152000>; // 48kHz on SSI1 clock
    status = "okay";
};

The only thing that I don't understand about this is why I need to set the system clock of the CPU DAI to <883200> in order to get an LRCLK of 48 kHz.

0 Kudos
4,574 Views
vladzouth
Contributor II

Hi Alexander,

I am implementing the max98357a codec on an imx6s as you. Thank you for this guide. It help me to write the right thing on my device-tree files. After booting my linux OS, it finds no soundcards on the system. Can you give me some advice to complete implementation. I activated the driver of the codec and choose simple-audio-card on the kernel menuconfig but i did see a soundcard yet.

Thanks you in advance ! 

SC

0 Kudos
4,574 Views
igorpadykov
NXP Employee
NXP Employee

Hi Alexander

one can check dts "assigned-clocks" for SSIn as in example on:

[alsa-devel] Simple-card without codec for testing purpose 

Check what mode is used, master or slave, in latter case clock should be

provided from external codec. Also one can check with jtag ssi registers

using sect.61.8.4.1 SSI Clock and Frame Sync Generation i.MX6SDL Reference Manual

http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6SDLRM.pdf

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos