Audio
概述
音频部分处理音频的输入输出,即录音和音频播放。不同的音频通路支持不同的音频处理能力,MTT E300 平台主要有如下几种音频通路类型:
- Peri I2S + Audio codec
- Display I2S + Display DPTX
- USB 音频
- 蓝牙音频
- 其它
这一章说明在没有 Audio DSP 介入的情况下,Peri I2S + Audio codec 和 Display I2S + Display DPTX 相关的内容。Peri I2S + Audio codec 音频通路在硬件上,结构通常如下图:

Peri I2S + audio codec 音频通路的中心是外设 audio codec,它集成模数转换器 (ADC) 和数模转换器 (DAC),负责完成物理世界中的模拟信号和 SoC 可以处理的数字信号之间的转换,对于音频播放,它将音频采样转为电压以用于模拟输出,对于录音,它将来自模拟输入的电压信号转为一系列音频采样。Audio codec 通过连接器外接扬声器、耳机、麦克风和数字麦克风等器件,并根据需要驱动这些器件与外部物理世界交互。
功能描述
MTT E300 平台 Linux 系统音频部分软硬件技术栈如下图所示:

Linux 内核音频 ALSA 子系统 整体结构如下图:

音频通路
MTT E300 平台 audio codec 与 SoC 之间的连接包括几个部分:
I2S:数字音频接口 (DAI),SoC 的多个GPIO口复用为I2S功能。I2S负责在 SoC 和 audio codec 之间传输音频数据,对于播放,I2S将音频采样数据从 SoC 的DDR搬到 audio codec。对于录音,I2S将音频采样数据从 audio codec 搬到 SoC 的DDR。I2C(可选):SoC 的多个GPIO口复用为I2C总线功能。 SoC 通过I2C总线配置 audio codec,如 audio codec 的内部通路,音量等。是否需要通过I2C总线来配置,因具体的 audio codec 而异,一是对于一些简单的 audio codec,完全不需要配置接口,二是 audio codec 不一定通过I2C来配置,也可能通过SPI之类的总线来传递控制命令。INT(可选):SoC 的单个GPIO口复用为中断接口。 对于支持接入耳机的 audio codec,通过这个中断上报耳机插拔事件。REFCLK(可选):也称为MCLK,或 audio codec 的系统时钟。 audio codec 需要它来工作。SoC 的单个GPIO口复用为MCLK时钟输出。有些 audio codec 也可以使用I2S这样的数字音频接口的BCLK作为它们的时钟,无需 SoC 提供专门的MCLK。通常 audio codec 预期MCLK为BCLK的倍数,通常为采样率的倍数。- 供电(可选):SoC 的多个
GPIO口用来控制为 audio codec 供电。 根据硬件设计来决定是否有需要。具体 audio codec 支持的功能及特性,因板子设计的不同而不同。关于 Peri-I2S,MTT E300 平台共集成 8 个 Peri-I2S 接口,支持对每个I2S接口进行独立控制,其中I2S0和I2S1可以配置为联合模式,支持在TDM模式下传输 8 个声道的 RX 或者 8 个声道的 TX。
Peri-I2S
MTT E300 平台的 Peri-I2S 支持如下特性:
- 支持
I2S2~72 声道 TX 和 2 声道 RX 数据传输; - 支持
I2S0~1在TDM模式和I2S模式下 4 声道 TX 和 4 声道 RX 数据传输; - 支持
I2S0~1在TDM模式下 8 声道 TX 和 8 声道 RX 数据传输; - 支持单个
I2S配置为主模式(Master)和从模式(Slave); - 支持左对齐和右对齐,
PCM短帧和长帧模式; - 支持 16kHz、44.1kHz、48kHz、88.2kHz、96kHz、176.4kHz 和 192kHz 采样频率;
- 支持设备端 16bits、24bits 和 32bits 采样深度(注:12bit、20bit 不支持);
- 支持
I2S传输时钟SCLK固定为 32bit 数据传输; - 支持
TDM模式的固定 32bit 传输; - 支持
I2S0~1在联合模式下共 8 声道 TX 和 8 声道 RX 数据同步传输; - 支持通过
DMA读写 RX 和 TX 数据; - 8 个
I2S共用一个AXI接口的DMA控制器。
MTT E300 平台 Peri-I2S 的一些限制:
- 特定
I2S的 TX 和 RX 共用时钟,TX 和 RX 同时工作时,TX 和 RX 的参数配置必须完全一致,包括采样率、通道数和采样深度等; I2S不支持实时获取DMA数据传输过程中的读写指针,无法支持应用层基于定时器的数据传输调度,只能支持中断驱动的数据传输;DMA描述符 FIFO 无法复位。
Display I2S + Display DPTX
Display I2S + Display DPTX 音频通路只支持音频播放,不支持录音,在硬件上,结构如下图:

