ADIS IMU device tree overlay

Dear Nvidia!

I would like to connect an ADIS16475 to the AGX ORIN 40pin header and add it as an iio device to the device tree to be recognized by the kernel. I would like to use spi0.0 for the communication and have GPIO11 as a data ready pin and GPIO12 as a reset pin. I have created a device tree overlay based on the IMU’s specifications as follows:

//include <dt-bindings/pinctrl/pinctrl-tegra.h>
include <dt-bindings/gpio/tegra234-gpio.h>
include <dt-bindings/interrupt-controller/irq.h>
include <dt-bindings/gpio/gpio.h>
include <dt-common/jetson/tegra234-p3737-0000-p3701-0000.h>
include <dt-bindings/pinctrl/pinctrl-tegra.h>

/ {
overlay-name = “adis16475 IMU”;
jetson-header-name = “Jetson 40pin Header”;
compatible = JETSON_COMPATIBLE;

fragment@0 {
	target-path = "/spi@3210000/spi@0";

	__overlay__ {
		status = "disabled";
	};
};

fragment@1 {
	target = <&spi0>;

	__overlay__ {
		status = "okay";

		adis_imu: adis16475@0 {
			compatible = "adi,adis16475-3";
			reg = <0x00>;
			spi-cpha;
			spi-cpol;
			spi-max-frequency = <2000000>;
			interrupt-parent = <&tegra_main_gpio>;
			interrupts = <TEGRA234_MAIN_GPIO(R, 4) IRQ_TYPE_EDGE_RISING>;
			reset-gpios = <&tegra_main_gpio TEGRA234_MAIN_GPIO(H, 7) GPIO_ACTIVE_LOW>;
		};
	};
};

fragment@2 {
	target = <&pinmux>;
	__overlay__ {
		pinctrl-names = "default";
		pinctrl-0 = <&jetson_io_pinmux>;

		jetson_io_pinmux: exp-header-pinmux {
			hdr40-pin11 {
				nvidia,pins = HDR40_PIN11;
				#nvidia,function = "spi1";
				nvidia,pin-label = "spi0_dr";
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};
			hdr40-pin12 {
				nvidia,pins = HDR40_PIN12;
				#nvidia,function = "spi1";
				nvidia,pin-label = "adis_reset";
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
				#nvidia,pull = <TEGRA_PIN_PULL_UP>;
			};
			hdr40-pin19 {
				nvidia,pins = "spi1_mosi_pz5";
				nvidia,function = "spi1";
				nvidia,pin-label = "spi1_dout";
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};
			hdr40-pin21 {
				nvidia,pins = "spi1_miso_pz4";
				nvidia,function = "spi1";
				nvidia,pin-label = "spi1_din";
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};
			hdr40-pin23 {
				nvidia,pins = "spi1_sck_pz3";
				nvidia,function = "spi1";
				nvidia,pin-label = "spi1_sck";
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};
			hdr40-pin24 {
				nvidia,pins = "spi1_cs0_pz6";
				nvidia,function = "spi1";
				nvidia,pin-label = "spi1_cs0";
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};
			hdr40-pin26 {
				nvidia,pins = "spi1_cs1_pz7";
				nvidia,function = "spi1";
				nvidia,pin-label = "spi1_cs1";
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};

		};
	};
};

};

The device appears in /sys/bus/iio/devices/ however I get zeros in the measurement fields.
Can you help me solving this issue.

Thank you for your help.

Hi nagymihaly,

Are you using the devkit or custom board for AGX Orin?
What’s your Jetpack version in use?

Have you verified SPI loopback test before connecting with your IMU module?

Please share the full dmesg for further check.

Hi Kevin!

I am using the NVidia devkit. I am using R35 (release), REVISION: 4.1 (as stated in /etc/nv_tegra_release) and my kernel version is 5.10.120-tegra.

Yes I have verified that the SPI line is working when accessing it through /etc/spidev0.0.

The adis16475 driver is compiled as a kernel module and when I load it with modprobe I get the last three lines of kernel messages (as stated in the attached dmesg file).

agx_adis_dmesg.txt (70.2 KB)

Moreover, I get some non-zero values in some input fields (e.g. calibbias) but they seem unrealistic.

Thanks!

[   89.782532] adis_lib: module verification failed: signature and/or required key missing - tainting kernel
[   89.803512] irq: IRQ327: trimming hierarchy from :pmc@c360000
[   90.066715] adis16475 spi0.0: Device ID(16475) and product ID(8190) do not match.

It seems the error reported from your custom adis16475 driver.
Could you add more messages in the driver to debug the issue?

Are they the correct pins you used for interrupt and reset?

I was trying to get the device tree identifiers of pins 11 and 12 of the 40 pin header (UART1_RTS and I2S2_CLK).I found these defines in tegra234-gpio.h and tegra234-p3737-0000-p3701-0000.h, but I am not completely sure that these are the correct settings. Can you please verify this?

Also, do the serial and i2s devices have to be disabled in the device tree for the pins to work?
I will try to add some prints in the driver. The driver itself is verified working on another platform that is why my assumption is that the device tree overlay is wrong.

Thanks!

They are the correct header file for the macro of pin definition.

From the error log, it seems some reading is wrong. I would suggest you can also asking your vendor for details.

I added some prints where the driver tries to get the product ID of the IMU. It seems like it does not get the full product ID from the IMU:

The print in dmesg is the following:
SPI tx buffer: 0, 0, 232, 4, 114, 0, 0, 0, 0, 0, rx buffer: 0, 0, 0, 91

The tx buffer contains the read request message sent to the IMU and the rx buffer contains the result.

Meanwhile if I add the same print to a module running on a Raspberry Pi 5 I get the correct reply:
SPI tx buffer: 0, 0, 232, 4, 114, 0, 0, 0, 0, 0, rx buffer: 0, 0, 64, 91

Do you mean 64 missing on SPI rx buffer when you are using AGX Orin?
Please also check if the level of SPI signal are correct for both cases. (AGX Orin and Raspberry Pi 5)

Yes, the 64 is missing in the rx buffer on the AGX Orin.

I checked the signals with a logic analyzer, and the 64 (0x40) is missing in the spi message as well.
I am going to attach a screeshot of the waveforms on both Pi5 and AGX Orin.


From the waveform you shared, they seem both working with SPI mode 3. (SCK High in idle, sampling at rising)

But I found the default state of MOSI and MISO are different:
For AGX Orin: Low
For Pi5: High

Please help to check the default state for MISO/MOSI and also the SPI mode you want to use(configured).

Yes I am using SPI mode 3 on both devices since spi-cpha and spi-cpol are set in both devicetree overlays.
I tried to modify the default state of the MOSI and MISO pins by adding nvidia,pull = <TEGRA_PIN_PULL_UP>; to the pinmux fragment in the overlay but it made no effect. Or is there another way to do this?

There is a post about this issue which was suggested to me on the Analog Devices forum. The patch detailed in the initial post solves my issue as well.

1 Like