PCM audio CM3 on I2S1_M1

I’m facing a problem with the Radxa CM3.

For our application we want to use the I2S1_M1 bus for digital audio(on pins 25, 26, 27 & 49).

The codec we use will be configured from our own application, so not through Alsa/Pulseaudio.

The CM3 has to generate the clock and framesync, because the codec can only be slave. The framesync must be a short pulse, so we use pcm: dsp_b.

I disabled the internal RK817 codec via an overlay.
Through another overlay I set the correct pins, and made an audio card.

Aplay -l shows my playback device, arecord -l shows the recording device.

Playback works fine, the CM3 creates clock and framesync. The audio from the codec is clear.

When recording audio, the CM3 also generates the clock and framesync. We see pcm data on the oscilloscope, but the recording is completely silent (not even noise).
I tried recording with the following commands:

  • arecord recording.wav
  • arecord -D hw:1,0 –f S16_LE -c 2 -r 8000 recording.wav
  • parecord recording.wav

To test the codec I connected it to another pcm device, it works fine in both directions. So I’m sure my hardware is okay.

I’ve tested this on multiple radxa images:

  • Debian Bullseye 20221101-0118
  • Debian Bullseye 20220901-0102
  • Debian Buster 20220311-0259
  • Ubuntu Focal Server 20221001-0126

Am I missing something why recording doesn’t work?

This is my overlay to create the audiocard (I’ve also tested with “flatmax,bare” and “linux,spdif-dit/spdif-dir” but these have the same problem):

/dts-v1/;
/plugin/;

/ {
    compatible = "rockchip,rk3566";

    fragment@0 {
        target-path = "/";
        __overlay__ {
                my_soundcard {
                    compatible = "simple-audio-card";
                    simple-audio-card,name = "i2smasterdummy";
                    simple-audio-card,format = "dsp_b";
                    status="okay";

                   simple-audio-card,cpu {
                        sound-dai = <&i2s1_8ch>;
                        //dai-tdm-slot-num = <2>;
                        //dai-tdm-slot-width = <32>;
                   };
                   simple-audio-card,codec {
                        sound-dai = <&codec_dummy>;
                   };

                };
                codec_dummy: codec_dummy {
                compatible = "rockchip,dummy-codec";
                #sound-dai-cells = <0>;
                status = "okay";
            };

        };
    };

    fragment@1 {
        target = <&i2s1_8ch>;
        __overlay__ {
            #sound-dai-cells = <0>;
            rockchip,clk-trcm = <1>;  //0: both tx_lrck/bclk and rx_lrck/bclk are used; 1: only tx_lrck/bclk is used; 2: only rx_lrck/bclk is used
            pinctrl-0 = <&i2s1m1_sclktx &i2s1m1_lrcktx &i2s1m1_sdo0 &i2s1m1_sdi0>;
            rockchip,playback-channels = <2>;
            rockchip,capture-channels = <2>;
            status = "okay";
        };
    };
        fragment@2{
                target = <&i2s2_2ch>;
                __overlay__ {
                        status = "disabled";
                };
        };
};

We are currently looking into this. However, have you tried to set the output like mentioned in this post?

Yes, I had already seen this post, and tried this as well.
I don’t have the option to use i2s3, so I changed that to i2s1.

I have the same problem with Flatmax’s overlay.

I’ve created and tested a branch on the buidlroot.rockchip repo which generates I2S audio on the cm3 boards using the i2s1 bus.

We finally got it done.

On the Flatmax buildroot we immediately had audio over the i2s1 bus.
Buildroot is not suitable for our application. So we took the rk3308 codec from buildroot, and compiled it as a kernel module.

I loaded this module in the Debian image of Radxa, with the dt-overlay from Flatmax.

This works, but only if the i2s1_mclk is also in the “pinctrl-0” section (even though we don’t use this pin).

Thanks for the support!

Our overlay:

/dts-v1/;
/plugin/;

// Example dts overlay for the rk33xx

/ {
        compatible = "rockchip,rk3399";

        fragment@0 {
                        target = <&i2s1_8ch>;
                        __overlay__ {
                                rockchip,clk-trcm = <1>;
                                pinctrl-names = "default";
                                pinctrl-0 = <&i2s1m1_sclktx
                                             &i2s1m1_lrcktx
                                             &i2s1m1_sdi0
                                             &i2s1m1_sdo0
                                             &i2s1m1_mclk>;

                                status = "okay";
                        };
        };

        fragment@1 {
                target-path = "/";
                __overlay__ {
                        sound {
                                status = "okay";
                                compatible = "simple-audio-card";
                                simple-audio-card,name = "test";
                                simple-audio-card,format="dsp_b";

                                simple-audio-card,bitclock-master = <&cpu_dai>;
                                simple-audio-card,frame-master = <&cpu_dai>;
                                simple-audio-card,mclk-fs = <256>;

                                cpu_dai: simple-audio-card,cpu {
                                        sound-dai = <&i2s1_8ch>;
                                };

                                codec_dai: simple-audio-card,codec {
                                        sound-dai = <&i2s1_out>;
                                };

                        };

                        i2s1_out: i2s1-out {
              #sound-dai-cells = <0>;
              compatible = "flatmax,bare";
              status = "okay";
      };
                };
        };

        fragment@2 {
                target = <&hdmi_sound>;
                __overlay__ {
                        status = "disabled";
                };
        };
};