Add support of MAX98091 codec to Edge (Pi)

Hello,

I want to add the support of MAX98091 codec in the Edge-Pi. I saw that Edge-pi has the driver of MAX98090 which is compatible with MAX98091. So, I hope I don’t have to do much but my concern is with device tree entry. How do I create a node for my codec and which gpios will I have to use from Edge V GPIO Pin-outs? I see few I2S0 lines which I think will be required to transfer the audio signal but not aware which to select.

Also, what is the functionality of ‘2S0_LRCK_TX/GPIO3_D2’ line? Or there is I2S0 instead of 2S0!!

Thanx.

Hi @Parth
You can refer the Captain Schematic for your design:

Rockchip SoC use TX & RX total two PINs for LRCK.

@Gouwa
I am sharing my hardware connections of Khadas Edge V to MAX98091. So, will you please have a look at it?
I want to confirm whether my connections are okay or not.

2 Likes

Yes, checked, I think it’s okay.

Just be note to follow the reference design to connecto the TX/RX pins.

Good day!

1 Like

I have shorted LRCK_TX and LRCK_RX pins of khadas board and then it is given to MAX98091 LRCLK pin.

You might need the 33R or similar value registor for better signal quality.

Thanx.

One more thing. I am sharing my device tree entry for max98091. Would you please have a look at it?
I am getting an error from rockchip-max98090.c file.

DTS Entry:

sound {
status = “okay”;
compatible = “rockchip,rockchip-audio-max98090”;
rockchip,model = “ROCKCHIP-I2S”;
pinctrl-names = “default”;
rockchip,i2s-controller = <&i2s0>;
rockchip,audio-codec = <&max98091>;
};

max98091: max98091@10 {
compatible = “maxim,max98091”;
reg = <0x10>;
clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = “mclk”;
#sound-dai-cells = <1>;
interrupt-parent = <&gpio1>;
interrupts = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
pinctrl-names = “default”;
pinctrl-0 = <&max98091_irq>;
};

max98091 {
max98091_irq: max98091_irq {
rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; /* GPIO1_B7 */
};

@Terry or @goenjoy may help you out.

@Gouwa

Thank You. I really appreciate this.

@Terry and @goenjoy Can you guide on this matter?

Refer to rt5651 for configuration. For example, add es8316, modify the record:

--- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge-android.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge-android.dts
@@ -29,18 +29,16 @@
                linux,no-autorepeat;
        };
 
-       rt5651-sound {
+       es8316-sound {
                status = "okay";
                compatible = "simple-audio-card";
 
                pinctrl-names = "default";
-               pinctrl-0 = <&rt5651_hpdet>;
-
-
+               pinctrl-0 = <&es8316_speak>;
+               
                simple-audio-card,format = "i2s";
-               simple-audio-card,name = "realtek,rt5651-codec";
+               simple-audio-card,name = "rockchip,es8316-codec";
                simple-audio-card,mclk-fs = <256>;
-               simple-audio-card,hp-det-gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>;
                simple-audio-card,widgets =
                        "Microphone", "Mic Jack",
                        "Headphone", "Headphone Jack";
@@ -50,10 +48,10 @@
                        "Headphone Jack", "HPOL",
                        "Headphone Jack", "HPOR";
                simple-audio-card,cpu {
-                       sound-dai = <&i2s1>;
+                       sound-dai = <&i2s0>;
                };
                simple-audio-card,codec {
-                       sound-dai = <&rt5651>;
+                       sound-dai = <&es8316>;
                };
        };
 };
@@ -90,11 +88,11 @@
        charge-dev = <&bq25703>;
 };
 
