H3 I2S0 DT overlay
5 5

43 posts in this topic

Recommended Posts

Hi,

 

OPiPC with latest mainline (ARMBIAN 5.34 user-built Ubuntu 16.04.3 LTS 4.13.12-sunxi).

Need to test the I2S0. From what I see in patches, the I2S driver code is already there so I just need an overlay to use it.

 

Is there any DT overlay for using the H3 I2S0 with any codec ?

Even as a generic simple-audio-codec ?

 

Christos

 

MitchD likes this

Share this post


Link to post
Share on other sites
2 hours ago, Christos said:

Is there any DT overlay for using the H3 I2S0 with any codec ?

Not yet. You need to activate the i2s but, set up pin multiplexing (using pinctrl* properties) and pair it with a coded using simple-audio-card. AFAIK there is no "generic" codec available so you'll have to choose something compatible and enabled in the kernel config.

 

 

Share this post


Link to post
Share on other sites
13 minutes ago, zador.blood.stained said:

Not yet. You need to activate the i2s but, set up pin multiplexing (using pinctrl* properties) and pair it with a coded using simple-audio-card. AFAIK there is no "generic" codec available so you'll have to choose something compatible and enabled in the kernel config.

 

 

 

Hmm.. tried by using the 'snd-soc-dummy' generic linux codec, as you mention this might not be present, right?

 

For pins,  it looks they are already patched in when I do the 'Mainline' build selection.

-> https://github.com/armbian/build/blob/master/patch/kernel/sunxi-next/00-20-add-i2s-DT-pins.patch

Since this patch is there, do I need to do anything more for them?

 

 

Share this post


Link to post
Share on other sites

@zador.blood.stained

Most likely I do something in error here..

 

This is the overlay I use

/dts-v1/;
/plugin/;

/ {
    compatible = "allwinner,sun8i-h3";

    fragment@0 {
        target = <&i2s0>;
        __overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&i2s0_pins>;
            status = "okay";
        };
    };

    fragment@1 {
	target-path = "/";
        __overlay__ {
                codec_dummy:codec_dummy {
                	#sound-dai-cells = <0>;
                	compatible = "linux,snd-soc-dummy";
                	status = "okay";
            	};
        };
    };


    fragment@2 {
		target-path = "/";
		__overlay__ {
				sound {
	            	compatible = "simple-audio-card";
    	        	simple-audio-card,name = "simple-card-test";
                	status = "okay";
    	        	simple-audio-card,cpu {
    	        	    sound-dai = <&i2s0>;
    	        	};
    	        	simple-audio-card,codec {
    	        	    sound-dai = <&codec_dummy>;
					};
				};
        };
    };


};

 

Uboot is not complaining on boot

Found U-Boot script /boot/boot.scr
3708 bytes read in 203 ms (17.6 KiB/s)
## Executing script at 43100000
U-boot loaded from SD
Boot script loaded from mmc
237 bytes read in 164 ms (1000 Bytes/s)
5700002 bytes read in 539 ms (10.1 MiB/s)
6790768 bytes read in 610 ms (10.6 MiB/s)
Found mainline kernel configuration
31409 bytes read in 1097 ms (27.3 KiB/s)
1164 bytes read in 169 ms (5.9 KiB/s)
Applying user provided DT overlay simple-codec-overlay.dtbo
4179 bytes read in 686 ms (5.9 KiB/s)
Applying kernel provided DT fixup script (sun8i-h3-fixup.scr)
## Executing script at 44000000
## Loading init Ramdisk from Legacy Image at 43300000 ...

 

but I2S0 is not present, either with aplay -l nor in dmesg.

 

Is there something that I need to change in my overlay or is some kind of bug?..

 

 

uboot.txt

simple-codec-overlay.dts

dmesg.txt

Share this post


Link to post
Share on other sites
45 minutes ago, Christos said:

Most likely I do something in error here..

/dts-v1/;
/plugin/;

