Imx6ull with Max98357a

Hello!

I try to get an external codec (MAX98357A) running on the Colibri i.MX6ULL module, but until now with no success.

When I try to play something using the aplay, the program gets stuck, but listing the devices seems to work

root@colibri-imx6ull:/usr/share/sounds/alsa# ls /dev/snd/
by-path  controlC0  pcmC0D0p  timer
root@colibri-imx6ull:~# aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
sysdefault:CARD=max98357a
    max98357a,
    Default Audio Device

In the device tree,I edit the imx6ull-colibri file, I have the following settings to use SAI2 as output

// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright 2018 Toradex AG
*/

#include "imx6ull.dtsi"
#include "imx6ull-colibri-lcdif.dtsi"
#include <dt-bindings/pwm/pwm.h>

/ {
    aliases {
        ethernet0 = &fec2;
        ethernet1 = &fec1;
    };

    memory {
        reg = <0x80000000 0x10000000>;
    };

  ......

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

    sound {
        compatible = "simple-audio-card";
        simple-audio-card,name = "max98357a";
        simple-audio-card,format = "i2s";
        simple-audio-card,bitclock-master = <&dailink_master>;
        simple-audio-card,frame-master = <&dailink_master>;

        simple-audio-card,codec {
            sound-dai = <&codec_ext>;
            //clocks = <&clks IMX6UL_CLK_SAI2>;
        };
        
         dailink_master: simple-audio-card,cpu {
            sound-dai = <&sai2>;
        };
    };
};

&sai2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_sai2>;
    assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
              <&clks IMX6UL_CLK_SAI2>;
    assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <0>, <36864000>, <589824000>;
    fsl,sai-mclk-direction-output;
    status = "okay";
};

......

&iomuxc {
    imx6ull-colibri {
        pinctrl_adc1: adc1grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO00__GPIO1_IO00        0x3000 /* SODIMM 8 */
                MX6UL_PAD_GPIO1_IO01__GPIO1_IO01        0x3000 /* SODIMM 6 */
                MX6UL_PAD_GPIO1_IO08__GPIO1_IO08        0x3000 /* SODIMM 4 */
                MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x3000 /* SODIMM 2 */
            >;
        };

         ......

         pinctrl_sai2: sai2grp {
            fsl,pins = <
                MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK    0x17088
                MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC    0x17088
                MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA    0x11088
            >;
        };
      
       pinctrl_uart1_ctrl1: uart1-ctrl1-grp { /* Additional DTR, DCD */
                        fsl,pins = <
                                //MX6UL_PAD_JTAG_TDI__GPIO1_IO13          0x70a0 /* SODIMM 31 */
                                MX6UL_PAD_LCD_DATA18__GPIO3_IO23        0x10b0 /* SODIMM 29 */
                               //MX6UL_PAD_JTAG_TDO__GPIO1_IO12          0x90b1 /* SODIMM 23 */
                                MX6UL_PAD_LCD_DATA19__GPIO3_IO24        0x10b0 /* SODIMM 37 */
                        >;
         };

         pinctrl_gpio1: gpio1-grp {
                        fsl,pins = <
                                MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25     0x10b0 /* SODIMM 77 */
                                MX6UL_PAD_JTAG_TCK__GPIO1_IO14          0x70a0 /* SODIMM 99 */
                                MX6UL_PAD_NAND_CE1_B__GPIO4_IO14        0x10b0 /* SODIMM 133 */
                                MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24     0x10b0 /* SODIMM 135 */
                                MX6UL_PAD_UART3_CTS_B__GPIO1_IO26       0x10b0 /* SODIMM 100 */
                               //MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15       0x70a0 /* SODIMM 102 */
                                MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07       0x10b0 /* SODIMM 104 */
                                MX6UL_PAD_UART3_RTS_B__GPIO1_IO27       0x10b0 /* SODIMM 186 */
                        >;
         };

    }; /* imx6ull { */
};

If I now try to play some audio, I get the following error:

