A simple driver for the IMX415 sensor on Jetson Linux r32.6.1, Part 1 — Device Tree

Intro
This article covers the process of creating a device tree for a V4L2 sub-driver, using the Sony IMX415 sensor as an example.
1. V4L2 Architecture on Jetson
In NVIDIA Jetson Linux, the video subsystem is built on top of the V4L2 Media Controller Framework.
It includes the following components:
- V4L2 subdevice sensor driver
- CSI (nvcsi) — the physical camera interface
- VI (Video Input)
- Optional ISP (nvargus-daemon)
A typical data flow looks like this:
Sensor → CSI → VI → ISP → NVArgus → /dev/videoX
Sensor control is performed over the I2C protocol.
2. Device Tree Preparation
To communicate with the sensor over I2C and receive data via MIPI CSI, we need to create an imx415 node in the device tree.
Our device tree will consist of two files:
1) tegra194-camera-jakku-rbpcv2-imx415.dtsi
Where we will define:
#define CAM0_PWDN TEGRA194_MAIN_GPIO(Q, 5)
imx415_a@1a {
clocks = <&bpmp_clks TEGRA194_CLK_EXTPERIPH1>;
clock-names = "extperiph1", "pllp_grtba";
mclk = "extperiph1";
сlock-frequency = <27000000>;
reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;
};
...
gpios = ;
label = "cam0-pwdn";
Here we define the sensor’s master clock (extperiph1), set the default frequency to 27 MHz (27000000 Hz), and specify the reset pin: 118 (PQ5).
2) tegra194-camera-rbpcv2-imx415.dtsi
Here we define the V4L2 entity connections: Sensor → CSI → VI.
We also specify the number of connected sensors (1) and the number of MIPI CSI lanes (4 lanes).
VI:
imx415_vi_in0: endpoint {
port-index = <0>;
bus-width = <4>;
remote-endpoint = <&imx415_csi_out0>;
};
MIPICSI:
imx415_csi_in0: endpoint@0 {
status="okay";
port-index = <0>;
bus-width = <4>;
remote-endpoint = <&imx415_out0>;
};
imx415_csi_out0: endpoint@1 {
status="okay";
remote-endpoint = <&imx415_vi_in0>;
};
IMX415:
imx415_out0: endpoint {
status="okay";
port-index = <0>;
bus-width = <4>;
remote-endpoint = <&imx415_csi_in0>;
};
In this simple example, we will implement only one operating mode for the IMX415:
mode0: Frame size: 3840×2160, Frame rate: 25 FPS, Bit depth: 10 bits per pixel
Now we define mode0 in the device tree:
mode0 {
mclk_khz = "27000";
num_lanes = "4";
tegra_sinterface = "serial_a";
phy_mode = "DPHY";
...
dynamic_pixel_bit_depth = "10";
csi_pixel_bit_depth = "10";
mode_type = "bayer";
pixel_phase = "gbrg";
active_w = "3840";
active_h = "2160";
...
default_framerate = "25";
...
embedded_metadata_height = "1";
};
The device tree files can be downloaded from the following link:
tegra194-camera-jakku-rbpcv2-imx415.dtsi link
tegra194-camera-rbpcv2-imx415.dtsi link
3. Build Process
Save the .dtsi files into the following directory: /hardware/nvidia/platform/t19x/jakku/kernel-dts/common/
In the file tegra194-p3509-0000-a00.dtsi, include our .dtsi files by adding the following:
#include "tegra194-camera-jakku-rbpcv2-imx415.dtsi"
Build using the following command:
make ARCH=arm64 O=$TEGRA_KERNEL_OUT dtbs
For more details about the build process, refer to the article.
We also design custom carrier boards for Jetson Orin NX / Jetson AGX Orin / Jetson Nano and Nano Super.
