Request to add ad5761 kernel module

We’re working on a custom carrier board that a/o contains a number of ad5761 SPI DAC’s. For now, I’ve added the module out-of-tree and it builds fine with torizoncore-builder, but it would be nice if this module could be added to the default Torizon OS build.

torizon@verdin-am62-15403508:~$ uname -a
Linux verdin-am62-15403508 6.6.84-7.2.0-g8bf00740f043 #1-Torizon SMP PREEMPT Thu Mar 27 16:42:10 UTC 2025 aarch64 GNU/Linux
torizon@verdin-am62-15403508:~$ zcat /proc/config.gz | grep -i ad5761
# CONFIG_AD5761 is not set
torizon@verdin-am62-15403508:~$ tdx-info
Please, run as root.
torizon@verdin-am62-15403508:~$ sudo !$
sudo tdx-info
Password:

Software summary
------------------------------------------------------------
Bootloader:               U-Boot
Kernel version:           6.6.84-7.2.0-g8bf00740f043 #1-Torizon SMP PREEMPT Thu Mar 27 16:42:10 UTC 2025
Kernel command line:      root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ostree=/ostree/boot.1/torizon/947ee8683ad82a83d33f6194096f6486c6c2c5788c22a5248d00640fe7359adb/0
Distro name:              NAME="Torizon OS"
Distro version:           VERSION_ID=7.2.0-build.13
Distro variant:           VARIANT="Docker"
Hostname:                 verdin-am62-15403508
------------------------------------------------------------

Hardware info
------------------------------------------------------------
HW model:                 Toradex Verdin AM62 WB on Ara Giesen Main Board
Toradex version:          0072 V1.1D
Serial number:            15403508
Processor arch:           aarch64
------------------------------------------------------------
torizon@verdin-am62-15403508:~$

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Hello! Thank you for your detailed explanation and command output.

At the moment, Torizon OS does not include the AD5761 kernel driver by default; as you have noticed, the kernel configuration shows CONFIG_AD5761 is not set. For now, the recommended approach is exactly what you have done: build and deploy the AD5761 as an external (out-of-tree) kernel module using TorizonCore Builder.

To streamline this process and make it robust for production, you can use a configuration file with TorizonCore Builder (recommended for production scenarios). Here’s a sample configuration you can adapt:

input:
  easy-installer:
    local: images/torizon-core-docker-verdin-am62-Tezi_7.2.0.tar
customization:
  kernel:
    modules:
      - source-dir: your-ad5761-module/
        autoload: no       # Set to 'yes' to autoload at boot
output:
  easy-installer:
    local: torizon-core-docker-custom

Then, run:

torizoncore-builder build --file your-config.yaml

More information and both the YAML and the standalone command methods (for development) are explained here:

For inclusion in the official Torizon OS, such a change would require modifications to the base OS configuration, which is not covered in public documentation. As such, the modular/out-of-tree kernel module workflow with regular updates is both stable and maintainable.

If you need the driver to be autoloaded at boot, ensure to set autoload: yes in your YAML. Also, if you plan to ship your product, you can automate the process with your CI/CD pipeline.

If you need more guidance on building or deploying the module, feel free to ask!

Best regards,
Toradex AI Assistant.

Greetings @lamare,

Just to confirm you want the CONFIG_AD5761 configuration to be enabled for the Verdin AM62, correct?

Are there any other kernel configurations needed for this? Or is it the only one?

Best Regards,
Jeremias

Hi, @jeremias.tx

Well, the idea would have been to just enable the CONFIG_AD5761 configuration, but it turned out the driver doesn’t support setting the voltage range from the device tree, so I had to patch it.

This is the patch:

diff --git a/ad5761-mod/ad5761.c b/ad5761-mod/ad5761.c
index 6aa1a06..42af52d 100644
--- a/ad5761-mod/ad5761.c
+++ b/ad5761-mod/ad5761.c
@@ -13,6 +13,7 @@
 #include <linux/iio/sysfs.h>
 #include <linux/regulator/consumer.h>
 #include <linux/platform_data/ad5761.h>
+#include <linux/of.h>
 
 #define AD5761_ADDR(addr)		((addr & 0xf) << 16)
 #define AD5761_ADDR_NOOP		0x0
@@ -354,6 +355,8 @@ static int ad5761_probe(struct spi_device *spi)
 	enum ad5761_voltage_range voltage_range = AD5761_VOLTAGE_RANGE_0V_5V;
 	struct ad5761_platform_data *pdata = dev_get_platdata(&spi->dev);
 
