A simple driver for the IMX415 sensor on Jetson Linux r32.6.1, Part 2 — Driver

Intro
This article covers the process of creating a V4L2 sub-driver for the IMX415 sensor on the NVIDIA Xavier NX platform running Jetson Linux r32.6.1.
We will examine the video subsystem architecture, the sensor driver structure, as well as the integration with the Device Tree1. Basis for the I2C Driver
For the I2C driver, we need the struct i2c_driver structure.
Within it, we must implement two callbacks: probe and remove, which are called when the driver is loaded and unloaded, respectively.
static struct i2c_driver imx415_i2c_driver = {
...
.probe = imx415_probe,
.remove = imx415_remove,
.id_table = imx415_id,
};
When imx415_probe is called, the following actions are performed:
1) I2C client passed in to probe.
priv->i2c_client = tc_dev->client = client;
2) Set the name for the tegra camera device (sensor name).
strncpy(tc_dev->name, "imx415", sizeof(tc_dev->name));
3) Initialize regmap configuration.
tc_dev->dev_regmap_config = &sensor_regmap_config;
4) Initialize sensor common ops and tegra camera control ops.
tc_dev->sensor_ops = &imx415_common_ops;
tc_dev->tcctrl_ops = &imx415_ctrl_ops;
5) Register device to initialize the framework context.
err = tegracam_device_register(tc_dev);
6) Set sensor data as private data of tc_dev.
tegracam_set_privdata(tc_dev, (void *)priv);
7) Run board setup to ensure the sensor hardware is accessible.
err = imx415_board_setup(priv);
8) Registers the device as a V4L2 subdevice
err = tegracam_v4l2subdev_register(tc_dev, true);
2) Using sensor common ops
Let’s examine the camera_common_sensor_ops structure, which provides L4T functions for interacting with the sensor:
static struct camera_common_sensor_ops imx415_common_ops = {
.numfrmfmts = ARRAY_SIZE(imx415_frmfmt),
.frmfmt_table = imx415_frmfmt,
.power_on = imx415_power_on,
.power_off = imx415_power_off,
.write_reg = imx415_write_reg,
.read_reg = imx415_read_reg,
.parse_dt = imx415_parse_dt,
.power_get = imx415_power_get,
.power_put = imx415_power_put,
.set_mode = imx415_set_mode,
.start_streaming = imx415_start_streaming,
.stop_streaming = imx415_stop_streaming,
};
Most of the functions can be implemented using the IMX185 driver as an example.
For our purposes, the following functions are of particular interest:
imx415_set_mode
imx415_start_streaming
imx415_stop_streaming
Let’s examine them in more detail.
3) function imx415_set_mode
Here, we configure the internal register settings of the IMX415 sensor.
err = imx415_write_table(priv, mode_table[s_data→mode_prop_idx]);
Where:
s_data->mode_prop_idx is the index of the mode in which the sensor should be started
mode_table is a structure defined in imx415_mode_tbls.h
static imx415_reg *mode_table[] = {
[IMX415_MODE_3840X2160_10BIT_25FPS] = imx415_3840x2160_10bit_25fps,
[IMX415_MODE_START_STREAM] = imx415_start,
[IMX415_MODE_STOP_STREAM] = imx415_stop,
};
The imx415_3840x2160_10bit_25fps structure contains register values in the format: address : value.
The register values for the selected mode can be found in the IMX415-AAQR-C datasheet.
4) The imx415_start_streaming function
This function is called after imx415_set_mode.
It starts the sensor and begins data output via the MIPI CSI protocol.
err = imx415_write_table(priv, mode_table[IMX415_MODE_START_STREAM]);
5) The imx415_stop_streaming function
Calling this function stops the sensor operation.
err = imx415_write_table(priv, mode_table[IMX415_MODE_STOP_STREAM]);
6) Build
The driver source code can be downloaded from the following links:
imx415.c link
imx415_mode_tbls.h link
For the build, place the files in the directory: /nvidia/drivers/media/i2c
Then, add the following to the Kconfig file:
config VIDEO_IMX415
tristate "IMX415 camera sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
---help---
This is a Video4Linux2 sensor-level driver for the Sony
IMX415 camera sensor
To compile this driver as a module, choose M here: the module
will be called imx415.
Add the following to the Makefile:
obj-$(CONFIG_VIDEO_IMX415) += imx415.o
Start the build with the following command:
make ARCH=arm64 O=$TEGRA_KERNEL_OUT modules
For more details about the build process, refer to the article.
The driver source code can be downloaded from the following links:
imx415.c link
imx415_mode_tbls.h link
For the build, place the files in the directory: /nvidia/drivers/media/i2c
Then, add the following to the Kconfig file:
config VIDEO_IMX415
tristate "IMX415 camera sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
---help---
This is a Video4Linux2 sensor-level driver for the Sony
IMX415 camera sensor
To compile this driver as a module, choose M here: the module
will be called imx415.
Add the following to the Makefile:
obj-$(CONFIG_VIDEO_IMX415) += imx415.o
Start the build with the following command:
make ARCH=arm64 O=$TEGRA_KERNEL_OUT modules
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.