/ {
	compatible = "allwinner,sun8i-h3";

 	fragment@0 { 
 		target-path = "/"; 
 		__overlay__ { 
			pcm5102a: pcm5102a {
			#sound-dai-cells = <0>;
			compatible = "ti,pcm5102a";
			pcm510x,format = "i2s";
			};
 		}; 
 	}; 

	fragment@1 {
		target = <&i2s0>;
		__overlay__ {
			status = "okay";
			pinctrl-0 = <&i2s0_pins>;
			sound-dai = <&pcm5102a>;
			pinctrl-names = "default";
		};
	};

	fragment@2 {
		target-path = "/";
		__overlay__ {
			sound_i2s {
				compatible = "simple-audio-card";
				simple-audio-card,name = "I2S-master";
				simple-audio-card,mclk-fs = <256>;
				simple-audio-card,format = "i2s";
		                status = "okay";

				simple-audio-card,cpu {
					sound-dai = <&i2s0>;
				};

				simple-audio-card,codec {
					sound-dai = <&pcm5102a>;
				};
			};
		};
	};
};

 

Share this post


Link to post
Share on other sites

Hi @Valery Rezvyakov

 

Thank you for the hint, I understand that you use the pcm5102a codec which is the same as a dummy linux codec.

Yet after I tried it, is again not showing up.

The I2S0 is at i2s@01c22000 and that is not shown up in the dmesg although uboot DT is not complaining again with your modified overlay.

Again the uboot DT is passing ok without error, dmesg is not showing I2S0 and aplay -l is not showing it

Quote

christos@orangepipc:~$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: allwinnerhdmi [allwinner,hdmi], device 0: 1c22800.i2s-i2s-hifi i2s-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

christos@orangepipc:~$

 

I'm attaching the related dmesg.

 

dmesg2.txt

Share this post


Link to post
Share on other sites
14 hours ago, Christos said:

Thus anyone can try it and see the results.

make linux-menuconfig (by buildroot)
 
 Device Drivers
     ----->Sound card support
           ----->Advanced Linux Sound Archtecture
                 ------>ALSA for Soc audio support
                        --------->Allwinner Soc Audio support
                                 [*]Allwinner A10 I2S Support

patch:

diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index 22408bc..7842de4 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -30,8 +30,10 @@ config SND_SUN8I_CODEC_ANALOG
 
 config SND_SUN4I_I2S
 	tristate "Allwinner A10 I2S Support"
+       depends on OF
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	select REGMAP_MMIO
+       select SND_SOC_PCM5102A
 	help
 	  Say Y or M if you want to add support for codecs attached to
 	  the Allwinner A10 I2S. You will also need to select the

On the Orange:

 

dpkg -i linux-headers-next-sunxi_5.34_armhf.deb

 

file sun8i-h3-I2S-out.dts :


armbian-add-overlay sun8i-h3-I2S-out.dts
reboot

results:

root@orangepipc:~# uname -a
Linux orangepipc 4.13.12-sunxi #6 SMP Tue Nov 14 02:58:07 MSK 2017 armv7l GNU/Linux


root@orangepipc:~# cat /proc/asound/cards
 0 [I2Smaster      ]: I2S-master - I2S-master
                      I2S-master
 1 [Codec          ]: H3_Audio_Codec - H3 Audio Codec
                      H3 Audio Codec
 2 [allwinnerhdmi  ]: allwinner_hdmi - allwinner,hdmi
                      allwinner,hdmi
root@orangepipc:~# dmesg |grep i2s
[    9.529374] asoc-simple-card sound_i2s: pcm5102a-hifi <-> 1c22000.i2s mapping ok
[   10.406113] asoc-simple-card sound: i2s-hifi <-> 1c22800.i2s mapping ok
root@orangepipc:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: I2Smaster [I2S-master], device 0: 1c22000.i2s-pcm5102a-hifi pcm5102a-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: allwinnerhdmi [allwinner,hdmi], device 0: 1c22800.i2s-i2s-hifi i2s-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

 

MitchD and Christos like this

Share this post


Link to post
Share on other sites

Hi @Valery Rezvyakov

 

Thank you for this solution, it does produce the output/playback device indeed.