-&i2s1 {
+&i2s0 {
        status = "okay";
        rockchip,i2s-broken-burst-len;
-       rockchip,playback-channels = <2>;
-       rockchip,capture-channels = <2>;
+       rockchip,playback-channels = <8>;
+       rockchip,capture-channels = <8>;
        #sound-dai-cells = <0>;
 };
 
@@ -119,16 +117,17 @@
        i2c-scl-rising-time-ns = <300>;
        i2c-scl-falling-time-ns = <15>;
 
-       rt5651: rt5651@1a {
+       
+       es8316: es8316@10 {
                #sound-dai-cells = <0>;
-               compatible = "rockchip,rt5651";
-               reg = <0x1a>;
+               compatible = "everest,es8316";
+               reg = <0x10>;
                clocks = <&cru SCLK_I2S_8CH_OUT>;
                clock-names = "mclk";
                pinctrl-names = "default";
                pinctrl-0 = <&i2s_8ch_mclk>;
-               status = "okay";
-       };
+               spk-con-gpio = <&gpio4 30 GPIO_ACTIVE_HIGH>;    
+       };      
 };
 
 &i2c6 {
@@ -708,11 +707,11 @@
                };
        };
 
-       rt5651 {
-               rt5651_hpdet: rt5651-hpdet {
-                       rockchip,pins = <1 0 RK_FUNC_GPIO &pcfg_pull_up>; /* GPIO1_A0 */
+       es8316 {
+               es8316_speak: es8316-speak {
+                       rockchip,pins = <4 30 RK_FUNC_GPIO &pcfg_pull_up>; /* GPIO1_A0 */
                };
-       };
+       }; 
hlm@Server:/users/hlm/7_Edge/hardware/rockchip/audio$ git log -p
commit 576153c6a91cde9b5e4400068eb7f786862bc4bf
Author: goenjoy <goenjoy@khadas.com>
Date:   Sat Jan 11 10:48:57 2020 +0800

    audio : add es8316 config [2/2]

diff --git a/tinyalsa_hal/audio_hw.c b/tinyalsa_hal/audio_hw.c
index 5a93d75..676ad04 100755
--- a/tinyalsa_hal/audio_hw.c
+++ b/tinyalsa_hal/audio_hw.c
@@ -560,7 +560,7 @@ static inline bool hasExtCodec()
       memset(line, 0, 80);
       while((fgets(line,80,fd))!= NULL){
           line[80-1]='\0';
-          if(strstr(line,"realtekrt5651co")){
+          if(strstr(line,"rockchipes8316c")){
               ret = true;
               break;
           }
@@ -783,7 +783,7 @@ if (!hasExtCodec()){
                        AUDIO_DEVICE_OUT_ALL_SCO)) {
         card = adev->out_card[SND_OUT_SOUND_CARD_SPEAKER];
         if(card != (int)SND_OUT_SOUND_CARD_UNKNOWN) {
-                       if (out->device & (AUDIO_DEVICE_OUT_WIRED_HEADSET |AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) { 
+                       if (out->device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_WIRED_HEADSET |AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) {      
                    out->pcm[SND_OUT_SOUND_CARD_SPEAKER] = pcm_open(card, out->pcm_device,
                                                  PCM_OUT | PCM_MONOTONIC, &out->config);
                    if (out->pcm[SND_OUT_SOUND_CARD_SPEAKER] && !pcm_is_ready(out->pcm[SND_OUT_SOUND_CARD_SPEAKER])) {
diff --git a/tinyalsa_hal/codec_config/es8316_config.h b/tinyalsa_hal/codec_config/es8316_config.h
old mode 100644
new mode 100755
index 0694994..118d828
--- a/tinyalsa_hal/codec_config/es8316_config.h
+++ b/tinyalsa_hal/codec_config/es8316_config.h
@@ -98,25 +98,25 @@ const struct config_control es8316_voip_off_controls[] = {
 const struct config_route_table es8316_config_table = {
     //speaker
     .speaker_normal = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_speaker_normal_controls,
         .controls_count = sizeof(es8316_speaker_normal_controls) / sizeof(struct config_control),
     },
     .speaker_incall = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_speaker_incall_controls,
         .controls_count = sizeof(es8316_speaker_incall_controls) / sizeof(struct config_control),
     },
     .speaker_ringtone = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_speaker_ringtone_controls,
         .controls_count = sizeof(es8316_speaker_ringtone_controls) / sizeof(struct config_control),
     },
     .speaker_voip = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_speaker_voip_controls,
         .controls_count = sizeof(es8316_speaker_voip_controls) / sizeof(struct config_control),
@@ -124,25 +124,25 @@ const struct config_route_table es8316_config_table = {
 
     //earpiece
     .earpiece_normal = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_earpiece_normal_controls,
         .controls_count = sizeof(es8316_earpiece_normal_controls) / sizeof(struct config_control),
     },
     .earpiece_incall = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_earpiece_incall_controls,
         .controls_count = sizeof(es8316_earpiece_incall_controls) / sizeof(struct config_control),
     },
     .earpiece_ringtone = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_earpiece_ringtone_controls,
         .controls_count = sizeof(es8316_earpiece_ringtone_controls) / sizeof(struct config_control),
     },
     .earpiece_voip = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_earpiece_voip_controls,
         .controls_count = sizeof(es8316_earpiece_voip_controls) / sizeof(struct config_control),
@@ -150,37 +150,37 @@ const struct config_route_table es8316_config_table = {
 
     //headphone
     .headphone_normal = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_headphone_normal_controls,
         .controls_count = sizeof(es8316_headphone_normal_controls) / sizeof(struct config_control),
     },
     .headphone_incall = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_headphone_incall_controls,
         .controls_count = sizeof(es8316_headphone_incall_controls) / sizeof(struct config_control),
     },
     .headphone_ringtone = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_headphone_ringtone_controls,
         .controls_count = sizeof(es8316_headphone_ringtone_controls) / sizeof(struct config_control),
     },
     .speaker_headphone_normal = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_speaker_headphone_normal_controls,
         .controls_count = sizeof(es8316_speaker_headphone_normal_controls) / sizeof(struct config_control),
     },
     .speaker_headphone_ringtone = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_speaker_headphone_ringtone_controls,
         .controls_count = sizeof(es8316_speaker_headphone_ringtone_controls) / sizeof(struct config_control),
     },
     .headphone_voip = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_headphone_voip_controls,
         .controls_count = sizeof(es8316_headphone_voip_controls) / sizeof(struct config_control),
@@ -188,25 +188,25 @@ const struct config_route_table es8316_config_table = {
 
     //headset
     .headset_normal = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_headset_normal_controls,
         .controls_count = sizeof(es8316_headset_normal_controls) / sizeof(struct config_control),
     },
     .headset_incall = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_headset_incall_controls,
         .controls_count = sizeof(es8316_headset_incall_controls) / sizeof(struct config_control),
     },
     .headset_ringtone = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_headset_ringtone_controls,
         .controls_count = sizeof(es8316_headset_ringtone_controls) / sizeof(struct config_control),
     },
     .headset_voip = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_headset_voip_controls,
         .controls_count = sizeof(es8316_headset_voip_controls) / sizeof(struct config_control),
