1 1
felipeduque

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 }

to

{ 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:

 

 

Spoiler

/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,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

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