Add support of MAX98091 codec with VIM3L

Hi Folks,

I am working on adding support for MAX98091 codec in the VIM3L.
I found that VIM3L has the driver of MAX98090 at

linux/sound/soc/codecsmax98090.c

and it is compatible with MAX98091.
hardware pin configuration with codec(MAX98091) are as per below,

MAX98091

But I am not able to find the DTS or overlay reference for the same.
Is there any reference available ?
I have also been through this thread , which seems helpful, but this is different hardware.

It would be appreciated if any reference/doc available to move ahead.

Thanking you in anticipation.

1 Like
Documentation/devicetree/bindings/sound/max98090.txt

^ Linux kernel bindings are here, and β€œgit grep max98090” returns a ton of prior art. Good luck :slight_smile:

3 Likes

Hi @chewitt,

As per your suggestion i did changes in device tree and it seems sound card is getting probed,

Below is my device tree,


aml_sound: auge_sound {
                compatible = "amlogic, g12a-sound-card";
                aml-audio-card,name = "AML-AUGESOUND";

                aml-audio-card,dai-link@1 {
                        format = "i2s";
                        mclk-fs = <256>;
                        //continuous-clock;
                        //bitclock-inversion;
                        //frame-inversion;
                        /* master mode */
                        bitclock-master = <&tdmb>;
                        frame-master = <&tdmb>;
                        /* slave mode */
                        //bitclock-master = <&tdmccodec>;
                        //frame-master = <&tdmccodec>;
                        /* suffix-name, sync with android audio hal used for */
                        suffix-name = "alsaPORT-tdm";
                        cpu {
                                sound-dai = <&tdmb>;
                                dai-tdm-slot-tx-mask = <1 1>;
                                dai-tdm-slot-rx-mask = <1 1>;
                                dai-tdm-slot-num = <2>;
                                dai-tdm-slot-width = <32>;
                                system-clock-frequency = <12288000>;
                        };
                        codec {
                                sound-dai = <&max98090>;
                        };
                };

        };


&i2c3 {
        status = "okay";
        pinctrl-names="default";
        pinctrl-0=<&i2c3_master_pins2>;
        clock-frequency = <100000>; 

        max98090:audio-codec@10 {
                #sound-dai-cells = <0>;
                compatible = "maxim,max98090";
                reg = <0x10>;
                #clock-cells = <0>;
                interrupt-parent = <&gic>;
                pinctrl-names = "default";
                interrupt_pin = <&gpio GPIOZ_15 GPIO_ACTIVE_HIGH>;
                status = "okay";
        };
};

After booting here my entry of this sound card


root@Khadas:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: AMLAUGESOUND [AML-AUGESOUND], device 0: TDM-B-HiFi-alsaPORT-tdm HiFi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0

I did alsamixer change and made some of the volume properties to be high
And I tried playing sample wave files using aplay but getting below error


root@Khadas:~# **aplay -D hw:0,0 test.wav** 

Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
****aplay: set_params:1403: Unable to install hw params:****
ACCESS:  RW_INTERLEAVED
FORMAT:  S16_LE
SUBFORMAT:  STD
SAMPLE_BITS: 16
FRAME_BITS: 32
CHANNELS: 2
RATE: 8000
PERIOD_TIME: 125000
PERIOD_SIZE: 1000
PERIOD_BYTES: 4000
PERIODS: 4
BUFFER_TIME: 500000
BUFFER_SIZE: 4000
BUFFER_BYTES: 16000
TICK_TIME: 0

This seems failure while setting die sysclk at max98090_dai_set_sysclk, here it tried to set
As per below from dmesg logs

[   77.745494] aml_tdm_open
[   77.745502] Not init audio effects
[   77.745978] audio_ddr_mngr: frddrs[0] registered by device ff660000.audiobus:tdm@1
[   77.746364] aml_card_hw_params-438
[   77.746368] aml_card_hw_params-445
[   77.746373] max98090_dai_set_sysclk-2002 clk_id-0, freq-2048000, dir-0
[   77.746377] max98090_dai_set_sysclk-2019 freq-2048000 
[   77.746385] max98090 3-0010: Invalid master clock frequency
[   77.752055] asoc-aml-card auge_sound: ASoC: machine hw_params failed: -22
[   77.759005] audio_ddr_mngr: frddr_set_sharebuffer_enable sel:1, dst_src:3
[   77.759012] aml_dai_tdm_hw_free(), disable mclk for TDM-B
[   77.759339] tdm playback mute: 1, lane_cnt = 8

