![cover](https://img-blog.csdnimg.cn/direct/89540f92fbb0453d9773c6aacdb61155.jpeg)
RK3568 音频驱动实验
本文为RK3568声卡实验,仅供学习参考
作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生在读,研究方向无线联邦学习
擅长领域:驱动开发,嵌入式软件开发,BSP开发
作者主页:一个平凡而乐于分享的小比特的个人主页
文章收录专栏:RK3568驱动开发,本专栏为rk3568驱动开发学习记录
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖
RK3568 音频驱动实验
1. 音频接口简介
1.1 为何需要音频编解码芯片?
处理器要想“听到”外界的声音必须要把外界的声音转化为自己能够理解的“语言”,处理器能理解的就是0和1,也就是二进制数据。所以我们需要先把外界的声音转换为处理器能理解的 0和1,在信号处理领域,外界的声音是模拟信号,处理器能理解的是数字信号,因此这里就涉及到一个模拟信号转换为数字信号的过程,而完成这个功能的就是 ADC 芯片。同理,如果处理器要向外界传达自己的“心声”,也就是放音,那么就涉及到将处理器能理解的 0 和1转化为外界能理解的连续变化的声音,这个过程就是将数字信号转化为模拟信号而完成这个功能的是 DAC 芯片。
音频不单单是能出声、能听到就行。我们往往需要听到的声音动听、录进去的语音贴近真实、可以调节音效、对声音能够进行一些处理(需要 DSP 单元)、拥有
统一的标准接口,方便开发等等。将这些针对声音的各种要求全部叠加到 DAC 和 ADC 芯片上,那么就会得到一个专门用于音频的芯片,也就是音频编解码芯片,英文名字就是 Audio CODEC,所以我们在手机或者电脑的介绍中看到“CODEC”这个词语,一般说的都是音频编解码。
既然音频 CODEC 的本质是 ADC 和 DAC,那么采样率和采样位数就是衡量一款音频CODEC 最重要的指标。比如常见音频采样率有 8K、44.1K、48K、192K甚至 384K 和 768K采样位数常见的有 8 位、16 位、24 位、32 位。采样率和采样位数越高,那么音频 CODEC越能真实的还原声音,也就是大家说的 HIFI。因此大家会看到高端的音频播放器都会有很高的采样率和采样位数,同样的价格也会越高。当然了,实际的效果还与其他部分有关,采样率和采样位数只是其中重要的指标之一。
1.2 RK809 Codec简介
RK809 集成了高性能 24 位 ADC 和高性能 24 位 DAC。录音路径由 MIC PGA 和音频 ADC组成。DAC 将数字信号转换为模拟信号,ab 类驱动器采用实地结构,用于耳机应用,THD 非常低(-90dB @1KHz@-3dBFS 源)。同时,集成了用于扬声器应用的d类驱动程序。扬声器和耳机可以同时使用。集成 I2S 接口,与处理器通信。
RK809音频系统框图 :
1.3 I2S总线接口
I2S(1nter-IC Sound)总线有时候也写作 IS,I2S 是飞利浦公司提出的一种用于数字音频设备之间进行音频数据传输的总线。和 I2C、SPI 这些常见的通信协议一样,I2S 总线用于主控制器和音频 CODEC 芯片之间传输音频数据。因此,要想使用 I2S 协议,主控制器和音频CODEC 都得支持 I2S 协议,RK3568 支持 I2S 协议,RK809 同样也支持 I2S,所以本章实验就是使用 I2S 协议来完成的。I2S 接口需要 3 根信号线(如果需要实现收和发,那么就要 4根信号线,收和发分别使用一根信号线):
SCK:串行时钟信号,也叫做位时钟(BCLK),音频数据的每一位数据都对应一个 SCK,立体声都是双声道的,因此 SCK=2X采样率X采样位数。比如采样率为 44.1KHz、16 位的立体声音频,那么 SCK=2x44100x16=1411200Hz=1.4112MHz。
WS:字段(声道)选择信号,也叫做 LRCK,也叫做帧时钟,用于切换左右声道数据,WS为“1”表示正在传输左声道的数据,WS 为“0”表示正在传输右声道的数据。WS 的频率等于采样率,比如采样率为 44.1KHz 的音频,WS=44.1KHz。
SD:串行数据信号,也就是我们实际的音频数据,如果要同时实现放音和录音,那么就需要 2根数据线,比如 RK809的 SDI和 SDO,就是分别用于录音和放音。不管音频数据是多少位的,数据的最高位都是最先传输的。数据的最高位总是出现在一帧开始后(LRCK 变化)的第2 个 SCK 脉冲处。另外,有时候为了使音频 CODEC 芯片与主控制器之间能够更好的同步,会引入另外一个叫做 MCLK 的信号,也叫做主时钟或系统时钟,一般是采样率的 256 倍或384 倍。下图就是一帧立体声音频时序图:
2. 硬件原理图
J5950端子上部为音频功放输出端口
我们将喇叭接到上面,实物图连接:
3. 音频驱动使能
RK 官方已经写好了 RK809 CODEC 驱动,因此我们直接配置内核使能 RK809 CODEC 驱动即可,按照如下所示步骤使能 RK809 CODEC 驱动。
瑞芯微提供的 RK3568 1inux SDK 默认配置了 RK809 CODEC 驱动,所以我们不用配置了,不过我们需要知道,打开 kermellarch/arm64/configsrockchip linux defconfig 文件,看到以下内容。
3698 # CONFIG_SND_SOC_RK3228 is not set
3699 # CONFIG_SND_SOC_RK3308 is not set
3700 CONFIG_SND_SOC_RK3328=y
3701 # CONFIG_SND_SOC_RK630 is not set
3702 CONFIG_SND_SOC_RK817=y
3703 CONFIG_SND_SOC_RK_CODEC_DIGITAL=y
3704 CONFIG_SND_SOC_RL6231=y
3705 CONFIG_SND_SOC_RT5616=y
第3702行,配置了 RK809 CODEC 驱动,你没有看错,这个就是 RK809 CODEC 驱动,只是写了 RK817,说明 RK809与RK817 CODEC 部分驱动代码做了兼容!
RK809 CODEC 源码路径为 kernel/sound/soc/codecshk817 codec.c。这里我们就不去分析这部分代码了,有兴趣的可以自行去分析,结合RK809的寄存器手册。
3.1 配置电源管理芯片RK809
在使用 RK809 CODEC 之前要使能 RK809,因为音频只属于这个电源管理芯片的一部分而详细请参考kerel/Documentation/devicetree/bindings/mfd/rk809.txt 文档。打开 arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi,找到以下内容。
1088 &i2c0 {
1089 status = "okay";
1090
......
1109 rk809: pmic@20 {
1110 compatible = "rockchip,rk809";
1111 reg = <0x20>;
1112 interrupt-parent = <&gpio0>;
1113 interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
1114
1115 pinctrl-names = "default", "pmic-sleep",
1116 "pmic-power-off", "pmic-reset";
1117 pinctrl-0 = <&pmic_int>;
1118 pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>;
1119 pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>;
1120 pinctrl-3 = <&soc_slppin_gpio>, <&rk817_slppin_rst>;
1121
1122 rockchip,system-power-controller;
1123 wakeup-source;
......
1356 rk809_codec: codec {
1357 #sound-dai-cells = <0>;
1358 compatible = "rockchip,rk809-codec", "rockchip,rk817-codec";
1359 clocks = <&cru I2S1_MCLKOUT>;
1360 clock-names = "mclk";
1361 assigned-clocks = <&cru I2S1_MCLKOUT>, <&cru I2S1_MCLK_TX_IOE>;
1362 assigned-clock-rates = <12288000>;
1363 assigned-clock-parents = <&cru I2S1_MCLKOUT_TX>, <&cru I2S1_MCLKOUT_TX>;
1364 pinctrl-names = "default";
1365 pinctrl-0 = <&i2s1m0_mclk>;
1366 hp-volume = <20>;
1367 spk-volume = <3>;
1368 mic-in-differential;
1369 status = "okay";
1370 };
1371 };
第 1109 行,可以看出 RK809 是挂载在 I2C0 上。上面的配置都是 RK 官方配置好的,或者需要参考配置文档,可以看上面说的Documentation/devicetree/bindings/mfdhk809.txt.第 1356-1370 行,这部分是 RK809 CODEC 音频驱动设备树配置,可以看到 compatible 属性为"rockchip,rk809-codec".“rockchip,rk817-codec”,可以查看 kemel/sound/soc/codecs/rk817 codec.c是否也有类似的字符串,有的话说明就匹配上了,后面代码看到我们是用了 I2S1,mclk 为12288000 Hz。
打开kemel/sound/soc/codecs/rk817 codec.c文件
1346 static const struct of_device_id rk817_codec_dt_ids[] = {
1347 { .compatible = "rockchip,rk817-codec" },
1348 {},
1349 };
1350 MODULE_DEVICE_TABLE(of, rk817_codec_dt_ids);
1351
1352 static struct platform_driver rk817_codec_driver = {
1353 .driver = {
1354 .name = "rk817-codec",
1355 .of_match_table = rk817_codec_dt_ids,
1356 },
1357 .probe = rk817_platform_probe,
1358 .remove = rk817_platform_remove,
1359 .shutdown = rk817_platform_shutdown,
1360 };
可以看到第1347行compatible属性与RK809 CODEC 音频驱动设备树compatible匹配
3.2 声卡设备数配置
上面配置的是音频驱动,现在我们来看看声卡。SimpleCard 是 ASoC(Advanced LinuxSound Architecture,高级 Linux 音频架构) 通用的声卡驱动,可支持大部分标准声卡的添加。RK809也是使用了这个通用的声卡。现在我们来看看这个声卡是如何将 RK809 驱动关联起来的。声卡驱动文件路径sound/soc/generic/simmple-card.c。
打开/kernel/arch/arm64/boot/dts/rockchip/rk3568-linux.dtsi
41 rk809_sound: rk809-sound {
42 status = "okay";
43 compatible = "simple-audio-card";
44 simple-audio-card,format = "i2s";
45 simple-audio-card,hp-det-gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>;
46 simple-audio-card,name = "rockchip,rk809-codec";
47 simple-audio-card,widgets = "Headphones", "Headphones Jack";
48 simple-audio-card,mclk-fs = <256>;
49 simple-audio-card,cpu {
50 sound-dai = <&i2s1_8ch>;
51 };
52 simple-audio-card,codec {
53 sound-dai = <&rk809_codec>;
54 };
第 43行,配置兼容属性为 simple-audio-card,匹配的就是 sound/soc/generic/simple-card.c驱动。
第44行,设置声卡协议格式为 i2s 标准格式。
第46行,”设置声卡的名字为“rockchip,rk809-codec’。
第 48行,默认情况下,mclk 为采样率的 256 倍。
第 49-51 行,这里连接硬件,也就是连接I2S。
第 52-54 行,设置 CODEC 为rk809 codec,也就是我们前面的 RK809 CODEC 音频驱
动。
4. wav格式文件下载
请自行下载qq音乐客户端,再通过qq音乐把歌曲以MP3格式下载到本地,请参考:qq音乐怎么转换mp3格式?两种直接下载MP3格式的方法,各大平台有效
最后通过野葱视频转换器将MP3格式音乐转换成wav格式,请参考:哪里能下载wav格式的音乐?
以下是笔者下载音乐文件格式:
将.wav格式音乐拷贝到开发板/usr/share/sounds目录下,如图:
5. GPIO管脚设置
从原理图可以看出,GPIO3_C3管脚默认值是1,即关闭状态,我们要将其值设置为0
输入命令:
root@RK356X:/usr/share/sounds# gpioset 3 19=0
再输入命令,进行查看确认:
root@RK356X:/usr/share/sounds# gpioget 3 19
0
6. 声卡设置与测试
6.1 amixer使用方法
6.1.1 查看帮助信息
声卡相关选型默认都是关闭的,比如耳机和喇叭的左右声道输出等。因此我们在使用之前一定要先设置好声卡,alsa-utils 自带了 amixer这个声卡设置工具。输入如下命令即可査看 amixer的帮助信息:
amixer --help //查看帮助信息
root@RK356X:/usr/share/sounds# amixer --help
Usage: amixer <options> [command]
Available options:
-h,--help this help
-c,--card N select the card
-D,--device N select the device, default 'default'
-d,--debug debug mode
-n,--nocheck do not perform range checking
-v,--version print version of this program
-q,--quiet be quiet
-i,--inactive show also inactive controls
-a,--abstract L select abstraction level (none or basic)
-s,--stdin Read and execute commands from stdin sequentially
-R,--raw-volume Use the raw value (default)
-M,--mapped-volume Use the mapped volume
Available commands:
scontrols show all mixer simple controls
scontents show contents of all mixer simple controls (default command)
sset sID P set contents for one mixer simple control
sget sID gete mixer simple control
controls show all controls for all controls for given card
cset cID P set control conteone control
从图 可以看出,amixer 软件命令分为两组,scontrols、scontents、sset 和 sget 为一组。controls、contents、cset 和 cget 为另一组。这两组的基本功能都是一样的,只不过“s“开头的是 simple(简单)组,这一组命令是简化版,本教程最终使用“s”开头的命令设置声卡,因为少输入很多字符。
6.1.2 查看设置项
amixer scontrols //查看所有设置项
root@RK356X:/usr/share/sounds# amixer scontrols
Simple mixer control 'Playback Path',0
Simple mixer control 'Capture MIC Path',0
6.1.3 查看设置值
amixer scontents //查看设置值
root@RK356X:/usr/share/sounds# amixer scontents
Simple mixer control 'Playback Path',0
Capabilities: enum
Items: 'OFF' 'RCV' 'SPK' 'HP' 'HP_NO_MIC' 'BT' 'SPK_HP' 'RING_SPK' 'RING_HP' 'RING_HP_NO_MIC' 'RING_SPK_HP'
Item0: 'OFF'
Simple mixer control 'Capture MIC Path',0
Capabilities: enum
Items: 'MIC OFF' 'Main Mic' 'Hands Free Mic' 'BT Sco Mic'
Item0: 'MIC OFF'
6.1.4 设置声卡
知道了设置项和设置值,那么设置声卡就很简单了,直接使用下面命令即可:
amixer sset 设置项目 设置值
或:
amixer cset 设置项目 设置值
6.1.5 获取声卡设置值
如果要读取当前声卡某项设置值的话使用如下命令:
amixer sget 设置项目
或
amixer cget 设置项目
6.2 音乐播放设置
6.2.1 使用amixer设置声卡
第一次使用声卡之前一定要先使用 amixer 设置声卡,打开耳机或者喇叭,并且设置喇叭或者耳机音量,还有就是开启左右声道,输入如下命令:
amixer cset name='Master Playback Volume' 'on','on'
amixer cset name='Master Playback Volume' '30','30'
6.2.2 使用aplay播放WAV格式音乐
声卡设置好以后就可以使用 aplay 软件播放 wav 格式的音乐测试一下,aplay 也是 alsa-utils提供的。默认已经在/usr/share/sounds 路径下存放了一个音频了,我们可以直接拿来测试,测试命令如下:
aplay /usr/share/sounds/C400004a29p81sntRV.wav
如果一切设置正常的话就会开始播放音乐。
RK3568S声卡测试
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)