Adding Camera Devices to Device Tree

Hello,
I am currently trying to enable a AR0144 module with the Jetson, and I am unable to mount the camera as a video device. I have built and booted from a new kernel containing the appropriate sensor driver code files, so I suspect these issues are involving the device tree.

Following the Dev Guide, I have done the following:

  • Created a .dtsi based off the e3333-camera.dtsi with my sensor's parameters
  • Removed the plugin manager include (as I do not believe I am using it) in the base.dts
  • Replaced the current camera.dtsi include and replaced it with the .dtsi I have created

Here is where I am confused- do I need to compile the .dts separately using the dtc tool, and move the .dtb into the boot directory? I have tried using the dtc, but it is unable to read the .dts in its current format (I suspect I need a pre-compiler)

Do I even need to do this? Or is there a different way to register devices in the device tree?

Any information to get me in the right direction would be greatly appreciated!
-Ryan

Device trees are worked with by people in source code format…the dts. Within the kernel these are typically “wrapped” to be convenient for C to use them…which means that if the source is in the kernel then you need to build the dtbs target for the processing to produce an end result (and if you don’t configure first to match your existing system it might fail in many ways).

If you have a specific dts file (and not a C file wrapping a device tree) then it is quite simple to convert between formats and won’t be an issue.

Newer releases of L4T no longer use the one in “/boot” (the “FDT” key/value pair of extlinux.conf will not do what you expect…though it could do something). There is device tree content in various locations for different stages of boot (including in a partition…in some cases signed), and so the flash.sh tool is used to put the device tree in (no, you do not need to flash the rootfs, and the correct options cause rootfs to not be flashed).

Example of using “dtc” (separate examples with contrived names just for show):

dtc -I fs -O dts -o extracted_from_proc.dts /proc/device-tree
dtc -I dts -O dtb -o extracted_as_binary.dtb extracted_from_proc.dts
dtc -I dtb -O dts -o back_to_plain_text.dts extracted_as_binary.dtb

The docs for your release (e.g., R28.1 or R28.2) contain information on flashing device tree. Basically, if you give flash.sh a command to flash a particular content, and tell it to reuse rootfs, then rootfs is not flashed (nor built).

Thanks for the reply, linuxdev!
Unfortunately I am more confused…

I’m not sure if using the dtc to compile my altered dts is the path I should even be taking, as there is no mention of it in the development guide steps.

The steps listed in the Devguide are:

  1. Locate the following file: hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-bast.dsi
  2. In the DSI, remove the following line: #include
  3. Locate the following file: hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-bast.dsi
  4. Replace the following line with an include statement specifying the DTSI of your new device #include

After performing those steps, rebuilding and rebooting from a new kernel, the sensor is not recognized as a video device. I have ensured that the names in the .dtsi and driver file match.

Here is my .dtsi for the device

/*
 * Copyright (c) 2015-2017, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that 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/>.
 */

