Skip to main content

I2S

1. Introduction

RM_IO (Rockchip Matrix IO) is a technology that allows flexible routing of low-speed peripheral signals, such as UART and I2C, to designated I/O pins via register configuration. It breaks the traditional constraint of binding functions to specific pins, supporting the free assignment of functions across multiple pins. Through software configuration, developers can change pin functions in real time without rewiring, thus saving hardware resources. Since this section involves a significant amount of kernel and device tree configuration, it is essential to have SDK compilation as a prerequisite. Please complete the learning and configuration of the "SDK Environment Setup" before proceeding to ensure foundational support for debugging and porting subsequent functional modules.

2. Audio Codec

An audio codec is a critical component for processing audio signals, enabling audio input and output. Common audio codecs in embedded systems and consumer electronics include ES8156 and ES7210. Each chip has different advantages depending on the application scenario. Below is an introduction to these two audio codecs:

  1. ES8156: A high-quality audio output codec, suitable for products such as smart speakers and Bluetooth speakers, focusing on high-quality audio output and decoding capabilities.

    ES7210: An audio input codec, suitable for voice recognition and audio recording applications, supporting various audio input interfaces, commonly found in voice recognition and wearable devices.

These audio codecs provide different functions and advantages in practical applications, offering audio input/output, signal processing, and high-quality audio transmission. To ensure smooth communication between these devices and the system, proper kernel driver and device tree configurations are crucial. Next, we will analyze the kernel and device tree configurations for these two audio codecs.

3. ES7210

3.1 Kernel Configuration

  1. Navigate to the SDK directory and execute the following command to open the configuration interface:

    ./build.sh kernel-config
  2. Search for SND_SOC_ES7210 in the kernel configuration and select it.

3.2 Device Tree Configuration

  1. Taking ES7210 as an example, ES7210 supports 4 MIC audio inputs. Add the following content to the kernel-6.1/arch/arm/boot/dts/rk3506g-luckfox-lyra.dts file (configure according to the actual board model and storage medium):

    /{
    es7210_sound: es7210-sound {
    status = "okay";
    compatible = "simple-audio-card";
    simple-audio-card,format = "i2s";
    simple-audio-card,mclk-fs = <256>;
    simple-audio-card,name = "rockchip-es7210";

    simple-audio-card,cpu {
    sound-dai = <&sai1>;
    };
    simple-audio-card,codec {
    sound-dai = <&es7210>;
    };
    };
    };
  2. I2C Configuration

    &i2c1 {
    status = "okay";
    pinctrl-names = "default";
    //clock-frequency = <5000>; // 5kHz for es8388
    pinctrl-0 = <&rm_io12_i2c1_scl &rm_io13_i2c1_sda>;

    es7210: es7210@40 {
    status = "okay";
    #sound-dai-cells = <0>;
    compatible = "ES7210_MicArray_0";
    reg = <0x40>;
    clocks = <&mclkout_sai1>;
    clock-names = "mclk";
    assigned-clocks = <&mclkout_sai1>;
    assigned-clock-rates = <12288000>;
    };
    };

    &pinctrl {
    rm_io13 {
    rm_io13_i2c1_sda: rm-io13-i2c1-sda {
    rockchip,pins =
    <0 RK_PB5 33 &pcfg_pull_up>;
    };
    };

    rm_io12 {
    rm_io12_i2c1_scl: rm-io12-i2c1-scl {
    rockchip,pins =
    <0 RK_PB4 32 &pcfg_pull_up>;
    };
    };
    };
  3. I2S Configuration

    &sai1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = < &rm_io8_sai1_mclk
    &rm_io7_sai1_sclk
    &rm_io6_sai1_lrck
    &rm_io5_sai1_sdi
    &rm_io4_sai1_sdo0>;
    };

4. ES8156

4.1 Kernel Configuration

  1. Download the kernel patch es8156 and integrate the ES8156 driver into the SDK kernel.

    git am 0001-add-es8156-driver.patch
  2. Navigate to the SDK directory and execute the following command to open the configuration interface:

    ./build.sh kernel-config
  3. Search for SND_SOC_ES8156 in the kernel configuration and select it.

4.2 Device Tree Configuration

  1. Taking ES8156 as an example, ES8156 supports stereo audio output.

        es8156_sound: es8156-sound {
    status = "okay";
    compatible = "simple-audio-card";
    simple-audio-card,format = "i2s";
    simple-audio-card,mclk-fs = <256>;
    simple-audio-card,name = "rockchip-es8156";
    simple-audio-card,widgets =
    "Speaker", "LOUT",
    "Speaker", "ROUT";
    simple-audio-card,routing =
    "SDIN", "Channel Select Mux",
    "Channel Select Mux", "DACL",
    "Channel Select Mux", "DACR",
    "DACL", "LOUT",
    "DACR", "ROUT",
    "SDOUT TRISTATE", "SDIN",
    "SDOUT", "SDOUT TRISTATE";
    simple-audio-card,cpu {
    sound-dai = <&sai1>;
    };
    simple-audio-card,codec {
    sound-dai = <&es8156>;
    };
    };
  2. I2C Configuration

    &i2c1 {
    status = "okay";
    pinctrl-names = "default";
    //clock-frequency = <5000>; // 5kHz for es8388
    pinctrl-0 = <&rm_io12_i2c1_scl &rm_io13_i2c1_sda>;

    es8156: es8156@8 {
    status = "okay";
    #sound-dai-cells = <0>;
    compatible = "everest,es8156";
    reg = <0x08>;
    clocks = <&mclkout_sai1>;
    clock-names = "mclk";
    assigned-clocks = <&mclkout_sai1>;
    assigned-clock-rates = <12288000>;
    };

    };

    &pinctrl {
    rm_io13 {
    rm_io13_i2c1_sda: rm-io13-i2c1-sda {
    rockchip,pins =
    <0 RK_PB5 33 &pcfg_pull_up>;
    };
    };

    rm_io12 {
    rm_io12_i2c1_scl: rm-io12-i2c1-scl {
    rockchip,pins =
    <0 RK_PB4 32 &pcfg_pull_up>;
    };
    };
    };
  3. I2S Configuration

    &sai1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = < &rm_io8_sai1_mclk
    &rm_io7_sai1_sclk
    &rm_io6_sai1_lrck
    &rm_io5_sai1_sdi
    &rm_io4_sai1_sdo0>;
    };

