测试指南
测试环境
- 硬件
-
测试板:带有第三方 codec 芯片的测试板
-
PC:用于和测试板交互
-
串口线:连接测试板的调试串口
-
- 软件
-
PC 端串口终端软件
-
alsa-lib 和 alsa-utils 第三方软件包
-
第三方 codec 驱动
-
创建声卡的 machine 驱动
-
创建声卡
- machine 驱动
声卡的驱动分为三部分:platform 驱动、codec 驱动、machine 驱动。对于本章节来说,platform 驱动即 S 驱动。codec 驱动一般会由 codec 厂家提供,内核中也提供了大量的 codec 驱动源码,可以选择相应的 codec 芯片进行测试,本章节会选用 allwinner 的 ac102 芯片。所以在测试前需要做的就是编写声卡的 machine 驱动,machine 驱动实现 platform 驱动和 codec 驱动的耦合,创建声卡,同时确定 dai 和 codec_dai 的连接方式以及支持的格式、采样深度等信息。
创建声卡的一个非常重要的结构体是 link,该结构体用来指定 platform 和 codec 的耦合关系,主要的成员变量如下:struct snd_soc_dai_link { /* config - must be set by machine driver */ const char *name; const char *stream_name; struct snd_soc_dai_link_component *cpus; unsigned int num_cpus; struct snd_soc_dai_link_component *codecs; unsigned int num_codecs; struct snd_soc_dai_link_component *platforms; unsigned int num_platforms; /* format to set on init */ unsigned int dai_fmt; /* machine stream operations */ const struct snd_soc_ops *ops; ... };
dai_link 中成员变量的一些定义规则(规则定义可参考 link 结构体定义或函数 soc_dai_link_sanity_check):-
codecs 必须定义,codecs->name 和 codecs->of_node 必须定义其一,不可以都定义,也不可以都不定义。codecs->dai_name 必须定义
-
cpus 可不定义。但定义时,cpus->name 和 cpus->of_node 二者定义其一,不可以都定义。cpus->dai_name 可定义,也可不定义。cpus->name 和 cpus->of_node 未定义时,将会通过 cpus->dai_name 进行匹配。cpus->dai_name 未定义时,将会通过 cpus->name 或 cpus->of_node 进行匹配。
-
platforms 可不定义。但定义时 platforms->name 和 platforms->of_node 二者定义其一,不可以都定义。platforms->dai_name 在 ALSA 框架中并未使用。
ALSA 框架中提供了一些宏,用来定义上述的一些成员变量,比较常用的是通过宏 DEFS 进行定义。现在内核中比较通用的做法是通过 DEFS 将成员变量定义为空,在声卡的 probe 函数中通过读取 DTS 定义 cpus/codecs/platforms 的 node 变量。这样做的优点是修改 codec 外部配置或连接方式时,只需编译 DTS 即可,不需要重新编译内核。
dai_fmt 变量定义 S 和 codec 之间的音频数据传输方式。
ops 定义 machine 驱动所支持的操作函数集。
将定义的 link 结构体变量赋值给 struct snd_soc_card 结构体的 link 成员变量,然后调用 card 即可完成声卡的注册,具体可参考内核中提供的一些 machine 驱动。
-
- 声卡 DTS
配置需要在 DTS 中配置声卡的结点,才能正确调用声卡的 machine 驱动。DTS 中声卡的结点配置如下(以 allwinner 的 ac102 为例说明):
soundCard { compatible = "artinchip,aic-ac102"; aic,codec-chip = <&ac102>; aic,i2s-controller = <&i2s1>; status = "okay"; };
machine 驱动通过读取 aic,codec-chip 和 aic,i2s-controller 属性获取相应的 s 和 codec 结点。SOC 一般是通过 C 接口对 codec 芯片进行控制,所以需要在 C 控制器下挂接 codec 芯片&i2c3 { pinctrl-names = "default"; pinctrl-0 = <&i2c3_pins_b>; status = "okay"; ac102: ac102@33 { compatible = "allwinner,ac102"; reg = <0x33>; }; };
音频测试
- 测试音频播放
aplay test.wav
test_wavplay /sdcard/wav/test.wav //播放 SD 卡音频文件
- 测试音频录音
arecord -d 10 -f dat -t wav test.wav
-
-d:指定录音时长,单位为秒
-
-f:指定录制的格式,dat 表示 16bit 小端数据,48K 采样率,立体声
-
-t:指定生成的文件格式,为 wav 文件
-
test.wav:生成的 wav 文件名
-