MAX98357A audio on i.MX8M Plus

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

MAX98357A audio on i.MX8M Plus

Jump to solution
2,614 Views
MicMoba
Contributor V

I am trying to interface a max98357a audio codec to an i.MX8M Plus EVK running Linux. I made a breakout board to get the SAI pins from the audio connector. The codec seems to register correctly as a sound card using the simple-card driver, but I can't see any activity on the SAI3_BCLK line.

aplay -l

**** List of PLAYBACK Hardware Devices ****

card 0: MAX98357A [SAI3 MAX98357A], device 0: 30c30000, sai-HiFi HiFi-0 []

  Subdevices: 1/1

  Subdevice #0: subdevice #0

cat /proc/asound/cards

0 [MAX98357A      ]: SAI3_MAX98357A  - SAI3 MAX98357A

                                 SAI3 MAX98357A

 

I can't see any activity on the BCLK line when I use speaker-test or aplay test.wav

 

 

#include "imx8mp.dtsi"

/ {
	codec: max98357a {
		compatible = "maxim,max98357a";
		#sound-dai-cells = <0>;
		sdmode-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
	};
	sound {
		compatible = "simple-audio-card";
		pinctrl-names = "default";
		pinctrl-0 = <&sdmode_en>;
		simple-audio-card,name = "SAI3 MAX98357A";
		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 = <&sai3>;
		};
		codec_dai: simple-audio-card,codec {
			sound-dai = <&codec>;
		};
	};
};

&sai3 {
        #saund-dai-cells = <0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_sai3>;
	status = "okay";
        fsl,sai-asynchronous;
};

&sdma2 {
   status = "okay";
};

&iomuxc {
	imx8mm-som {
		pinctrl_sai3: sai3grp {
			fsl,pins = <
				MX8MP_IOMUXC_SAI3_TXFS_AUDIOMIX_SAI3_TX_SYNC     0xd6
				MX8MP_IOMUXC_SAI3_TXC_AUDIOMIX_SAI3_TX_BCLK      0xd6
				MX8MP_IOMUXC_SAI3_TXD_AUDIOMIX_SAI3_TX_DATA00     0xd6
			>;
		};
		sdmode_en: sdmodegrp {
			fsl,pins = <
				MX8MP_IOMUXC_SAI3_RXFS_GPIO4_IO28	0x26
			>;
		};
	};
};

 

0 Kudos
1 Solution
2,560 Views
MicMoba
Contributor V

I solved my issue.

There were two clock entries missing in the sai3 section.

&sai3 {
	#saund-dai-cells = <0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_sai3>;
	clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_IPG>, <&clk IMX8MP_CLK_DUMMY>, <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1>, <&clk IMX8MP_CLK_DUMMY>, <&clk IMX8MP_CLK_DUMMY>, <&clk IMX8MP_AUDIO_PLL1_OUT>, <&clk IMX8MP_AUDIO_PLL2_OUT>;
	clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
	assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
	assigned-clock-parents = <&clk IMC8MP_AUDIO_PLL2_OUT>;
	assigend-clock-rates = <183456000>;
	fsl,sai-asynchronous;
	status = "okay";
};

Now I can play wav, mp3, mp4

aplay test.wav

gst-launch-1.0 playbin uri=file:///video.mp4

gst-launch-1.0 playbin uri=file:///audio.mp3

 

View solution in original post

0 Kudos
9 Replies
2,572 Views
MicMoba
Contributor V

Here my final DT.

#include "imx8mp.dtsi"

/ {
	codec: max98357a {
		compatible = "maxim,max98357a";
		#sound-dai-cells = <0>;
		sdmode-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
	};
	sound {
		compatible = "simple-audio-card";
		pinctrl-names = "default";
		pinctrl-0 = <&sdmode_en>;
		simple-audio-card,name = "SAI3 MAX98357A";
		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 = <&sai3>;
		};
		codec_dai: simple-audio-card,codec {
			sound-dai = <&codec>;
			clocks = <&clk IMX8MP_CLK_SAI3>;
		};
	};
};

&sai3 {
	#saund-dai-cells = <0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_sai3>;
	assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
	assigned-clock-parents = <&clk IMC8MP_AUDIO_PLL2_OUT>;
	assigend-clock-rates = <183456000>;
	fsl,sai-asynchronous;
	status = "okay";
};

&sdma2 {
   status = "okay";
};

&iomuxc {
	imx8mm-som {
		pinctrl_sai3: sai3grp {
			fsl,pins = <
				MX8MP_IOMUXC_SAI3_TXFS_AUDIOMIX_SAI3_TX_SYNC     0x106
				MX8MP_IOMUXC_SAI3_TXC_AUDIOMIX_SAI3_TX_BCLK      0x106
				MX8MP_IOMUXC_SAI3_TXD_AUDIOMIX_SAI3_TX_DATA00     0x106
			>;
		};
		sdmode_en: sdmodegrp {
			fsl,pins = <
				MX8MP_IOMUXC_SAI3_RXFS_GPIO4_IO28	0x166
			>;
		};
	};
};