+	dev_info(&spi->dev, "Probing AD5761 family DAC: %s\n", spi_get_device_id(spi)->name);
+
 	iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (!iio_dev)
 		return -ENOMEM;
@@ -364,8 +367,20 @@ static int ad5761_probe(struct spi_device *spi)
 	spi_set_drvdata(spi, iio_dev);
 
 	ret = ad5761_get_vref(st, chip_info);
-	if (ret)
+	if (ret) {
+		dev_err(&spi->dev, "Failed to get voltage reference\n");
 		return ret;
+	}
+
+	// Device tree override for voltage range
+	if (spi->dev.of_node) {
+		u32 dt_range;
+		ret = of_property_read_u32(spi->dev.of_node, "adi,voltage-range", &dt_range);
+		if (!ret && dt_range < ARRAY_SIZE(ad5761_range_params)) {
+			voltage_range = dt_range;
+			dev_info(&spi->dev, "Using voltage range from device tree: %u\n", dt_range);
+		}
+	}
 
 	if (pdata)
 		voltage_range = pdata->voltage_range;
@@ -373,8 +388,12 @@ static int ad5761_probe(struct spi_device *spi)
 	mutex_init(&st->lock);
 
 	ret = ad5761_spi_set_range(st, voltage_range);
-	if (ret)
+	if (ret) {
+		dev_err(&spi->dev, "Failed to set voltage range\n");
 		goto disable_regulator_err;
+	}
+
+	dev_info(&spi->dev, "AD5761 DAC initialized with vref=%dmV, range=%d\n", st->vref, voltage_range);
 
 	iio_dev->info = &ad5761_info;
 	iio_dev->modes = INDIO_DIRECT_MODE;
@@ -385,6 +404,7 @@ static int ad5761_probe(struct spi_device *spi)
 	if (ret)
 		goto disable_regulator_err;
 
+	dev_info(&spi->dev, "AD5761 family DAC registered as IIO device\n");
 	return 0;
 
 disable_regulator_err:
@@ -399,6 +419,8 @@ static void ad5761_remove(struct spi_device *spi)
 	struct iio_dev *iio_dev = spi_get_drvdata(spi);
 	struct ad5761_state *st = iio_priv(iio_dev);
 
+	dev_info(&spi->dev, "Removing AD5761 family DAC driver\n");
+
 	iio_device_unregister(iio_dev);
 
 	if (!IS_ERR_OR_NULL(st->vref_reg))

Would be great if that could be included. I don’t know what will happen if you’d only enable CONFIG_AD5761, while I still need the patches and would have to compile out-of-tree anyway.

Best regards,

Arend Lammertink.

but it turned out the driver doesn’t support setting the voltage range from the device tree, so I had to patch it.

That does complicate things then. If you require a patch for this driver to work the way you want, then unfortunately that’s something we generally don’t handle. We typically don’t accept such patches since they come with a maintenance burden that we would have to upkeep over time.

If this is the case you’d probably need to stick to compiling this modified driver out of tree.

Best Regards,
Jeremias

Hi @jeremias.tx

Thanks again for your reply.

We’re currently still in the development stage and are also building a .NET application that will run inside a Docker container on the device. For now, deployment is simply a matter of generating a Torizon Easy Installer image that we can load locally onto the SOMs during production.

However, looking ahead, our customer will eventually need to comply with the EU Cyber Resilience Act. In that context, a full integration with the Torizon Cloud — especially for remote updates, monitoring, and fleet management — seems like a very attractive option.

We’ll evaluate that more closely at a later stage, but I’m already wondering how situations like this are typically handled, since customers ultimately require a fully supported and auditable software stack in order to meet EU CRA requirements. One of the main reasons we chose Toradex SOMs is precisely because it appeared that we could offload these challenges to Toradex, allowing us to focus on application development rather than managing compliance ourselves.

So, if we or our customer were to adopt aTorizon Device and Fleet Management offering, could we expect Toradex to take responsibility for maintaining lightly patched kernel modules like this one?

Best regards,
Arend

We typically, do not apply or maintain Linux kernel patches provided by customers. This potentially introduces a lot of complexity on our end, especially since such a patch would theoretically affect all of our customers.

We would recommend potentially working with a partner of ours to upstream your changes officially to the Linux kernel source if you believe your patch should be in the driver by default. Or if you’re familiar with the Linux kernel you could try to upstream the patch yourself. If this was a change officially accepted by the Linux kernel maintainers then the discussion could be different. Is this something you would interested to pursue?

Best Regards,
Jeremias