I2s-out overlay to enable i2s0

Aa let me explain.
many DACs require a master clock (mclk) besides the serial clock (sclk) and word clock (lrclk) ro make the internal oversampling to realize digital filtering etc. I know that that clock is not a part of the I2S standard but.
When you look at the pinout of PiS that clock (mclk) should be traced out to
68 PDM_CLK_M_M2 I2S0_8CH_MCLK GPIO2_A4 7
sclk to
12 GPIO2_A5 I2S0_8CH_SCLK_TX 69
lrclk to
22 GPIO2_A7 I2S0_8CH_LRCK_TX 71
data to
18 GPIO2_B1 I2S0_8CH_SDO0 73
so the driver should output all those clocks. The dummy-codec is patched to output the mclk and you can see in your dump that it gets that clock successfully.

[ 1.658822] dummy_codec dummy-codec: get mclk success

But can you see it on the instrument? that was my question.

Ok, I take a look if there are more clocks active this evening.

But I think the device supports this mode:
19.3.11 TDM left shift mode2 (PCM format). Using only one Pin
SDI0/SDO0 for all 8 channels

That is different to
19.3.1 I2S normal mode which has 2 channels but can have 4 IO Pins
SDI0-3/SDO0-3 = 4 * 2 channels
I think you mean this mode.

I like to setup the PiS for the waveform like in chapter 19.3.11. Have all 8 channel with only one IO Pin, so that all 8 channels are transmitted/received within one frame. For that It needs only 4 wires. Clock, Sync, In, Out

Ok Thats what I mean. I experienced the same behavior before that simple-card ignoring the clock setting when I was working with nanopi but in those cases it was the sunxi I2S driver itself that failed.
Please check the mclk when you have time.

I am playing with music streaming devices and in most cases when you start playing or stopping tracks the I2S driver start and stop the clocks and therefor it outputs pops and clicks very annoying.
So I have modified the rockchip I2S driver to keep the clocks always on.
The modified driver is in my github account same place as the overlays if someone needs that…
You can also find there a kernel I have build (deb packages) that gets rid of all those loop devices.

I have check the clocks:
I2S0_8CH_MCLK: n.a
I2S0_8CH_SCLK_TX: 3.078 Mhz
I2S0_8CH_LRCK_TX: 48 Khz

When reading the DT-docs for i2s-tdm then you are right it is splitting using multiple IO lines
There is nothing about tdm slots.

But, the confusing thing is the doc for rockcip-i2s:

  • clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names.
  • clock-names: should contain followings:
    • “i2s_hclk”: clock for I2S BUS
    • “i2s_clk” : clock for I2S controller
  • rockchip,playback-channels: max playback channels, if not set, 8 channels default.
  • rockchip,capture-channels: max capture channels, if not set, 2 channels default.
  • rockchip,bclk-fs: configure the i2s bclk fs.

8 channel as default ??? for a device which can handle only 2 channels. Have they mixed up the device driver ? So that the i2s_8ch should use rockchip-i2s and the i2s_2ch should use the rockchip-i2s-tdm

I think, I try to set the driver to rk3066-i2s

Edit:
not working -22
Now i try to use i2s_0
Edit-2
not functional. is not on the header, so it can not work

It confirms what I thought. I have tested the 2channel driver with the same result as you very obvious since it is not hardware connected.
As I said before I did some work with the tdm driver to keep the clocks on constantly I will go back and try to maybe find some answers

