Deployment of custom audio codec driver

Dear Toradex,

I have questions about deploying a custom audio codec driver to the Verdin Mallow board with AM62 D 1GB IT V1.1A.

I want to add a custom audio codec driver for AK4621 so the yocto build (I use tdx-reference-multimedia-image) includes the codec driver in /lib/modules/6.1.80-6.6.0-devel+git.xxx and I can modprobe it afterward. However, I am not sure how to compile it and include it within yocto build. I tried to compile it separately in: build/tmp/work-shared/verdin-am62/kernel-source/sound/soc/codecs directory by adding ak4621.c and ak4621.h files and modifying Kconfig and Makefile. It compiles, but when I copy it into the board and try to modprobe, I get: Exec format error. I suppose it is because it compiles the .ko file as 6.1.80+git.xxx version instead of 6.1.80-6.6.0-devel+git.xxx version so it does not match.

In the sound/soc/codecs folder, there are many drivers but only a few are present in the final yocto build. What controls this behavior? Which file limits the number of drivers that should be compiled into the image?

I need to compile my custom driver within the build itself. I created custom layers (meta-custom) and added a patch to the device tree (it works, the device tree is patched). Is it possible to simply add my .c and .h files into the sound/soc/codecs folder during the build, somehow patch the Kconfig and Makefile, and get the correct compiled version of this codec?

Is there a simpler way?

Thank you in advance.

Best regards

Matej I.

Hello @Matt,

The modules which are compiled in the Yocto build and included in the image are defined by the kernel configuration and other external modules which are included in your image.

For your case, it seems that including an external module would be the most straight-forward way to add the driver for your audio codec.
You can find documentation about how to do this with Yocto on the following page from our developer website: Custom meta layers, recipes and images in Yocto Project (hello-world examples) | Toradex Developer Center

Best Regards,
Bruno

Dear Bruno,

thank you for the information, I was able to build the Yocto image with codec driver. However, I have a following questions.

After boot, the system does not see my driver. Commands “aplay -l” or “arecord -l” output: “no soundcards”. The codec is placed and connected to the Mallow board. Modprobe snd-soc-ak4621 succesfully loaded the driver.

It is possible that I made a mistake in device tree configuration as I do not understand it completely. I used parts of Toradex development board configuration with nau8822 codec and ak4642 bindings information.

My device tree patch to k3-am625-verdin-nonwifi-mallow.dts looks like this:

diff --git a/arch/arm64/boot/dts/ti/k3-am625-verdin-nonwifi-mallow.dts b/arch/arm64/boot/dts/ti/k3-am625-verdin-nonwifi-mallow.dts
index 9cae12106e0e6..6ed7d53ef4251 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-verdin-nonwifi-mallow.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-verdin-nonwifi-mallow.dts
@@ -14,9 +14,56 @@
 #include "k3-am62-verdin-mallow.dtsi"
 
 / {
-	model = "Toradex Verdin AM62 on Mallow Board";
+	model = "Toradex Verdin AM62 XXX on Mallow Board";
 	compatible = "toradex,verdin-am62-nonwifi-mallow",
 		     "toradex,verdin-am62-nonwifi",
 		     "toradex,verdin-am62",
 		     "ti,am625";
+		     
+	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,name = "ak4621";
+		simple-audio-card,routing =
+			"Headphones", "LOUT1",
+			"Headphones", "ROUT1",
+			"Speaker", "LOUT2",
+			"Speaker", "ROUT2",
+			"LIN1", "Mic In",
+			"RIN1", "Mic In";
+		simple-audio-card,widgets =
+			"Headphones", "Headphones",
+			"Speaker", "Speaker",
+			"Microphone", "Mic In",
+
+		codec_dai: simple-audio-card,codec {
+			clocks = <&audio_refclk1>;
+			sound-dai = <&ak4621>;
+		};
+
+		simple-audio-card,cpu {
+			sound-dai = <&mcasp0>;
+		};
+	};
 };
+
+&main_i2c1 {
+	status = "okay";
+
+	/* Audio Codec */
+	ak4621: codec@12 {
+		compatible = "asahi-kasei,ak4621";
+		reg = <0x12>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2s1_mclk>;
+		#sound-dai-cells = <0>;
+	};
+};
+
+&mcasp0 {
+	status = "okay";
+};

The “compatible” should correspond to the custom ak4621 codec driver name, as well as routing and widgets. However, I do not know if “reg = <0x12>;” is correct or not (how should I obtain this value?). In the case of nau8822, reg=<0x1a>. Pinctrl and other settings were copied from development board device tree, see k3-am62-verdin.dtsi, is this a correct setting?

I also changed the /etc/asound.conf file to default settings:

pcm.!default {
    type hw
    card 0
}

ctl.!default {
    type hw           
    card 0
}

But I suppose this is useless as long as the system sees no soundcards. Dmesg does not print anything about ak4621. So my questions are:

  1. Does the device tree configuration seem correct for Mallow board, AM62 with custom AK4621 codec?
  2. How to setup reg value in device tree codec setting?
  3. Should I also change something else for the codec to be visible?

Thank you.

Best regards
Matej I.

Hello @Matt,

The reg = <0x12>, in the context of this devicetree, refers to the I2C address of the Codec.
However, from a quick search, it does not seem that the ak4642 codec is configurable via I2C.
If this is the case, the device tree would need to be different to account for that.

We have a lot of useful general documentation about devicetrees in Device Tree Technical Overview | Toradex Developer Center.
The most recommended approach would be to find a devicetree or devicetree overlay example for your codec, and see what kind of interfaces are used and what configurations are made for it, using this example as a starting point.


Please note that the Verdin modules currently have some audio-related configurations that happens on-device at first boot.
Therefore, to use another codec, it would be recommended to change the alsa-state recipe on meta-toradex-ti.

Best Regards,
Bruno

Dear Bruno,

Thank you for the information.
Do you mean ak4621 codec? The problem of not seeing any output in dmesg was that the tdx-reference-multimedia-image on Mallow board is loading k3-am625-verdin-nonwifi-dev.dtb instead of k3-am625-verdin-nonwifi-mallow.dtb that I modified. I patched the dev version and the changes are visible.

As for alsa-state, that is irrelevant as long as the device is not loaded properly, is that correct? I changed it to the default settings anyway as shown in my previous comment.

Ak4621 is probably not configurable via I2C so I switched to the correct routing (spi). I removed the verdin-am62_spidev_overlay.dtbo from overlays.txt so it does not colide on address @0. However, alsa does not see the codec yet.

I think now it is a problem of connection between spi, alsa, and codec modificaton.

Thank you.

Best regards

Matej I.

Hello @Matt,

Yes, that is correct, I mistyped it previously.


That is correct. This behavior recently changed, so if you use one of the latest nightlies as a base it will no longer be an issue.


You may want to have a look at the documentation for the SPI devicetree: spi-controller.yaml - Documentation/devicetree/bindings/spi/spi-controller.yaml - Linux source code (v6.1.86) - Bootlin

It is possible that configuring the correct chip-select may be the issue here.

Best Regards,
Bruno