@@ -214,19 +214,19 @@ const struct config_route_table es8316_config_table = {
 
     //bluetooth
     .bluetooth_normal = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_bluetooth_normal_controls,
         .controls_count = sizeof(es8316_bluetooth_normal_controls) / sizeof(struct config_control),
     },
     .bluetooth_incall = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0_1,
         .controls = es8316_bluetooth_incall_controls,
         .controls_count = sizeof(es8316_bluetooth_incall_controls) / sizeof(struct config_control),
     },
     .bluetooth_voip = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0_1,
         .controls = es8316_bluetooth_voip_controls,
         .controls_count = sizeof(es8316_bluetooth_voip_controls) / sizeof(struct config_control),
@@ -234,19 +234,19 @@ const struct config_route_table es8316_config_table = {
 
     //capture
     .main_mic_capture = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_main_mic_capture_controls,
         .controls_count = sizeof(es8316_main_mic_capture_controls) / sizeof(struct config_control),
     },
     .hands_free_mic_capture = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_hands_free_mic_capture_controls,
         .controls_count = sizeof(es8316_hands_free_mic_capture_controls) / sizeof(struct config_control),
     },
     .bluetooth_sco_mic_capture = {
-        .sound_card = 0,
+        .sound_card = 1,
 
     //capture
     .main_mic_capture = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_main_mic_capture_controls,
         .controls_count = sizeof(es8316_main_mic_capture_controls) / sizeof(struct config_control),
     },
     .hands_free_mic_capture = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0,
         .controls = es8316_hands_free_mic_capture_controls,
         .controls_count = sizeof(es8316_hands_free_mic_capture_controls) / sizeof(struct config_control),
     },
     .bluetooth_sco_mic_capture = {
-        .sound_card = 0,
+        .sound_card = 1,
         .devices = DEVICES_0_1,
         .controls = es8316_bluetooth_sco_mic_capture_controls,
         .controls_count = sizeof(es8316_bluetooth_sco_mic_capture_controls) / sizeof(struct config_control),
@@ -269,27 +269,12 @@ const struct config_route_table es8316_config_table = {
         .controls = es8316_voip_off_controls,
         .controls_count = sizeof(es8316_voip_off_controls) / sizeof(struct config_control),
     },
-#ifdef BOX_HAL
     //hdmi
     .hdmi_normal = {
         .sound_card = 0,
         .devices = DEVICES_0,
         .controls_count = 0,
     },
-#else
-    //hdmi
-    .hdmi_normal = {
-        .sound_card = 1,
-        .devices = DEVICES_0,
-        .controls_count = 0,
-    },
-#endif
-    //spdif
-    .spdif_normal = {
-        .sound_card = 1,
-        .devices = DEVICES_0,
-        .controls_count = 0,
-    },
 
     //usb audio
     .usb_normal = {
1 Like

Thanx @goenjoy

But when I use simple-audio-card then my ASoC driver(rockchip,rockchip-audio-max98090) is not getting probed. Just for your information, I am sharing my device tree entry so that you can tell me if I am doing something wrong.

sound {
status = “okay”;
compatible = “simple-audio-card”;
simple-audio-card,format = “i2s”;
simple-audio-card,name = “rockchip,rockchip-audio-max98090”;
simple-audio-card,mclk-fs = <256>;
pinctrl-0 = <&headset_connect>;

	pinctrl-names = "default";
	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";
	simple-audio-card,cpu {
		sound-dai = <&i2s0>;
	};
	simple-audio-card,codec {
		sound-dai = <&max98091>;
	};
};

max98091: max98091@10 {
compatible = “maxim,max98091”;
reg = <0x10>;
clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = “mclk”;
#sound-dai-cells = <1>;
interrupt-parent = <&gpio1>;
interrupts = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
pinctrl-names = “default”;
pinctrl-0 = <&max98091_irq>;
};

max98091 {
max98091_irq: max98091_irq {
rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; /* GPIO1_B7 */
};
};

headset {
	headset_connect: headset_connect {
		rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; /* GPIO1_B7 */
	};
};

&i2s0 {
status = “okay”;
rockchip,i2s-broken-burst-len;
rockchip,playback-channels = <8>;
rockchip,capture-channels = <8>;
#sound-dai-cells = <0>;
};

And one more thing is I don’t find speaker name and mic name related to MAX98091 codec in audio_hw.c file and there is no max98091_config.h file.

How do I make changes in audio_hw.c file because I am using max98091 codec. And Do I have to create max98091_config.h file?

kernel/sound/soc/rockchip/
Do you have the following files in this directory?
rockchip_max98090.o

Yes, I do have that file in the directory

So @goenjoy which audio card I should be using?

root@Khadas:~# cat /proc/asound/cards 
 0 [SPDIF          ]: SPDIF - SPDIF
                      SPDIF
 1 [realtekrt5651co]: realtek_rt5651- - realtek,rt5651-codec
                      realtek,rt5651-codec
 2 [rkhdmidpsound  ]: rk-hdmi-dp-soun - rk-hdmi-dp-sound
                      rk-hdmi-dp-sound
1 Like

So, you are saying that I can not use max98090 codec since max98090_config.h is not present in the source.

I’m not sure, but you can refer to other documents for similar additions. But this is the latter thing. At least you need to recognize the corresponding sound card first.
image

That makes sense.

So, what should be I looking for in terms of corresponding sound card to max98091. I mean How can I find corresponding sound card?

As long as the configuration is OK and the hardware is OK, enter

cat /proc/asound/cards

and the max98090 character will appear naturally, This means that the corresponding sound card has been identified.