Useful Links - ICM42688 Setup
This wiki page contains information on how to set up the SRX-IMU00-DEV device from SYSROX for NVIDIA Jetson platforms. The steps are applicable to other platforms with a Linux kernel greater than 5.15.
These instructions target the SPI variant of the ICM42688.
JetPack 6
The next section was tested on the Jetson Orin Nano board running JetPack 6.2 (L4T 36.4.3)
Kernel Customization
First, enable the Linux kernel driver that supports the InvenSense ICM-426xx motion tracking devices over SPI, since the NVIDIA Jetson devices do not enable it by default.
Prepare the necessary directories
First, install the NVIDIA board support package by downloading the Driver Package (BSP) and Sample Root Filesystem from the drivers section on the following link. Extract the downloaded files with the following commands inside a work directory.
mkdir nvidia-jetson tar xf Jetson_Linux_R36.4.3_aarch64.tbz2 -C nvidia-jetson/ sudo tar xpf Tegra_Linux_Sample-Root-Filesystem_R36.4.3_aarch64.tbz2 -C \ nvidia-jetson/Linux_for_Tegra/rootfs
Now run the following scripts inside the Linux_for_Tegra directory:
cd nvidia-jetson/Linux_for_Tegra sudo ./tools/l4t_flash_prerequisites.sh sudo ./apply_binaries.sh
(Optional step) Create a default user:
sudo ./tools/l4t_create_default_user.sh -u <user_name> -p <password>
Obtaining the kernel sources
To obtain the kernel sources, run the following commands:
cd <install-path>/Linux_for_Tegra/source ./source_sync.sh -k -t jetson_36.4.3
Obtaining the Jetson-Linux toolchain
Then, it is required to download the Jetson-Linux toolchain from the Jetson release page located here. Execute the following commands to download and extract the toolchain:
mkdir $HOME/jetson-toolchain cd $HOME/jetson-toolchain wget https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v3.0/toolchain/aarch64--glibc--stable-2022.08-1.tar.bz2 tar xf aarch64--glibc--stable-2022.08-1.tar.bz2
Applying the patches
Before building the kernel, enable support for the InvenSense ICM-426xx SPI driver by applying a patch to the kernel sources, as the support for the sensor ICM-42688-P was added in kernel version 6.10, as shown on this page.
The first thing is to apply this patch to the kernel sources located in the <install path>/Linux_for_Tegra/source/kernel/kernel-jammy-src directory. You can copy the following patch and save it to a .patch file.
From 9976f503c81cbb14aa3e0d1920388dc1915c33ae Mon Sep 17 00:00:00 2001
From: Ridgerun support@ridgerun.com>
Date: Wed, 14 Jan 2026 16:35:47 -0600
Subject: [PATCH] iio: imu: inv_icm42600: add icm42688 support
---
.../devicetree/bindings/iio/imu/invensense,icm42600.yaml | 1 +
drivers/iio/imu/inv_icm42600/inv_icm42600.h | 2 ++
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 5 +++++
drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c | 3 +++
drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c | 3 +++
5 files changed, 14 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
index 4c1c083d0e92..8b58b152d64a 100644
--- a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
+++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml
@@ -31,6 +31,7 @@ properties:
- invensense,icm42602
- invensense,icm42605
- invensense,icm42622
+ - invensense,icm42688
reg:
maxItems: 1
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h
index 995a9dc06521..8a3b99de1096 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h
@@ -22,6 +22,7 @@ enum inv_icm42600_chip {
INV_CHIP_ICM42602,
INV_CHIP_ICM42605,
INV_CHIP_ICM42622,
+ INV_CHIP_ICM42688,
INV_CHIP_NB,
};
@@ -303,6 +304,7 @@ struct inv_icm42600_state {
#define INV_ICM42600_WHOAMI_ICM42602 0x41
#define INV_ICM42600_WHOAMI_ICM42605 0x42
#define INV_ICM42600_WHOAMI_ICM42622 0x46
+#define INV_ICM42600_WHOAMI_ICM42688 0x47
/* User bank 1 (MSB 0x10) */
#define INV_ICM42600_REG_SENSOR_CONFIG0 0x1003
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
index ca85fccc9839..e1c86dd894b1 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
@@ -87,6 +87,11 @@ static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
.name = "icm42622",
.conf = &inv_icm42600_default_conf,
},
+ [INV_CHIP_ICM42688] = {
+ .whoami = INV_ICM42600_WHOAMI_ICM42688,
+ .name = "icm42688",
+ .conf = &inv_icm42600_default_conf,
+ },
};
const struct iio_mount_matrix *
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c
index 53891010a91d..42d22b14d005 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c
@@ -84,6 +84,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = {
}, {
.compatible = "invensense,icm42622",
.data = (void *)INV_CHIP_ICM42622,
+ }, {
+ .compatible = "invensense,icm42688",
+ .data = (void *)INV_CHIP_ICM42688,
},
{}
};
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c
index 323789697a08..7443391f1660 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c
@@ -80,6 +80,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = {
}, {
.compatible = "invensense,icm42622",
.data = (void *)INV_CHIP_ICM42622,
+ }, {
+ .compatible = "invensense,icm42688",
+ .data = (void *)INV_CHIP_ICM42688,
},
{}
};
--
2.43.0
Next, add the following line at the end of the default kernel configuration file located in the path <install path>/Linux_for_Tegra/source/kernel/kernel-jammy-src/arch/arm64/configs/defconfig using a text editor of your choice:
CONFIG_INV_ICM42600_SPI=m
to load it as a module.
After that, you need to modify the device-tree of your board, in this case, for the Jetson Orin Nano the device-tree is called tegra234-p3768-0000+p3767-0005-nv.dts and it is located in the folder <install path>/Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public. For this step, create a file in that folder called tegra234-p3768-0000-a0.dtsi.
For example, and include the following content in that file:
#include <dt-bindings/gpio/tegra234-gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
bus@0 {
spi@3210000 {
/delete-node/ spi@0;
icm42688@0 {
compatible = "invensense,icm42688";
status = "okay";
reg = <0x0>;
spi-max-frequency = <12000000>;
spi-cpha;
spi-cpol;
interrupt-parent = <&gpio>;
interrupts = <TEGRA234_MAIN_GPIO(I, 6) IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "INT1";
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
};
};
};
The next step is to include the file we created above in the main file i.e. tegra234-p3768-0000+p3767-0005-nv.dts, like this:
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/dts-v1/;
#include "tegra234-p3768-0000+p3767-0005.dts"
#include "tegra234-p3768-0000+p3767-xxxx-nv-common.dtsi"
#include "tegra234-p3768-0000-a0.dtsi"
/ {
bus@0 {
host1x@13e00000 {
nvdla0@15880000 {
status = "disabled";
};
nvdla1@158c0000 {
status = "disabled";
};
pva0@16000000 {
status = "disabled";
};
};
};
};
Building the Linux kernel
Then, run the following commands to build the Jetson Linux kernel and its in-tree modules:
cd <install-path>/Linux_for_Tegra/source export CROSS_COMPILE=$HOME/jetson-toolchain/aarch64--glibc--stable-2022.08-1/bin/aarch64-buildroot-linux-gnu- make -C kernel
Now, to install the kernel image and its in-tree modules execute the following commands:
export INSTALL_MOD_PATH=<install-path>/Linux_for_Tegra/rootfs/ sudo -E make install -C kernel cp kernel/kernel-jammy-src/arch/arm64/boot/Image <install-path>/Linux_for_Tegra/kernel/Image
Building the DTBs
To build the DTBs go to the kernel sources directory and run the following commands:
cd <install-path>/Linux_for_Tegra/source export CROSS_COMPILE=$HOME/jetson-toolchain/aarch64--glibc--stable-2022.08-1/bin/aarch64-buildroot-linux-gnu- export KERNEL_HEADERS=$PWD/kernel/kernel-jammy-src make dtbs
Execute the following command to install the dtbs:
cp kernel-devicetree/generic-dts/dtbs/* <install-path>/Linux_for_Tegra/kernel/dtb/
Flashing the device
To flash the board, follow this guide, depending on the device you are using. If it is a Jetson Orin Nano with an SD Card, put the board in forced recovery mode and execute the following command:
sudo ./tools/kernel_flash/l4t_initrd_flash.sh --external-device mmcblk0p1 \ -c tools/kernel_flash/flash_l4t_external.xml -p "-c bootloader/generic/cfg/flash_t234_qspi.xml" \ --showlogs --network usb0 jetson-orin-nano-devkit internal
JetPack 5
Kernel Customization
Prepare the necessary directories
First, install the NVIDIA board support package by downloading the Driver Package (BSP) and Sample Root Filesystem from the Jetson Linux R35.6.1 release. Extract the downloaded files with the following commands inside a work directory.
mkdir nvidia-jetson tar xf Jetson_Linux_R35.6.1_aarch64.tbz2 -C nvidia-jetson/ sudo tar xpf Tegra_Linux_Sample-Root-Filesystem_R35.6.1_aarch64.tbz2 -C \ nvidia-jetson/Linux_for_Tegra/rootfs
Now run the following script inside the Linux_for_Tegra directory:
cd nvidia-jetson/Linux_for_Tegra sudo ./apply_binaries.sh
(Optional step) Create a default user:
sudo ./tools/l4t_create_default_user.sh -u <user_name> -p <password>
Obtaining the kernel sources
To obtain the kernel sources, run the following commands:
cd nvidia-jetson/Linux_for_Tegra/ ./source_sync.sh -k -t jetson_35.6.1
Obtaining the Jetson-Linux toolchain
Download and extract the Jetson-Linux toolchain:
mkdir $HOME/jetson-toolchain tar xf aarch64--glibc--stable-final.tar.gz -C $HOME/jetson-toolchain
Export the toolchain variables:
export ARCH=arm64 export CROSS_COMPILE=$HOME/jetson-toolchain/bin/aarch64-buildroot-linux-gnu-
Applying the patches
Support for the ICM42688 sensor is not enabled by default in the JetPack 5.1.5 kernel. Apply the same patch used for newer kernels to add ICM42688 support to the inv_icm42600 driver.
Apply the patch in the following directory:
Linux_for_Tegra/sources/kernel/kernel-5.10/
Kernel configuration
Enable the SPI driver as a module:
cd Linux_for_Tegra/sources/kernel/kernel-5.10 make O=kernel_out tegra_defconfig
Add the following line to the configuration:
CONFIG_INV_ICM42600_SPI=m
Then update the configuration:
make O=kernel_out olddefconfig
Device Tree modification
The Jetson Xavier NX Developer Kit (SD card version) uses the following device tree:
tegra194-p3668-0000-p3509-0000.dts
The SPI controller for the 40-pin expansion header is SPI1, located at spi@3210000.
Edit the following file:
hardware/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-p3668-common.dtsi
Replace the spi@0 (CS0) child node under spi@3210000 with the following content:
spi@0 {
compatible = "invensense,icm42688";
status = "okay";
reg = <0x0>;
spi-max-frequency = <12000000>;
spi-cpha;
spi-cpol;
interrupt-parent = <&tegra_main_gpio>;
interrupts = <TEGRA194_MAIN_GPIO(R, 0) IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "INT1";
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
Building the Linux kernel
Build the kernel and its in-tree modules:
export KSRCDIR=<install-path>/Linux_for_Tegra/sources/kernel/kernel-5.10 make -C $KSRCDIR O=$KSRCDIR/kernel_out -j$(nproc)
Install the kernel modules into the root filesystem:
sudo -E make -C $KSRCDIR O=$KSRCDIR/kernel_out \ modules_install INSTALL_MOD_PATH=../rootfs
Copy the kernel image:
cp $KSRCDIR/kernel_out/arch/arm64/boot/Image \ ../kernel/Image
Building the DTBs
Build the device tree blobs:
make -C $KSRCDIR O=$KSRCDIR/kernel_out dtbs -j$(nproc)
Install the DTB:
cp $KSRCDIR/kernel_out/arch/arm64/boot/dts/**/tegra194-p3668-0000-p3509-0000.dtb \ ../kernel/dtb/
Flashing the device
Put the Jetson Xavier NX Developer Kit into forced recovery mode and flash the SD card:
cd ../ sudo ./flash.sh jetson-xavier-nx-devkit mmcblk0p1
Installation Check
Pinmux Configuration
Once the board has been flashed successfully, we need to map the SPI ports on the Jetson Orin Nano using Jetson IO:
- 1. Use Jetson-IO to configure pins:
sudo /opt/nvidia/jetson-io/jetson-io.py
- 2. Once inside select "Configure Jetson 40-pin Header"
- 3. Choose "Configure header pins manually".
- 4. Select "spi1" and save changes.
- 5. Reboot the system to apply the changes.
Connecting the Hardware
The connection will be as follows (From SRX-IMU00-DEV/ICM42688 to the Jetson 40-pin expansion header):
- 1. 3V3 pin --> 3.3V (pin 1)
- 2. GND pin --> GND (any of the following pins: 6, 9, 14, 20, 25, 30, 34 or 39)
- 3. MOSI/SDI pin --> SPI0_MOSI (pin 19)
- 4. MISO/SDO pin --> SPI0_MISO (pin 21)
- 5. CLK/SCL pin --> SPI0_SCK (pin 23)
- 6. CS pin --> SPI0_CS0* (pin 24)
- 7. INT pin --> GPIO07 (pin 32)
You can refer to the Jetson Orin Nano Developer Kit Carrier Board Specification to learn more about the 40-pin expansion header connections.
How to load the driver
To load the driver, run the following commands on the board:
sudo modprobe inv-icm42600 sudo modprobe inv-icm42600-spi
Verify it was properly loaded running the next command:
sudo dmesg | grep -i spi # Sample output: [ 63.776310] SPI driver inv-icm42600-spi has no spi_device_id for invensense,icm42600 [ 63.776343] SPI driver inv-icm42600-spi has no spi_device_id for invensense,icm42602 [ 63.776346] SPI driver inv-icm42600-spi has no spi_device_id for invensense,icm42605 [ 63.776347] SPI driver inv-icm42600-spi has no spi_device_id for invensense,icm42622 [ 63.776348] SPI driver inv-icm42600-spi has no spi_device_id for invensense,icm42688 [ 63.776884] inv-icm42600-spi spi0.0: mounting matrix not found: using identity... [ 63.776965] inv-icm42600-spi spi0.0: supply vdd not found, using dummy regulator [ 63.777221] inv-icm42600-spi spi0.0: supply vddio not found, using dummy regulator
Permissions
To use the device, please check the permissions:
sudo chmod -R 777 /sys/bus/iio/devices/iio\:device* sudo chmod 777 /dev/iio\:device*
Add a service to set permissions on /sys virtual directory:
sudo tee /etc/systemd/system/iio-perms.service > /dev/null <<'EOF' [Unit] Description=Set permissions for IIO devices After=multi-user.target Wants=multi-user.target [Service] Type=oneshot ExecStart=/bin/sh -c 'chmod -R 777 /sys/bus/iio/devices/iio:device* || true' RemainAfterExit=yes [Install] WantedBy=multi-user.target EOF
Enable the service:
sudo systemctl daemon-reload sudo systemctl enable iio-perms.service sudo systemctl start iio-perms.service
Create iio group and udev rule to set permission on /dev/iio:
# Create iio group sudo groupadd -f iio # Add current user to the group sudo usermod -aG iio "$USER" # apply group change: newgrp iio
Create udev rule:
sudo tee /etc/udev/rules.d/99-iio.rules > /dev/null <<'EOF' KERNEL=="iio:device*", SUBSYSTEM=="iio", GROUP="iio", MODE="0660" EOF
Reload udev rules:
sudo udevadm control --reload-rules sudo udevadm trigger --subsystem-match=iio
Add the iio-icm driver to be loaded on boot:
echo inv-icm42600-spi | sudo tee /etc/modules-load.d/icm42600.conf
Check with the example
Please, use this example to test the connectivity.