For whatever reason, I got it working now.
My DT so far:

   i2s_tdm: i2s@ff300000 {
            compatible = "rockchip,rk3308-i2s-tdm";
            reg = < 0x00 0xff300000 0x00 0x1000 >;
            interrupts = < 0x00 0x30 0x04 >;
            clocks = < 0x02 0x4c 0x02 0x4e 0x02 0xa4 0x02 0x6e 0x02 0x6f 0x02 0x03 0x02 0x04 >;
            clock-names = "mclk_tx\0mclk_rx\0hclk\0mclk_tx_src\0mclk_rx_src\0mclk_root0\0mclk_root1";
            dmas = < 0x25 0x00 0x25 0x01 >;
            dma-names = "tx\0rx";
            resets = < 0x02 0x89 0x02 0x8a >;
            reset-names = "tx-m\0rx-m";
            rockchip,cru = < 0x02 >;
            rockchip,grf = < 0x4b >;
            rockchip,mclk-calibrate;
            pinctrl-names = "default";
            pinctrl-0 = < 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a >;
            status = "okay";
            rockchip,clk-trm = <1>;
            rockchip,bclk-fs = <128>;
            #sound-dai-cells = <0>;
            phandle = < 0xbe >;
    };

   tdm_sound {
            compatible = "simple-audio-card";
            simple-audio-card,name = "rockpis-tdm";
            simple-audio-card,format = "dsp_b";
            simple-audio-card,mclk-fs = < 128 >;
            simple-audio-card,bitclock-master = <&tdm_snd_cpu>;
            simple-audio-card,frame-master = <&tdm_snd_cpu>;
            status = "okay";

            tdm_snd_cpu: simple-audio-card,cpu {
                dai-tdm-slot-num = <8>;
                dai-tdm-slot-width = <16>;
                sound-dai = <&i2s_tdm>;
            };

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

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

I have check that with speaker-test -c 8 -s [1-8] to see that all channels run independently.
Saw on logic analyser:
Clock: 6.144 Mhz
Sync: 48Khz

Only the channels seems to mixed up between speaker-test and the position on tdm. but this can be changed by alsa settings.

Hurra. Now I have drink a box of beer and hopefully radxa pay it :smile::beers:

1 Like

Nice Not giving up too easy pays off sometimes.
If you dont want to mess with the dtb you can use this.

https://raw.githubusercontent.com/eragefe/Rockpi-S/master/8ch_simple_card.dts

I loaded that on my armbian image and it seems to work. It should work on radxas image as well.

Yes this DT stuff is hard to understand. I think the main issue was to set the clock master to the dummy-codec. I found this somewhere in an other rockship DT.
The overlay is a better solution, right. But i was easier for my to mod the base dtb :wink:

armbian was my first attempt using this board. But I have stopped using It, because of not working USB and USB-otg. Is this working now ?
I prefer a newer kernel,because there is a patch out for USB-Audio 2.0 which is mandatory for me. With armbian, I think i will only compile that. With raxda image, I will have to backport it. Also my own stuff was from rasberian which is also using a newer kernel.
When USB on armbian is working, than it would save me a lot of unwanted work

Yes I can confirm that. I tested my overlay yesterday on latest armbian with current kernel and since the dummy codec was not precompiled there I used the pcm5102a codec.

The card comes up fine but 8-ch didnt work so I was on my way to dive in to TDM driver.
But loading the same overlay using the dummy codec on armbian with legacy kernel seems to work fine.
So the trick was to get the codec to set the clock right.

@eragefe I had some time today and decided to test my original goal of i2s with the 5.x kernel :slight_smile:

Would you have some pointers for me w.t.r simple-card.

I’ll port of the dummy-codec over soon, but is there anything else that might also need porting?

# This is with the new Armbian build
# Armbian_20.11_Rockpi-s_buster_current_5.9.10_minimal.img
root@rockpi-s:~# uname -a
Linux rockpi-s 5.9.10-rockchip64 #20.11 SMP PREEMPT Mon Nov 23 13:36:07 CET 2020 aarch64 GNU/Linux
# dmesg
[    8.818446] rk3308-acodec ff560000.acodec: Don't need hp-ctl gpio
[    8.818488] rk3308-acodec ff560000.acodec: Don't need spk-ctl gpio
[    8.818522] rk3308-acodec ff560000.acodec: Don't need pa-drv gpio
[    8.818529] rk3308-acodec ff560000.acodec: De-pop as much as possible
[    8.818658] rk3308-acodec ff560000.acodec: Don't need micbias-en gpio
[    8.818704] rk3308-acodec ff560000.acodec: no vmicbias regulator found
[    8.818715] rk3308-acodec ff560000.acodec: Check ext_micbias: 0
[    8.818751] The acodec version is: a
[    8.888772] asoc-simple-card acodec-sound: ASoC: no DMI vendor name!
[    8.901359] asoc-simple-card sound_i2s: ASoC: no DMI vendor name!
[    8.907407] rockchip-i2s-tdm ff300000.i2s: Trying to bind component to card "i2s_8ch_0" but is already bound to card "SimpleDAC"
[    8.907426] asoc-simple-card sound: ASoC: failed to instantiate card -19

And here is the overlay file.

root@rockpi-s:~# cat /boot/overlay-user/simple_card.dts
// Definitions for DummyDAC
/dts-v1/;
/plugin/;

/ {
        compatible = "radxa,rockpis", "rockchip,rk3308";

        fragment@0 {
                target = <&i2s_8ch_0>;

                __overlay__ {
                        #sound-dai-cells = <0>;
                        status = "okay";
                        };
               };

        fragment@1 {
                target-path = "/";

                __overlay__ {
                        i2s0_out: i2s0-out {
                                #sound-dai-cells = <0>;
                                compatible = "ti,pcm5102a";
                                status = "okay";
                                };

                        sound_i2s {
                                simple-audio-card,name = "SimpleDAC";
                                compatible = "simple-audio-card";
                                simple-audio-card,format = "i2s";
                                simple-audio-card,bitclock-master = <&cpu_dai>;
                                simple-audio-card,frame-master = <&cpu_dai>;
                                simple-audio-card,mclk-fs = <256>;
                                status = "okay";

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

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

The cards register, even though dmesg show signs of impending trouble…

root@rockpi-s:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: rockchiprk3308a [rockchip,rk3308-acodec], device 0: ff320000.i2s-rk3308-hifi rk3308-hifi-0 [ff320000.i2s-rk3308-hifi rk3308-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: SimpleDAC [SimpleDAC], device 0: ff300000.i2s-pcm5102a-hifi pcm5102a-hifi-0 [ff300000.i2s-pcm5102a-hifi pcm5102a-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
# speaker-test leads to a nice kernel panic
[  475.652740] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[  475.653255] Modules linked in: 8723ds cfg80211 rfkill zstd snd_soc_pcm5102a snd_soc_rk3308 snd_soc_simple_card snd_soc_rockchip_i2s_tdm snd_soc_simple_card_utils snd_soc_core snd_pcm_dmaengine snd_pcm snd_timer snd soundcore cpufreq_dt zram ip_tables x_tables autofs4 realtek dwmac_rk stmmac_platform stmmac mdio_xpcs
[  475.655832] CPU: 2 PID: 1935 Comm: speaker-test Not tainted 5.9.10-rockchip64 #20.11
[  475.656522] Hardware name: Radxa ROCK Pi S (DT)
[  475.656943] pstate: a0000005 (NzCv daif -PAN -UAO BTYPE=--)
[  475.657614] pc : dapm_update_dai_unlocked.isra.0+0x40/0x108 [snd_soc_core]
[  475.658369] lr : snd_soc_dapm_update_dai+0x40/0x68 [snd_soc_core]
[  475.658917] sp : ffff8000130bba10
[  475.659225] x29: ffff8000130bba10 x28: ffff0000161b0000
[  475.659717] x27: ffff0000133e4d1c x26: 0000000000000000
[  475.660206] x25: ffff0000133e4c24 x24: ffff0000161b0000
[  475.660695] x23: ffff0000133e4c00 x22: ffff0000128c8cd8
[  475.661184] x21: ffff0000128c8c00 x20: 0000000000000002
[  475.661673] x19: ffffffffffffffd8 x18: 0000000000000000
[  475.662160] x17: 0000000000000000 x16: 0000000000000000
[  475.662647] x15: 0000000000000000 x14: 0000000000000000
[  475.663137] x13: 0000000000000000 x12: 0000000000000001
[  475.663625] x11: 0000000000000004 x10: 0101010101010101
[  475.664114] x9 : 0000000000000001 x8 : 7f7f7f7f7f7f7f7f
[  475.664603] x7 : 0000000000000000 x6 : 0000000000000000
[  475.665091] x5 : 0000000000000000 x4 : 0000000000000000
[  475.665579] x3 : ffff0000163d7148 x2 : ffff000014046480
[  475.666067] x1 : ffff0000133e4c00 x0 : 0000000000000000
[  475.666557] Call trace:
[  475.666930]  dapm_update_dai_unlocked.isra.0+0x40/0x108 [snd_soc_core]
[  475.667647]  snd_soc_dapm_update_dai+0x40/0x68 [snd_soc_core]
[  475.668300]  soc_pcm_hw_params+0x32c/0x5a8 [snd_soc_core]
[  475.668864]  snd_pcm_hw_params+0xf0/0x400 [snd_pcm]
[  475.669371]  snd_pcm_common_ioctl+0x2d8/0x1078 [snd_pcm]
[  475.669914]  snd_pcm_ioctl+0x30/0x48 [snd_pcm]
[  475.670337]  __arm64_sys_ioctl+0xa8/0xf0
[  475.670710]  el0_svc_common.constprop.0+0x70/0x188
[  475.671154]  do_el0_svc+0x24/0x90
[  475.671471]  el0_sync_handler+0x90/0x198
[  475.671835]  el0_sync+0x158/0x180
[  475.672168] Code: f84d8ed3 eb1302df d100a273 540001a0 (f9400a61)
[  475.672726] ---[ end trace a07ab07415ed41c6 ]---

Is it not possible to have both the Audio jack and the I2S output active at the same time? If I read your 8ch_simple_card seems to disable the i2s_8ch_2 node that the audio codec maps to?

EDIT: The 8ch_simple_card also has a similar kernel panic when trying speaker-test -c2

Yes you are right there. The overlay disables the audio codec.
The dtb in armbian latest you using implementing several simple-card nodes
analog-sound {
compatible = “simple-audio-card”;
simple-audio-card,format = “i2s”;
simple-audio-card,mclk-fs = <0x100>;
simple-audio-card,name = “Analog”;
status = “disabled”;
phandle = <0x6f>;

            simple-audio-card,cpu {
                    sound-dai = <0x07>;
            };

            simple-audio-card,codec {
                    sound-dai = <0x08>;
            };
    };

thats why you see those error messages in your dump.

BUT first I have to understand what you want to do.
Play something that you want to output both at the i2s pins and the analog output simultaneously?

If this is the case and you can register both cards correctly (maybe I can assist with that) then I guess you could send the stream to card1 and pipe it to card0.
Usually people do that to connect an input and an output device to send sound from a mic to a loudspeaker for example.

Anyway I did some testing yesterday and if you use this overlay everything works fine.

https://raw.githubusercontent.com/eragefe/Rockpi-S/master/armbian-5.9.y-kernel.dts
and with both cards

https://raw.githubusercontent.com/eragefe/Rockpi-S/master/armbian-5.9.y-both-cards.dts

Welcome to Armbian 20.11 Focal with Linux 5.9.10-rockchip64

System load: 4% Up time: 0 min
Memory usage: 33% of 213M IP: 192.168.1.138
CPU temp: 34°C Usage of /: 6% of 15G

[ Menu-driven system configuration (beta): sudo apt update && sudo apt install armbian-config ]

Last login: Thu Dec 3 02:15:34 2020 from 192.168.1.100
root@rockpi-s:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: rockchiprk3308a [rockchip,rk3308-acodec], device 0: ff320000.i2s-rk3308-hifi rk3308-hifi-0 [ff320000.i2s-rk3308-hifi rk3308-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: SimpleDAC [SimpleDAC], device 0: ff300000.i2s-pcm5102a-hifi pcm5102a-hifi-0 [ff300000.i2s-pcm5102a-hifi pcm5102a-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
root@rockpi-s:~# speaker-test -c2 -D plughw:1

speaker-test 1.2.2

Playback device is plughw:1
Stream parameters are 48000Hz, S16_LE, 2 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 128 to 131072
Period size range from 64 to 65536
Using max buffer size 131072
Periods = 4
was set period_size = 32768
was set buffer_size = 131072
0 - Front Left
1 - Front Right
Time per period = 2.776536
0 - Front Left
1 - Front Right
Time per period = 5.460972
0 - Front Left
^C 1 - Front Right
Time per period = 0.830656
root@rockpi-s:~# speaker-test -c2 -D plughw:0

speaker-test 1.2.2

Playback device is plughw:0
Stream parameters are 48000Hz, S16_LE, 2 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 128 to 131072
Period size range from 64 to 65536
Using max buffer size 131072
Periods = 4
was set period_size = 32768
was set buffer_size = 131072
0 - Front Left
1 - Front Right
Time per period = 2.749659
0 - Front Left
1 - Front Right
^CTime per period = 4.607317
root@rockpi-s:~#

1 Like

And 8 channels armbian 5.9

https://raw.githubusercontent.com/eragefe/Rockpi-S/master/armbian-5.9.y-kernel-8ch.dts

Welcome to Armbian 20.11 Focal with Linux 5.9.10-rockchip64

System load: 10% Up time: 0 min
Memory usage: 33% of 213M IP: 192.168.1.138
CPU temp: 35°C Usage of /: 6% of 15G

Last login: Thu Dec 3 14:36:05 2020 from 192.168.1.100
root@rockpi-s:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: SimpleDAC [SimpleDAC], device 0: ff300000.i2s-pcm5102a-hifi pcm5102a-hifi-0 [ff300000.i2s-pcm5102a-hifi pcm5102a-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: rockchiprk3308a [rockchip,rk3308-acodec], device 0: ff320000.i2s-rk3308-hifi rk3308-hifi-0 [ff320000.i2s-rk3308-hifi rk3308-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
root@rockpi-s:~# speaker-test -c8 -D plughw:0

speaker-test 1.2.2

Playback device is plughw:0
Stream parameters are 48000Hz, S16_LE, 8 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 128 to 131072
Period size range from 64 to 65536
Using max buffer size 131072
Periods = 4
was set period_size = 32768
was set buffer_size = 131072
0 - Front Left
4 - Center
1 - Front Right
7 - Side Right
3 - Rear Right
2 - Rear Left
6 - Side Left
5 - LFE
Time per period = 19.191959
0 - Front Left
4 - Center
1 - Front Right
7 - Side Right
3 - Rear Right
2 - Rear Left
6 - Side Left
5 - LFE
Time per period = 21.844418
0 - Front Left
4 - Center
1 - Front Right
7 - Side Right
3 - Rear Right
2 - Rear Left
^CWrite error: -4,Interrupted system call
xrun_recovery failed: -4,Interrupted system call
Transfer failed: Interrupted system call
root@rockpi-s:~#

1 Like

Hi eragefe,

Back in time I tried your overlay with the official Radxa image, it was working fine.

Yesterday I tried again with the latest image, I updated the system and then tried to load your dtbo, but it doesn’t work, I don’t see any card listed with aplay -l

What can I do to make it working?

Please forget what I wrote, it works fine (I had an issue with group permissions)

the card still has the old name “My_card”, it’s not aligned with the new source file “is2out”

could you please update the .dtbo, or explain how to generate the .dtbo from the .dts, within the Radxa image?

If you want to compile myfile.dts
try
dtc -@ -H epapr -O dtb -o myfile.dtbo -Wno-unit_address_vs_reg myfile.dts

Perfect, many thanks!

Hey @peterk Which kernel were you using here? Was it an Armbian image?

No, the raxda verion. It is 4.4.157. The dt changes may also work with armbian.

Is there a MS Windows 10 64bit version of this i2S0 overlay to work with Visual Studio?