The {cpu-family} provides three Serial Audio Interfaces (SAI).
On the ConnectCore 6UL SBC Pro, the SAI2 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 LINE_IN_A_ and LINE_IN_B_ lines of the AUDIO and SPK connectors. 
- 
Microphone audio input through the MIC_ lines of the AUDIO connector. 
 
- 
- 
Analog outputs: line-out, headphone, speakers: - 
Line-out audio output through the LINE_OUT_ lines of the AUDIO connector. 
- 
Headphone audio output through the on-board jack connector. 
- 
Speaker audio output through the SPKL_ and SPKR_ lines of the SPK 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 SAI2 port of the ConnectCore 6UL 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:
- 
SoC Audio for NXP i.MX CPUs ( CONFIG_SND_IMX_SOC)
- 
SoC Audio support for i.MX boards with max98088/max98089 ( CONFIG_SND_SOC_IMX_MAX98088)
These options are enabled as built-in on the default ConnectCore 6UL kernel configuration file.
Kernel driver
The drivers for the audio interface and MAX98089 codec are located at:
| File | Description | 
|---|---|
| SAI driver | |
| Driver interface with codec | |
| MAX98088/9 codec driver | 
Device tree bindings and customization
The SAI interface is documented at
Documentation/devicetree/bindings/sound/fsl-sai.txt.
The interface between the SAI and the codec is documented at
Documentation/devicetree/bindings/sound/imx-audio-max98088.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: SAI2 on ConnectCore 6UL SBC Pro
Definition of the SAI
[...]
sai2: sai@0202c000 {
	#sound-dai-cells = <0>;
	compatible = "fsl,imx6ul-sai", "fsl,imx6sx-sai";
	reg = <0x0202c000 0x4000>;
	interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&clks IMX6UL_CLK_SAI2_IPG>,
		 <&clks IMX6UL_CLK_DUMMY>,
		 <&clks IMX6UL_CLK_SAI2>,
		 <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>;
	clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
	dmas = <&sdma 37 24 0>,
	       <&sdma 38 24 0>;
	dma-names = "rx", "tx";
	status = "disabled";
};
[...]&sai2 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&pinctrl_sai2>;
	pinctrl-1 = <&pinctrl_sai2_sleep>;
	assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
			  <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>,
			  <&clks IMX6UL_CLK_SAI2>;
	assigned-clock-rates = <0>, <786432000>, <12288000>;
	assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
	status = "okay";
};
[...]
&iomuxc {
	[...]
	imx6ul-ccimx6ul {
		[...]
		pinctrl_sai2: sai2grp {
			fsl,pins = <
				MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA	0x11088
				MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA	0x11088
				MX6UL_PAD_JTAG_TMS__SAI2_MCLK		0x17088
				MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK	0x17088
				MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC	0x17088
				/* Interrupt */
				MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07	0x80000000
			>;
		};
		pinctrl_sai2_sleep: sai2grp_sleep {
			fsl,pins = <
				MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15	0x3000
				MX6UL_PAD_JTAG_TCK__GPIO1_IO14		0x3000
				MX6UL_PAD_JTAG_TMS__GPIO1_IO11		0x3000
				MX6UL_PAD_JTAG_TDO__GPIO1_IO12		0x3000
				/* Interrupt */
				MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07	0x3000
			>;
		};
	};
};Interface between SAI and audio codec
[...]
sound_max98089: sound-max98089 {
	compatible = "fsl,imx-audio-max98088";
	model = "imx-max98088";
	cpu-dai = <&sai2>;
	audio-codec = <&max98089>;
	asrc-controller = <&asrc>;
	gpr = <&gpr>;
	audio-routing =
		"Headphone Jack", "HPL",
		"Headphone Jack", "HPR",
		"Ext Spk", "SPKL",
		"Ext Spk", "SPKR",
		"LineOut", "RECL",
		"LineOut", "RECR",
		"Mic1", "MIC1",
		"Mic2", "MIC2",
		"LineInA", "INA1",
		"LineInA", "INA2",
		"LineInB", "INB1",
		"LineInB", "INB2";
	status = "okay";
};
[...]Audio codec (I2C1 slave)
&i2c1 {
	[...]
	max98089: codec@10 {
		compatible = "maxim,max98089";
		reg = <0x10>;
		clocks = <&clks IMX6UL_CLK_SAI2>;
		clock-names = "mclk";
		interrupt-parent = <&gpio5>;
		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
		status = "okay";
	};
	[...]
};Using 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 (volumes, gains, 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.wavTo play an mp3 file using gstreamer:
# gst-launch-1.0 filesrc location=sound.mp3 ! id3demux ! queue ! beepdec ! alsasinkAudio 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 10To record a mono WAV audio file from the microphone:
# arecord --format=S16_LE --channels=1 --rate=44100 micro.wav --duration=10 
         
   
   
        