你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32MP157 Linux系统移植开发篇16:Linux内核音频驱动移植

[复制链接]
STMCU小助手 发布时间:2022-9-30 15:28
1.实验原理
FS-MP1A使用的是CS42L51音频芯片,SoC通过I2C和SAI与其进行数据交互,原理图如下:

79b118f387331bb663bdbf2536788b3b.jpg

SAI2管脚对应关系:

61ce5603d0204ebbe5ffb0117659c234.png

00b77ddabbdb06add4eba544f9daf83b.png

c07ad1d1df4d6c7fee2f62fc1ecc8ce6.png

I2C5管脚对应关系:

ce25e0398cccd3fd988ef8e9300a5104.png

芯片复位管脚对应关系:

23b9384095f188bd5100ee28aa6c1925.png


1.SAI2设备树节点

内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见:

sai2: sai@4400b000 {

compatible = "st,stm32h7-sai";

#address-cells = <1>;

#size-cells = <1>;

ranges = <0 0x4400b000 0x400>;

reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>;

interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;

resets = <&rcc SAI2_R>;

status = "disabled";

sai2a: audio-controller@4400b004 {

#sound-dai-cells = <0>;

compatible = "st,stm32-sai-sub-a";

reg = <0x4 0x1c>;

clocks = <&rcc SAI2_K>;

clock-names = "sai_ck";

dmas = <&dmamux1 89 0x400 0x01>;

status = "disabled";

};

sai2b: audio-controller@4400b024 {

#sound-dai-cells = <0>;

compatible = "st,stm32-sai-sub-b";

reg = <0x24 0x1c>;

clocks = <&rcc SAI2_K>;

clock-names = "sai_ck";

dmas = <&dmamux1 90 0x400 0x01>;

status = "disabled";

};

};

上述代码只对SAI2做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。

参考stm32mp15xx-dkx.dtsi对于SAI2设备节点的描述,增加SAI2内容如下:

&sai2 {

clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;

clock-names = "pclk", "x8k", "x11k";

pinctrl-names = "default", "sleep";

pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;

pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;

status = "okay";

sai2a: audio-controller@4400b004 {

#clock-cells = <0>;

dma-names = "tx";

clocks = <&rcc SAI2_K>;

clock-names = "sai_ck";

status = "okay";

sai2a_port: port {

sai2a_endpoint: endpoint {

remote-endpoint = <&cs42l51_tx_endpoint>;

format = "i2s";

mclk-fs = <256>;

dai-tdm-slot-num = <2>;

dai-tdm-slot-width = <32>;

};

};

};

sai2b: audio-controller@4400b024 {

dma-names = "rx";

st,sync = <&sai2a 2>;

clocks = <&rcc SAI2_K>, <&sai2a>;

clock-names = "sai_ck", "MCLK";

status = "okay";

sai2b_port: port {

sai2b_endpoint: endpoint {

remote-endpoint = <&cs42l51_rx_endpoint>;

format = "i2s";

mclk-fs = <256>;

dai-tdm-slot-num = <2>;

dai-tdm-slot-width = <32>;

};

};

};

};

由于stm32mp15-pinctrl.dtsi中对于SAI2管脚的定义与FS-MP1A实际使用管脚一致,所以无需修改。

2.CS42L51设备树节点
由于前文中已经增加过I2C5的节点信息,本节就不再重复,在原有I2C5节点添加CS42L51内容即可。


参考stm32mp15xx-dkx.dtsi对于codec芯片设备节点的描述,增加内容如下:

cs42l51: cs42l51@4a {

compatible = "cirrus,cs42l51";

reg = <0x4a>;

#sound-dai-cells = <0>;

VL-supply = <&v3v3>;

VD-supply = <&v1v8_audio>;

VA-supply = <&v1v8_audio>;

VAHP-supply = <&v1v8_audio>;

reset-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>;

clocks = <&sai2a>;

clock-names = "MCLK";

status = "okay";

cs42l51_port: port {

#address-cells = <1>;

#size-cells = <0>;

cs42l51_tx_endpoint: endpoint@0 {

reg = <0>;

remote-endpoint = <&sai2a_endpoint>;

frame-master;

bitclock-master;

};

cs42l51_rx_endpoint: endpoint@1 {

reg = <1>;

remote-endpoint = <&sai2b_endpoint>;

frame-master;

bitclock-master;

};

};

};

3.1.8V电源设备节点
前文已经说过如何添加电源节点,本节不再重复,在根节点添加&v1v8_audio节点,内容如下:

v1v8_audio: regulator-v1v8_audio {

compatible = "regulator-fixed";

regulator-name = "v1v8_audio";

regulator-min-microvolt = <1800000>;

regulator-max-microvolt = <1800000>;

regulator-always-on;

regulator-boot-on;

};

