The STM32MP15 provides three Inter-IC sound Interfaces (I2S).
On the ConnectCore MP15 Development Kit, the I2S2 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 I2S2 port of the ConnectCore MP15 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 STM32 I2S interface (SPI/I2S block) support (
CONFIG_SND_SOC_STM32_I2S) -
SoC Audio support for STM32 boards with max98088/max98089 (
CONFIG_SND_SOC_STM32_MAX98088)
These options are enabled as built-in on the default ConnectCore MP15 kernel configuration file.
Kernel driver
The drivers for the audio interface and MAX98089 codec are located at:
| File | Description |
|---|---|
I2S driver |
|
ASoC simple sound card driver |
|
MAX98088/9 codec driver |
Device tree bindings and customization
The I2S interface is documented at
Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml.
The device tree must contain entries for:
-
The I2S interface
-
The interface between the SAI and the audio codec
-
The audio codec
Example: I2S2 on ConnectCore MP15 Development Kit
Definition of the I2S
[...]
i2s2: audio-controller@4000b000 {
compatible = "st,stm32h7-i2s";
#sound-dai-cells = <0>;
reg = <0x4000b000 0x400>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dmamux1 39 0x400 0x01>,
<&dmamux1 40 0x400 0x01>;
dma-names = "rx", "tx";
status = "disabled";
};
[...]
&i2s2 {
#clock-cells = <0>;
#sound-dai-cells = <0>;
clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
clock-names = "pclk", "i2sclk", "x8k", "x11k";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&ccmp15_i2s2_pins_a>;
pinctrl-1 = <&ccmp15_i2s2_sleep_pins_a>;
digi,i2s-master;
status = "okay";
};
[...]
&pinctrl {
[...]
ccmp15_i2s2_pins_a: i2s2-0 {
pins {
pinmux = <STM32_PINMUX('I', 3, AF5)>, /* I2S2_SDO */
<STM32_PINMUX('I', 2, AF5)>, /* I2S2_SDI */
<STM32_PINMUX('I', 0, AF5)>, /* I2S2_WS */
<STM32_PINMUX('C', 6, AF5)>, /* I2S2_MCK */
<STM32_PINMUX('I', 1, AF5)>; /* I2S2_CK */
slew-rate = <1>;
drive-push-pull;
bias-disable;
};
};
ccmp15_i2s2_sleep_pins_a: i2s2-sleep-0 {
pins {
pinmux = <STM32_PINMUX('I', 3, ANALOG)>, /* I2S2_SDO */
<STM32_PINMUX('I', 2, ANALOG)>, /* I2S2_SDI */
<STM32_PINMUX('I', 0, ANALOG)>, /* I2S2_WS */
<STM32_PINMUX('C', 6, ANALOG)>, /* I2S2_MCK */
<STM32_PINMUX('I', 1, ANALOG)>; /* I2S2_CK */
};
};
};
Interface between I2S and audio codec
[...]
sound_max98089: sound-max98089 {
compatible = "simple-audio-card";
simple-audio-card,name = "stm32max98088";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&cpu_dai>;
simple-audio-card,frame-master = <&cpu_dai>;
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";
cpu_dai: simple-audio-card,cpu {
sound-dai = <&{i2s_port}>;
system-clock-direction-out;
clocks = <&{clocks_spi_k}>;
};
codec_dai: simple-audio-card,codec {
sound-dai = <&max98089>;
};
};
[...]
Audio codec (i2c2 slave)
&i2c2 {
[...]
max98089: codec@10 {
compatible = "maxim,max98089";
reg = <0x10>;
clocks = <&rcc SPI2_K>;
clock-names = "mclk";
#sound-dai-cells = <0>;
#clock-cells = <0>;
status = "disabled";
};
[...]
};
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.wav
To play an mp3 file:
# mpg123 sound.mp3
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