So can you advise here on what could I debug further ?

Thanking you in Anticipation.

This is the Amlogic 4.9 vendor kernel. I have limited knowledge of audio in the upstream kernel and zero knowledge about audio in this codebase (the drivers are completely different). Sorry :frowning:

1 Like

Hi @chewitt
Thanks for help!!!

Hi @numbqq and @Frank
Can you folks please advise here ?

@KD_1993 Here is a example about add ES8316 codec support, you can check.

@numbqq
Thank you for the reference, i followed them and changed as per below,


aml_sound: auge_sound {
                compatible = "amlogic, g12a-sound-card";
                aml-audio-card,name = "AML-AUGESOUND";
+                simple-audio-card,widgets ="Microphone", "Mic Jack","Headphone", "Headphone Jack";
+              simple-audio-card,routing ="Mic Jack", "MICBIAS1","IN1P", "Mic Jack","Headphone Jack", "HPOL","Headphone Jack", "HPOR";
                aml-audio-card,dai-link@3 {
                        format = "i2s";
+                        mclk-fs = <2048>;

Here After changing I cannot here anything here with below logs,

oot@Khadas:~# dmesg 
[  806.151783] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  806.152123] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  806.152451] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  806.152778] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  807.790302] aml_tdm_open
[  807.790310] Not init audio effects
[  807.790466] audio_ddr_mngr: frddrs[0] registered by device ff660000.audiobus:tdm@1
[  807.790820] aml_card_hw_params-438
[  807.790825] aml_card_hw_params-445
[  807.790830] max98090_dai_set_sysclk-2002 clk_id-0, freq-16384000, dir-0
[  807.790833] aml_card_hw_params-458
[  807.790860] set mclk:16384000, mpll:32768000, get mclk:16384000, mpll:32767999
[  807.790863] aml_card_hw_params-464
[  807.790869] asoc aml_dai_set_tdm_fmt, 0x4001, ffffffc0735be118, id(1), clksel(1)
[  807.790872] aml_dai_set_tdm_fmt(), fmt not change
[  807.790875] HW parma done aml_card_hw_params-470
[  807.790889] dump_pcm_setting(ffffffc0735be118)
[  807.790893] 	pcm_mode(1)
[  807.790895] 	sysclk(2048000)
[  807.790898] 	sysclk_bclk_ratio(4)
[  807.790901] 	bclk(512000)
[  807.790904] 	bclk_lrclk_ratio(64)
[  807.790906] 	lrclk(8000)
[  807.790909] 	tx_mask(0x3)
[  807.790912] 	rx_mask(0x3)
[  807.790915] 	slots(2)
[  807.790918] 	slot_width(32)
[  807.790920] 	lane_mask_in(0x2)
[  807.790923] 	lane_mask_out(0x1)
[  807.790926] 	lane_oe_mask_in(0x0)
[  807.790929] 	lane_oe_mask_out(0x0)
[  807.790931] 	lane_lb_mask_in(0x0)
[  807.790944] set mclk:2048000, mpll:8192000, get mclk:2048000, mpll:8191999
[  807.790948] aml_dai_set_clkdiv, div 4, clksel(1)
[  807.790955] aml_dai_set_bclk_ratio, select I2S mode
[  807.790966] aml_dai_tdm_hw_params(), enable mclk for TDM-B
[  807.790999] aml_tdm_prepare(), reset fddr
[  807.791015] spdif_a fifo ctrl, frddr:0 type:1, 16 bits, chmask 0x3, swap 0x10
[  807.791021] spdif_info: rate: 8000, channel status ch0_l:0x100, ch0_r:0x100, ch1_l:0x200, ch1_r:0x200
[  807.791028] hdmitx: audio: get FS_MAX
[  807.791034] audio_ddr_mngr: frddr_set_sharebuffer_enable sel:1, dst_src:3
[  807.791659] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  807.792233] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  807.792577] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  807.792912] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  807.793285] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  807.793613] tdm playback mute: 0, lane_cnt = 8
[  807.793712] asoc-aml-card auge_sound: tdm playback enable
[  807.793719] spdif_a is set to enable
[  807.807470] i2c i2c-3: master_xfer[0] W, addr=0x10, len=1
[  807.807478] i2c i2c-3: master_xfer[1] R, addr=0x10, len=1
[  807.807958] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  841.423336] asoc-aml-card auge_sound: tdm playback stop
[  841.423364] spdif_a is set to disable
[  841.423432] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  841.423783] audio_ddr_mngr: frddr_set_sharebuffer_enable sel:1, dst_src:3
[  841.423788] aml_dai_tdm_hw_free(), disable mclk for TDM-B
[  841.423805] tdm playback mute: 1, lane_cnt = 8
[  841.423883] audio_ddr_mngr: frddrs[0] released by device ff660000.audiobus:tdm@1
[  841.426258] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  846.599720] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  846.600061] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  846.600388] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2
[  846.600714] i2c i2c-3: master_xfer[0] W, addr=0x10, len=2