root@orangepipc:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: I2Smaster [I2S-master], device 0: 1c22000.i2s-pcm5102a-hifi pcm5102a-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: allwinnerhdmi [allwinner,hdmi], device 0: 1c22800.i2s-i2s-hifi i2s-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@orangepipc:~#

Is there any way to have also the input enabled?

root@orangepipc:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@orangepipc:~#

Currently it is only the playback visible, is there any codec that we could use in order to give us the record input too?

 

 

Share this post


Link to post
Share on other sites
On ‎14‎.‎11‎.‎2017 at 3:03 PM, Christos said:

Currently it is only the playback visible, is there any codec that we could use in order to give us the record input too?

Get the source & create a simple Makefile:

mkdir adau7002
cd adau7002
wget https://raw.githubusercontent.com/trsqr/media_tree/bd676c0c04ec94bd830b9192e2c33f2c4532278d/sound/soc/codecs/adau7002.c
nano Makefile

Makefile contents:

obj-m := adau7002.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

install:
	sudo cp adau7002.ko /lib/modules/$(shell uname -r)
	sudo depmod -a

Those indentations are a single tab character - use spaces & it won't work.

Build:

make all install

Next, we create a new device tree overlay. Create a file i2s-soundcard-overlay.dts with this content:

 

/dts-v1/;
/plugin/;

/ {
	compatible = "allwinner,sun8i-h3";


    fragment@0 {
        target-path = "/";
        __overlay__ {
            adau7002_codec: adau7002_codec {
                #sound-dai-cells = <0>;
                compatible = "adi,adau7002";
                status = "okay";
            };
        };
    };

 

	fragment@1 {
		target = <&i2s0>;
		__overlay__ {
			status = "okay";
			pinctrl-0 = <&i2s0_pins>;
			sound-dai = <&adau7002_codec>;
			pinctrl-names = "default";
		};
	};

	fragment@2 {
		target-path = "/";
		__overlay__ {
			sound_i2s {
            compatible = "simple-audio-card";
            simple-audio-card,format = "i2s";
            simple-audio-card,name = "adau7002";
            simple-audio-card,bitclock-slave = <&dailink0_slave>; 
            simple-audio-card,frame-slave = <&dailink0_slave>; 

            simple-audio-card,widgets = 
                    "Microphone", "Microphone Jack"; 
            simple-audio-card,routing = 
                    "PDM_DAT", "Microphone Jack"; 


            status = "okay";
            simple-audio-card,cpu {
                sound-dai = <&i2s0>;
            };
            dailink0_slave: simple-audio-card,codec {
                sound-dai = <&adau7002_codec>;

            };
			};
		};
	};
};

Compile & install the overlay:

armbian-add-overlay i2s-soundcard-overlay.dts

Reboot and you'll have a microphone recording device

root@orangepipc:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: adau7002 [adau7002], device 0: 1c22000.i2s-adau7002-hifi adau7002-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

I don't have anything to test it with, but alsamixer shows a sound card with the chosen name and no controls, which is what you would expect.

lsmod | grep snd

 


root@orangepipc:~# lsmod | grep snd
snd_soc_hdmi_codec     16384  1
snd_soc_simple_card    16384  0
snd_soc_adau7002       16384  1
snd_soc_simple_card_utils    16384  1 snd_soc_simple_card
snd_soc_core          118784  7 snd_soc_adau7002,sun4i_codec,sun4i_i2s,sun8i_codec_analog,snd_soc_hdmi_codec,snd_soc_simple_card_utils,snd_soc_simple_card
snd_pcm_dmaengine      16384  1 snd_soc_core
snd_pcm                69632  4 sun4i_i2s,snd_pcm_dmaengine,snd_soc_hdmi_codec,snd_soc_core
snd_timer              24576  1 snd_pcm
snd                    45056  3 snd_timer,snd_soc_core,snd_pcm
soundcore              16384  1 snd

 

Christos likes this

Share this post


Link to post
Share on other sites

@Valery Rezvyakov

 

Many thanks, very nice.

 

How can we have both of those overlays working together, meaning to have both playback and capture devices present.

As it is now, it enables either playback or capture, but we need both of them active.

Tried to enable both overlays, but only one of them gets through to pulseaudio/alsa.