/ {
	host1x {
		vi@15700000 {
			num-channels = <6>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					e3333_vi_in0: endpoint {
						csi-port = <0>;
						bus-width = <2>;
						remote-endpoint = <&e3333_csi_out0>;
					};
				};
				port@1 {
					reg = <1>;
					e3333_vi_in1: endpoint {
						csi-port = <1>;
						bus-width = <2>;
						remote-endpoint = <&e3333_csi_out1>;
					};
				};
				port@2 {
					reg = <2>;
					e3333_vi_in2: endpoint {
						csi-port = <2>;
						bus-width = <2>;
						remote-endpoint = <&e3333_csi_out2>;
					};
				};
				port@3 {
					reg = <3>;
					e3333_vi_in3: endpoint {
						csi-port = <3>;
						bus-width = <2>;
						remote-endpoint = <&e3333_csi_out3>;
					};
				};
				port@4 {
					reg = <4>;
					e3333_vi_in4: endpoint {
						csi-port = <4>;
						bus-width = <2>;
						remote-endpoint = <&e3333_csi_out4>;
					};
				};
				port@5 {
					reg = <5>;
					e3333_vi_in5: endpoint {
						csi-port = <5>;
						bus-width = <2>;
						remote-endpoint = <&e3333_csi_out5>;
					};
				};
			};
		};

		nvcsi@150c0000 {
			num-channels = <6>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						e3333_csi_in0: endpoint@0 {
							csi-port = <0>;
							bus-width = <2>;
							remote-endpoint = <&e3333_ar0144_out0>;
						};
					};
					port@1 {
						reg = <1>;
						e3333_csi_out0: endpoint@1 {
							remote-endpoint = <&e3333_vi_in0>;
						};
					};
				};
			};
			channel@1 {
				reg = <1>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						e3333_csi_in1: endpoint@2 {
							csi-port = <1>;
							bus-width = <2>;
							remote-endpoint = <&e3333_ar0144_out1>;
						};
					};
					port@1 {
						reg = <1>;
						e3333_csi_out1: endpoint@3 {
							remote-endpoint = <&e3333_vi_in1>;
						};
					};
				};
			};
			channel@2 {
				reg = <2>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						e3333_csi_in2: endpoint@4 {
							csi-port = <2>;
							bus-width = <2>;
							remote-endpoint = <&e3333_ar0144_out2>;
						};
					};
					port@1 {
						reg = <1>;
						e3333_csi_out2: endpoint@5 {
							remote-endpoint = <&e3333_vi_in2>;
						};
					};
				};
			};
			channel@3 {
				reg = <3>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						e3333_csi_in3: endpoint@6 {
							csi-port = <3>;
							bus-width = <2>;
							remote-endpoint = <&e3333_ar0144_out3>;
						};
					};
					port@1 {
						reg = <1>;
						e3333_csi_out3: endpoint@7 {
							remote-endpoint = <&e3333_vi_in3>;
						};
					};
				};
			};
			channel@4 {
				reg = <4>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						e3333_csi_in4: endpoint@8 {
							csi-port = <4>;
							bus-width = <2>;
							remote-endpoint = <&e3333_ar0144_out4>;
						};
					};
					port@1 {
						reg = <1>;
						e3333_csi_out4: endpoint@9 {
							remote-endpoint = <&e3333_vi_in4>;
						};
					};
				};
			};
			channel@5 {
				reg = <5>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						e3333_csi_in5: endpoint@10 {
							csi-port = <5>;
							bus-width = <2>;
							remote-endpoint = <&e3333_ar0144_out5>;
						};
					};
					port@1 {
						reg = <1>;
						e3333_csi_out5: endpoint@11 {
							remote-endpoint = <&e3333_vi_in5>;
						};
					};
				};
			};
		};
	};

	i2c@3180000 {
		tca9548@77 {
			i2c@0 {
				ar0144_a@10 {
					compatible = "nvidia,ar0144";
					reg = <0x10>;
					devnode = "video0";

					/* Physical dimensions of sensor */
					physical_w = "3.674";
					physical_h = "2.738";

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

					/**
					* A modeX node is required to support v4l2 driver
					* implementation with NVIDIA camera software stack
					*
					* mclk_khz = "";
					* Standard MIPI driving clock, typically 24MHz
					*
					* num_lanes = "";
					* Number of lane channels sensor is programmed to output
					*
					* tegra_sinterface = "";
					* The base tegra serial interface lanes are connected to
					*
					* discontinuous_clk = "";
					* The sensor is programmed to use a discontinuous clock on MIPI lanes
					*
					* dpcm_enable = "true";
					* The sensor is programmed to use a DPCM modes
					*
					* cil_settletime = "";
					* MIPI lane settle time value.
					* A "0" value attempts to autocalibrate based on mclk_multiplier
					*
					*
					*
					*
					* active_w = "";
					* Pixel active region width
					*
					* active_h = "";
					* Pixel active region height
					*
					* pixel_t = "";
					* The sensor readout pixel pattern
					*
					* readout_orientation = "0";
					* Based on camera module orientation.
					* Only change readout_orientation if you specifically
					* Program a different readout order for this mode
					*
					* line_length = "";
					* Pixel line length (width) for sensor mode.
					* This is used to calibrate features in our camera stack.
					*
					* mclk_multiplier = "";
					* Multiplier to MCLK to help time hardware capture sequence
					* TODO: Assign to PLL_Multiplier as well until fixed in core
					*
					* pix_clk_hz = "";
					* Sensor pixel clock used for calculations like exposure and framerate
					*
					*
					*
					*
					* inherent_gain = "";
					* Gain obtained inherently from mode (ie. pixel binning)
					*
					* min_gain_val = ""; (floor to 6 decimal places)
					* max_gain_val = ""; (floor to 6 decimal places)
					* Gain limits for mode
					*
					* min_exp_time = ""; (ceil to integer)
					* max_exp_time = ""; (ceil to integer)
					* Exposure Time limits for mode (us)
					*
					*
					* min_hdr_ratio = "";
					* max_hdr_ratio = "";
					* HDR Ratio limits for mode
					*
					* min_framerate = "";
					* max_framerate = "";
					* Framerate limits for mode (fps)
					*/
					mode0 { // ar0144_MODE_2592X1944
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_a";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "800";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

					/* mode1 { //ar0144_MODE_2592X1458
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_a";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "2592";
						active_h = "1458";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

					mode2 { //ar0144_MODE_1280X720
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_a";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "720";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "1752";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "2.787078";
						max_framerate = "120";
						min_exp_time = "22";
						max_exp_time = "358733";
					}; */

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

						port@0 {
							reg = <0>;
							e3333_ar0144_out0: endpoint {
								csi-port = <0>;
								bus-width = <2>;
								remote-endpoint = <&e3333_csi_in0>;
							};
						};
					};
				};
			};

			i2c@1 {
				ar0144_b@10 {
					compatible = "nvidia,ar0144";
					reg = <0x10>;
					devnode = "video1";

					/* Physical dimensions of sensor */
					physical_w = "3.671";
					physical_h = "2.738";

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

					/**
					* A modeX node is required to support v4l2 driver
					* implementation with NVIDIA camera software stack
					*
					* mclk_khz = "";
					* Standard MIPI driving clock, typically 24MHz
					*
					* num_lanes = "";
					* Number of lane channels sensor is programmed to output
					*
					* tegra_sinterface = "";
					* The base tegra serial interface lanes are connected to
					*
					* discontinuous_clk = "";
					* The sensor is programmed to use a discontinuous clock on MIPI lanes
					*
					* dpcm_enable = "true";
					* The sensor is programmed to use a DPCM modes
					*
					* cil_settletime = "";
					* MIPI lane settle time value.
					* A "0" value attempts to autocalibrate based on mclk_multiplier
					*
					*
					*
					*
					* active_w = "";
					* Pixel active region width
					*
					* active_h = "";
					* Pixel active region height
					*
					* pixel_t = "";
					* The sensor readout pixel pattern
					*
					* readout_orientation = "0";
					* Based on camera module orientation.
					* Only change readout_orientation if you specifically
					* Program a different readout order for this mode
					*
					* line_length = "";
					* Pixel line length (width) for sensor mode.
					* This is used to calibrate features in our camera stack.
					*
					* mclk_multiplier = "";
					* Multiplier to MCLK to help time hardware capture sequence
					* TODO: Assign to PLL_Multiplier as well until fixed in core
					*
					* pix_clk_hz = "";
					* Sensor pixel clock used for calculations like exposure and framerate
					*
					*
					*
					*
					* inherent_gain = "";
					* Gain obtained inherently from mode (ie. pixel binning)
					*
					* min_gain_val = ""; (floor to 6 decimal places)
					* max_gain_val = ""; (floor to 6 decimal places)
					* Gain limits for mode
					*
					* min_exp_time = ""; (ceil to integer)
					* max_exp_time = ""; (ceil to integer)
					* Exposure Time limits for mode (us)
					*
					*
					* min_hdr_ratio = "";
					* max_hdr_ratio = "";
					* HDR Ratio limits for mode
					*
					* min_framerate = "";
					* max_framerate = "";
					* Framerate limits for mode (fps)
					*/
					mode0 { // ar0144_MODE_2592X1944
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_b";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "800";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

				/*	mode1 { //ar0144_MODE_2592X1458
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_b";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "2592";
						active_h = "1458";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

					mode2 { //ar0144_MODE_1280X720
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_b";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "720";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "1752";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "2.787078";
						max_framerate = "120";
						min_exp_time = "22";
						max_exp_time = "358733";
					}; */

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

						port@0 {
							reg = <0>;
							e3333_ar0144_out1: endpoint {
								csi-port = <1>;
								bus-width = <2>;
								remote-endpoint = <&e3333_csi_in1>;
							};
						};
					};
				};
			};

			i2c@2 {
				ar0144_c@36 {
					compatible = "nvidia,ar0144";
					reg = <0x10>;
					devnode = "video2";

					/* Physical dimensions of sensor */
					physical_w = "3.674";
					physical_h = "2.738";

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

					/**
					* A modeX node is required to support v4l2 driver
					* implementation with NVIDIA camera software stack
					*
					* mclk_khz = "";
					* Standard MIPI driving clock, typically 24MHz
					*
					* num_lanes = "";
					* Number of lane channels sensor is programmed to output
					*
					* tegra_sinterface = "";
					* The base tegra serial interface lanes are connected to
					*
					* discontinuous_clk = "";
					* The sensor is programmed to use a discontinuous clock on MIPI lanes
					*
					* dpcm_enable = "true";
					* The sensor is programmed to use a DPCM modes
					*
					* cil_settletime = "";
					* MIPI lane settle time value.
					* A "0" value attempts to autocalibrate based on mclk_multiplier
					*
					*
					*
					*
					* active_w = "";
					* Pixel active region width
					*
					* active_h = "";
					* Pixel active region height
					*
					* pixel_t = "";
					* The sensor readout pixel pattern
					*
					* readout_orientation = "0";
					* Based on camera module orientation.
					* Only change readout_orientation if you specifically
					* Program a different readout order for this mode
					*
					* line_length = "";
					* Pixel line length (width) for sensor mode.
					* This is used to calibrate features in our camera stack.
					*
					* mclk_multiplier = "";
					* Multiplier to MCLK to help time hardware capture sequence
					* TODO: Assign to PLL_Multiplier as well until fixed in core
					*
					* pix_clk_hz = "";
					* Sensor pixel clock used for calculations like exposure and framerate
					*
					*
					*
					*
					* inherent_gain = "";
					* Gain obtained inherently from mode (ie. pixel binning)
					*
					* min_gain_val = ""; (floor to 6 decimal places)
					* max_gain_val = ""; (floor to 6 decimal places)
					* Gain limits for mode
					*
					* min_exp_time = ""; (ceil to integer)
					* max_exp_time = ""; (ceil to integer)
					* Exposure Time limits for mode (us)
					*
					*
					* min_hdr_ratio = "";
					* max_hdr_ratio = "";
					* HDR Ratio limits for mode
					*
					* min_framerate = "";
					* max_framerate = "";
					* Framerate limits for mode (fps)
					*/
					mode0 { // ar0144_MODE_2592X1944
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_c";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "800";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

					/*mode1 { //ar0144_MODE_2592X1458
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_c";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "2592";
						active_h = "1458";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

					mode2 { //ar0144_MODE_1280X720
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_c";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "720";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "1752";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "2.787078";
						max_framerate = "120";
						min_exp_time = "22";
						max_exp_time = "358733";
					}; */

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

						port@0 {
							reg = <0>;
							e3333_ar0144_out2: endpoint {
								csi-port = <2>;
								bus-width = <2>;
								remote-endpoint = <&e3333_csi_in2>;
							};
						};
					};
				};
			};

			i2c@3 {
				ar0144_d@10 {
					compatible = "nvidia,ar0144";
					reg = <0x10>;
					devnode = "video3";

					/* Physical dimensions of sensor */
					physical_w = "3.674";
					physical_h = "2.738";

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

					/**
					* A modeX node is required to support v4l2 driver
					* implementation with NVIDIA camera software stack
					*
					* mclk_khz = "";
					* Standard MIPI driving clock, typically 24MHz
					*
					* num_lanes = "";
					* Number of lane channels sensor is programmed to output
					*
					* tegra_sinterface = "";
					* The base tegra serial interface lanes are connected to
					*
					* discontinuous_clk = "";
					* The sensor is programmed to use a discontinuous clock on MIPI lanes
					*
					* dpcm_enable = "true";
					* The sensor is programmed to use a DPCM modes
					*
					* cil_settletime = "";
					* MIPI lane settle time value.
					* A "0" value attempts to autocalibrate based on mclk_multiplier
					*
					*
					*
					*
					* active_w = "";
					* Pixel active region width
					*
					* active_h = "";
					* Pixel active region height
					*
					* pixel_t = "";
					* The sensor readout pixel pattern
					*
					* readout_orientation = "0";
					* Based on camera module orientation.
					* Only change readout_orientation if you specifically
					* Program a different readout order for this mode
					*
					* line_length = "";
					* Pixel line length (width) for sensor mode.
					* This is used to calibrate features in our camera stack.
					*
					* mclk_multiplier = "";
					* Multiplier to MCLK to help time hardware capture sequence
					* TODO: Assign to PLL_Multiplier as well until fixed in core
					*
					* pix_clk_hz = "";
					* Sensor pixel clock used for calculations like exposure and framerate
					*
					*
					*
					*
					* inherent_gain = "";
					* Gain obtained inherently from mode (ie. pixel binning)
					*
					* min_gain_val = ""; (floor to 6 decimal places)
					* max_gain_val = ""; (floor to 6 decimal places)
					* Gain limits for mode
					*
					* min_exp_time = ""; (ceil to integer)
					* max_exp_time = ""; (ceil to integer)
					* Exposure Time limits for mode (us)
					*
					*
					* min_hdr_ratio = "";
					* max_hdr_ratio = "";
					* HDR Ratio limits for mode
					*
					* min_framerate = "";
					* max_framerate = "";
					* Framerate limits for mode (fps)
					*/
					mode0 { // ar0144_MODE_2592X1944
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_d";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "2592";
						active_h = "1944";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

				/*	mode1 { //ar0144_MODE_2592X1458
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_d";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "2592";
						active_h = "1458";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

					mode2 { //ar0144_MODE_1280X720
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_d";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "720";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "1752";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "2.787078";
						max_framerate = "120";
						min_exp_time = "22";
						max_exp_time = "358733";
					}; */

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

						port@0 {
							reg = <0>;
							e3333_ar0144_out3: endpoint {
								csi-port = <3>;
								bus-width = <2>;
								remote-endpoint = <&e3333_csi_in3>;
							};
						};
					};
				};
			};

			i2c@4 {
				ar0144_e@10 {
					compatible = "nvidia,ar0144";
					reg = <0x10>;
					devnode = "video4";

					/* Physical dimensions of sensor */
					physical_w = "3.674";
					physical_h = "2.738";

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

					/**
					* A modeX node is required to support v4l2 driver
					* implementation with NVIDIA camera software stack
					*
					* mclk_khz = "";
					* Standard MIPI driving clock, typically 24MHz
					*
					* num_lanes = "";
					* Number of lane channels sensor is programmed to output
					*
					* tegra_sinterface = "";
					* The base tegra serial interface lanes are connected to
					*
					* discontinuous_clk = "";
					* The sensor is programmed to use a discontinuous clock on MIPI lanes
					*
					* dpcm_enable = "true";
					* The sensor is programmed to use a DPCM modes
					*
					* cil_settletime = "";
					* MIPI lane settle time value.
					* A "0" value attempts to autocalibrate based on mclk_multiplier
					*
					*
					*
					*
					* active_w = "";
					* Pixel active region width
					*
					* active_h = "";
					* Pixel active region height
					*
					* pixel_t = "";
					* The sensor readout pixel pattern
					*
					* readout_orientation = "0";
					* Based on camera module orientation.
					* Only change readout_orientation if you specifically
					* Program a different readout order for this mode
					*
					* line_length = "";
					* Pixel line length (width) for sensor mode.
					* This is used to calibrate features in our camera stack.
					*
					* mclk_multiplier = "";
					* Multiplier to MCLK to help time hardware capture sequence
					* TODO: Assign to PLL_Multiplier as well until fixed in core
					*
					* pix_clk_hz = "";
					* Sensor pixel clock used for calculations like exposure and framerate
					*
					*
					*
					*
					* inherent_gain = "";
					* Gain obtained inherently from mode (ie. pixel binning)
					*
					* min_gain_val = ""; (floor to 6 decimal places)
					* max_gain_val = ""; (floor to 6 decimal places)
					* Gain limits for mode
					*
					* min_exp_time = ""; (ceil to integer)
					* max_exp_time = ""; (ceil to integer)
					* Exposure Time limits for mode (us)
					*
					*
					* min_hdr_ratio = "";
					* max_hdr_ratio = "";
					* HDR Ratio limits for mode
					*
					* min_framerate = "";
					* max_framerate = "";
					* Framerate limits for mode (fps)
					*/
					mode0 { // ar0144_MODE_2592X1944
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_e";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "800";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

				/*	mode1 { //ar0144_MODE_2592X1458
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_e";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "2592";
						active_h = "1458";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

					mode2 { //ar0144_MODE_1280X720
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_e";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "720";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "1752";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "2.787078";
						max_framerate = "120";
						min_exp_time = "22";
						max_exp_time = "358733";
					}; */

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

						port@0 {
							reg = <0>;
							e3333_ar0144_out4: endpoint {
								csi-port = <4>;
								bus-width = <2>;
								remote-endpoint = <&e3333_csi_in4>;
							};
						};
					};
				};
			};

			i2c@5 {
				ar0144_f@10 {
					compatible = "nvidia,ar0144";
					reg = <0x10>;
					devnode = "video5";

					/* Physical dimensions of sensor */
					physical_w = "3.674";
					physical_h = "2.738";

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

					/**
					* A modeX node is required to support v4l2 driver
					* implementation with NVIDIA camera software stack
					*
					* mclk_khz = "";
					* Standard MIPI driving clock, typically 24MHz
					*
					* num_lanes = "";
					* Number of lane channels sensor is programmed to output
					*
					* tegra_sinterface = "";
					* The base tegra serial interface lanes are connected to
					*
					* discontinuous_clk = "";
					* The sensor is programmed to use a discontinuous clock on MIPI lanes
					*
					* dpcm_enable = "true";
					* The sensor is programmed to use a DPCM modes
					*
					* cil_settletime = "";
					* MIPI lane settle time value.
					* A "0" value attempts to autocalibrate based on mclk_multiplier
					*
					*
					*
					*
					* active_w = "";
					* Pixel active region width
					*
					* active_h = "";
					* Pixel active region height
					*
					* pixel_t = "";
					* The sensor readout pixel pattern
					*
					* readout_orientation = "0";
					* Based on camera module orientation.
					* Only change readout_orientation if you specifically
					* Program a different readout order for this mode
					*
					* line_length = "";
					* Pixel line length (width) for sensor mode.
					* This is used to calibrate features in our camera stack.
					*
					* mclk_multiplier = "";
					* Multiplier to MCLK to help time hardware capture sequence
					* TODO: Assign to PLL_Multiplier as well until fixed in core
					*
					* pix_clk_hz = "";
					* Sensor pixel clock used for calculations like exposure and framerate
					*
					*
					*
					*
					* inherent_gain = "";
					* Gain obtained inherently from mode (ie. pixel binning)
					*
					* min_gain_val = ""; (floor to 6 decimal places)
					* max_gain_val = ""; (floor to 6 decimal places)
					* Gain limits for mode
					*
					* min_exp_time = ""; (ceil to integer)
					* max_exp_time = ""; (ceil to integer)
					* Exposure Time limits for mode (us)
					*
					*
					* min_hdr_ratio = "";
					* max_hdr_ratio = "";
					* HDR Ratio limits for mode
					*
					* min_framerate = "";
					* max_framerate = "";
					* Framerate limits for mode (fps)
					*/
					mode0 { // ar0144_MODE_2592X1944
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_f";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "800";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

				/*	mode1 { //ar0144_MODE_2592X1458
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_f";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "2592";
						active_h = "1458";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "2688";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "1.816577";
						max_framerate = "30";
						min_exp_time = "34";
						max_exp_time = "550385";
					};

					mode2 { //ar0144_MODE_1280X720
						mclk_khz = "24000";
						num_lanes = "2";
						tegra_sinterface = "serial_f";
						discontinuous_clk = "no";
						dpcm_enable = "false";
						cil_settletime = "0";

						active_w = "1280";
						active_h = "720";
						pixel_t = "bayer_bggr";
						readout_orientation = "90";
						line_length = "1752";
						inherent_gain = "1";
						mclk_multiplier = "6.67";
						pix_clk_hz = "160000000";

						min_gain_val = "1.0";
						max_gain_val = "16";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						min_framerate = "2.787078";
						max_framerate = "120";
						min_exp_time = "22";
						max_exp_time = "358733";
					}; */

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

						port@0 {
							reg = <0>;
							e3333_ar0144_out5: endpoint {
								csi-port = <5>;
								bus-width = <2>;
								remote-endpoint = <&e3333_csi_in5>;
							};
						};
					};
				};
			};
		};
	};

	e3333_lens_ar0144@P5V27C {
		min_focus_distance = "0.0";
		hyper_focal = "0.0";
		focal_length = "2.67";
		f_number = "2.0";
		aperture = "2.0";
	};

	tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";
		/**
		* Physical settings to calculate max ISO BW
		*
		* num_csi_lanes = <>;
		* Total number of CSI lanes when all cameras are active
		*
		* max_lane_speed = <>;
		* Max lane speed in Kbit/s
		*
		* min_bits_per_pixel = <>;
		* Min bits per pixel
		*
		* vi_peak_byte_per_pixel = <>;
		* Max byte per pixel for the VI ISO case
		*
		* vi_bw_margin_pct = <>;
		* Vi bandwidth margin in percentage
		*
		* max_pixel_rate = <>;
		* Max pixel rate in Kpixel/s for the ISP ISO case
		* Set this to the highest pix_clk_hz out of all available modes.
		*
		* isp_peak_byte_per_pixel = <>;
		* Max byte per pixel for the ISP ISO case
		*
		* isp_bw_margin_pct = <>;
		* Isp bandwidth margin in percentage
		*/
		num_csi_lanes = <12>;
		max_lane_speed = <1500000>;
		min_bits_per_pixel = <10>;
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		max_pixel_rate = <160000>;
		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 {
			module0 {
				badge = "e3333_bottomleft_P5V27C";
				position = "bottomleft";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "ar0144 30-0036";
					proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@0/ar0144_a@10";
				};
				drivernode1 {
					pcl_id = "v4l2_lens";
					proc-device-tree = "/proc/device-tree/e3333_lens_ar0144@P5V27C/";
				};
			};
			module1 {
				badge = "e3333_centerleft_P5V27C";
				position = "centerleft";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "ar0144 31-0036";
					proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@1/ar0144_b@10";
				};
				drivernode1 {
					pcl_id = "v4l2_lens";
					proc-device-tree = "/proc/device-tree/e3333_lens_ar0144@P5V27C/";
				};
			};
			module2 {
				badge = "e3333_centerright_P5V27C";
				position = "centerright";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "ar0144 32-0036";
					proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/ar0144_c@10";
				};
				drivernode1 {
					pcl_id = "v4l2_lens";
					proc-device-tree = "/proc/device-tree/e3333_lens_ar0144@P5V27C/";
				};
			};
			module3 {
				badge = "e3333_topleft_P5V27C";
				position = "topleft";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "ar0144 33-0036";
					proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/ar0144_d@10";
				};
				drivernode1 {
					pcl_id = "v4l2_lens";
					proc-device-tree = "/proc/device-tree/e3333_lens_ar0144@P5V27C/";
				};
			};
			module4 {
				badge = "e3333_bottomright_P5V27C";
				position = "bottomright";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "ar0144 34-0036";
					proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/ar0144_d@10";
				};
				drivernode1 {
					pcl_id = "v4l2_lens";
					proc-device-tree = "/proc/device-tree/e3333_lens_ar0144@P5V27C/";
				};
			};
			module5 {
				badge = "e3333_topright_P5V27C";
				position = "topright";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "ar0144 35-0036";
					proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/ar0144_e@10";
				};
				drivernode1 {
					pcl_id = "v4l2_lens";
					proc-device-tree = "/proc/device-tree/e3333_lens_ar0144@P5V27C/";
				};
			};
		};
	};
};

