Simple-audio-card on I2S1, which clocks to use?

I’m trying to create a device tree overlay that creates an external sound card using simple-audio-card ASoC driver to interface with a WM8731 development board. Here’s my attempt at the overlay:

/dts-v1/;
/plugin/;

/ {

    compatible = "rockchip,rockpi","rockchip,rk3399";

    fragment@0 {
        target = <&i2s1>;
        __overlay__ {
            status = "okay";
        };
    };

    fragment@1 {
        target = <&i2c7>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            status = "okay";

            wm8731: wm8731@1a {
                #sound-dai-cells = <0>;
                compatible = "wlf,wm8731";
                reg = <0x1a>;
                status = "okay";
            };
        };
    };

    fragment@2 {
        target-path = "/sound-ext-card";
        __overlay__ {
           status = "okay";
           compatible = "simple-audio-card";
           simple-audio-card,format = "i2s";
           simple-audio-card,name = "rockchip,wm8731-codec";
           simple-audio-card,widgets =
              "Microphone", "Mic Jack",
              "Headphone", "Headphone Jack";
           simple-audio-card,routing =
              "Mic Jack", "MICIN",
              "Headphone Jack", "LHPOUT",
              "Headphone Jack", "RHPOUT";
           simple-audio-card,bitclock-master = <&sac_cpu>;
           simple-audio-card,frame-master = <&sac_cpu>;
           sac_cpu: simple-audio-card,cpu {
               sound-dai = <&i2s1>;
           };
           sac_codec: simple-audio-card,codec {
               sound-dai = <&wm8731>;
           };
       };
   };

};

This almost works - I get a new card/device (card 2: rockchipwm8731c [rockchip,wm8731-codec], device 0) showing up in aplay -l, but when I try to play a .wav file through it, i hear nothing. actually i hear almost nothing, except for some very faint noise/glitches. When I scope the I2S lines, I see this:

The SCLK frequency is 46.88 kHz, and there are 64 SCLK cycles per LRCK cycle. What I would expect to see, is SCLK running at 48 kHz * 2 * 16 = 1.536 MHz, and then 32 SCLK cycles per LRCK cycle. So
something is obviously wrong here: the clock is running way too slow, and ratio of SCLK to LRCK is
off by a factor of 2.

When I look at the way the ES8316 (on-board codec) is configured in the device tree, I notice a few things different. First, there is the simple-audio-card,mclk-fs property, which is set to 256 for the ES8316. If I try to set that to anything in my overlay, I get a device which responds with “unable to install hw params” while trying aplay.

The other thing I noticed in this .dsti is that the ES8316 sub-node of the i2c1 device node makes reference to some clock parameters:

es8316: es8316@11 {
	#sound-dai-cells = <0>;
	compatible = "everest,es8316";
	reg = <0x11>;
	clocks = <&cru SCLK_I2S_8CH_OUT>;
	clock-names = "mclk";
	pinctrl-names = "default";
	pinctrl-0 = <&i2s_8ch_mclk>;
};

What is the meaning of this “&cru SCLK_I2S_8CH_OUT”? Should I put something similar (perhaps 2CH_OUT?) in my overlay? What are my options?

In summary, how should I configure the clocks for this I2S1 overlay?

I can’t tell you what’s going wrong with your sclk being so low, BUT, I can tell you that the LRCK = 64xSCLK ratio is just fine and no cause for concern. In fact, a more typical configuration for i2s is actually to set it up at 48k232 = 3M.

Here is the wonderful thing about i2s: You can interface devices that speak in different sample sizes together without anybody knowing about it. A 24 or 32 bit device will write 24 or 32 bit samples. A 16 bit device will receive the samples and ignore the extra bits, using only the 16 most significant bits. It will be able to play back the sample without trouble.

Similarly in the opposite direction – a 16 bit device will write 16 bit samples, the 24 or 32 bit device will read 24 or 32 bits, and the least significant bits will just be padding.

Its only when you get into other wire protocols, like DSP mode, where the two sides have to agree on the sample length, because it is the only way to know where the 2nd, 3rd, etc. samples begin.

@groupvelocity

Some PR about the WM8731, I think it’s your work?

https://github.com/radxa/kernel/pull/4/commits/449f587e3b866a2e9a119bf0669848c28d7e6eaa

very interesting, thanks for the link - that is not my PR. but if the audioinjector driver works, then it should work for my dev board as well (it’s the same codec, and in fact i was able to get it working on raspberry pi with the audioinjector driver).

i was able to compile and install the driver/overlay from that PR, but upon rebooting, i get the following in dmesg:

audioinjector-stereo sound-ext-card: ASoC: machine hw_params failed: -22

and aplay gives a similar error:

Playing WAVE 'LRMonoPhase4.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
aplay: set_params:1363: Unable to install hw params:
ACCESS:  RW_INTERLEAVED
FORMAT:  S16_LE
SUBFORMAT:  STD
SAMPLE_BITS: 16
FRAME_BITS: 32
CHANNELS: 2
RATE: 48000
PERIOD_TIME: 125000
PERIOD_SIZE: 6000
PERIOD_BYTES: 24000
PERIODS: 4
BUFFER_TIME: 500000
BUFFER_SIZE: 24000
BUFFER_BYTES: 96000
TICK_TIME: 0

so i’m not sure this driver works (although i would be so glad if it did!)

…take a look with audioinjector card.

there wil be some errors while booting but playback will work.
but there are reports people getting -22 error… i will try to reproduce

just to follow-up, I ended up getting this codec working by adapting the rpi-proto driver and overlay from Raspberry Pi. the result is here on github.

so that’s not using simple-audio-card, and i wasn’t able to get the audioinjector driver working. but this other approach did work for me. thanks everyone for your guidance!

could you please check arecord

yes I have, here’s a video demonstrating its operation with the mic input.

if you are having trouble with it, you may need to go into alsamixer and adjust some parameters, namely the input mux, mic enable, and mic boost.

sorry can´t even rebuild your repo - even with dtc1.6
i had to merge it directly to kernel(stock) build process.
but i´ts the same with my files.

alwas getting pcm_read error

please submit an issue to my github repo describing the build issue.

i was also getting pcm_read error’s before i realized that i had the frame clock wired incorrectly. unlike the raspberry pi, which uses the same pin for both LRCK_TX and LRCK_RX, the rockpi has two separate pins for this (pins 35 and 36). so maybe double-check that wiring.

this could be the answer. you are fantastic .

i will have to check but year damn i´m so fucking blind :smiley:
but year on the other device i liked to use i removed pin36 from i2s1 pinctrl config because it is used by the soundcard itself…
i got error that the pin was already used… but i did´t see the diffrence how rockpi4 use lrck…

also…
perhaps radxa wasn´t telling the hole story? or did´t remember?:smiley:
https://wiki.radxa.com/Rockpi4/FAQs

> ##### Is there I2S on 40pin header?
*> *
> The I2S signal is 12/35/36/38/40 pins of the header, which is the same as Tinker Board. It should be compatible with Raspberry Pi but we haven’t actually tested and DAC HAT.

i will do some rewiring an report back

incredible getting record working on audioinjector! THANK YOU SO MUCH !!!

so just connected pin35<–>pin36 with 33R resistor did the job
now i will have to look at the other soundcard i wanted to use.
thanks again !

glad it worked out for you! funny that we both made the same mistake with the wiring.