root@colibri-imx6ull:/usr/share/sounds/alsa# aplay Front_Right.wav
[  670.576389] fsl-sai 202c000.sai: failed to derive required Tx rate: 1411200
[  670.583621] fsl-sai 202c000.sai: ASoC: can't set 202c000.sai hw params: -22
ALSA lib ../../../alsa-lib-1.2.1.2/src/pcm/pcm_direct.c:1271:(snd1_pcm_direct_initialize_slave) unable to install hw params
ALSA lib ../../../alsa-lib-1.2.1.2/src/pcm/pcm_dmix.c:1101:(snd_pcm_dmix_open) unable to initialize slave

Hi @codygu , welcome to our Community. Could you share the codec schematic design so I can understand this issue better?

Hi @benjamin.tx ,following is the codec schematic design


Please try the following sound node in your device.

 sound {
    compatible = "simple-audio-card";
    simple-audio-card,name = "max98357a";
    simple-audio-card,format = "i2s";
    simple-audio-card,bitclock-master = <&dailink_master>;
    simple-audio-card,frame-master = <&dailink_master>;
	
	simple-audio-card,cpu {
		sound-dai = <&sai2>;
	};
	
	dailink_master: simple-audio-card,codec {
		sound-dai = <&codec_ext>;
		clocks = <&clks IMX6UL_CLK_SAI2>;
	};
	status = "okay";
    
};

Hi @benjamin.tx ,I tried the sound node.After compiling the device tree and re-burning,I get the following error:


root@colibri-imx6ull:~# aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
sysdefault:CARD=imx6ulmax98357a
    imx6ul-max98357a,
    Default Audio Device
root@colibri-imx6ull:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: imx6ulmax98357a [imx6ul-max98357a], device 0: 202c000.sai-HiFi HiFi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@colibri-imx6ull:~# aplay -vv test.wav
Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Plug PCM: Rate conversion PCM (44100, sformat=S16_LE)
Converter: linear-interpolation
Protocol version: 10002
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 2
  rate         : 48000
  exact rate   : 48000 (48000/1)
  msbits       : 16
  buffer_size  : 5760
  period_size  : 1920
  period_time  : 40000
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 1920
  period_event : 0
  start_threshold  : 5760
  stop_threshold   : 5760
  silence_threshold: 0
  silence_size : 0
  boundary     : 1509949440
Slave: Direct Stream Mixing PCM
Its setup is:
  stream       : PLAYBACK
  access       : MMAP_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 2
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 16
  buffer_size  : 5292
  period_size  : 1764
  period_time  : 40000
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 1764
  period_event : 0
  start_threshold  : 5292
  stop_threshold   : 5292
  silence_threshold: 0
  silence_size : 0
  boundary     : 1387266048
Hardware PCM card 0 'imx6ul-max98357a' device 0 subdevice 0
Its setup is:
  stream       : PLAYBACK
  access       : MMAP_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 2
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 16
  buffer_size  : 5292
  period_size  : 1764
  period_time  : 40000
  tstamp_mode  : ENABLE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 1764
  period_event : 0
  start_threshold  : 1
  stop_threshold   : 1387266048
  silence_threshold: 0
  silence_size : 1387266048
  boundary     : 1387266048
  appl_ptr     : 0
  hw_ptr       : 0
#+                                                 | 00%

When I enter cmd “alsamixer” ,the terminal shows “This sound device does not have any controls”
100

The following is boot log, I circled the error about the audio.

The reason AlsaMixer provides no control option is MAX98357 chip doesn’t come with any registry one can manipulate. Do you hear any sound when an audio file is played? Or you can even measure MAX98357’s output with an oscilloscope.

I hear no sound when an audio file is played.

root@colibri-imx6ull:~# aplay -vv test.wav
Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
  .....
  boundary     : 1387266048
  appl_ptr     : 0
  hw_ptr       : 0
###+                                               | 05%^

``

The progress bar seems to be stuck there

Please post the entire system log by the command journalctl -b 0 . This command can be executed after aplay -vv test.wav. You may have to kill(ctrl+c) aplay -vv test.wav if it gets stuck.

Please view the attachment.
log.txt (79.8 KB)

try to enable mclk pin for sai2 in the device tree.