What else can I troubleshoot?

This path implies it is part of a kernel build using target dtbs:

hardware/nvidia/platform/t18x/quill/kernel-dts/

Basically you’ll want to configure the kernel to match your existing kernel via the running system’s “/proc/config.gz”. From there you can make any edits or changes desired, including device tree files. This will produce various “.dtb” files…one will contain the content from the named dts/dtsi file.

The kernel itself will not be what you replace since this format of kernel does not in and of itself contain device trees.

You’ll need to flash the particular device tree file rather than the kernel. I do not know enough about your particular changes to tell you which file goes where. Someone who knows about the device tree changes related to this sensor will have to answer.

Awesome! This clears up some stuff. Let me tinker around with this!

Added note: If you download kernel source with “source_sync.sh” this directory is part of what you get. Without source_sync.sh you have to obtain the out-of-tree code separately. Example to use source_sync.sh (I don’t know if you have already done this, but someone looking at this thread later probably will be confused if their kernel source doesn’t have this):

./source_sync.sh -k tegra-l4t-r28.2

Hi,

We have designed a board based on e3333 with i2c expander. From my limited understanding, do we just have to rebuild the device tree using e3333-camera.dtsi to get the six cameras working or do we need to modify the ov5693.c?

Regards
Paul

I have no knowledge of that particular camera. In situations like this usually you only need to modify the device tree. This could be via the dtsi file and a “make dtbs” target in kernel source, or by other means…but it is unlikely the “.c” file itself needs to be edited if someone has indicated it is a device tree change (but I can’t verify your solution really is device tree).

From my understanding, the driver code simply merges your camera information with V4l2 controls, so you shouldn’t need to alter that (unless you want to add some debug messages).

Unfortunately I still haven’t been able to successfully resister my new camera to the device tree, so I dont have any info on how to properly alter the dts/dtsi for new camera hardware.
My last attempt ended with a Kernel that didn’t boot…but i did generate a new DTB, so I guess there was some progress…