Iio driver not being loaded

Hi,
I have a Jetson orin nano on a custom carrier board. I am using Jetpack 6
I have an MCP3914 connected to the pins that would have been SPI1.0 on the 40 pin header if it was the developer kit. I have verified that I can communicate with the MCP3914 using spidev, but the Jetson spi device latency is too high and inconsistent when running in user space to get a decent sample rate.
(I have tried isolating a core and running my program on that core in realtime mode but I still have the latency issue.)
I have since discovered that there is an MCP3911 driver in the linux kernel that is compatible with the MCP3914.
I added the MCP3911 driver into the config and I added the MCP3914 to the device tree in the following file:
/Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-p3768-0000+pp3767-xxxx-nv-common.dtsi

This is how the relevant section looks now:
/* SPI1, 40pin header, Pin 19(MOSI), Pin 21(MISO), Pin 23(CLK), Pin 24(CS) */
spi@3210000{
status = “okay”;
/spi@0 {
compatible = “tegra-spidev”;
reg = <0x0>;
spi-max-frequency = <50000000>;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
/
adc@0 {
compatible = “microchip,mcp3911”;
reg = <0>;
interrupt-parent = <&gpio>;
interrupts = <6 2>;
spi-max-frequency = <20000000>;
microchip,device-addr = <0>;
};

		spi@1 {
			compatible = "tegra-spidev";
			reg = <0x1>;
			spi-max-frequency = <50000000>;
			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x10>;
				nvidia,tx-clk-tap-delay = <0x0>;
			};
		};
	};

Note: I have also tried adding it as a child of spi@0 instead of replacing spi@0 but it also didn’t work.

After making the dtbs, rebuilding the kernel and flashing the Jetson, I have verified that if I use dtc to convert /boot/dtb/kernel_tegra234-p3768-0000+p3767-0004-nv.dtb on the device to a dts file, it does contain my modifications.

However I can’t find any iio devices being created and there is absolutely no mention of adc or MCP391x or anything else that might be related to it in the dmesg output (attached).
dmesg.txt (52.1 KB)

My assumption is that I’m doing something wrong, but I can’t seem to figure out what that is.
Any help would be greatly appreciated.

Thank you.

Hi stanley.adams,

If you connect your ADC module with CS0 of SPI1, please just porting the related configurations in spi@0.
From your current dmesg, I can’t find any log about MCP3911 driver.
It maybe caused from the node does not been probed/recognized currently.

Hi KevinFFF,
I just want to understand correctly.
The only configuration parameters in spi@0 that I haven’t got equivalents of are in the “controller-data” section.
So do you mean I must copy the “controller-data” section into my adc@0 definition?
(I was under the impression that the values in the controller-data section were just passed to the driver, which is why I didn’t copy them previously.)

This is what the adc@0 section looks like now:
adc@0 {
compatible = “microchip,mcp3911”;
reg = <0x00>;
interrupt-parent = <0xe2>;
interrupts = <0x06 0x02>;
spi-max-frequency = <0x1312d00>;
microchip,device-addr = <0x00>;

			controller-data {
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x10>;
				nvidia,tx-clk-tap-delay = <0x00>;
			};
		};

This still doesn’t work. I have exactly the same result.

Please share the full dmesg and DTB(/boot/dtb/kernel_XXX.dtb) from your board.

Hi Kevin,
I have attached the files as requested.
dtb files weren’t accepted, so I added a .txt extension. I hope it works, but just in case I also decompiled it to a .dts file which I have also attached.

kernel_tegra234-p3768-000+p3767-0004-nv.dts.txt (310.2 KB)
dmesg.txt (52.2 KB)
kernel_tegra234-p3768-0000+p3767-0004-nv.dtb.txt (238.5 KB)

I don’t see any dmesg related to mcp3911.

How did you build the driver? Into the kernel image or kernel module?
Could you also share the result of the following command on your board?

$ zcat /proc/config.gz | grep CONFIG_MCP3911

It is built into the kernel image.

zcat /proc/config.gz | grep CONFIG_MCP3911
CONFIG_MCP3911=y

Could you try porting the configuration into spi@0 node instead of creating the adc@0 node in device tree?

Have you also asked your vendor for the porting guide of MCP3911 module?
You should get the driver probed first.

Ok, I have made a small amount of progress.
If I edit /boot/extlinux/extlinux.conf and add the following line to primary:
FDT /boot/dtb/kernel_tegra234-p3768-0000+p3767-0004-nv.dtb
It then actually creates an iio device in /sys/bus/iio/devices with several analog channels that could in theory be read.

Unfortunately, it never attempts to communicate with the ADC at all. There is no activity on the SPI bus, even during boot. So it seems like it never even attempts to probe the hardware.

Unfortunately I don’t have a vendor I can ask since the carrier board is my own design.
I never considered any difficulty getting something as simple as SPI to work, but the Jetson Nano SPI implementation seems to be really bad.

Okay, it seems the dtb is loaded from UEFI binary by default in JP6.
After you add FDT, it will load it from the path you specified.
For the overall logic to load dtb, you can refer to DTB Support for details.

Please share the full device tree and dmesg currently for further check.

I mean the vendor of MCP3914 module.
They may better know how to bring up their module.

Hi Kevin,

Here is the result of dmesg, as well as the device tree (both the dtb and decompiled to a dts)
dmesg.txt (52.1 KB)
kernel_tegra234-p3768-0000+p3767-0004-nv.dts.txt (310.1 KB)
kernel_tegra234-p3768-0000+p3767-0004-nv.dtb.txt (238.4 KB)

I know this device tree is in use, because spidev0.0 no-longer exists in /dev and there is an iio device in /sys/bus/iio

Here is the result of ls /sys/bus/iio/devices/iio:device0
in_voltage0_offset in_voltage1_scale_available in_voltage3_scale in_voltage5_raw in_voltage7_offset of_node
in_voltage0_raw in_voltage2_offset in_voltage3_scale_available in_voltage5_scale in_voltage7_raw power
in_voltage0_scale in_voltage2_raw in_voltage4_offset in_voltage5_scale_available in_voltage7_scale subsystem
in_voltage0_scale_available in_voltage2_scale in_voltage4_raw in_voltage6_offset in_voltage7_scale_available uevent
in_voltage1_offset in_voltage2_scale_available in_voltage4_scale in_voltage6_raw in_voltage_oversampling_ratio
in_voltage1_raw in_voltage3_offset in_voltage4_scale_available in_voltage6_scale in_voltage_oversampling_ratio_available
in_voltage1_scale in_voltage3_raw in_voltage5_offset in_voltage6_scale_available name

If I use the un-modified device tree file, then the iio device doesn’t exist and spidev0.0 is available in /dev

I still can’t find any mention of adc or mcp3911 in the dmesg output, and there is never any activity on the SPI lines.

I can communicate with the ADC using spidev if I return to the old device tree, so I know the hardware is fine.
I just don’t know how to get the mcp3911 driver to probe the device and read values.