I2s-out overlay to enable i2s0

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?

@eragefe & @peterk i am currently working with the i2S and your overlays to enable it are perfect thanks! So far i am able to read a 4ch I2S ADC. I am working on the DAC side now. We need to make sure the ADC and DAC are phase synchronous so the MCLK is important. The overlay doesnt output a CLK on the MCLK line (pin 7 I think on the PIs) I want to be able to scale it (256 * LRCLK etc). I can see in the reference manual all the registers to set up the clock and they seem ok when i read it with busy box devmem. My question is have you got the MCLK working with the I2S in master mode? and can you explain how to enable it in the device tree overlays? Interestingly the dmic overlay enables the MCLK so there must be a way? Thanks, Josh

@10josh29
Right,I have also noticed that there is no output at MCKL. I do not try to activate it, because I do not need it. Have a ADAU1467 connected to i2s-tdm with 8ch. The ADAU has 8 ARC. Connected to the ADAU are 4 pcm5102a and 1 pcm1802.
Using the PIS only as communication frontend for the ADAU to feed the audio streams to the ADAU.

No I tried months ago but it was only a very few tries since I dont need it in my case.
I use PIS as I2S slave with an external clock that serves as master clock in my application.
I have sent a question in this forum at that time with NO answer and let it go.
But you say that “the dmic overlay enables the MCLK” Is it something you have confirmed? and in that case can you post that overlay so I can see it. Maybe I can find out things.

Thank you for your replies! I hope you dont mind me tagging both of you at the same time, more minds the better! So far i have an ADAU1978 and a CS4344 DAC connected to the I2C and I2S lines (CODECs are quite hard to buy at the moment!) I can record 4 channel audio from the ADC as the ADAU can use the LRCLK for the PLL. The DAC however needs a MCLK at a multiple of the LRCLK frequency. @eragefe to answer your question i have scoped the MCLK, LRCLK and BCLK and seen that the DMIC overlay (pasted below) does toggle the MCLK pin but none of the others, this might be because the same pin is used for PCM CLK? It is interesting how you have used the MCLK as an input, is that in your existing overlay and how do you use it? I saw your question. Sadly as im mostly a hardware background i know very little about writing and reading these device trees. My application is quite unique. Im using the ADCs to measure magnetic fields in multiple axis to perform various DSP functions. The DACs can inject signals into the antennas so therefore need to be synchronised. I couldnt upload the overlay however it can be sound in the dtb/overlays folder within the boot directory of the kernal. If you could take a look and see what needs to change to enable that output that would be great. The low level registers in the CPU all seem to bet set up correctly.
Thanks
Josh

/dts-v1/;

/ {
model = “Radxa ROCK Pi S”;
compatible = “radxa,rockpis-rk3308\0rockchip,rk3308”;

fragment@0 {
	target-path = [ 2f 00 ];

	__overlay__ {

		pdm-i2s-dais {
			status = "okay";
			#sound-dai-cells = < 0x00 >;
			compatible = "rockchip,rk3308-multi-dais\0rockchip,multi-dais";
			dais = < 0xffffffff 0xffffffff >;
			capture,channel-mapping = < 0x08 0x00 >;
			playback,channel-mapping = < 0x00 0x08 >;
			bitclock-inversion = < 0x00 0x00 >;
			phandle = < 0x01 >;
		};

		vad-sound {
			status = "okay";
			compatible = "rockchip,multicodecs-card";
			rockchip,card-name = "rockchip,rk3308-vad";
			rockchip,cpu = < 0x01 >;
			rockchip,codec = < 0xffffffff 0xffffffff >;
		};
	};
};

fragment@1 {
	target = < 0xffffffff >;

	__overlay__ {
		status = "disabled";
	};
};

fragment@2 {
	target = < 0xffffffff >;

	__overlay__ {
		status = "okay";
		rockchip,audio-src = < 0xffffffff >;
		rockchip,det-channel = < 0x00 >;
		rockchip,mode = < 0x01 >;
		rockchip,buffer-time-ms = < 0xc8 >;
		#sound-dai-cells = < 0x00 >;
	};
};

fragment@3 {
	target = < 0xffffffff >;

	__overlay__ {
		status = "okay";
		#sound-dai-cells = < 0x00 >;
		rockchip,no-dmaengine;
		pinctrl-names = "default";
		pinctrl-0 = < 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff >;
	};
};

fragment@4 {
	target = < 0xffffffff >;

	__overlay__ {
		rockchip,no-dmaengine;
	};
};

__symbols__ {
	pdm_i2s_dais = "/fragment@0/__overlay__/pdm-i2s-dais";
};

__fixups__ {
	pdm_8ch = "/fragment@0/__overlay__/pdm-i2s-dais:dais:0\0/fragment@2/__overlay__:rockchip,audio-src:0\0/fragment@3:target:0";
	i2s_8ch_2 = "/fragment@0/__overlay__/pdm-i2s-dais:dais:4\0/fragment@4:target:0";
	acodec = "/fragment@0/__overlay__/vad-sound:rockchip,codec:0";
	vad = "/fragment@0/__overlay__/vad-sound:rockchip,codec:4\0/fragment@2:target:0";
	acodec_sound = "/fragment@1:target:0";
	pdm_m2_clk = "/fragment@3/__overlay__:pinctrl-0:0";
	pdm_m2_clkm = "/fragment@3/__overlay__:pinctrl-0:4";
	pdm_m2_sdi0 = "/fragment@3/__overlay__:pinctrl-0:8";
	pdm_m2_sdi1 = "/fragment@3/__overlay__:pinctrl-0:12";
	pdm_m2_sdi2 = "/fragment@3/__overlay__:pinctrl-0:16";
	pdm_m2_sdi3 = "/fragment@3/__overlay__:pinctrl-0:20";
};

__local_fixups__ {

	fragment@0 {

		__overlay__ {

			vad-sound {
				rockchip,cpu = < 0x00 >;
			};
		};
	};
};

};

As far as I understand is that pdm and i2s_8_ch mclk share the same pin.
I think, that is not a issue we can solve with overlays.
That is somewhat related to the rockchip-i2c-tdm.c driver. It seems to me that they have forgot to set the mux for this pin right.
You may look, if rockship have an updated version of this driver.