LinuxWM8960和声卡驱动

设备树

6.6.52版本Kernel中NXP已经默认在imx6ul-14x14-evk.dtsi中配置好了wm8960的节点,但是是配置在i2c2下,而正点原子阿尔法开发板中wm8960接在i2c1下,所以要把节点从i2c2移到i2c1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";

/* 省略其他节点 */

codec: wm8960@1a {
#sound-dai-cells = <0>;
compatible = "wlf,wm8960";
reg = <0x1a>;
wlf,shared-lrclk;
wlf,hp-cfg = <3 2 3>;
wlf,gpio-cfg = <1 3>;
clocks = <&clks IMX6UL_CLK_SAI2>;
clock-names = "mclk";
};
};

根节点下还需要创建一个sound节点,NXP默认也已经配置好了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/ {
/* 省略其他节点 */

sound-wm8960 {
compatible = "fsl,imx-audio-wm8960";
model = "wm8960-audio";
audio-cpu = <&sai2>;
audio-codec = <&codec>;
audio-asrc = <&asrc>;
hp-det-gpio = <&gpio5 4 0>;
audio-routing =
"Headphone Jack", "HP_L",
"Headphone Jack", "HP_R",
"Ext Spk", "SPK_LP",
"Ext Spk", "SPK_LN",
"Ext Spk", "SPK_RP",
"Ext Spk", "SPK_RN",
"LINPUT2", "Mic Jack",
"LINPUT3", "Mic Jack",
"RINPUT1", "AMIC",
"RINPUT2", "AMIC",
"Mic Jack", "MICB",
"AMIC", "MICB";
status = "okay"; /* must add this */
};
}

注意最后的status = "okay"必须要加,不然ALSA识别不到。

Menuconfig里默认已经启用了wm8960在imx系列board上的区别,ALSA模拟OSS的API也已经关闭,保持默认即可。

alsa-lib & alsa-utils

照着教程来做就可以,不一样的地方在于,65.4.2节移植alsa-utils时,makefile可能会报错:

mv: 无法获取"t-ja.gmo" 的文件状态(stat): 没有那个文件或目录
make[2]: *** [ja.gmo] 错误 1

而且报错不止一个文件,都位于alsaconf/po/下,解决办法是自己创建一个空文件 ~/alsa-utils-xxx/alsaconf/po/t-ja.gmo,缺什么就添加什么,反正alsaconf这个功能暂时用不到。

aplay报错

按照教程执行aplay后kernel报错:

Playing WAVE ‘RWR.wav’ : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo

imx-sdma 20ec000.dma-controller: sdma or sdma firmware not ready!

fsl-sai 202c000.sai: ASoC: error at soc_component_trigger on 202c000.sai: -12

aplay: pcm_write:2178: write error: Input/output error

考虑到这四条消息是一起跳出来的,上网查了一圈ASoC错误很少有人提及,一般都是时钟配置有问题,要么就是硬件设计时的错误,但考虑到我直接用的是NXP原厂的设备树,并且板子是现成的开发板,基本可以排除硬件设计原因。因此我猜测问题是由sdma没初始化引起的,因为alsa会调用sdma来进行音频流的传输。

参考这篇文章进行sdma的配置:正点原子I.MAX6ULL kernel6.6移植遇到的问题

配置完成后,重新编译kernel,下载,再调用aplay,就能够成功播放了。

alsactl 提示no such file or directory

参考文章
制作根文件系统的时候没有/var/lock的目录,alsactl默认会在/var/lock目录操作,所以就会失败。解决办法是mkdir -p /var/lock


LinuxWM8960和声卡驱动
http://akichen891.github.io/2025/04/16/LinuxWM8960和声卡驱动/
作者
Aki
发布于
2025年4月16日
更新于
2025年4月16日
许可协议