Where does the device-tree instance of a sensor driver appear?

I’m following the “Sensor Driver Programming Guide R32.1” to build a Sensor Driver in my Jetson TX2 with JetPack 4.2 installed. By now, I have an empty driver just to test the flashing procedure, but I’m not able to see anything yet. I’ve done the following:

  1. Build the .dtsi and locate it in “\hardware\nvidia\platform\t18x\common\kernel-dts\t18x-common-modules\tegra186-camera-test001-a00.dtsi”.
/* TEST001 */
/ {
	host1x {
		vi@15700000 {
			num-channels = <1>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					TEST_vi_in0: endpoint {
						port-index = <0>;
						bus-width = <4>;
						remote-endpoint = <&TEST_csi_out0>;
					};
				};
			};
		};

		nvcsi@150c0000 {
			num-channels = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						TEST_csi_in0: endpoint@0 {
							port-index = <0>;
							bus-width = <4>;
							remote-endpoint = <&TEST_test001_out0>;
						};
					};
					port@1 {
						reg = <1>;
						TEST_csi_out0: endpoint@1 {
							remote-endpoint = <&TEST_vi_in0>;
						};
					};
				};
			};
		};
	};
}

/ {
	i2c@3180000 {
		test001@70 {
			compatible = "nvidia,test001";
			reg = <0x70>;
			devnode = "video0";
			physical_w = "11.26";
			physical_h = "5.98";
			sensor_model ="test001";
			post_crop_frame_drop = "0";
			use_decibel_gain = "true";
			delayed_gain = "true";
			use_sensor_mode_id = "true";

			mode0 {
				mclk_khz = "40000"; 		
				num_lanes = "4"; 			
				tegra_sinterface = "serial_a";
				phy_mode = "DPHY"; 			
				discontinuous_clk = "no";	
				dpcm_enable = "false";		
				cil_settletime = "0";		
				dynamic_pixel_bit_depth = "12";
				csi_pixel_bit_depth = "12";	
				mode_type = "bayer";		
				pixel_phase = "rggb";	

				active_w = "1920";		
				active_h = "1080";	
				readout_orientation = "0";
				line_length = "2200";	
				inherent_gain = "1";	
				mclk_multiplier = "2";	
										
				pix_clk_hz = "74250000";

				gain_factor = "10";	
				min_gain_val = "0"; 
				max_gain_val = "600"; 
				step_gain_val = "1.2";
				default_gain = "0";	
				min_hdr_ratio = "1";
				max_hdr_ratio = "1";
				framerate_factor = "1000000";
				min_framerate = "1500000";
				max_framerate = "338000000";
				step_framerate = "1";
				default_framerate = "338000000";
				exposure_factor = "1000000";
				min_exp_time = "15";
				max_exp_time = "660000"; 
				step_exp_time = "1";
				default_exp_time = "33334";
				embedded_metadata_height = "1";
			};
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					TEST_test001_out0: endpoint {
						port-index = <0>;
						bus-width = <4>;
						remote-endpoint = <&TEST_csi_in0>;
					};
				};
			};
		};
	};
};

/ {

	tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";
		num_csi_lanes = <4>;
		max_lane_speed = <1500000>;
		min_bits_per_pixel = <10>;
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		isp_peak_byte_per_pixel = <5>;
		isp_bw_margin_pct = <25>;

		modules {
			module0 {
				badge = "test001_bottom_TEST";
				position = "bottom";
				orientation = "0";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "test001 30-0070";
					proc-device-tree = "/proc/device-tree/i2c@3180000/test001@70";
				};
			};
		};
	};
};
  1. Build the .c file and locate it in “\kernel\nvidia\drivers\media\i2c\test001.c”
/*
 *test001.c - test001 sensor driver
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <media/tegra_v4l2_camera.h>
#include <media/tegracam_core.h>
#include <linux/debugfs.h>
#include "../platform/tegra/camera/camera_gpio.h"

struct test001 {
	struct i2c_client	        *i2c_client;
	struct v4l2_subdev	        *subdev;
	u8                          fuse_id[8];
	u32				            frame_length;
	s64                         last_wdr_et_val;
	struct camera_common_data	*s_data;
	struct tegracam_device		*tc_dev;
};

static const struct regmap_config test001_regmap_config = {
};

static const u32 ctrl_cid_list[] = {
};

static const struct of_device_id test001_of_match[] = {
	{
		.compatible = "nvidia,test001",
	},
	{ },
};

MODULE_DEVICE_TABLE(of, test001_of_match);

static const struct v4l2_subdev_internal_ops test001_subdev_internal_ops = {
};

static int test001_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	dev_info(dev, "Probing test001 sensor driver\n");
	return 0;
}

static int test001_remove(struct i2c_client *client)
{
	return 0;
}

static const struct i2c_device_id test001_id[] = {
	{ "test001", 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, test001_id);

static struct i2c_driver test001_i2c_driver = {
	.driver = {
		.name = "test001",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(test001_of_match),
	},
	.probe = test001_probe,
	.remove = test001_remove,
	.id_table = test001_id,
};

module_i2c_driver(test001_i2c_driver);

MODULE_DESCRIPTION("Media Controller driver for test001");
MODULE_AUTHOR("Euskadi");
MODULE_LICENSE("GPL v2");
  1. Add to Makefile at “\kernel\nvidia\drivers\media\i2c\Makefile”
obj-$(CONFIG_VIDEO_TEST001) += test001.o
  1. Add to Kconfig at “\kernel\nvidia\drivers\media\i2c\Kconfig”
config VIDEO_TEST001
	tristate "TEST001 camera sensor support"
	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
	---help---
	  This is a Video4Linux2 sensor-level driver for the TEST001
	  camera.

	  To compile this driver as a module, choose M here: the module
	  will be called test001.
  1. Build the kernel files. First, activate TEST001 at menuconfig and append “-tegra” to CONFIG_LOCALVERSION , then “make ARCH=arm64 O=$TEGRA_KERNEL_OUT Image -j12” and “make ARCH=arm64 O=$TEGRA_KERNEL_OUT dtbs -j12”

  2. Replace dtb files to “Linuf_for_tegra/kernel/dtb” directory, and replace /boot/Image of TX2 with the new one. After that, flash dtb:

sudo ./flash.sh -k kernel-dtb jetson-tx2 mmcblk0p1

Anyway, I am only able to see something related to the TEST001 driver in the /proc/config.gz kernel configuration, verifying it is activated (not as module).

When I do “dmesg”, shouldn’t I be seeing “Probing test001 sensor driver” somewhere? (printed at driver probe() function). And also, shouldn’t “test001@70” appear in the /proc/device-tree/i2c@3180000/ directory?

hello euskadi,

please also refer to [Device Registration] chapter, you may disable plugin-manger and Using Main Platform Device Tree File.
thanks