Also strangely it has spdif to enable , i am not sure why ?

I have seen many references providing audio routing but can’t find with the example in ES8316 !

So any further advice ?

Thanking you in anticipation.

Hi @numbqq @mo_ghh
I conclude that I2C is working fine and read/write operation successfully done. but getting issue in I2S communication.

root@Khadas:~# i2cdump -f -y 3 0x10
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 04 06 04 00 00 00 00 00 00 00 00 00 57 ed 42    .???.........W?B
10: 34 34 03 00 60 7f 7f 0f 0f 0f 00 00 00 00 00 00    44?.`?????......
20: 00 00 0c 01 10 0a 88 35 0a 3f 3f 3f 00 00 3f 3f    ..?????5????..??
30: 00 35 35 a3 1e 1f 00 3f 03 00 bf 03 00 80 0c fc    .55???.??.??.???
40: 06 08 00 01 04 00 39 00 00 00 00 00 00 00 00 00    ??.??.9.........
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 0f    ..............??
c0: 0f 1b 10 00 00 00 00 00 00 00 00 00 00 00 00 00    ???.............
d0: 00 00 30 00 00 00 00 00 00 00 00 00 00 00 00 00    ..0.............
e0: 01 00 00 85 80 1f 1f 0a 0a 00 00 00 00 00 00 00    ?..??????.......
f0: 00 00 00 00 00 00 10 00 07 01 00 00 00 00 00 52    ......?.??.....R

can you please suggest how to debug or any other references.

hi @numbqq

now we can play sound,but capture audio using arecord command is not working.
it seems that issue in widget, audio routing ,tdm slots.
can you please suggest how to fix the record issue or any documentation for audio routing?

Hi @numbqq @Terry

I am able to play audio from the codec , but currently I am using hardware clock generated from codec it self,
When I switched clock source to software mclk (I2S_MCLK0),it did not work,

By probing on oscilloscope I found that it is not properly configuring.

So my query is how do I configure VIM3L I2S_MCLK0 to 13Mhz ?

–
Thanks

Can you provide your dts configuration?

hi @numbqq

Below is my dts configuration.

> aml-audio-card,dai-link@3 {
>                         format = "i2s";
>                         dai-format = "i2s";
>                         mclk-fs = <256>;
>                         //continuous-clock;
>                         //bitclock-inversion;
>                         //frame-inversion;
>                         /* master mode */
>                         bitclock-master = <&tdmb>;
>                         frame-master = <&tdmb>;
>                         /* slave mode */
>                         //bitclock-master = <&tdmccodec>;
>                         //frame-master = <&tdmccodec>;
>                         /* suffix-name, sync with android audio hal used for */
>                         //suffix-name = "alsaPORT-tdm";
>                         cpu {
>                                 sound-dai = <&tdmb>;
>                                 dai-tdm-slot-tx-mask = <1 1>;
>                                 dai-tdm-slot-rx-mask = <1 1>;
>                                 dai-tdm-slot-num = <2>;
>                                 dai-tdm-slot-width = <32>;
>                                 system-clock-frequency = <12288000>;
>                         };
>                         codec {
>                                 sound-dai = <&max98090>;
>                         };
>                 };
> &i2c3 {
>         status = "okay";
>         pinctrl-names="default";
>         pinctrl-0=<&i2c3_master_pins2>;
>         clock-frequency = <100000>; /* default 100k */
> 
>         max98090:audio-codec@10 {
>                 #sound-dai-cells = <0>;
>                 compatible = "maxim,max98090";
>                 reg = <0x10>;
>                 
>                 #clock-cells = <0>;
>                 clocks = <&clkaudio CLKID_AUDIO_MCLK_B
>                                  &clkc CLKID_MPLL1
>                                  &clkc CLKID_MPLL0
>                                  &clkaudio CLKID_AUDIO_SPDIFOUT_A>;
> 
>                 clock-names = "mclk", "clk_srcpll",
>                          "samesource_srcpll", "samesource_clk";
>                 interrupt-parent = <&gpio>;
>                 maxim,dmic-freq = <3500000>;    
>                 maxim,micbias = <1>;
>                 pinctrl-names = "default";
>                 interrupt_pin = <&gpio GPIOZ_15 GPIO_ACTIVE_HIGH>;
>                 status = "okay";
>         };
> };
> tdmb: tdm@1 {
> 		compatible = "amlogic, sm1-snd-tdmb";
> 		#sound-dai-cells = <0>;
> 		dai-tdm-lane-slot-mask-in = <0 1 0 0 >;
> 		dai-tdm-lane-slot-mask-out = <1 0 0 0>;
> 		//dai-tdm-lane-slot-mask-in = <0 0 0 0 0 0 0 0>;
> 		//dai-tdm-lane-slot-mask-out = <1 1 1 1 1 1 1 1>;
> 		dai-tdm-clk-sel = <1>;
> 		clocks = <&clkaudio CLKID_AUDIO_MCLK_B
> 				&clkc CLKID_MPLL1
> 				&clkc CLKID_MPLL0
> 				&clkaudio CLKID_AUDIO_SPDIFOUT_A>;
> 		clock-names = "mclk", "clk_srcpll",
> 			"samesource_srcpll", "samesource_clk";
> 		pinctrl-names = "tdm_pins";
> 		pinctrl-0 = <&tdmb_mclk &tdmout_b &tdmin_b>;
> 		/*pinctrl-0 = < &tdmout_b &tdmin_b>;*/
> 		mclk_pad = <0>;  /* 0: mclk_0; 1: mclk_1 */
> 
> 		/*
> 		 * 0: tdmout_a;
> 		 * 1: tdmout_b;
> 		 * 2: tdmout_c;
> 		 * 3: spdifout;
> 		 * 4: spdifout_b;
> 		 */
> 		samesource_sel = <3>;
> 
> 		/*enable default mclk(12.288M), before extern codec start*/
> 		start_clk_enable = <1>;
> 
> 		/*tdm clk tuning enable*/
> 		clk_tuning_enable = <1>;
> 
> 		status = "okay";
> 	};

Can you try this?

max98090:audio-codec@10 {
         #sound-dai-cells = <0>;
         compatible = "maxim,max98090";
         reg = <0x10>;
         
         #clock-cells = <0>;
         clocks = <&tdmb 0>;
         clock-names = "mclk";
         interrupt-parent = <&gpio>;
         maxim,dmic-freq = <3500000>;    
         maxim,micbias = <1>;
         pinctrl-names = "default";
         interrupt_pin = <&gpio GPIOZ_15 GPIO_ACTIVE_HIGH>;
         status = "okay";
 };

Hi @numbqq
As per your suggestion i did the changes but not reflected and one more thing is MCLK is not stable and looks like getting floating value on I2S_MCLK pin.

can you please provide more suggestions!

Please provide your full dts and full kernel log.

hi @numbqq

shared on mail.

thanks.

Have you also changed the overlays of i2s? overlays/kvim3l/i2s.dts

The overlay node will overwrite your modifications in kvim3l_linux .dts, you also need to bump changes to overlays/kvim3l/i2s.dts.

hi @numbqq

I have removed overlays from the uboot env to avoid such kind of mess :smiley:

Can you try this ?

codec {
    sound-dai = <&dummy_codec &dummy_codec
    &amlogic_codec &max98090>;
};