这次调试wm8960音频驱动遇到了好多的坑,研究好几天终于调试好了。
驱动调试步骤
驱动能不能成功加载是调试的第一大步骤,也是最关键的步骤之一。
1.查看硬件原理图:
2.打开对应的设备树(stm32mp157a-xxx.dtsi):
因为wm8960是挂载到I2C4上,所以在设备树I2C4节点上添加wm8960设备节点。
wm8960: wm8960@1a {
compatible = "wlf,wm8960";
reg = <0x1a>;
#sound-dai-cells = <0>;
status = "okay";
wlf,shared-lrclk;
clocks = <&sai2a>;
clock-names = "mclk";
port {
#address-cells = <1>;
#size-cells = <0>;
wm8960_tx_endpoint: endpoint@0 {
reg = <0x0>;
remote-endpoint = <&sai2b_endpoint>;
frame-master;
bitclock-master;
};
wm8960_rx_endpoint: endpoint@1 {
reg = <0x1>;
remote-endpoint = <&sai2a_endpoint>;
frame-master;
bitclock-master;
};
};
};
其中节点的clocks =< sai2a >是需要看原理图使用的是SAI2A 还是SAI2B作为主时钟。
3.SAI2配置:
&sai2 {
clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
clock-names = "pclk", "x8k", "x11k";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
status = "okay";
sai2a: audio-controller@4400b004 {
dma-names = "rx";
#clock-cells = <0>;
clocks = <&rcc SAI2_K>;
clock-names = "sai_ck";
status = "okay";
sai2a_port: port {
sai2a_endpoint: endpoint {
remote-endpoint = <&wm8960_rx_endpoint>;
format = "i2s";
mclk-fs = <256>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <16>;
};
};
};
sai2b: audio-controller@4400b024 {
dma-names = "tx";
st,sync = <&sai2a 2>;
clocks = <&rcc SAI2_K>, <&sai2a>;
clock-names = "sai_ck", "MCLK";
status = "okay";
sai2b_port: port {
sai2b_endpoint: endpoint {
remote-endpoint = <&wm8960_tx_endpoint>;
format = "i2s";
mclk-fs = <256>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <16>;
};
};
};
};
其中比较重要的是sai2a,sai2b的输入输出问题,上述原理图描述的是sai2a作为ADC(capture),sai2b作为DAC(playback),所以,此时sai2a节点中的dma-names = ‘tx’,sai2b则是dma-names = ‘rx’,另外还有st,sync = <&sai2a 2>;
这里可以参考内核源码路径:Documentation/devicetree/bindings/sound/st,stm32-sai.txt文档
4.sound节点配置
sound: sound {
compatible = "audio-graph-card";
label = "wm8960-audio";
mclk-fs = <256>;
dai-format = "i2s";
widgets =
"Microphone", "Mic Jack",
"Line", "Line In",
"Line", "Line Out",
"Speaker", "Speaker",
"Headphone", "Headphone Jack";
routing =
"Headphone Jack", "HP_L",
"Headphone Jack", "HP_R",
"Speaker", "SPK_LP",
"Speaker", "SPK_LN",
"Speaker", "SPK_RP",
"Speaker", "SPK_RN",
"LINPUT1", "MICB",
"LINPUT3", "MICB";
dais = <&sai2a_port &sai2b_port>;
status = "okay";
};
5.配置引脚(stm32mp15-pinctrl.dtsi):
sai2a_pins_a: sai2a-0 {
pins {
pinmux = <STM32_PINMUX('I', 6, AF10)>;
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
};
sai2a_sleep_pins_a: sai2a-1 {
pins {
pinmux = <STM32_PINMUX('I', 6, ANALOG)>;
};
};
sai2b_pins_b: sai2b-2 {
pins {
pinmux = <STM32_PINMUX('E', 11, AF10)>,
<STM32_PINMUX('I', 5, AF10)>,
<STM32_PINMUX('I', 7, AF10)>,
<STM32_PINMUX('E', 0, AF10)>;
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
};
sai2b_sleep_pins_b: sai2b-3 {
pins {
pinmux = <STM32_PINMUX('E', 11, ANALOG)>,
<STM32_PINMUX('I', 5, ANALOG)>,
<STM32_PINMUX('I', 7, ANALOG)>,
<STM32_PINMUX('E', 0, ANALOG)>;
};
};
6.查看启动信息:
如果出现上述的启动打印信息,证明wm8960驱动加载成功了。接下来看看有无有出现声卡节点。
[root@stm32mp157]:~# ls /dev/snd/
by-path/ controlC0 pcmC0D0c pcmC0D1p timer
pcmC0D0c 是录音设备
pcmC0D1p 是播放设备
[root@stm32mp157]:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: wm8960audio [wm8960-audio], device 1: 4400b024.audio-controller-wm8960-hifi wm8960-hifi-1 [4400b024.audio-controller-wm8960-hifi wm8960-hifi-1]
Subdevices: 1/1
Subdevice #0: subdevice #0
[root@stm32mp157]:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: wm8960audio [wm8960-audio], device 0: 4400b004.audio-controller-wm8960-hifi wm8960-hifi-0 [4400b004.audio-controller-wm8960-hifi wm8960-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
声卡0,设备0 -->是录音设备
声卡0,设备1 -->是播放设备
7.故障问题
如果使用命令:aplay xxx.wav,一直卡在命令行不结束,没有任何的报错信息,你需要查看原理图,是否对应设备树的配置问题。
如果aplay xxx.wav ,出现以下报错信息:
[root@-stm32mp157]:~# aplay -Dhw:0.0 /usr/share/sounds/alsa/Rear_Right.wav
ALSA lib …/…/…/alsa-lib-1.2.1.2/src/pcm/pcm_hw.c:1829:(_snd_pcm_hw_open) Invalid value for card
aplay: main:828: audio open error: No such device
需要使用aplay -l 查看播放的设备号,查看/etc/asound.conf配置的是否正确。可以使用命令 aplay -Dhw:0.1 xxx.wav 来指定设备播放。
asound.conf配置文件
曾经驱动加载也成功了,就是没有声音,查了硬件和驱动都没有什么问题,alsamixer也设置了声音的高低,还是不行,发现asound.conf也会有一定的影响。
pcm.dmix_44100{
type dmix
ipc_key 5678293
ipc_key_add_uid yes
slave{
pcm "hw:0,0"
period_time 40000
buffer_time 360000
format S16_LE
rate 44100
}
}
pcm.!dsnoop_44100{
type dsnoop
ipc_key 5778293
ipc_key_add_uid yes
slave{
pcm "hw:0,1"
period_time 40000
buffer_time 360000
format S16_LE
rate 44100
}
}
pcm.asymed{
type asym
playback.pcm "dmix_44100"
capture.pcm "dsnoop_44100"
}
pcm.dsp0{
type plug
slave.pcm "asymed"
}
pcm.!default{
type plug
route_policy "average"
slave.pcm "asymed"
}
ctl.!default{
type hw
card 0
}
ctl.mixer0{
type hw
card 0
}
心得体会
当遇到问题的时候,不要急,驱动打印信息会帮你找到失败的原因,还是不行的话,可以参考别人成功的案例,在硬件电路改成一样的,看是否是硬件或者芯片的问题。
附上wm8960驱动文件和asound.conf的配置文件链接:wm8960驱动文件及asound.conf配置文件
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)