文章目录
- 写在前面
- ALSA代码架构
- 重要概念
- a Kcontrol
- b widget
- c route
- 工具使用
- amixer 的用法
- arecord
- aplay
- alsactrl
- 如何设置通路
- 1 确认出入口
- 2 mic通路
- 3 speaker通路
- 耳机拔插检测
- 遇到mic不收声的问题
写在前面
这一章节主要是介绍px30移植5640驱动的过程,实现的目标如下
1 rt5640驱动移植
2 alsa通路配置
3 alsa通路保存默认配置信息
如果对alsa框架想详细了解可以参考这位大神的博客。
https://www.cnblogs.com/xinghuo123/category/1786302.html
ALSA代码架构
kernel/sound
目录 | 内容 |
---|---|
/aoa | 苹果主板驱动 |
/arm | arm架构相关驱动 |
/atmel | atmel设备驱动 |
/core | 该目录包含了ALSA驱动的中间层,它是整个ALSA驱动的核心部分 |
/drivers | 不同架构中一些驱动共享文件放置一些与CPU、BUS架构无关的公用代码 |
/i2c | ALSA自己的I2C控制代码 |
/isa | isa声卡的上层模块 |
/mips | MIPS声卡设备驱动 |
/oos | oos架构 |
/parisc | gsc声卡驱动 |
/pci | pci声卡 |
/ppc | powerPC架构有关 |
/sh | SUPERH声卡驱动 |
/soc | system-on-chip |
/sparc | Sparc声卡驱动 |
/synth | synth中间层 |
/usb | usb-audio驱动 |
名词解释:
CPU DAI : 主控端的 Audio Data Interface,比如 I²S,Spdif,Pdm,Tdm (就是通常所说的platform层)
CODEC DAI:即 Codec (通常所说的codec层)
DAI_LINK : 绑定 Cpu_Dai 和 Codec_Dai 为一个声卡,等同于 Machine Driver (platform
层)。
DMAENGINE:用于 Cpu 和 I²S/Spdif 等 Dai 之间的 Dma 传输引擎,实际是通过 Dma
来进行数据的搬运。
DAPM:动态音频电源管理,用于动态管理 Codec 等的电源管理,根据通路的开启配置开
关,以达到保证功能的前提下功耗尽量小。
JACK:耳机的接口检测,大部分使用 Codec 自身的检测机制,小部分使用 IO 来进行模拟。
目录层级结构
框架 | 代码 |
---|---|
codec层 | kernel/sound/soc/codecs/rt5640.c |
platfrom层 | |
Machine | Driver 层 kernel/sound/soc/rockchip/rockchip_px30_rt5640.c |
重要概念
DAPM
DAPM是Dynamic Audio Power Management的缩写,直译过来就是动态音频电源管理的意思,DAPM是为了使基于linux的移动设备上的
音频子系统,在任何时候都工作在最小功耗状态下。DAPM对用户空间的应用程序来说是透明的,所有与电源相关的开关都在ASoc core
中完成。用户空间的应用程序无需对代码做出修改,也无需重新编译,DAPM根据当前激活的音频流(playback/capture)和声卡中的
mixer等的配置来决定那些音频控件的电源开关被打开或关闭。
a Kcontrol
一个kcontrol代表着一个mixer(混音器),或者是一个mux(多路开关),又或者是一个音量控制器等等
b widget
可以理解为对kcontrol的进一步升级和封装,同样指音频系统中的某个部件,如mixer,mux;
c route
一个路径的连接至少包含以下几个元素:起始端widget,跳线path,到达端widget,其实route就是连接起各个widget
可以看出,这三大组件的关系是由点及面的。
工具使用
我的linux系统中自带了aplay arecord amixer 使用这个测试,不详细介绍工具的使用了,网上资料太多了,只是介绍个简单的用法
amixer 的用法
总结来说就是
amixer controls 查看命令
amixer cget 得到命令
amixer cset 设置命令
重点是分析下音频流如何打开,并且流向自己想要的方向
arecord
arecord -D hw:0,0 -d 10 -f dat -t wav test.wav
-D :指定声卡
-d: 指定录制时间
-f : 指定音频格式
-t :指定录制文件格式
aplay
aplay play.wav
alsactrl
保存设置
alsactl store
恢复设置
alsactl restore
要实现所有的通路 ,可以打开之后,使用alsactl store 保存配置,默认路径在:/var/lib/alsa/asound.state 之后开机时通过将alsactl restore写入脚本恢复
如何设置通路
重难点再次,根据官方手册,讲解一下如何配置通路。
1 确认出入口
先看一下原理图,将收音和放音的设备接到哪里,即先确认下这张图的入口和出口
我就以入口是IN2P 出口为SPORP为例,说明一下通路配置
2 mic通路
步骤 根据mx-[n] 查找rtl5640.h 然后查找相应的Kcontrol 或者route
amixer cset name="RECMIXL BST2 Switch" 1 #MX-3C[1]
amixer cset name="Stereo ADC MIXL ADC1 Switch" 1 #MX-27[14]
amixer cset name="ADC Capture Switch" 1 #MX-1C[15]amixer cset name="RECMIXR OUT MIXR Switch" 1 # MX-3E[0]
3 speaker通路
amixer cset name="DAI select" 0
amixer cset name='DAC MIXR INF1 Switch' 1 #MX-29 [6]
amixer cset name="Stereo DAC MIXR DAC R1 Switch" 1 # MX-2A[6]
amixer cset name="OUT MIXR DAC R1 Switch" 1 #MX-52 [0]amixer cset name="SPK MIXR OUT MIXR Switch" 1 # MX-47 [1]amixer cset name="Speaker Channel Switch" 1 #MX-01[6]
amixer cset name="SPOR MIX SPKVOL R Switch" 1 #MX-49[12]
amixer cset name="Speaker R Playback Switch" 1 #MX-01[7]
amixer cset name="Speaker Playback Volume" 26
耳机拔插检测
设备树 : kernel/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-rgb-v10-linux.dts
rk_headset: rk-headset {compatible = "rockchip_headset";headset_gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;pinctrl-names = "default";pinctrl-0 = <&hp_det>;status ="okay";
};
kernel/arch/arm64/configs/px30_linux_defconfig
CONFIG_SWITCH=y
CONFIG_SWITCH_GPIO=y
CONFIG_RK_HEADSET=y
涉及文件夹
/kernel/drivers/headset_observe/
文件名 | 功能 |
---|---|
rk_headset.c | 检测耳机拔插 |
rockchip_headset_core.c | 核心函数 |
rk_headset_irq_hook_adc.c |
简单的调用流程
遇到mic不收声的问题
我再调试过程中,rt5640遇到了录音这块死活没有声音的问题,查了好久,发现我手里的驱动代码DAPM好像有点问题
这个代码里没有描述MICBIAS1和IN1P IN2P IN3P,修改了一下代码
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.cstatic const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
+ {"IN1P", NULL, "MICBIAS1"},
+ {"IN2P", NULL, "MICBIAS1"},
+ {"IN3P", NULL, "MICBIAS1"},
}