4.SOC声卡驱动节点
内核中包含audio-graph-card驱动,驱动将声卡各个部分关联起来,驱动正常工作需添加对应设备树节点。

在根节点写下添加sound节点:

sound {

compatible = "audio-graph-card";

label = "STM32MP1-FSMP1A";

routing =

"layback" , "MCLK",

"Capture" , "MCLK",

"MICL" , "Mic Bias";

dais = <&sai2a_port &sai2b_port>;

status = "okay";

};

2.实验平台
华清远见开发环境,FS-MP1A平台;

3.实验目的
熟悉基于Linux操作系统下的音频设备驱动移植配置过程。

4.实验步骤

1.导入交叉编译工具链
linux@ubuntu source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

2.添加SAI2节点
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在文件末尾添加如下内容:

&sai2 {

clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;

clock-names = "pclk", "x8k", "x11k";

pinctrl-names = "default", "sleep";

pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;

pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;

status = "okay";

sai2a: audio-controller@4400b004 {

#clock-cells = <0>;

dma-names = "tx";

clocks = <&rcc SAI2_K>;

clock-names = "sai_ck";

status = "okay";

sai2a_port: port {

sai2a_endpoint: endpoint {

remote-endpoint = <&cs42l51_tx_endpoint>;

format = "i2s";

mclk-fs = <256>;

dai-tdm-slot-num = <2>;

dai-tdm-slot-width = <32>;

};

};

};

sai2b: audio-controller@4400b024 {

dma-names = "rx";

st,sync = <&sai2a 2>;

clocks = <&rcc SAI2_K>, <&sai2a>;

clock-names = "sai_ck", "MCLK";

status = "okay";

sai2b_port: port {

sai2b_endpoint: endpoint {

remote-endpoint = <&cs42l51_rx_endpoint>;

format = "i2s";

mclk-fs = <256>;

dai-tdm-slot-num = <2>;

dai-tdm-slot-width = <32>;

};

};

};

};

3.添加CS42L51节点
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在I2C5节点中添加如下内容:

cs42l51: cs42l51@4a {

compatible = "cirrus,cs42l51";

reg = <0x4a>;

#sound-dai-cells = <0>;

VL-supply = <&v3v3>;

VD-supply = <&v1v8_audio>;

VA-supply = <&v1v8_audio>;

VAHP-supply = <&v1v8_audio>;

reset-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>;

clocks = <&sai2a>;

clock-names = "MCLK";

status = "okay";

cs42l51_port: port {

#address-cells = <1>;

#size-cells = <0>;

cs42l51_tx_endpoint: endpoint@0 {

reg = <0>;

remote-endpoint = <&sai2a_endpoint>;

frame-master;

bitclock-master;

};

cs42l51_rx_endpoint: endpoint@1 {

reg = <1>;

remote-endpoint = <&sai2b_endpoint>;

frame-master;

bitclock-master;

};

};

};

4.添加v1v8_audio电源节点
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在根节点中添加如下内容:

v1v8_audio: regulator-v1v8_audio {

compatible = "regulator-fixed";

regulator-name = "v1v8_audio";

regulator-min-microvolt = <1800000>;

regulator-max-microvolt = <1800000>;

regulator-always-on;

regulator-boot-on;

};

5.添加Sound节点
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在根节点中添加如下内容:

sound {

compatible = "audio-graph-card";

label = "STM32MP1-FSMP1A";

routing =

"layback" , "MCLK",

"Capture" , "MCLK",

"MICL" , "Mic Bias";

dais = <&sai2a_port &sai2b_port>;

status = "okay";

};

6.配置内核
由于内核源码默认配置以及支持CS42L51,本节列出主要选项,如下:

linux@ubuntu make menuconfig

Device Drivers --->

<*> Sound card support --->

<*> Advanced Linux Sound Architecture --->

<*> ALSA for SoC audio support --->

STMicroelectronics STM32 SOC audio support --->

<*> STM32 SAI interface (Serial Audio Interface) support

CODEC drivers --->

<*> Cirrus Logic CS42L51 CODEC (I2C)

<*> ASoC Audio Graph sound card support

7.编译内核及设备树
linux@ubuntu make -j4 uImage dtbs LOADADDR=0xC2000040

8.重启测试
将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,启动后启动信息中出现如下内容:

4111bf32942002a48bfbecd83b829e6c.jpg

插上耳机,终端输入录音命令:

root@fsmp1a:# arecord -D record_codec -f S16_LE -d 10 test.wav

终端输入播放命令:

root@fsmp1a:# aplay test.wav

————————————————
版权声明:华清远见IT开放实验室


收藏 评论0 发布时间:2022-9-30 15:28

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版