Where is the documentation on I2S support in Radxa Zero 2 Pro?

I’ve been trying to find any supporting documents related to I2S communication for connecting a WM8960 audio codec HAT with the Radxa Zero 2 Pro. There is nothing mentioned related to the I2S for the Radxa Zero 2 Pro which has the Amlogic A311D and the A311D has I2S support. If anyone experienced with Radxa and WM8960 integration is out there please shed some light on the dark arts of I2S communication
Thank you in advance.

Here is a dts based on zero, it is similar to zero2: https://github.com/radxa-pkg/radxa-overlays/pull/389/files
Currently not merged because we didn’t find the right alsamixer configuration, currently it will output at the same time as hdmi

2 Likes

Hi, the pull request you shared is for pcm5102a codec. Is there any Radxa Board with support for WM8960 that I can refer for writing my own dts overlay for wm8960?

I have written a device tree overlay for integrating wm8960. Since I don’t use hdmi sound output I disabled the sound node in the overlay and configured the i2c and tdm interfaces with the help of claude 3.7

/plugin/;


#include <dt-bindings/clock/axg-clkc.h>


/ {
 metadata {
        title = "Enable WM8960 Audio Codec on TDM B - Test 11";
        compatible = "radxa,zero2", "amlogic,a311d", "amlogic,g12b";
        category = "audio";
        description = "Enable WM8960 Audio Codec on TDM B interface";
        exclusive = "tdmif_b";
    };
    fragment@0 {
        // Disable the existing sound node that uses TDMB for HDMI audio
        target-path = "/";
        __overlay__ {
            sound {
                status = "disabled";
            };
        };
    };

    fragment@1 {
        target-path = "/";
        __overlay__ {
            wm8960_mclk: wm8960_mclk {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency = <12288000>; // 12.288MHz standard audio clock
            };
        };
    };

    fragment@2 {
        // Target the I2C EE_M3 bus (i2c3)
        target = <&i2c3>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            status = "okay";

            wm8960: wm8960@1a {
                compatible = "wlf,wm8960";
                reg = <0x1a>;
                #sound-dai-cells = <0>;
                // Using proper power supplies that match Raspberry Pi voltage requirements
                AVDD-supply = <&ao_5v>;
                DVDD-supply = <&vcc_3v3>;
            };
        };
    };

    fragment@3 {
        // Create a new sound node for WM8960
        target-path = "/";
        __overlay__ {
            sound_wm8960 {
                compatible = "amlogic,axg-sound-card";
                model = "RADXA-ZERO2-WM8960";
                
                audio-widgets = 
                    "Headphone", "Headphone Jack",
                    "Speaker", "External Speaker",
                    "Microphone", "Mic Jack";
                
                audio-routing =
                    "Headphone Jack", "HP_L",
                    "Headphone Jack", "HP_R",
                    "External Speaker", "SPK_LP",
                    "External Speaker", "SPK_LN",
                    "LINPUT1", "Mic Jack",
                    "LINPUT2", "Mic Jack",
                    "LINPUT3", "Mic Jack",
                    "RINPUT1", "Mic Jack",
                    "RINPUT2", "Mic Jack",
                    "RINPUT3", "Mic Jack";
                
                status = "okay";
                
                // Reuse these clock settings from the original sound node
                clocks = <&clkc CLKID_MPLL2>,
                         <&clkc CLKID_MPLL0>,
                         <&clkc CLKID_MPLL1>;

                assigned-clocks = <&clkc CLKID_MPLL2>,
                                  <&clkc CLKID_MPLL0>,
                                  <&clkc CLKID_MPLL1>;
                assigned-clock-parents = <0>, <0>, <0>;
                assigned-clock-rates = <294912000>,
                                       <270950400>,
                                       <393216000>;
                
                // Import the existing FRDDRs
                dai-link-0 {
                    sound-dai = <&frddr_a>;
                };

                dai-link-1 {
                    sound-dai = <&frddr_b>;
                };

                dai-link-2 {
                    sound-dai = <&frddr_c>;
                };
                
                // TDM B interface for WM8960
                dai-link-3 {
                    sound-dai = <&tdmif_b>;
                    dai-format = "i2s";
                    dai-tdm-slot-tx-mask-0 = <1 1>;
                    dai-tdm-slot-rx-mask-0 = <1 1>;
                    mclk-fs = <256>;
                    
                    codec {
                        sound-dai = <&wm8960>;
                    };
                };
            };
        };
    };

    fragment@4 {
        // Configure TDMB interface for I2S mode
        target = <&tdmif_b>;
        __overlay__ {
            status = "okay";
            pinctrl-0 = <&tdm_b_sclk_pins>, <&tdm_b_fs_pins>, <&tdm_b_din0_pins>, <&tdm_b_din1_pins>;
            pinctrl-names = "default";
            i2s-mode = <1>; // I2S mode
            mclk-fs = <256>;
        };
    };
    
    fragment@5 {
        target = <&tdmout_b>;
        __overlay__ {
            status = "okay";
        };
    };
    
    fragment@6 {
        // Enable I2C3 for the WM8960 codec
        target = <&i2c3>;
        __overlay__ {
            status = "okay";
            // Note: This overlay assumes the I2C3 pins are already defined in the base DTS
            // If you need specific pin configurations, please provide the pin definitions
        };
    };
};

I can see the sound card recognized with

➜  ~ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: RADXAZERO2WM896 [RADXA-ZERO2-WM8960], device 2: fe.dai-link-2 (*) []
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 0: RADXAZERO2WM896 [RADXA-ZERO2-WM8960], device 3: fe.dai-link-1 (*) []
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 0: RADXAZERO2WM896 [RADXA-ZERO2-WM8960], device 4: fe.dai-link-0 (*) []
  Subdevices: 0/1
  Subdevice #0: subdevice #0
➜  ~ 

But when I run speaker-test there is no audio out of the speaker but it is recognized.

➜  ~ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: RADXAZERO2WM896 [RADXA-ZERO2-WM8960], device 2: fe.dai-link-2 (*) []
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 0: RADXAZERO2WM896 [RADXA-ZERO2-WM8960], device 3: fe.dai-link-1 (*) []
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 0: RADXAZERO2WM896 [RADXA-ZERO2-WM8960], device 4: fe.dai-link-0 (*) []
  Subdevices: 0/1
  Subdevice #0: subdevice #0
➜  ~ 

speaker-test 

speaker-test 1.2.8

Playback device is default
Stream parameters are 48000Hz, S16_LE, 1 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 128 to 2097152
Period size range from 64 to 1048576
Using max buffer size 2097152
Periods = 4
was set period_size = 524288
was set buffer_size = 2097152
 0 - Mono
^C

Using i2cdetect I can see the i2c device at the 0x1a address

[sudo] password for radxa: 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
20: -- -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --  

If anyone have knowledge about amlogic axg sound interface let me know what is wrong with the audio dts and how I can debug this issue. Any help is much appreciated.