In the armbianEnv.txt file, in the line specifying the overlays, whichever overlay gets there last, only that device is shown in alsa

 

If the line is

user_overlays=sun8i-h3-I2S-out i2s-soundcard-overlay

then

root@orangepipc:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: allwinnerhdmi [allwinner,hdmi], device 0: 1c22800.i2s-i2s-hifi i2s-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@orangepipc:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: adau7002 [adau7002], device 0: 1c22000.i2s-adau7002-hifi adau7002-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@orangepipc:~#

we have new capture but no new playback

 

If the line is

user_overlays=i2s-soundcard-overlay sun8i-h3-I2S-out

then

root@orangepipc:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: I2Smaster [I2S-master], device 0: 1c22000.i2s-pcm5102a-hifi pcm5102a-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: allwinnerhdmi [allwinner,hdmi], device 0: 1c22800.i2s-i2s-hifi i2s-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@orangepipc:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 2: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@orangepipc:~#

we have new playback but no new capture

 

How can we have both of them active?

Playback and Capture?

 

Share this post


Link to post
Share on other sites
4 hours ago, Christos said:

How can we have both of them active?

Playback and Capture?


 Sorry, I am no expert here, having started from zero knowledge to get my mic up & running.

In order to get both capture & playback working, I think you'll have to create a new, combined overlay using simple card (extending my one perhaps). Some hints at https://www.kernel.org/doc/Documentation/devicetree/bindings/sound/simple-card.txt

Share this post


Link to post
Share on other sites

@Valery Rezvyakov

 

I'm also a novice regarding DT so trying to find any info available.

 

Either way you did an excellent job here.

Thank you very much!

 

Hope someone can give us a helping hand here on how to have a combined overlay.

 

 

Share this post


Link to post
Share on other sites
On 15.11.2017 at 7:00 PM, Christos said:

How can we have both of those overlays working together, meaning to have both playback and capture devices present.

Obviously you need a codec that supports both playback and capture at the same time, assuming there are no additional HW requirements for this.

Share this post


Link to post
Share on other sites
37 minutes ago, zador.blood.stained said:

Obviously you need a codec that supports both playback and capture at the same time, assuming there are no additional HW requirements for this.

Well, this is what I initialy done

-> https://forum.armbian.com/topic/5643-h3-i2s0-dt-overlay/?do=findComment&comment=43519

I did verify in the generated .o/.ko that the dummy codec device (which has both concurrent capture/playback) gets compiled in the source tree.

But for some unknown reason it did not work with the new I2S.

Could be my overlay, dont know.

Also, that has no HW limitations, it can be used from anyone without hardware (if the underline I2S driver is ok of course..)

Share this post


Link to post
Share on other sites
32 minutes ago, Christos said:

But for some unknown reason it did not work with the new I2S.

