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

sound/soc/stm/stm32_i2s.c

I2S driver

sound/soc/generic/simple-card.c

ASoC simple sound card driver

|sound/soc/codecs/max98088.c |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

.STM32MP15 device tree [source,code] ---- […​]

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"; };

[…​] ----

.ConnectCore MP15 Development Kit device tree [source,code,subs="+attributes"] …​. &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"; };

[…​] …​. [source,code,subs="+attributes"] …​. &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

.ConnectCore MP15 Development Kit device tree [source,code] ---- […​]

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 = <&i2s2>; system-clock-direction-out; clocks = <&rcc SPI2_K>; };

codec_dai: simple-audio-card,codec { sound-dai = <&max98089>; }; };

[…​] ----

=== Audio codec (i2c2 slave)

.ConnectCore MP15 Development Kit device tree [source,code,subs="+attributes"] ---- &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

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

To play a wav file:

[source,code,subs="+attributes"] …​. # aplay sound.wav …​.

To play an mp3 file:

[source,code,subs="+attributes"] …​. # mpg123 sound.mp3 …​.

=== Audio recording

[NOTE] 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:

[source,code,subs="+attributes"] …​. # arecord -f cd sound.wav --duration 10 …​.

To record a mono WAV audio file from the microphone:

[source,code,subs="+attributes"] …​. # arecord --format=S16_LE --channels=1 --rate=44100 micro.wav --duration=10 …​.