Display I2S + Display DPTX 音频通路类似于 Peri-I2S+极简 audio codec 的情况,Display DPTX 扮演 audio codec 的角色,但无需太多专门的控制,如 I2C,也无需 SoC 处理供电、提供参考时钟,或处理耳机插拔事件中断。MTT E300 平台中,Display I2S 和 Peri-I2S 是不同的 IP,MTT E300 平台共集成 6 个 Display I2S 接口,它们支持的特性如下:
- 采样深度灵活配置,范围从 16bits 至 32bits。
- 支持的采样率范围从 8KHz ~ 192KHz。
各个 Display I2S 接口和各个 Display DPTX 之间的对应关系如下:
| Display I2S | Display DPTX |
|---|---|
| I2S0 和 I2S1 | Display DPTX0 |
| I2S2 | Display DPTX1 |
| I2S3 | Display DPTX2 |
| I2S4 和 I2S5 | Display DPTX3 |
驱动程序提供对硬件能力的子集的支持。
MTT E300 Linux 内核音频设备驱动程序基于 ASoC 框架实现,涉及到的内核文件主要有如下这些:
| 文件路径 | 说明 |
|---|---|
sound/soc/m1000/m1000*i2s*_.csound/soc/m1000/m1000*i2s*_.hsound/soc/m1000/m1000*snd_irq.csound/soc/m1000/m1000_snd_irq.hsound/soc/m1000/m1000_snd_pcm.csound/soc/m1000/m1000_snd_pcm.hsound/soc/m1000/m1000_snd_regs.csound/soc/m1000/m1000_snd_regs.h | Peri I2S 驱动程序实现 |
sound/soc/m1000/m1000_disp_i2s*_.csound/soc/m1000/m1000*disp_i2s*_.h | Display I2S 驱动程序实现 |
sound/soc/m1000/m1000_snd_card_dummy_peri_drv.c | Dummy machine 驱动程序,供实现特定板子的 machine 驱动程序时参考 |
sound/soc/m1000/m1000_snd_card_dptx_drv.c | Display I2S + Display DPTX 音频通路 machine 驱动程序 |
sound/soc/m1000/m1000_snd_card_rt5672_drv.c | 基于 Realtek ALC5672 audio codec 的 machine 驱动程序,供参考 |
sound/soc/codecs/* | 内核主线代码中的 codec 驱动程序 |
Peri I2S 和 Display I2S 驱动程序实现为 ASoC 的 Platform 类驱动程序,codec 驱动程序实现为 ASoC 的 Codec 类驱动程序,声卡实现为 ASoC 的 Machine 类驱动程序。
API 说明
音频设备驱动程序通过 ALSA API 暴露给用户空间程序使用。
约束说明
Peri I2S + audio codec 音频通路:
- 播放和录音同时工作时,播放和录音的参数必须完全一致;
- 无法支持基于定时器的数据传输调度。
Display I2S + Display DPTX 音频通路的正常工作依赖于 Display DPTX 的正常工作。
配置流程
步骤 1:配置 Display I2S + Display DPTX
- 内核配置
- 设备树配置
要使用 Display I2S + Display DPTX 音频通路,需要打开对应的内核配置开关,将相关驱动编译到内核中或编译为模块。相关配置在内核配置菜单 menuconfig 中的位置如下图:

位置为 Device Drivers -> Sound card support -> Advanced Linux Sound Architecture -> ALSA for SoC audio support -> ASoC support for MooreThreads -> ASoC support for MooreThreads boards using a DPTX sound。Display I2S + Display DPTX 音频通路相关的内核配置有多个,开启 ASoC support for MooreThreads boards using a DPTX sound 时,相关的配置项也会被自动打开,如 sound/soc/m1000/Kconfig:
config SND_SOC_M1000_DPTX_SOUND
tristate "ASoC support for MooreThreads boards using a DPTX sound"
depends on HAVE_CLK && M1000_DPTX
select SND_SOC_MTHREADS_DISP_I2S
help
Say Y or M here if you want to add support for SoC audio on MooreThreads
M1000 boards using the DPTX sound.
SND_SOC_MTHREADS_DISP_I2S 配置会被自动打开。
Display I2S + Display DPTX 音频通路的设备树配置,需要配置音频通路中的各个设备,包括 Display I2S 和 machine (声卡)。MTT E300 有 6 组 Display I2S,其设备树配置分为两部分,一部分配置与板子无关的资源,如时钟、中断、寄存器范围等,这部分配置所在设备树文件路径为 arch/arm64/boot/dts/m1000/m1000-main.dtsi,以 Display I2S0 为例,设备树节点如下:
i2s9_8ch: i2s@54C000 {
#sound-dai-cells = <0>;
compatible = "mthreads,m1000-disp-i2s";
reg = <0x0 0x54C000 0x0 0x1000>, /* Disp i2s0 reg */
<0x0 0x562000 0x0 0x1000>, /* Disp i2s0 DAA reg */
<0x0 0x563000 0x0 0x1000>; /* Disp i2s0 DAAS reg */
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 0x148 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&crg DISP_I2S0_CLK>, <&crg DISP_I2S0_MUX_CLK>, <&crg
DISP_DIV_I2S0_0>, <&crg DISP_DIV_I2S1_0>, <&crg DISP_I2S0_APB_REGIME_CLK>;
clock-names = "disp_i2s_sclk", "disp_i2s_mux_clk",
"disp_div_i2s0_clk", "disp_div_i2s1_clk", "disp_i2s_apb_regime_clk";
mthreads,disp_i2s = <0>;
status = "disabled";
};
另一部分配置与板子有关的资源,这部分配置位于特定板子的设备树文件,以
Display I2S0 为例,配置设备开启,设备树节点如下:
&i2s9_8ch {
status = "okay";
};
Display I2S + Display DPTX 音频通路的 machine (声卡) 设备树节点配置声卡开关,它位于特定板子的设备树文件中,设备树节点如下:
m1000_disp_sound: m1000-disp-sound {
compatible = "mthreads,mthreads-dptx-sound";
status = "okay";
};
status 为 okay 表示开启该设备树节点。
步骤 2:配置 Peri I2S + Audio codec
- 内核配置
- 设备树配置
要使用 Peri I2S + Audio codec 音频通路,需要打开对应的内核配置开关,将相关驱动编译到内核中或编译为模块。新的板子,需要根据所选的 audio codec 添加新的声卡配置项,声卡用到的 I2S 和 audio codec 等模块的内核配置开关,通常由声卡配置项开关时自动选择。Peri I2S + Audio codec 音频通路的内核配置开关示例如基于 Realtek ALC5672 的声卡配置开 关,它在内 kernel 配置菜单 menuconfig 中的位置如下图:

