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