Why? I did not connect this pin to Max98357a.How do I write the device tree?

Device Tree: add

MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x17088

under pinctrl_sai2: sai2grp

&iomuxc {
    imx6ull-colibri {
         ......

         pinctrl_sai2: sai2grp {
            fsl,pins = <
                MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK    0x17088
                MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC    0x17088
                MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA    0x11088
                MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x17088
            >;
        };
     ......
 };

Is that?

Hi @benjamin.tx, I tried to enable mclk pin, but still stuck.

yes. MX6UL_PAD_JTAG_TMS is used by backlight node in the default device tree if lcd is enabled.

It still dosen’t work.The test result is still the same as before.

I changed dts as following,but still unwork.

#include "imx6ull.dtsi"
#include "imx6ull-colibri-lcdif.dtsi"
#include <dt-bindings/pwm/pwm.h>

/ {
    aliases {
        ethernet0 = &fec2;
        ethernet1 = &fec1;
    };

    memory {
        reg = <0x80000000 0x10000000>;
    };

  ......

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

    sound {
        compatible = "simple-audio-card";
        simple-audio-card,name = "max98357a";
        simple-audio-card,format = "i2s";
        simple-audio-card,bitclock-master = <&dailink_master>;
        simple-audio-card,frame-master = <&dailink_master>;

        simple-audio-card,codec {
            sound-dai = <&codec_ext>;
        };
        
         dailink_master: simple-audio-card,cpu {
            sound-dai = <&sai2>;
            clocks = <&clks IMX6UL_CLK_SAI2>;
        };
    };
};

&sai2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_sai2>;
    assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
              <&clks IMX6UL_CLK_SAI2>;
    assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <0>, <12288000>;
    fsl,sai-mclk-direction-output;
    status = "okay";
};

......

&backlight {
	status = "disabled";
};

&iomuxc {
    imx6ull-colibri {
        pinctrl_adc1: adc1grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO00__GPIO1_IO00        0x3000 /* SODIMM 8 */
                MX6UL_PAD_GPIO1_IO01__GPIO1_IO01        0x3000 /* SODIMM 6 */
                MX6UL_PAD_GPIO1_IO08__GPIO1_IO08        0x3000 /* SODIMM 4 */
                MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x3000 /* SODIMM 2 */
            >;
        };

         ......

         pinctrl_sai2: sai2grp {
            fsl,pins = <
                MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK    0x17088
                MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC    0x17088
                MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA    0x11088
                MX6UL_PAD_JTAG_TMS__SAI2_MCLK        0x17088
            >;
        };
      
       pinctrl_uart1_ctrl1: uart1-ctrl1-grp { /* Additional DTR, DCD */
                        fsl,pins = <
                                //MX6UL_PAD_JTAG_TDI__GPIO1_IO13          0x70a0 /* SODIMM 31 */
                                MX6UL_PAD_LCD_DATA18__GPIO3_IO23        0x10b0 /* SODIMM 29 */
                               //MX6UL_PAD_JTAG_TDO__GPIO1_IO12          0x90b1 /* SODIMM 23 */
                                MX6UL_PAD_LCD_DATA19__GPIO3_IO24        0x10b0 /* SODIMM 37 */
                        >;
         };

         pinctrl_gpio1: gpio1-grp {
                        fsl,pins = <
                                MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25     0x10b0 /* SODIMM 77 */
                                MX6UL_PAD_JTAG_TCK__GPIO1_IO14          0x70a0 /* SODIMM 99 */
                                MX6UL_PAD_NAND_CE1_B__GPIO4_IO14        0x10b0 /* SODIMM 133 */
                                MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24     0x10b0 /* SODIMM 135 */
                                MX6UL_PAD_UART3_CTS_B__GPIO1_IO26       0x10b0 /* SODIMM 100 */
                               //MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15       0x70a0 /* SODIMM 102 */
                                MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07       0x10b0 /* SODIMM 104 */
                                MX6UL_PAD_UART3_RTS_B__GPIO1_IO27       0x10b0 /* SODIMM 186 */
                        >;
         };

    }; /* imx6ull { */
};