5. ES7210 和 ES8156

When registering drivers, a single I2S group can only bind to one sound card. If multiple chips share a single I2S group, multiple chip nodes need to be added to the device tree of the sound card.

 es8156_es7210_sound: es8156-es7210-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,name = "rockchip-es8156-es7210";
simple-audio-card,widgets =
"Speaker", "LOUT",
"Speaker", "ROUT";
simple-audio-card,routing =
"SDIN", "Channel Select Mux",
"Channel Select Mux", "DACL",
"Channel Select Mux", "DACR",
"DACL", "LOUT",
"DACR", "ROUT",
"SDOUT TRISTATE", "SDIN",
"SDOUT", "SDOUT TRISTATE";


simple-audio-card,dai-link@0 {
format = "i2s";
cpu {
sound-dai = <&sai1>;
};
codec {
sound-dai = <&es8156>;
};
};

simple-audio-card,dai-link@1 {
format = "i2s";
cpu {
sound-dai = <&sai1>;
};
codec {
sound-dai = <&es7210>;
};
};

};

6. Hardware Connections

  1. The hardware used for testing is the Waveshare Audio Driver HAT. Please refer to its Wiki for detailed information. The pinout is as follows:

ES8156

LyraAudio Driver HAT
3V3_OUTVDD_3V3
GNDGND
RM_IO12(SCL)X2A_I2C0_SCK
RM_IO13(SDA)X2A_I2C0_SDA
RM_IO8(SA1 MCLK)X2A_I2S1_MCLK_CON
RMI_O7(SA1 SCLK)X2A_I2S1_BCLK_CON
RM_IO6(SA1 LRCK)X2A_I2S1_LRCK_CON
RM_IO5(SA1 SDI)/
RM_IO4(SA1 SDO)X2A_I2S1_SPEAKER

ES7210

LyraAudio Driver HAT
3V3_OUTVDD_3V3
GNDGND
RM_IO12(SCL)X2A_I2C0_SCK
RM_IO13(SDA)X2A_I2C0_SDA
RM_IO8(SA1 MCLK)X2A_I2S1_MCLK_CON
RMI_O7(SA1 SCLK)X2A_I2S1_BCLK_CON
RM_IO6(SA1 LRCK)X2A_I2S1_LRCK_CON
RM_IO5(SA1 SDI)X2A_I2S0_SDIO
RM_IO4(SA1 SDO)/

ES8156&ES7210

LyraAudio Driver HAT
3V3_OUTVDD_3V3
GNDGND
RM_IO12(SCL)X2A_I2C0_SCK
RM_IO13(SDA)X2A_I2C0_SDA
RM_IO8(SA1 MCLK)X2A_I2S1_MCLK_CON
RMI_O7(SA1 SCLK)X2A_I2S1_BCLK_CON
RM_IO6(SA1 LRCK)X2A_I2S1_LRCK_CON
RM_IO5(SA1 SDI)X2A_I2S0_SDIO
RM_IO4(SA1 SDO)X2A_I2S1_SPEAKER

7. Basic Applications

7.1 Sound Card Configuration

  1. Check if the sound card is registered successfully.

    cat /proc/asound/cards
  2. View sound card devices.

    card 0: rockchipes8156e [rockchip-es8156-es7210], device 1: ff310000.sai-ES7210 4CH ADC 0 ES7210 4CH ADC 0-1 [ff310000.sai-ES7210 4CH ADC 0 ES7210 4CH ADC 0-1]
    Subdevices: 1/1
    Subdevice #0: subdevice #0
  3. Sound card driver directory:

    root@luckfox:~# ls -l /dev/snd/by-path/
    total 0
    lrwxrwxrwx 1 root root 12 Jan 1 00:00 platform-es8156-es7210-sound -> ../controlC0

7.2 Recording and Playback

  1. arecord will use the default sample rate. Typically, the default sample rate for arecord is 44100 Hz (44.1 kHz), which is the standard sample rate for CD audio.

    arecord -f cd -Dhw:0,1 -d 30 test.wav
    • Note: The audio card is card 0, and the device index is 1, so you should use -Dhw:0,1 in the command, rather than -Dhw:0 or -Dhw:1.
  2. Playback.

    aplay test.wav