STM32MP157 Linux系统移植开发篇16:Linux内核音频驱动移植
本文章为《STM32MP157 Linux系统移植开发篇》系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板)。stm32mp157是ARM双核,2个A7核,1个M4核,A7核上可以跑Linux操作系统,M4核上可以跑FreeRTOS、RT-Thread等实时操作系统,STM32MP157开发板所以既可以学嵌入式linux,也可以学stm32单片机。
针对FS-MP1A开发板,除了Linux系统移植篇外,还包括其他多系列教程,包括Cortex-A7开发篇、Cortex-M4开发篇、扩展板驱动移植篇、Linux应用开发篇、FreeRTOS系统移植篇、Linux驱动开发篇、硬件设计篇、人工智能机器视觉篇、Qt应用编程篇、Qt综合项目实战篇等。欢迎关注,更多stm32mp157开发教程及视频,可加技术交流Q群459754978,感谢关注。
关于FS-MP1A开发板:
手机淘宝分享码:复制本行文字打开手淘₤T4FPXn3YYJ2₤
链接:https://item.taobao.com/item.htm?id=622457259672
1.实验原理
FS-MP1A使用的是CS42L51音频芯片,SoC通过I2C和SAI与其进行数据交互,原理图如下:
SAI2管脚对应关系:
I2C5管脚对应关系:
芯片复位管脚对应关系:
原理图网络编号 | 对应管脚 | 管脚功能 | 管脚功能码 |
SAI2_MCLKA | PE0 | SAI2_MCLK_A | AF10 |
SAI2_SDB | PF11 | SDA2_SD_B | AF10 |
SAI2_SCKA | PI5 | SAI2_SCK_A | AF10 |
SAI_SDA | PI6 | SAI2_SD_A | AF10 |
SAI2_FSA | PI7 | SAI2_FS_A | AF10 |
AUDIO_RST | PC0 | IO | ANALOG |
I2C5_SDA | PA11 | I2C5_SDA | AF4 |
I2C5_SCL | PA12 | I2C5_SDA | AF4 |
- SAI2设备树节点
参考文档:
Documentation/devicetree/bindings/sound/st,stm32-sai.txt
内核中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实际使用管脚一致,所以无需修改。
- CS42L51设备树节点
由于前文中已经增加过I2C5的节点信息,本节就不再重复,在原有I2C5节点添加CS42L51内容即可。
参考文档:
Documentation/devicetree/bindings/sound/cs42l51.txt
参考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;
};
};
};
- 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;
};
- SOC声卡驱动节点
内核中包含audio-graph-card驱动,驱动将声卡各个部分关联起来,驱动正常工作需添加对应设备树节点。
参考文档:
Documentation/devicetree/bindings/sound/audio-graph-card.txt
在根节点写下添加sound节点:
sound {
compatible = "audio-graph-card";
label = "STM32MP1-FSMP1A";
routing =
"Playback" , "MCLK",
"Capture" , "MCLK",
"MICL" , "Mic Bias";
dais = <&sai2a_port &sai2b_port>;
status = "okay";
};
2.实验平台
华清远见开发环境,FS-MP1A平台;
3.实验目的
熟悉基于Linux操作系统下的音频设备驱动移植配置过程。
4.实验步骤
- 导入交叉编译工具链
linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
- 添加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>;
};
};
};
};
- 添加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;
};
};
};
- 添加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;
};
- 添加Sound节点
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在根节点中添加如下内容:
sound {
compatible = "audio-graph-card";
label = "STM32MP1-FSMP1A";
routing =
"Playback" , "MCLK",
"Capture" , "MCLK",
"MICL" , "Mic Bias";
dais = <&sai2a_port &sai2b_port>;
status = "okay";
};
- 配置内核
由于内核源码默认配置以及支持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
- 编译内核及设备树
linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040
- 重启测试
将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,启动后启动信息中出现如下内容:
插上耳机,终端输入录音命令:
root@fsmp1a:# arecord -D record_codec -f S16_LE -d 10 test.wav
终端输入播放命令:
root@fsmp1a:# aplay test.wav
注意:由于3.5mm的4段式耳机接口还分为两种,一种是美标版(CTIA),也称为“苹果标准”,同时小米、魅族也是使用这种标准;另外一种是国标版(OMTP),也称为“诺基亚标准”,现在绝大多数诺基亚和大多数国产手机都是使用这种标准。FS-MP1A使用的是国标版,所以部分耳机并不能正常实现录播功能。
硬件平台:华清远见FS-MP1A开发板(STM32MP157)
部分开发教程下载:加QQ群459754978,群文件里有。
部分视频课程收看:华清远见研发中心的个人空间_哔哩哔哩_Bilibili
淘宝购买链接:https://item.taobao.com/item.htm?id=622457259672
手机淘宝分享码:复制本行文字打开手淘₤T4FPXn3YYJ2₤
STM32MP157 Linux系统移植开发篇16:Linux内核音频驱动移植相关推荐
- p750tm安装linux系统,Android 开发环境(虚拟机,LINUX, secureCRT)安装过程.pdf
Android 开发环境(虚拟机,LINUX, secureCRT)安装过程 Android linux 开发环境(虚拟机,LINUX, secureCRT )安装过程 注意 由于selinux 打开 ...
- 嵌入式linux系统应用开发
关于嵌入式系统 平时大家说的嵌入式其实范围比较广的,是一种软硬件可裁剪,以应用为中心开发的专用系统,硬件平台可以是单片机,或者以ARM系列的处理器.单片机一般直接裸奔程序,不过现在有了好多基于单片 ...
- STM32MP157 Linux系统移植开发篇14:Linux内核RGB LCD驱动移植
本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...
- STM32MP157 Linux系统移植开发篇4: BootLoader(Uboot)移植
本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...
- STM32MP157 Linux系统移植开发篇17:Linux内核摄像头驱动移植
本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...
- STM32MP157 Linux系统移植开发篇11:Linux HDMI驱动移植
本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...
- stm32mp1安装linux系统,stm32mp1linux开发环境搭建(cortex a7)
原标题:stm32mp1linux开发环境搭建(cortex a7) 写在前面: 本文章为<STM32MP1系列教程之Cortex-A7开发篇>系列中的一篇,全系列总计11篇.笔者使用的开 ...
- 嵌入式LINUX系统程序开发
嵌入式LINUX系统程序开发 1.Ubuntu 18.04镜像源配置 2.Ubuntu上用gcc进行编写程序 2.1.gcc的安装 2.2.gcc的常用命令 2.3.编译运行程序 3.Windows下 ...
- 开发板通过usb连linux,虚拟机Linux系统和开发板通过USB转串口连接的两种方法
通过USB转串口连接虚拟机中的Linux系统和开发板,开始时候总是出现错误,显示什么串口重叠,最后求助高手帮我通过其他连接方式解决了问题,今天在网上查找资料,终于明白了开始错误的原因:开发板提供的驱动 ...
- 基于linux的应用开发视频教程,基于LINUX+ARM的视频系统的应用和开发
摘要: 随着经济的发展,人民生活水平的提高,嵌入式智能产品越来越多的进入到到我们生活领域,这些产品不仅给我们带来方便,同时也在改变着我们的生活,并且嵌入式产品界面和视频的开发也越来越受到关注,成为研究 ...
最新文章
- 服务器自动安全审计,用于Linux服务器的自动安全审计工具
- 在centos6.5上安装mongodb数据库
- JSON学习笔记(一)- 语法
- 一网打尽!每个程序猿都该了解的黑客技术大汇总
- IOS基础学习日志(七)利用dispatch_once创建单例及使用
- 认识目标文件的格式—— a.out COFF PE ELF
- 常用排序算法-java实现(希尔,归并)
- 14. Thinking carefullly about copying behavior in resource-managing classes
- 万年历c语言代码3000年,求万年历代码!
- uniapp个人中心界面模板
- 提示参数错误html页面,网页上有错误怎么修复提示参数错误
- html5查询通配符,通配符有哪些?
- OHS 12C中导入第三方SSL证书
- 用CSS 实现水波扩散的特效
- 计算机网络cidr是啥,计算机网络(4.11)网络层- 无分类编址CIDR
- swiper.js横向轮播插件
- Ubuntu 设置固定 IP 最简单的方法!
- oracle索引的事
- 第七章 1什么是活动目录?活动目录有那些优点?
- Milon.MorFIX,myie2查找wkipedia的plugin
热门文章
- 罗克韦尔AB PLC与西门子Basic精简触摸屏进行通信的具体方法演示
- 专业的格式转换工具pdf2cad发布v11,支持当前所有的Windows和Mac操作系统
- html动画人物走路,动画人物走路教程
- spring-boot java.lang.ClassNotFoundException: org.thymeleaf.spring5.ISpringTemplateEngine
- java 定时任务 cron
- cbnertvirtual内部框架下载_关于matepad pro谷歌框架
- java 异步发送消息_Java模拟异步消息的发送与回调
- 码栈使用过程中常见操作动作说明
- 如何做到微信机器人不封号_如何正确使用微信聊天机器人才能避免被封号?
- vue仿网易云音乐播放器界面