The debugging wm8960 audio driver encountered a lot of pits. After several days of research, it was finally debugged.
Drive commissioning steps
Whether the driver can be loaded successfully is not only the first step of debugging, but also one of the most critical steps.
1. View the hardware schematic diagram:
2. Open the corresponding device tree (stm32mp157a XXX. Dtsi):
Because wm8960 is mounted on I2C4, add wm8960 device node on I2C4 node of device tree.
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; }; }; };
The node clocks = < SAI2A > depends on whether the schematic uses SAI2A or SAI2B as the master clock.
3.SAI2 configuration:
&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>; }; }; }; };
The more important one is the input and output problem of sai2a and sai2b. The above schematic diagram describes sai2a as ADC (capture) and sai2b as DAC(playback). Therefore, at this time, DMA names in sai2a node = 'tx', sai2b is DMA names = 'rx', and St, sync = < & sai2a 2 >;
Here you can refer to the kernel source code path: Documentation/devicetree/bindings/sound/st,stm32-sai.txt document
4.sound node configuration
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. Configuration pin (stm32mp15 pinctrl. Dtsi):
sai2a_pins_a: sai2a-0 { pins { pinmux = <STM32_PINMUX('I', 6, AF10)>; /* SAI2_SD_A */ bias-disable; drive-push-pull; slew-rate = <0>; }; }; sai2a_sleep_pins_a: sai2a-1 { pins { pinmux = <STM32_PINMUX('I', 6, ANALOG)>; /* SAI2_SD_A */ }; }; sai2b_pins_b: sai2b-2 { pins { pinmux = <STM32_PINMUX('E', 11, AF10)>, /* SAI2_SD_B */ <STM32_PINMUX('I', 5, AF10)>, /* SAI2_SCK_A */ <STM32_PINMUX('I', 7, AF10)>, /* SAI2_FS_A */ <STM32_PINMUX('E', 0, AF10)>; /* SAI2_MCLK_A */ bias-disable; drive-push-pull; slew-rate = <0>; }; }; sai2b_sleep_pins_b: sai2b-3 { pins { pinmux = <STM32_PINMUX('E', 11, ANALOG)>, /* SAI2_SD_B */ <STM32_PINMUX('I', 5, ANALOG)>, /* SAI2_SCK_A */ <STM32_PINMUX('I', 7, ANALOG)>, /* SAI2_FS_A */ <STM32_PINMUX('E', 0, ANALOG)>; /* SAI2_MCLK_A */ }; };
6. View startup information:
If the above start printing message appears, it proves that wm8960 driver loading is successful. Next, let's see if there are any sound card nodes.
[root@stm32mp157]:~# ls /dev/snd/ by-path/ controlC0 pcmC0D0c pcmC0D1p timer
pcmC0D0c is a recording device
pcmC0D1p is a playback device
[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
Sound card 0, device 0 -- > is a recording device
Sound card 0, device 1 -- > is a playback device
7. Fault problem
If you use the command: aplay xxx.wav, it is stuck in the command line all the time and there is no error message. You need to check the schematic diagram and whether it corresponds to the configuration problem of the device tree.
If aplay xxx.wav, the following error message appears:
[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
You need to use aplay -l to check the playing device number and check whether / etc/asound.conf is configured correctly. You can use the command aplay -Dhw:0.1 xxx.wav to specify the device playback.
asound.conf configuration file
Once the driver was loaded successfully, but there was no sound. After checking the hardware and driver, there was no problem. alsamixer also set the sound level, but it still didn't work. It was found that asound.conf would also have a certain impact.
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 }
experience
When you encounter a problem, don't worry. Driving the printing information will help you find the cause of the failure. If it doesn't work, you can refer to the successful cases of others and change the hardware circuit to the same one to see whether it is a hardware or chip problem.
Attach wm8960 driver file and asound.conf configuration file link: