MCLK setup for custom codec on Mallow V1.1 and AM62

Dear Support,

I have following questions regarding AK4621 audio codec deployed on Mallow Board with AM62. I build the Yocto tdx-reference-multimedia-image with custom layer. It provides ak4621 codec (custom made and set explicitely to 48000 Hz) and patch the device tree as follows:

diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
index a82bf2f7485e8..de3bdee4dfcd9 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
@@ -11,35 +11,26 @@
 / {
 	sound {
 		compatible = "simple-audio-card";
-		simple-audio-card,bitclock-master = <&codec_dai>;
-		simple-audio-card,format = "i2s";
-		simple-audio-card,frame-master = <&codec_dai>;
+		simple-audio-card,bitclock-master = <&codec_dai>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,frame-master = <&codec_dai>;
 		simple-audio-card,mclk-fs = <256>;
-		simple-audio-card,name = "verdin-nau8822";
+		simple-audio-card,name = "ak4621";
 		simple-audio-card,routing =
-			"Headphones", "LHP",
-			"Headphones", "RHP",
-			"Speaker", "LSPK",
-			"Speaker", "RSPK",
-			"Line Out", "AUXOUT1",
-			"Line Out", "AUXOUT2",
-			"LAUX", "Line In",
-			"RAUX", "Line In",
-			"LMICP", "Mic In",
-			"RMICP", "Mic In";
+			"Headphones", "LOUT1",
+			"Headphones", "ROUT1",
+			"LIN1", "Line In",
+			"RIN1", "Line In";
 		simple-audio-card,widgets =
 			"Headphones", "Headphones",
-			"Line Out", "Line Out",
-			"Speaker", "Speaker",
-			"Microphone", "Mic In",
 			"Line", "Line In";
 		codec_dai: simple-audio-card,codec {
-			sound-dai = <&nau8822_1a>;
+			sound-dai = <&ak4621>;
-		simple-audio-card,cpu {
+		cpu_dai: simple-audio-card,cpu {
 			sound-dai = <&mcasp0>;
@@ -101,17 +96,6 @@ &main_gpio0 {
 &main_i2c1 {
 	status = "okay";
-	/* Audio Codec */
-	nau8822_1a: audio-codec@1a {
-		compatible = "nuvoton,nau8822";
-		reg = <0x1a>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2s1_mclk>;
-		clock-names = "mclk";
-		clocks = <&audio_refclk1>;
-		#sound-dai-cells = <0>;
-	};
 	/* IO Expander */
 	gpio_expander_21: gpio@21 {
 		compatible = "nxp,pcal6416";
@@ -159,6 +143,16 @@ &main_mcan0 {
 /* Verdin SPI_1 */
 &main_spi1 {
 	status = "okay";
+	/* Audio Codec */
+	ak4621: audio-codec@0 {
+		compatible = "asahi-kasei,ak4621";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2s1_mclk>;
+		clock-names = "mclk";
+		clocks = <&audio_refclk1>;
+		reg = <0>;
+		#sound-dai-cells = <0>;
+	};
 /* Verdin UART_3 */

The codec is added via second patch. The settings in dt should be the same as with nau8822 (default to dev board), but the codec is connected via spi instead of i2c. The system recognizes the codec, “arecord -l” lists the soundcard. However, if I call “cat sys/kernel/debug/clk/clk_sumarry” I get this info:

Screenshot from 2024-05-13 15-39-30

It seems the audio_refclk is set to 12345689, which is wrong. I want to set the frequency to 12288000.

I also tried this patch to set it explicitely:

 		codec_dai: simple-audio-card,codec {
-			sound-dai = <&nau8822_1a>;
+			sound-dai = <&ak4621>;
+			clocks = <&audio_refclk1>;
+			system-clock-frequency = <12288000>;
+			mclk-fs = <256>;

When I run “arecord out.wav -f S24_LE -r 48000”, it freezes and when I cancel it, it outputs pcm_error:
Screenshot from 2024-05-13 16-06-28

The user side of alsa config should be correct. From what I have understood, the problem is probably with the clock setting. My question is, does the device tree settings seem correct?
It is possible that the problem is inside the codec .c file. After some debugging, the codec’s function “ak4621_dai_set_sysclk” is run first with correct 12288000 value but then it is called once again with value of 0:

Screenshot from 2024-05-11 16-13-33

I yet don’t know why. If the device tree settings is correct, I will try to modify the codec file.

Thank you.

Best regards

Matej I.

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Based on the details you’ve provided, it seems you’re on the right track with modifying the device tree to support the AK4621 codec on the Verdin AM62 platform. However, there are a few considerations to ensure the correct setup for the MCLK frequency.

  1. Device Tree Configuration: Your device tree modifications for integrating the AK4621 codec appear correct at a glance. You’ve correctly identified the codec node, specified the compatible codec, and linked the MCLK clock source (audio_refclk1). However, the explicit setting of the system clock frequency within the codec node is not standard practice in device tree definitions. The system-clock-frequency property is not recognized by the simple-audio-card bindings or most codec drivers directly.

  2. Clock Source Configuration: The issue with the audio_refclk1 being set to an incorrect frequency suggests that there might be a misconfiguration or misunderstanding of how the clock source is defined and enabled. Typically, the clock frequency is set in the clock controller node that audio_refclk1 refers to, not in the codec node itself. Ensure that the clock source (audio_refclk1) is correctly defined in the device tree, including its frequency. This might involve configuring a fixed-clock or a clock provider that can generate the desired frequency.

  3. Codec Driver: The behavior you’re observing with the ak4621_dai_set_sysclk function being called with a zero value suggests that there might be an issue in the ALSA machine driver’s interaction with the codec driver. It’s possible that the initial correct setting is being overridden by subsequent operations in the audio subsystem. This could be due to the ALSA core or the machine driver not correctly handling the clock settings or due to an issue within the codec driver itself.

  4. Debugging Steps:

    • Review Clock Configuration: Double-check the clock configuration for audio_refclk1 in the device tree. Ensure it’s defined correctly and capable of providing the required 12.288 MHz frequency.
    • Codec Driver Investigation: Investigate the codec driver, especially how it handles the set_sysclk callback. It’s crucial to understand why it might be called with a zero value. Adding debug prints in the codec driver and the machine driver might help trace the flow of clock settings.
    • ALSA System Configuration: Although you mentioned the ALSA user-side configuration should be correct, it’s worth reviewing the ALSA settings and ensuring they match the requirements of the AK

Please, also check if these links can help you solve your problem:

Display Output, Resolution and Timings (Linux) | Toradex Developer Center.

Hello @Matt,

I think some of the configuration you are doing on the codec_dai node should instead be done on the mcasp0 node, maybe on both, considering the frequency is set correctly initially.
The device tree binding for mcasp is available here: davinci-mcasp-audio.yaml « sound « bindings « devicetree « Documentation - linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules

Beyond this, it is a bit hard to be sure that all the configuration is in place for your custom codec.

Best regards,

Dear Bruno,

I tried many settings of mcasp0, the codec, cpu_dai or, codec_dai but I failed to set the master clock to the correct frequency. There is not oscillator on the ak4621 codec, so I set the master to cpu_dai (sound-dai = mcasp0). However, when I leave the defalt settings or modify the device tree of mcasp0, I still get 12345679 frequency of the master clock. Is this expected behaviour?

I understand the codec driver can change the frequency by adjusting fps and rate (my case is 256 * 48000 = 12288000) and this is also default settings of the codec driver so I theoretically do not have to update any bits. But this will work only if the master clock provides exactly 12288000 value, which is not the case.

I searched the dt for mcasp0, and the audio_refclk1 (or pinctrl_i2s_mclk, SODIMM 38) is not included in the mcasp definition. I added it in dt as follows: clocks=<&audio_refclk1> or assigned-clocks=<&audio_refclk1> or pinctrl-0=<&pinctrl_i2s_mclk>, but none worked, the value does not change.

I would like to get confirmed, that if I want to use cpu as master provider of mclk for the custom codec, I should:

    1. define simple-audio-card,bitclock-master and frame-master as cpu_dai (simple-audio-card,cpu)
    1. leave the sound-dai of cpu to <&mcasp0>
    1. add the definition of pinctrl and clocks to mcasp0 node
    1. When calling: “cat /sys/kernel/debug/clk/clk_summary”, see the change of master clock to the value defined by audio_refclk1 in dt

Is that correct?

Thank you for your time.

Matej I.

We have tried different settings but the problem with setting of audio_refclk1 persist.

I would like to confirm one thing that is not clear for me from datasheet and device tree. We are using Mallow board (but the .dts file is from development board as default): audio_refclk1 is a clock that comes from I2S_1_MCLK (Serial audio master clock), is that correct?

Hello @Matt,

Sorry for the delay on this topic.

I can confirm that audio_refclk1 is the clock used for the I2S_1_MCLK signal.

I will also try to find some information which may be helpful here.

We can also recommend one of our partners, which would be able to do this implementation for you. Please let me know if this is something that would make sense for you.

Best Regards,