Now I can playback wav-files with aplay.

A further issue is that I only can playback one file. After the playback finished and I want to playback the file again I get the error message that fsl-asi 30c30000.sai is failed to derive required TX rate of 1411200. The only way to get it work is to reset my board.

0 Kudos
2,561 Views
MicMoba
Contributor V

I solved my issue.

There were two clock entries missing in the sai3 section.

&sai3 {
	#saund-dai-cells = <0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_sai3>;
	clocks = <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_IPG>, <&clk IMX8MP_CLK_DUMMY>, <&audiomix_clk IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1>, <&clk IMX8MP_CLK_DUMMY>, <&clk IMX8MP_CLK_DUMMY>, <&clk IMX8MP_AUDIO_PLL1_OUT>, <&clk IMX8MP_AUDIO_PLL2_OUT>;
	clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
	assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
	assigned-clock-parents = <&clk IMC8MP_AUDIO_PLL2_OUT>;
	assigend-clock-rates = <183456000>;
	fsl,sai-asynchronous;
	status = "okay";
};

Now I can play wav, mp3, mp4

aplay test.wav

gst-launch-1.0 playbin uri=file:///video.mp4

gst-launch-1.0 playbin uri=file:///audio.mp3

 

0 Kudos
2,593 Views
MicMoba
Contributor V

After I add "clocks" to my codec_dai section I can see some frequency at the pins BCLK, LRCLK and DIN.

 

 

   ...
   codec_dai: simple-audio-card,codec {
      sound-dai = <&codec>;
      clocks = <&clk IMX8MP_CLK_SAI3>;
   };
   ...

 

 

When I start speaker-test I can measure the following frequencies:

BCLK = 187,4kHz

LRCLK = 5,86kHz

DIN = 8-48kHz

So the LRCLK is BCLK divided by 32. That is in my opinion correct. But I can't hear any sound out of the speaker.

 

0 Kudos
2,597 Views
MicMoba
Contributor V

Hello weidong_sun,

thanks for reply. I did the widgets and routing in the DT.

 

 

      ...
      simple-audio-card,widgets = "Speaker","Speakers";
      simple-audio-card,routing = "Speakers", "Speaker";
      ...

 

 

I think it is correct. My codec offers the sink "Speaker", isn't it?

 

 

static const struct snd_soc_dapm_widget max98357a_dapm_widgets[] = {
	SND_SOC_DAPM_OUTPUT("Speaker"),
};

static const struct snd_soc_dapm_route max98357a_dapm_routes[] = {
	{"Speaker", NULL, "HiFi Playback"},
};

 

 

I am thinking about the frequencies. In every example that I saw they use system-clock-frequency. But the DT documentation for simple-audio-card doesn't know that item. Is it only for SSI interface and SAI will do that on its own?

 

Thanks

0 Kudos
2,586 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi,

BCLK = 187,4kHz

LRCLK = 5,86kHz

DIN = 8-48kHz

 

do you konw the sample rate of your test.wav?   586KHZ?

 

Weidong

0 Kudos
2,582 Views
MicMoba
Contributor V

I use speaker-test and it puts out a rate of 48000Hz.

Stream parameters are 48000Hz, S16_LE, 1 channel

I also saw that the LRCLK was to low. The datasheet of MAX98357 says 7.6 to 8.4 kHz. The SAI3 CLK has 24MHz.

cat /sys/kernel/debug/clk/clk_summary | grep sai

So there is a factor of 130 between SAI3 clk and the BCLK. I assume that there is something wrong with the clocks.

0 Kudos
2,580 Views
MicMoba
Contributor V

I got my first sound

I add a assigned-clock-parents item to my sai-section

&sai3 {
   #sound-dai-cells = <0>;
   pinctrl-names = "default";
   pinctrl-0 = <&pinctrl_sai3>;
   status = "okay";
   assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
   assigend-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
   fsl,sai-synchronous;
};

 

0 Kudos
2,575 Views
weidong_sun
NXP TechSupport
NXP TechSupport

OK, got it.

good job!

 

0 Kudos
2,607 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi,

    The following are my suggestions:
1. You'd better write a machine driver yourself.
2. single audio card driver
After checking your sound node, it seems that widget and routing are missing. This may be the root cause of the speaker's failure to output audio. Something like this:
simple-audio-card,widgets =
"Microphone", "Microphone Jack",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"MIC1", "Microphone Jack",
"MIC2", "Microphone Jack",
"Microphone Jack", "micbias1",
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
Yours may be different from the above, you need to determine them according to the widget and routing in the codec driver. 

 

Hope above messages are helpful to you.

Have a nice day!

B.R,

weidong

0 Kudos