1 1

SPH0645 I2S microphone on NanoPi Neo Core

Recommended Posts

I was struggling to make SPH0645 I2S microphone to work with H3 mainline kernel (4.14.87), on NanoPi Neo Core. After weeks of distress, I finally made it work! Maybe some will find it useful. Here's what I did:


1- In file sound/soc/sunxi/sun4i-i2s.c, change the following line


{ SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 }


{ SUN8I_I2S_RX_CHAN_SEL_REG, 0x00001000 }

You may have to download the linux-source package for your kernel version, or you can build your own kernel. It's weird that in legacy kernel, this register was assigned 0x00001000 by default (and the mic worked easily on that kernel). Not sure why it's changed.


I'm not sure if this register can be accessed through an overlay. I tried my best but could not find a way to do it. Please, someone let me know if it's possible to do that, so we can avoid the driver compiling stuff.


2- Compile, generate and load the new sun4i-i2s.ko module.


3- Create a .dts file, sph0645-overlay.dts, with the following contents:





/ {
    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,mclk-fs = <512>;

            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>;



It's almost the same as the one @Valery Rezvyakov devised in this thread. The only difference is the line with


simple-audio-card,mclk-fs = <512>;

which specifies MCLK's oversample rate regarding the sampling frequency (i.e., if sampling frequency = 48KHz, mclk = 512 * 48k = 24,576MHz). As far as I understand, this is the base clock which generates other clock signals (bit clock, frame sync).  


4- Compile and add the .dts file.


5- Reboot and test with 

arecord -f S16_LE -c 2 -r 48000 -D hw:0,0 -v >test.wav

Please let me know if it works for you. Maybe I have forgotten something. 

Share this post

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

1 1