位置为 Device Drivers -> Sound card support -> Advanced Linux Sound Architecture -> ALSA for SoC audio support -> ASoC support for MooreThreads -> ASoC support for MooreThreads boards using a ALC5672 codec。Peri I2S + Audio codec 音频通路相关的内核配置有多个,开启 ASoC support for MooreThreads boards using a ALC5672 codec 时,相关的配置项也会被自动打开,如 sound/soc/m1000/Kconfig:
config SND_SOC_M1000_RT5672
tristate "ASoC support for MooreThreads boards using a ALC5672 codec"
depends on I2C && GPIOLIB && HAVE_CLK
select SND_SOC_MTHREADS_I2S
select SND_SOC_RT5670
select SND_SOC_ACPI if ACPI
help
Say Y or M here if you want to add support for SoC audio on MooreThreads
M1000 boards using the ALC5672 codec.
SND_SOC_MTHREADS_I2S、SND_SOC_RT5670 和 SND_SOC_ACPI 配置会被自动打开。
Peri I2S + Audio codec 音频通路的设备树配置,需要配置音频通路中的各个设备,包括 Peri I2S、Audio codec 和 machine (声卡)。MTT E300 有 8 组 Peri I2S,其设备树配置分为两部分,一部分配置与板子无关的资源,如时钟、中断、寄存器范围等,这部分配置所在设备树文件路径为 arch/arm64/boot/dts/m1000/m1000-main.dtsi,以 Peri I2S5 为例,设备树节点如下:
i2s5_2ch: i2s@72A000 {
compatible = "mthreads,peri-i2s";
reg = <0x0 0x72A000 0x0 0x1000>, /* Peri i2s5 reg */
<0x0 0x767000 0x0 0x1000>, /* Peri i2s5 DAA reg */
<0x0 0x768000 0x0 0x1000>; /* Peri i2s5 DAAS reg */
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 0x111 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&crg PERI_I2S5_SCLK>,
<&crg PERI_I2S5_PFUNC_CLK>,
<&crg PERI_I2S5_MUX_CLK>,
<&crg PERI_I2S0PLL3_DIV5>,
<&crg PERI_I2S1PLL3_DIV5>;
clock-names = "i2s_sclk", "i2s_pfunc_clk", "i2s_mux_clk",
"i2s0_pll3_div_clk", "i2s1_pll3_div_clk";
#sound-dai-cells = <0>;
mthreads,hd-chn-num = <1>;
status = "disabled";
};
另一部分配置与板子有关的资源,如所选用的 GPIO 口等,这部分配置位于特定板子
的设备树文件,以 Peri I2S5 为例,GPIO 口采用 GPIO127-130,设备树节点如下:
pin195:pin195 {
groups = "pin195";
function = "customized";
function-value = <1>;
drive-strength = <4>;
slew-rate = <1>;
};
pin196:pin196 {
groups = "pin196";
function = "customized";
function-value = <1>;
drive-strength = <4>;
slew-rate = <1>;
};
pin197:pin197 {
groups = "pin197";
function = "customized";
function-value = <1>;
drive-strength = <4>;
slew-rate = <1>;
};
pin198:pin198 {
groups = "pin198";
function = "customized";
function-value = <1>;
drive-strength = <4>;
slew-rate = <1>;
};
. . . . . .
&i2s5_2ch {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pin195 &pin196 &pin197 &pin198>;
};
Audio codec 的设备树配置,因具体 audio
codec 的选择而异,设备树节点中配置它所用到的各项资源,位于特定板子的设备树文件。以 Realtek ALC5672
audio
codec 为 例,它通过 I2C5 控制,通过 GPIO 口上报耳机插拔事件,它的设备树节点定义为 I2C5 设备树节点的子节点,具体如下:
&i2c5 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c5_default>;
rt5672: rt5672@1c {
#sound-dai-cells = <0>;
compatible = "realtek,rt5672";
reg = <0x1c>;
headset-gpios = <&gpio_peri MT_GPIO_GLB_NO(127) GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
status 为 okay 表示开启该设备树节点。Peri I2S + Audio codec 音频通路的 machine
(声卡) 设备树节点配置声卡包含的各个设备等资源,它位于特定板子的设备树文件中,以基于 Realtek ALC5672
audio codec 的声卡为例,设备树节点如下:
m1000_sound: m1000-sound {
compatible = "mthreads,mthreads-rt5672-sound";
mthreads,cpu = <&i2s5_2ch>;
mthreads,codec = <&rt5672 &rt5672>;
clocks = <&crg PAD_OUT5REFCLK>,
<&crg PERI_PLLOUT4_DIV_MUX1_CLK>,
<&crg PERI_PLLOUT4_DIV1_CLK>,
<&crg PERI_I2S0PLL3_DIV1>;
clock-names = "mclk", "div_mux_clk", "peri_pllout4_div1_clk",
"peri_i2s0pll3_div1";
status = "okay";
};
status 为 okay 表示开启该设备树节点,disabled 示关闭设备树节点。Peri I2S + Audio
codec 音频通路的设备树配置中,audio codec 和声卡的配置因具体的 audio
codec 选择而异,这里的内容仅供参考。
步骤 3:配置用户空间声卡
用户空间对于声卡的配置,可通过 alsa-ucm-conf 配置文件进行。alsa-ucm-conf 位于配置文件位于系统的 /usr/share/alsa/ucm2 目录下。
开发参考
Display I2S + Display DPTX 音频通路通常不需要专门针对板子做额外的开发。Peri I2S + Audio codec 音频通路,对于特定板子,需要如下的额外开发或配置:
- 配置 Peri I2S 的板级资源,如
GPIO口等; - 集成 Audio codec 的 Linux 内核设备驱动程序;
- 在设备树文件中为 Audio codec 设备添加设备树节点,配置它用到的各项资源,具体方法因 Audio codec 的选择而异;
- 编写 machine
(声卡) 驱动程序,可以参考
sound/soc/m1000/m1000_snd_card_dummy_peri_drv.c和sound/soc/m1000/m1000_snd_card_rt5672_drv.c等文件; - 配置声卡设备树节点。