一、硬件环境
本文为RK3288芯片,参考开发板型号为RK3288 EVB板,内核:Linux4.4,Android7.1编译,采用的音频芯片型号为AW811XX
二、内核驱动的配置
一个声卡包含cpu_dai,codec_dai,以及dai_link组成,分别对应cpu dai的dirver,比如I²S driver,spdif driver;codec driver,比如rt5640 codec driver;dai_link driver,也就是 machine driver,比如 sound/soc/rockchip/rockchip_rt5640.c。4.4的内核中支持两种方式创建声卡,一种是通用的simple-card framework,一种是传统的编写自定义的machine driver来创建。
本文使用simple-card,即简单通用的 machine driver。现添加步骤如下:
- 将厂家提供的文件包,包括驱动程序源文件(.c、.h文件)添加至sound/soc/codec/目录下,本文在该目录下新建了awinic文件夹,所有源文件统一放在该目录下。
- 修改 sound/soc/codec/Kconfig 以及 Makefile 加入驱动编译。具体添加信息如下:
sound/soc/codec/Kconfig:
config SND_SOC_AW881XX
tristate "Realtek AW881XX CODEC"
depends on I2C
sound/soc/codec/Makefile:
obj-$(CONFIG_SND_SOC_AW881XX) += snd-soc-aw881xx.o
snd-soc-aw881xx-objs := awinic/aw881xx.o awinic/aw881xx_monitor.o awinic/aw881xx_cali.o
- 在rockchip_defconfig文件下选中配置信息(图形化界面配置方法)
CONFIG_SND_SOC_AW881XX=y
- 添加相应的bin文件( aw881xx fw&cfg)。在 kernel/drivers/base/firmware_class.c 中添加 bin 文件目录, 目录由系统决定, 一般目录为/system/vendor/firmware 或/system/etc/firmware。
PRODUCT_COPY_FILES += \
vendor/hikvision/firmware/aw881xx_acf.bin:vendor/firmware/aw881xx_acf.bin
上述内核配置好后接下来配置相应设备树文件。
三、设备树参配置
由于采用的是simple-card框架,因此首先搭建该框架的设备树模型。具体如下:
sound: sound {
status = "okay";
compatible = "simple-audio-card"; //simple-card驱动属性名
simple-audio-card,format = "i2s"; //标准音频通讯接口
simple-adudio-card,name = "rockchip,aw881xx-codec"; //声卡名称
simple-audio-card,mclk-fs = <256>; //默认配置
simple-audio-card,widgets =
"Microphone", "Microphone Jack",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"MIC1", "Microphone Jack",
"MIC2", "Microphone Jack",
"Microphone Jack", "micbias1",
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
simple-audio-card,dai-link@0 {
format = "i2s";
cpu {
sound-dai = <&i2s>;
};
codec {
sound-dai = <&aw881xx>; //在该框架下的aw881xx芯片配置信息
};
};
/*下面为其它音频芯片配置信息,需要在该框架下添加音频芯片按照该模式添加*/
simple-audio-card,dai-link@1 {
format = "i2s";
cpu {
sound-dai = <&i2s>;
};
codec {
sound-dai = <&es7210>;
};
};
};
上述为simple-card框架,接着需要指定aw881xx节点信息,即本文所用音频芯片。具体如下:
&i2c2 {
status = "okay";
......
aw881xx: aw881xx@34 {
#sound-dai-cells = <0>;
compatible = "awinic,aw881xx_smartpa"; //aw881xx驱动中的属性名
reg = <0x34>; //厂家提供资料中的reg地址
reset-gpio = <&gpio7 9 GPIO_ACTIVE_HIGH>; //根据电路图实际情况进行填写。
fade-enable = <0>; //厂家提供资料里的配置信息。具体作用不详
pa-syn-enable = <0>; //厂家提供资料里的配置信息。具体作用不详
status = "okay";
};
......
};
四、调试与分析
在测试过程中,首先有两个测试指令确认声卡是否注册成功,如下(为了偷懒,直接选取的手册上的信息):
root@rk3366:/ # cat /proc/asound/cards
0 [rockchiprt5640c]: rockchip_rt5640 - rockchip,rt5640-codec
rockchip,rt5640-codec
root@rk3366:/ # ls -l /dev/snd/
crw-rw---- system audio 116, 2 2013-01-18 08:51 controlC0
crw-rw---- system audio 116, 4 2013-01-18 08:51 pcmC0D0c
crw-rw---- system audio 116, 3 2013-01-18 08:51 pcmC0D0p
主要有以下几个问题:
问题1:
通过上面第一个指令测试时,提示未发现设备,由此分析应该是驱动程序未加载进去,通过仔细检查发现问题所在。因为本人选取驱动时是通过make menuconfig图形化界面进行选取,而在编译时又执行了make ARCH=arm rockchip_defconfig,由于我未在该文件内添加CONFIG_SND_SOC_AW881XX=y指令,因此在执行上述命令后会将我通过图形化界面配置的信息进行清除,这个问题其实本人在上学阶段也遇到过,时间间隔太久搞忘记了。
修改之后,重新执行第一条测试指令,会发现我在设备树中注册的rockchip,aw881xx-codec声卡名称。
问题2:
当驱动什么的都注册成功后,需要测试实际音频信息,具体测试指令如下:
root@rk3366:/ # tinyplay
Usage: tinyplay file.wav [-D card] [-d device] [-p period_size] [-n n_periods]
|root@rk3366:/ # tinyplay /sdcard/test44.wav -D 0 -d 0 -p 1024 -n 3
Playing sample: 2 ch, 44100 hz, 32 bit
本文设备需要播放双通道的音频文件,若播放单通道或双通道以上的音频文件时会进行提示,因此我通过格式转换工厂制作了一个双通道的音频文件,因此这就为我调试一整天埋下了伏笔。-----通过上述命令测试,出现如下问题:
作者我从配置的每一个字母进行排查,以及针对提示错误对驱动程序进行逐级的查找,硬是没有发现什么问题,但是测试结果仍然出现这个问题,整整浪费了我一整天的时间。最后,找我同事拿了他们测试的标准音频文件,结果成了!原来问题出在我的音频文件上。
五、小结
之前在学校从未配置过音频驱动,这是作者我第一次配置,虽然配置信息厂家有提供且不多,但是实际仍然碰到了很多小问题,一般经验丰富的老手优势就在于经验丰富,有些小坑自动略过了,大坑也能依靠经验找到解决办法。