Because AFAIK snd-soc-dummy doesn't have DT bindings and can't be instantiated from DT, at least without patching (something like this - http://mailman.alsa-project.org/pipermail/alsa-devel/2014-August/080287.html, or like this - https://patchwork.kernel.org/patch/7679391/). 

This

On 13.11.2017 at 8:13 PM, Christos said:

compatible = "linux,snd-soc-dummy";

doesn't match any of_device_id tables so your simple-audio-card codec is connected to nothing.

Christos likes this

Share this post


Link to post
Share on other sites

Not related to armbian, but I made some work with friendlyarm kernel 4.11.2 for support i2s driver for h3/h5 with support 16/24 bit master/slave mode i2s (link) and build Volumio image for nanopi neo (link). In future I want to get same in mainline kernel.

zador.blood.stained likes this

Share this post


Link to post
Share on other sites

I tried to set my nanopi neo in I2S slave mode using the dts file in the thread and added the bitclock-master/frame-master lines

 

    fragment@2 {
        target = <&sound>;
        __overlay__ {
            compatible = "simple-audio-card";
            simple-audio-card,name = "G-Dis-DAC";
            simple-audio-card,format = "right_j";
            simple-audio-card,bitclock-master = <&codec_dai>;
            simple-audio-card,frame-master = <&codec_dai>;

            status="okay";

 

but the sound card doesnt show up after reboot. Is something wrong with the syntax or does the driver not support that?

Share this post


Link to post
Share on other sites

I did a new build for nanopi neo according to the orangepi_i2s link above and it works but as you can see in my example my codec accepts only right justified I2S format Do you know how to change the overlays for master/slave to get that format? Since those doesnt use simple-card at all?

Share this post


Link to post
Share on other sites

I mean applying the patch from that link https://github.com/ua3nbw-cf/orangepi_i2s  and building a new image you get two new overlays  you can set in armbian-config one for i2s master and one for i2s slave.

i2s slave looks like that.

 

+/dts-v1/;

+/plugin/;

+

+/ {

+ compatible = "allwinner,sun8i-h3";

+

+ fragment@0 {

+ target-path = "/";

+ __overlay__ {

+ pcm5102a: pcm5102a {

+ #sound-dai-cells = <0>;

+ compatible = "ti,pcm5102a";

+ };

+ };

+ };

+

+ fragment@1 {

+ target = <&i2s0>;

+ __overlay__ {

+ compatible = "allwinner,sun8i-h3-i2s-slave";

+ status = "okay";

+ pinctrl-0 = <&i2s0_pins &i2sclk_pins>;

+ sound-dai = <&pcm5102a>;

+ clock-source = "external";

+ clk-gpios = <&pio 0 6 1>, <&pio 6 6 1>, <&pio 6 7 1>; /* PA6 , PG6 , PG7 */

+ };

+ };

+

+ fragment@2 {

+ target = <&pio>;

+ __overlay__ {

+ i2sclk_pins: i2sclk_pins {

+ pins = "PA6", "PG6", "PG7";

+ function = "gpio_out";

+ };

+ };

+ };

+};

+

It uses the sun8i-i2s driver instead. But as you can see those overlays dont use simple-card thats why I wonder how one can set the I2S format in that overlay.

Share this post


Link to post
Share on other sites

Hi,

which board is being used as an i2s slave?...The current mainline driver should support slave configuration but I've never tested it(audioinjector board is on its way). It's also unclear what these clk-gpios are for; is it just logic to set the clocking rate? and if that is the case then it should be in the codec driver and not the dai.

CK

Share this post


Link to post
Share on other sites

I tested on my nanopi neo yesterday. I didnt had so much time but it seems to work both i slave and master mode. I will test some more to figure out how the fs switches work. My problem is that I am not a software guy and it is difficult to figure out how to set things like right_j format. I can see in the driver (sun8i-i2c) that it is support for that. 

Share this post


Link to post
Share on other sites

Hi @codekipper  realy nice to see you here :)

 

There is some work from nikkov that created the sun8i-i2s.c driver mentioned in earlier post, yet it is not included in the 4.14 mainline kernel probably he did not pushed it up

-> https://github.com/nikkov/friendlyarm-linux/tree/sunxi-4.11.y/sound/soc/sunxi

Though even this driver has not capture feature, its only playback.

 

Although not there yet, I still hope that at sometime soon we will have both capture and playback in 192KHz/24bit on I2S H3 driver with your excellent work.

 

Share this post


Link to post
Share on other sites

RJF and slave mode should work with the sun4i-i2s driver, although I've only tested i2s, LJR and master. The sun8i-i2s driver shouldn't be used but may prove useful for debugging(I used it for the lrclk setting to get hdmi audio working!).

Please show me your hardware. I've not seen a pcm5102 board with on-board clocks.

CK

Share this post


Link to post
Share on other sites

No I am not talking about pcm5102 boards. The reason I want to do this is to get lower jitter from the transport  nanopi neo in this case. I use own designed hardware based on a high quality clock that generates my bitclock and LRclock  and feeds those to the sbc that obviously must be in slave mode generating the data for me. Then  I reclock Bclk lrclk and data  and send them to a discrete R2R DAC. That is the reason I need the data to be i r_j format.

That works fine with Raspberry pi. But for some reason I always get better results using nanopi or odroid instead for RPi

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

5 5

  • Support the project

    We need your help to stay focused on the project.

    Choose the amount and currency you would like to donate in below.