How to Include a New Camera Sensor Device Tree

Hello there!

There is a HDMI to CSI-2 adapter board that I bought from Geekworm. It uses TC358743 IC. As far as I know L4T 35.4.1 version has driver support about that IC. But there is no device tree configuration about the driver. So, I’ve looked the Sensor Programming Guide. There is a tutorial for Device Registration. But I’ve got some questions.

At the “To register a device using the main platform device tree file” section, there should be a tegra194-p2888-0001-p2822-0000.dtsi file. But there is only a .dts file exist with that name and it doesn’t contain “include “tegra194-camera-plugin-manager.dtsi”” line. The source file looks like this:

tegra194-p2888-0001-p2822-0000.dts file:

/*
 * Copyright (c) 2017-2022, NVIDIA CORPORATION.  All rights reserved.
 *
 * 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.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * Top level DTS file for CVM:P2888-0001 and CVB:P2822-0000.
 */
#include "common/tegra194-p2888-0001-p2822-0000-common.dtsi"
#include "common/tegra194-p2822-camera-modules.dtsi"
#include "common/tegra194-audio-p2822-0000.dtsi"

#if defined(LINUX_VERSION) && LINUX_VERSION >= 419

/ {
	/* FIXME: K5.4 overrides */
	bpmp {
		i2c {
			spmic@3c {
				interrupt-parent = <&intc>;
				interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
			};
		};
	};

	hda@3510000 {
		power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>;
		resets = <&bpmp TEGRA194_RESET_HDA>,
			 <&bpmp TEGRA194_RESET_HDA2CODEC_2X>,
			 <&bpmp TEGRA194_RESET_HDA2HDMICODEC>;
		reset-names = "hda", "hda2codec_2x", "hda2hdmi";
	};

	serial@3100000 {
		compatible = "nvidia,tegra194-hsuart";
	};

	tegra-cache {
		status = "okay";
	};
};

#endif

I’ve created a dtsi file for the converter IC. And then I’ve copied the dtsi file to hardware/nvidia/platform/t19x/galen/kernel-dts/common location. The dtsi file looks like this:

tegra194-tc358743.dtsi

/*
 * Copyright (c) 2015-2020, NVIDIA CORPORATION.  All rights reserved.
 *
 * 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.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * 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 "dt-bindings/clock/tegra194-clock.h"

#define CAM0_RST_L	TEGRA194_MAIN_GPIO(H, 3)
#define CAM0_PWDN	TEGRA194_MAIN_GPIO(H, 6)

/ {
	tegra-capture-vi {
		num-channels = <1>;
		ports {
			#address-cells = <1>;
			#size-cells = <0>;
			port@0 {
				reg = <0>;
				tc358743_vi_in1: endpoint {
					port-index = <2>;
					bus-width = <2>;
					remote-endpoint = <&tc358743_csi_out0>;
				};
			};
		};
	};

	host1x@13e00000 {
		nvcsi@15a00000 {
			num-channels = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						tc358743_csi_in0: endpoint@0 {
							port-index = <2>;
							bus-width = <2>;
							remote-endpoint = <&tc358743_out1>;
						};
					};
					port@1 {
						reg = <1>;
						tc358743_csi_out0: endpoint@1 {
							remote-endpoint = <&tc358743_vi_in1>;
						};
					};
				};
			};
		};
	};

	i2c@3180000 {
		tc358743@0f {
			reset-gpios = <&tegra_main_gpio CAM0_RST_L GPIO_ACTIVE_HIGH>;
			vana-supply = <&p2822_avdd_cam_2v8>;
			vif-supply = <&p2822_vdd_1v8_cvb>;
			compatible = "toshiba,tc358743";
			/* I2C device address */
			reg = <0x0f>;

			/* V4L2 device node location */
			devnode = "video0";

			//clocks = <&tegra_car TEGRA210_CLK_EXTERN3>;
            #clock-cells = <0>;
            //clock-names = "refclk";
            //mclk = "cam_mclk1";
            //reset-gpios = <&gpio CAM1_PWDN GPIO_ACTIVE_HIGH>;


            /* Physical dimensions of sensor */
            physical_w = "4.713";
            physical_h = "3.494";
            /* Sensor Model */
            sensor_model ="tc358743";

			/* Define any required hw resources needed by driver */
			/* ie. clocks, io pins, power sources */
			avdd-reg = "vana";
			iovdd-reg = "vif";


			ports {
				#address-cells = <1>;
				#size-cells = <0>;

				port@0 {
					reg = <0>;
					tc358743_out1: endpoint {
                        port-index = <0>; /* CSI A */
                        bus-width = <2>;
                        phy_mode = "DPHY";
                        data-lanes = <1 2>;
                        clock-lanes = <0>;
                        //clock-noncontinuous;
                        link-frequencies = /bits/ 64 <594000000>;//297000000///594000000
                        remote-endpoint = <&tc358743_csi_in0>;
                    };
				};
			};
		};
	};

	gpio@2200000 {
		camera-control-output-low {
			gpio-hog;
			output-low;
			gpios = <CAM0_RST_L 0 CAM0_PWDN 0>;
			label = "cam0-rst", "cam0-pwdn";
		};
	};
	
	tegra-camera-platform {
    	status = "okay";
		compatible = "nvidia, tegra-camera-platform";
		num_csi_lanes = <2>;  // Changed 2 -> 4
		max_lane_speed = <1500000>;
		min_bits_per_pixel = <16>;  
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		max_pixel_rate = <240000>;
		isp_peak_byte_per_pixel = <5>;
		isp_bw_margin_pct = <25>;

    		/**
		* The general guideline for naming badge_info contains 3 parts, and is as follows,
		* The first part is the camera_board_id for the module; if the module is in a FFD
		* platform, then use the platform name for this part.
		* The second part contains the position of the module, ex. “rear” or “front”.
		* The third part contains the last 6 characters of a part number which is found
		* in the module's specsheet from the vender.
		*/
		modules {

		    module1 {
		        status = "okay";
		        badge = "tc358743_top_i2c6_b";
		        position = "front";
		        orientation = "1";
		        drivernode0 {
		            status = "okay";
		            /* Declare PCL support driver (classically known as guid)  */
		            pcl_id = "v4l2_sensor";
		            /* Driver's v4l2 device name */
		            devname = "tc358743 6-000f";
		            /* Declare the device-tree hierarchy to driver instance */
		            proc-device-tree = "/proc/device-tree/host1x/i2c@546c0000/tc358743@0f";
		        };
		    };
	
		};
	};
};

Where should I include this file? And can I compie with nvbuild.sh script? Do I have to use any other method for enabling the driver and compile the kernel?

Regards,
İbrahim

Looks like r35.x release had remove the plugin manager already.
Suppose you can just add your device tree and unassamble by dtc to confirm it.