The i.MX95 provides five transmit/receive Serial Audio Interfaces (SAI).

On the ConnectCore 95 Development Kit, the SAI3 interface is connected to a Maxim 98089 low-power stereo codec with the following features:

  • Analog inputs: line-in A, line-in B, microphone:

    • Two line-in audio inputs through the LINE1_IN_L/R and LINE2_IN_L/R lines in the expansion connector.

    • Microphone audio input through the on-board jack connector.

  • Analog outputs: line-out, headphone, speakers:

    • Line-out audio output through the LINE_OUT_L/R lines in the expansion connector.

    • Headphone audio output through the on-board jack connector.

    • Speaker audio output through the SPKL_P/N and SPKR_P/N lines in the expansion connector.

  • Digital input/out multi-format audio interface.

  • Digital processing, filters, volume control, amplifiers.

The codec is a slave chip that the CPU controls via the SAI3 port of the ConnectCore 95 system-on-chip. The CPU drives audio data using the inter-IC sound bus standard (I2S).

All audio output comes out through this codec and can be reproduced using a pair of speakers or headphones.

Kernel configuration

You can manage the audio driver support through the following kernel configuration options:

  • Generic ASoC Sound Card with ASRC support (CONFIG_SND_SOC_FSL_ASOC_CARD)

  • Maxim MAX98088/9 Low-Power, Stereo Audio Codec (CONFIG_SND_SOC_MAX98088)

These options are enabled as built-in on the default ConnectCore 95 kernel configuration file.

Kernel driver

The drivers for the audio interface and MAX98089 codec are located at:

File Description

sound/soc/fsl/fsl_sai.c

SAI driver

sound/soc/fsl/fsl-asoc-card.c

Generic ASoC Sound Card with ASRC support

sound/soc/codecs/max98088.c

Maxim MAX98088/9 Low-Power, Stereo Audio Codec

Device tree bindings and customization

The SAI interface is documented at Documentation/devicetree/bindings/sound/fsl,sai.yaml.

The interface between the SAI and the codec is documented at Documentation/devicetree/bindings/sound/fsl-asoc-card.txt.

The MAX98088/9 codec is documented at Documentation/devicetree/bindings/sound/max98088.txt.

The device tree must contain entries for:

  • The SAI interface

  • The interface between the SAI and the audio codec

  • The audio codec

Example: SAI3 on ConnectCore 95 Development Kit

Definition of the SAI

i.MX95 device tree
sai3: sai@42650000 {
	compatible = "fsl,imx95-sai";
	reg = <0x42650000 0x10000>;
	interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>, <&dummy>,
		<&scmi_clk IMX95_CLK_SAI3>, <&dummy>,
		<&dummy>;
	clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
	dmas = <&edma2 61 0 1>, <&edma2 60 0 0>;
	dma-names = "rx", "tx";
	status = "disabled";
};
ConnectCore 95 Development Kit device tree
/* Audio interface */
&sai3 {
	pinctrl-names = "default","sleep";
	pinctrl-0 = <&pinctrl_sai3>;
	pinctrl-1 = <&pinctrl_sai3_sleep>;
	assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
			  <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
			  <&scmi_clk IMX95_CLK_AUDIOPLL1>,
			  <&scmi_clk IMX95_CLK_AUDIOPLL2>,
			  <&scmi_clk IMX95_CLK_SAI3>;
	assigned-clock-parents = <0>, <0>, <0>, <0>,
				 <&scmi_clk IMX95_CLK_AUDIOPLL1>;
	assigned-clock-rates = <3932160000>,
			       <3612672000>, <393216000>,
			       <361267200>, <12288000>;
	fsl,sai-mclk-direction-output;
	status = "okay";
};
	[...]
/* Audio Interface */
pinctrl_sai3: sai3grp {
	fsl,pins = <
		IMX95_PAD_GPIO_IO17__SAI3_MCLK				0x31e
		IMX95_PAD_GPIO_IO16__SAI3_TX_BCLK			0x31e
		IMX95_PAD_GPIO_IO26__SAI3_TX_SYNC			0x31e
		IMX95_PAD_GPIO_IO20__SAI3_RX_DATA_BIT0		0x31e
		IMX95_PAD_GPIO_IO21__SAI3_TX_DATA_BIT0		0x31e
	>;
};

pinctrl_sai3_sleep: sai3grpsleep {
	fsl,pins = <
		IMX95_PAD_GPIO_IO17__GPIO2_IO_BIT17			0x200
		IMX95_PAD_GPIO_IO16__GPIO2_IO_BIT16			0x200
		IMX95_PAD_GPIO_IO26__GPIO2_IO_BIT26			0x200
		IMX95_PAD_GPIO_IO20__GPIO2_IO_BIT20			0x200
		IMX95_PAD_GPIO_IO21__GPIO2_IO_BIT21			0x200
	>;
};

Interface between SAI and audio codec

ConnectCore 95 Development Kit device tree
sound_max98089: sound-max98089 {
	compatible = "fsl,imx-audio-max98088";
	model = "max98088-audio";
	audio-cpu = <&sai3>;
	audio-codec = <&max98089>;
	audio-routing =
		"Headphone Jack", "HPL",
		"Headphone Jack", "HPR",
		"Ext Spk", "SPKL",
		"Ext Spk", "SPKR",
		"Line Out Jack", "RECL",
		"Line Out Jack", "RECR",
		"Mic Jack", "MIC2",
		"Line In Jack", "INA1",
		"Line In Jack", "INA2",
		"Line In Jack", "INB1",
		"Line In Jack", "INB2";
};

Audio codec (LPI2C4 slave)

ConnectCore 95 Development Kit device tree
&lpi2c4 {
	max98089: codec@10 {
		compatible = "maxim,max98089";
		reg = <0x10>;
		clocks = <&scmi_clk IMX95_CLK_SAI3>;
		clock-names = "mclk";
		dvdd-supply = <&reg_vdd_1v8_dummy>;
	};
};

Use the audio interface

Audio controls

The audio codec is controlled from Linux via the ALSA framework. Digi Embedded Yocto provides an initial configuration that enables:

  • Line in A

  • Line in B

  • Microphone

  • Headphones

  • Speakers

  • Line out

You can use the command line application alsamixer to manage these interfaces and their associated controls such as volume, gain, and filters.

Audio playback

Since all output routes are enabled by default, any sound will play on headphones, speakers, and line-out.

To play a wav file:

# aplay sound.wav

To play an mp3 file using gstreamer:

# gst-launch-1.0 filesrc location=sound.mp3 ! id3demux ! queue ! beepdec ! alsasink

Audio recording

Since microphone, line-in A, and line-in B input routes are enabled by default, any recorded sound will mix the audio coming from these inputs.

To record a stereo WAV audio file with 10 seconds duration from line-in:

# arecord -f cd sound.wav --duration 10

To record a mono WAV audio file from the microphone:

# arecord --format=S16_LE --channels=1 --rate=44100 micro.wav --duration=10