Kernel Patch BalenaOS Jetson Nano DevKit IMX477

Hello!

I am currently experimenting with the IMX477 HQ Camera on the Jetson Nano Developer Kit. I would like to use Balena in the future but I am not very familiar with Yocto and applying the kernel patches necessary to be able to use the camera.
I found these drivers from RidgeRun https://github.com/RidgeRun/NVIDIA-Jetson-IMX477-RPIV3 and would like to apply them (or the Arducam ones).

Thank you!

Hi,

i did something similar for the jetson xavier nx. Sadly i needed to take the hard route and apply a patch and build my own balena-os. If you have no experience with the yocto project, this will probably not help you :frowning:

This involves the following steps:

  1. create a patch to add the imx477 driver supprot
  2. add a new recipe for the isp modification, since you want to have good images

If you know about yocto, these code snippets might help you

patch for the jetson xavier nx
From ec2cc3d111e7423fb2b8266f7fd5e110d8171bd0 Mon Sep 17 00:00:00 2001
From: Langhalsdino <github@tausch.me>
Date: Fri, 10 Dec 2021 00:09:02 +0100
Subject: [PATCH] patch kernel to ridgerun state

---
 nvidia/drivers/media/i2c/imx477.c             |  38 +-
 .../tegra194-camera-jakku-rbpcv3-imx477.dtsi  |  20 +-
 .../common/tegra194-camera-rbpcv3-imx477.dtsi | 589 +++++++++++++-----
 .../common/tegra194-p3509-0000-a00.dtsi       |   1 -
 4 files changed, 459 insertions(+), 189 deletions(-)

diff --git a/nvidia/drivers/media/i2c/imx477.c b/nvidia/drivers/media/i2c/imx477.c
index 8f436bb..3809e00 100644
--- a/nvidia/drivers/media/i2c/imx477.c
+++ b/nvidia/drivers/media/i2c/imx477.c
@@ -259,46 +259,54 @@ static int imx477_set_exposure(struct tegracam_device *tc_dev, s64 val)
 	struct device *dev = tc_dev->dev;
 	const struct sensor_mode_properties *mode =
 	    &s_data->sensor_props.sensor_modes[s_data->mode_prop_idx];
-
 	int err = 0;
+	int i = 0;
 	imx477_reg ct_regs[2];
 	const s32 max_coarse_time = priv->frame_length - IMX477_MAX_COARSE_DIFF;
-	const s32 fine_integ_time_factor = priv->fine_integ_time *
-	    mode->control_properties.exposure_factor /
-	    mode->signal_properties.pixel_clock.val;
-	u32 coarse_time;
-	int i;
+	u32 coarse_time = 0;
+	u32 fine_int_time = 0;
+	u32 int_factor = val * mode->signal_properties.pixel_clock.val /
+	    mode->control_properties.exposure_factor;
+
+	coarse_time = int_factor / mode->image_properties.line_length;
+	fine_int_time = int_factor % mode->image_properties.line_length;
 
 	dev_dbg(dev, "%s: Setting exposure control to: %lld\n", __func__, val);
 
-	coarse_time = (val - fine_integ_time_factor)
-	    * mode->signal_properties.pixel_clock.val
-	    / mode->control_properties.exposure_factor
-	    / mode->image_properties.line_length;
+	dev_dbg(dev, "%s: Calculated coarse time: %d [lines]\n",
+		__func__, coarse_time);
+	dev_dbg(dev, "%s: Calculated fine integration time: %d [pixels]\n",
+		__func__, fine_int_time);
 
 	if (coarse_time < IMX477_MIN_COARSE_EXPOSURE)
 		coarse_time = IMX477_MIN_COARSE_EXPOSURE;
 	else if (coarse_time > max_coarse_time) {
 		coarse_time = max_coarse_time;
-		dev_dbg(dev,
+		dev_err(dev,
 			"%s: exposure limited by frame_length: %d [lines]\n",
 			__func__, max_coarse_time);
 	}
 
-	dev_dbg(dev, "%s: val: %lld [us], coarse_time: %d [lines]\n",
-		__func__, val, coarse_time);
-
 	imx477_get_coarse_integ_time_regs(ct_regs, coarse_time);
 
 	for (i = 0; i < 2; i++) {
 		err = imx477_write_reg(s_data, ct_regs[i].addr, ct_regs[i].val);
 		if (err) {
-			dev_dbg(dev,
+			dev_err(dev,
 				"%s: coarse_time control error\n", __func__);
 			return err;
 		}
 	}
 
+	err = imx477_write_reg(s_data, IMX477_FINE_INTEG_TIME_ADDR_MSB,
+			       (fine_int_time >> 8) & 0xFF);
+	err |= imx477_write_reg(s_data, IMX477_FINE_INTEG_TIME_ADDR_LSB,
+				fine_int_time & 0xFF);
+
+	if (err) {
+		dev_err(dev, "%s: fine integration time error\n", __func__);
+	}
+
 	return err;
 }
 
diff --git a/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-camera-jakku-rbpcv3-imx477.dtsi b/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-camera-jakku-rbpcv3-imx477.dtsi
index 2cc928e..9c74c83 100644
--- a/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-camera-jakku-rbpcv3-imx477.dtsi
+++ b/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-camera-jakku-rbpcv3-imx477.dtsi
@@ -1,5 +1,7 @@
 /*
- * Copyright (c) 2021, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2020, RidgeRun.  All rights reserved.
+ *
+ * Contact us: support@ridgerun.com
  *
  * 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
@@ -22,18 +24,17 @@
 #define CAM_I2C_MUX 	TEGRA194_AON_GPIO(CC, 3)
 
 / {
-	cam_i2cmux {
+	cam_i2cmux{
 		compatible = "i2c-mux-gpio";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		i2c-parent = <&cam_i2c>;
 		mux-gpios = <&tegra_aon_gpio CAM_I2C_MUX GPIO_ACTIVE_HIGH>;
-		i2c-parent = <&i2c7>;
 		i2c@0 {
 			reg = <0>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			rbpcv3_imx477_a@1a {
-				status = "disabled";
+            		rbpcv3_imx477_a@1a {
 				reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;
 			};
 		};
@@ -42,18 +43,17 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			rbpcv3_imx477_c@1a {
-				status = "disabled";
 				reset-gpios = <&tegra_main_gpio CAM1_PWDN GPIO_ACTIVE_HIGH>;
 			};
 		};
 	};
 
-	gpio@6000d000 {
+	gpio@2200000 {
 		camera-control-output-low {
 			gpio-hog;
 			output-low;
-			gpios = < CAM1_PWDN 0  CAM0_PWDN 0>;
-			label = "cam1-pwdn", "cam0-pwdn";
+			gpios = <CAM0_PWDN 0 CAM1_PWDN 0>;
+			label = "cam0-pwdn","cam1-pwdn";
 		};
 	};
-};
+};
\ No newline at end of file
diff --git a/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-camera-rbpcv3-imx477.dtsi b/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-camera-rbpcv3-imx477.dtsi
index 8b7b1c6..9a5e99d 100644
--- a/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-camera-rbpcv3-imx477.dtsi
+++ b/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-camera-rbpcv3-imx477.dtsi
@@ -1,5 +1,7 @@
 /*
- * Copyright (c) 2021, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2020, RidgeRun.  All rights reserved.
+ *
+ * Contact us: support@ridgerun.com
  *
  * 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
@@ -14,26 +16,29 @@
  * 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/media/camera.h>
 
 / {
 	host1x {
-		vi@15c10000 {
+		vi@15c10000  {
 			num-channels = <2>;
 			ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				port@0 {
+				vi_port0: port@0 {
 					reg = <0>;
 					rbpcv3_imx477_vi_in0: endpoint {
+						status = "okay";
 						port-index = <0>;
 						bus-width = <2>;
 						remote-endpoint = <&rbpcv3_imx477_csi_out0>;
 					};
 				};
-				port@1 {
+				vi_port1: port@1 {
 					reg = <1>;
 					rbpcv3_imx477_vi_in1: endpoint {
-						port-index = <4>;
+						status = "okay";
+						port-index = <2>;
 						bus-width = <2>;
 						remote-endpoint = <&rbpcv3_imx477_csi_out1>;
 					};
@@ -45,42 +50,47 @@
 			num-channels = <2>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			channel@0 {
+			csi_chan0: channel@0 {
 				reg = <0>;
 				ports {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					port@0 {
+					csi_chan0_port0: port@0 {
 						reg = <0>;
+						status = "okay";
 						rbpcv3_imx477_csi_in0: endpoint@0 {
 							port-index = <0>;
 							bus-width = <2>;
-							remote-endpoint = <&rbpcv3_imx477_dual_out0>;
+							remote-endpoint = <&rbpcv3_imx477_out0>;
 						};
 					};
-					port@1 {
+					csi_chan0_port1: port@1 {
 						reg = <1>;
+						status = "okay";
 						rbpcv3_imx477_csi_out0: endpoint@1 {
+							status = "okay";
 							remote-endpoint = <&rbpcv3_imx477_vi_in0>;
 						};
 					};
 				};
 			};
-			channel@1 {
+			csi_chan1: channel@1 {
 				reg = <1>;
 				ports {
 					#address-cells = <1>;
 					#size-cells = <0>;
-					port@2 {
+					csi_chan1_port0: port@0 {
 						reg = <0>;
 						rbpcv3_imx477_csi_in1: endpoint@2 {
 							port-index = <2>;
 							bus-width = <2>;
+							status = "okay";
 							remote-endpoint = <&rbpcv3_imx477_out1>;
 						};
 					};
-					port@3 {
+					csi_chan1_port1: port@1 {
 						reg = <1>;
+						status = "okay";
 						rbpcv3_imx477_csi_out1: endpoint@3 {
 							remote-endpoint = <&rbpcv3_imx477_vi_in1>;
 						};
@@ -91,7 +101,7 @@
 	};
 
 	cam_i2cmux {
-		i2c@0 {
+		i2c_0:i2c@0 {
 			imx477_cam0: rbpcv3_imx477_a@1a {
 				compatible = "ridgerun,imx477";
 				/* I2C device address */
@@ -101,95 +111,14 @@
 				devnode = "video0";
 
 				/* Physical dimensions of sensor */
-				physical_w = "3.680";
-				physical_h = "2.760";
+				physical_w = "7.564";
+				physical_h = "5.476";
 
 				sensor_model = "imx477";
 
 				use_sensor_mode_id = "true";
 
-				/**
-				* ==== Modes ====
-				* A modeX node is required to support v4l2 driver
-				* implementation with NVIDIA camera software stack
-				*
-				* == Signal properties ==
-				*
-				* phy_mode = "";
-				* PHY mode used by the MIPI lanes for this device
-				*
-				* tegra_sinterface = "";
-				* CSI Serial interface connected to tegra
-				* Incase of virtual HW devices, use virtual
-				* For SW emulated devices, use host
-				*
-				* pix_clk_hz = "";
-				* Sensor pixel clock used for calculations like exposure and framerate
-				*
-				* readout_orientation = "0";
-				* Based on camera module orientation.
-				* Only change readout_orientation if you specifically
-				* Program a different readout order for this mode
-				*
-				* == Image format Properties ==
-				*
-				* active_w = "";
-				* Pixel active region width
-				*
-				* active_h = "";
-				* Pixel active region height
-				*
-				* pixel_t = "";
-				* The sensor readout pixel pattern
-				*
-				* line_length = "";
-				* Pixel line length (width) for sensor mode.
-				*
-				* == Source Control Settings ==
-				*
-				* Gain factor used to convert fixed point integer to float
-				* Gain range [min_gain/gain_factor, max_gain/gain_factor]
-				* Gain step [step_gain/gain_factor is the smallest step that can be configured]
-				* Default gain [Default gain to be initialized for the control.
-				*     use min_gain_val as default for optimal results]
-				* Framerate factor used to convert fixed point integer to float
-				* Framerate range [min_framerate/framerate_factor, max_framerate/framerate_factor]
-				* Framerate step [step_framerate/framerate_factor is the smallest step that can be configured]
-				* Default Framerate [Default framerate to be initialized for the control.
-				*     use max_framerate to get required performance]
-				* Exposure factor used to convert fixed point integer to float
-				* For convenience use 1 sec = 1000000us as conversion factor
-				* Exposure range [min_exp_time/exposure_factor, max_exp_time/exposure_factor]
-				* Exposure step [step_exp_time/exposure_factor is the smallest step that can be configured]
-				* Default Exposure Time [Default exposure to be initialized for the control.
-				*     Set default exposure based on the default_framerate for optimal exposure settings]
-				*
-				* gain_factor = ""; (integer factor used for floating to fixed point conversion)
-				* min_gain_val = ""; (ceil to integer)
-				* max_gain_val = ""; (ceil to integer)
-				* step_gain_val = ""; (ceil to integer)
-				* default_gain = ""; (ceil to integer)
-				* Gain limits for mode
-				*
-				* exposure_factor = ""; (integer factor used for floating to fixed point conversion)
-				* min_exp_time = ""; (ceil to integer)
-				* max_exp_time = ""; (ceil to integer)
-				* step_exp_time = ""; (ceil to integer)
-				* default_exp_time = ""; (ceil to integer)
-				* Exposure Time limits for mode (sec)
-				*
-				* framerate_factor = ""; (integer factor used for floating to fixed point conversion)
-				* min_framerate = ""; (ceil to integer)
-				* max_framerate = ""; (ceil to integer)
-				* step_framerate = ""; (ceil to integer)
-				* default_framerate = ""; (ceil to integer)
-				* Framerate limits for mode (fps)
-				*
-				* embedded_metadata_height = "";
-				* Sensor embedded metadata height in units of rows.
-				* If sensor does not support embedded metadata value should be 0.
-				*/
-				mode0 { /* IMX477_MODE_3840x2160 */
+				mode0 { /* IMX477_MODE_4032X3040 */
 					mclk_khz = "24000";
 					num_lanes = "2";
 					tegra_sinterface = "serial_a";
@@ -198,13 +127,13 @@
 					dpcm_enable = "false";
 					cil_settletime = "0";
 
-					active_w = "3840";
-					active_h = "2160";
+					active_w = "4032";
+					active_h = "3040";
 					mode_type = "bayer";
 					pixel_phase = "rggb";
 					csi_pixel_bit_depth = "10";
 					readout_orientation = "90";
-					line_length = "11200";
+					line_length = "9024";
 					inherent_gain = "1";
 					mclk_multiplier = "80";
 					pix_clk_hz = "840000000";
@@ -222,8 +151,8 @@
 					max_framerate = "30000000"; /* 30.0 fps */
 					step_framerate = "1";
 					default_framerate = "30000000"; /* 30.0 fps */
-					min_exp_time = "13"; /* us */
-					max_exp_time = "683709"; /* us */
+					min_exp_time = "11"; /* us */
+					max_exp_time = "500000"; /* us */
 					step_exp_time = "1";
 					default_exp_time = "2495"; /* us */
 
@@ -244,7 +173,7 @@
 					pixel_phase = "rggb";
 					csi_pixel_bit_depth = "10";
 					readout_orientation = "90";
-					line_length = "7000";
+					line_length = "9024";
 					inherent_gain = "1";
 					mclk_multiplier = "80";
 					pix_clk_hz = "840000000";
@@ -262,8 +191,8 @@
 					max_framerate = "60000000"; /* 60.0 fps */
 					step_framerate = "1";
 					default_framerate = "60000000"; /* 60.0 fps */
-					min_exp_time = "13"; /* us */
-					max_exp_time = "683709"; /* us */
+					min_exp_time = "11"; /* us */
+					max_exp_time = "500000"; /* us */
 					step_exp_time = "1";
 					default_exp_time = "2495"; /* us */
 
@@ -273,10 +202,9 @@
 				ports {
 					#address-cells = <1>;
 					#size-cells = <0>;
-
 					port@0 {
 						reg = <0>;
-						rbpcv3_imx477_dual_out0: endpoint {
+						rbpcv3_imx477_out0: endpoint {
 							port-index = <0>;
 							bus-width = <2>;
 							remote-endpoint = <&rbpcv3_imx477_csi_in0>;
@@ -285,7 +213,7 @@
 				};
 			};
 		};
-		i2c@1 {
+		i2c_1: i2c@1 {
 			imx477_cam1: rbpcv3_imx477_c@1a {
 				compatible = "ridgerun,imx477";
 				/* I2C device address */
@@ -295,14 +223,14 @@
 				devnode = "video1";
 
 				/* Physical dimensions of sensor */
-				physical_w = "3.680";
-				physical_h = "2.760";
+				physical_w = "7.564";
+				physical_h = "5.476";
 
 				sensor_model = "imx477";
 
 				use_sensor_mode_id = "true";
 
-				mode0 { /* IMX477_MODE_3840x2160 */
+				mode0 { /* IMX477_MODE_4032X3040 */
 					mclk_khz = "24000";
 					num_lanes = "2";
 					tegra_sinterface = "serial_c";
@@ -311,13 +239,13 @@
 					dpcm_enable = "false";
 					cil_settletime = "0";
 
-					active_w = "3840";
-					active_h = "2160";
+					active_w = "4032";
+					active_h = "3040";
 					mode_type = "bayer";
 					pixel_phase = "rggb";
 					csi_pixel_bit_depth = "10";
 					readout_orientation = "90";
-					line_length = "11200";
+					line_length = "9024";
 					inherent_gain = "1";
 					mclk_multiplier = "80";
 					pix_clk_hz = "840000000";
@@ -335,8 +263,8 @@
 					max_framerate = "30000000"; /* 30.0 fps */
 					step_framerate = "1";
 					default_framerate = "30000000"; /* 30.0 fps */
-					min_exp_time = "13"; /* us */
-					max_exp_time = "683709"; /* us */
+					min_exp_time = "11"; /* us */
+					max_exp_time = "500000"; /* us */
 					step_exp_time = "1";
 					default_exp_time = "2495"; /* us */
 
@@ -357,7 +285,7 @@
 					pixel_phase = "rggb";
 					csi_pixel_bit_depth = "10";
 					readout_orientation = "90";
-					line_length = "7000";
+					line_length = "9024";
 					inherent_gain = "1";
 					mclk_multiplier = "80";
 					pix_clk_hz = "840000000";
@@ -375,8 +303,8 @@
 					max_framerate = "60000000"; /* 60.0 fps */
 					step_framerate = "1";
 					default_framerate = "60000000"; /* 60.0 fps */
-					min_exp_time = "13"; /* us */
-					max_exp_time = "683709"; /* us */
+					min_exp_time = "11"; /* us */
+					max_exp_time = "500000"; /* us */
 					step_exp_time = "1";
 					default_exp_time = "2495"; /* us */
 
@@ -386,7 +314,6 @@
 				ports {
 					#address-cells = <1>;
 					#size-cells = <0>;
-
 					port@0 {
 						reg = <0>;
 						rbpcv3_imx477_out1: endpoint {
@@ -400,38 +327,378 @@
 		};
 	};
 };
-
 / {
-	tegra-camera-platform {
+	tcp: 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>;
+		max_pixel_rate = <7500000>;
+		isp_peak_byte_per_pixel = <5>;
+		isp_bw_margin_pct = <25>;
+
+		modules {
+			cam_module0: module0 {
+				badge = "jakku_front_RBP194";
+				position = "front";
+				orientation = "1";
+				status = "okay";
+				cam_module0_drivernode0: drivernode0 {
+					status = "okay";
+					pcl_id = "v4l2_sensor";
+					devname = "imx477 9-001a";
+					proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/rbpcv3_imx477_a@1a";
+				};
+			};
+			cam_module1: module1 {
+				badge = "jakku_rear_RBP194";
+				position = "rear";
+				orientation = "1";
+				status = "okay";
+				cam_module1_drivernode0: drivernode0 {
+					status = "okay";
+					pcl_id = "v4l2_sensor";
+					devname = "imx477 10-001a";
+					proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@1/rbpcv3_imx477_c@1a";
+				};
+			};
+		};
+	};
+};
+/*
+ * Copyright (c) 2020, RidgeRun.  All rights reserved.
+ *
+ * Contact us: support@ridgerun.com
+ *
+ * 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/>.
+ */
+#include <dt-bindings/media/camera.h>
+
+/ {
+	host1x {
+		vi@15c10000  {
+			num-channels = <2>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				vi_port0: port@0 {
+					reg = <0>;
+					rbpcv3_imx477_vi_in0: endpoint {
+						status = "okay";
+						port-index = <0>;
+						bus-width = <2>;
+						remote-endpoint = <&rbpcv3_imx477_csi_out0>;
+					};
+				};
+				vi_port1: port@1 {
+					reg = <1>;
+					rbpcv3_imx477_vi_in1: endpoint {
+						status = "okay";
+						port-index = <2>;
+						bus-width = <2>;
+						remote-endpoint = <&rbpcv3_imx477_csi_out1>;
+					};
+				};
+			};
+		};
+
+		nvcsi@15a00000 {
+			num-channels = <2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			csi_chan0: channel@0 {
+				reg = <0>;
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					csi_chan0_port0: port@0 {
+						reg = <0>;
+						status = "okay";
+						rbpcv3_imx477_csi_in0: endpoint@0 {
+							port-index = <0>;
+							bus-width = <2>;
+							remote-endpoint = <&rbpcv3_imx477_out0>;
+						};
+					};
+					csi_chan0_port1: port@1 {
+						reg = <1>;
+						status = "okay";
+						rbpcv3_imx477_csi_out0: endpoint@1 {
+							status = "okay";
+							remote-endpoint = <&rbpcv3_imx477_vi_in0>;
+						};
+					};
+				};
+			};
+			csi_chan1: channel@1 {
+				reg = <1>;
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					csi_chan1_port0: port@0 {
+						reg = <0>;
+						rbpcv3_imx477_csi_in1: endpoint@2 {
+							port-index = <2>;
+							bus-width = <2>;
+							status = "okay";
+							remote-endpoint = <&rbpcv3_imx477_out1>;
+						};
+					};
+					csi_chan1_port1: port@1 {
+						reg = <1>;
+						status = "okay";
+						rbpcv3_imx477_csi_out1: endpoint@3 {
+							remote-endpoint = <&rbpcv3_imx477_vi_in1>;
+						};
+					};
+				};
+			};
+		};
+	};
+
+	cam_i2cmux {
+		i2c_0:i2c@0 {
+			imx477_cam0: rbpcv3_imx477_a@1a {
+				compatible = "ridgerun,imx477";
+				/* I2C device address */
+				reg = <0x1a>;
+
+				/* V4L2 device node location */
+				devnode = "video0";
+
+				/* Physical dimensions of sensor */
+				physical_w = "7.564";
+				physical_h = "5.476";
+
+				sensor_model = "imx477";
+
+				use_sensor_mode_id = "true";
+
+				mode0 { /* IMX477_MODE_4032X3040 */
+					mclk_khz = "24000";
+					num_lanes = "2";
+					tegra_sinterface = "serial_a";
+					phy_mode = "DPHY";
+					discontinuous_clk = "no";
+					dpcm_enable = "false";
+					cil_settletime = "0";
+
+					active_w = "4032";
+					active_h = "3040";
+					mode_type = "bayer";
+					pixel_phase = "rggb";
+					csi_pixel_bit_depth = "10";
+					readout_orientation = "90";
+					line_length = "9024";
+					inherent_gain = "1";
+					mclk_multiplier = "80";
+					pix_clk_hz = "840000000";
+
+					gain_factor = "16";
+					framerate_factor = "1000000";
+					exposure_factor = "1000000";
+					min_gain_val = "16"; /* 1.00x */
+					max_gain_val = "356"; /* 22x */
+					step_gain_val = "1";
+					default_gain = "16"; /* 1.00x */
+					min_hdr_ratio = "1";
+					max_hdr_ratio = "1";
+					min_framerate = "2000000"; /* 2.0 fps */
+					max_framerate = "30000000"; /* 30.0 fps */
+					step_framerate = "1";
+					default_framerate = "30000000"; /* 30.0 fps */
+					min_exp_time = "11"; /* us */
+					max_exp_time = "500000"; /* us */
+					step_exp_time = "1";
+					default_exp_time = "2495"; /* us */
+
+					embedded_metadata_height = "2";
+				};
+				mode1 { /* IMX477_MODE_1920X1080 */
+					mclk_khz = "24000";
+					num_lanes = "2";
+					tegra_sinterface = "serial_a";
+					phy_mode = "DPHY";
+					discontinuous_clk = "no";
+					dpcm_enable = "false";
+					cil_settletime = "0";
+
+					active_w = "1920";
+					active_h = "1080";
+					mode_type = "bayer";
+					pixel_phase = "rggb";
+					csi_pixel_bit_depth = "10";
+					readout_orientation = "90";
+					line_length = "9024";
+					inherent_gain = "1";
+					mclk_multiplier = "80";
+					pix_clk_hz = "840000000";
+
+					gain_factor = "16";
+					framerate_factor = "1000000";
+					exposure_factor = "1000000";
+					min_gain_val = "16"; /* 1.00x */
+					max_gain_val = "356"; /* 22x */
+					step_gain_val = "1";
+					default_gain = "16"; /* 1.00x */
+					min_hdr_ratio = "1";
+					max_hdr_ratio = "1";
+					min_framerate = "2000000"; /* 2.0 fps */
+					max_framerate = "60000000"; /* 60.0 fps */
+					step_framerate = "1";
+					default_framerate = "60000000"; /* 60.0 fps */
+					min_exp_time = "11"; /* us */
+					max_exp_time = "500000"; /* us */
+					step_exp_time = "1";
+					default_exp_time = "2495"; /* us */
+
+					embedded_metadata_height = "2";
+				};
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					port@0 {
+						reg = <0>;
+						rbpcv3_imx477_out0: endpoint {
+							port-index = <0>;
+							bus-width = <2>;
+							remote-endpoint = <&rbpcv3_imx477_csi_in0>;
+						};
+					};
+				};
+			};
+		};
+		i2c_1: i2c@1 {
+			imx477_cam1: rbpcv3_imx477_c@1a {
+				compatible = "ridgerun,imx477";
+				/* I2C device address */
+				reg = <0x1a>;
+
+				/* V4L2 device node location */
+				devnode = "video1";
+
+				/* Physical dimensions of sensor */
+				physical_w = "7.564";
+				physical_h = "5.476";
+
+				sensor_model = "imx477";
+
+				use_sensor_mode_id = "true";
+
+				mode0 { /* IMX477_MODE_4032X3040 */
+					mclk_khz = "24000";
+					num_lanes = "2";
+					tegra_sinterface = "serial_c";
+					phy_mode = "DPHY";
+					discontinuous_clk = "no";
+					dpcm_enable = "false";
+					cil_settletime = "0";
+
+					active_w = "4032";
+					active_h = "3040";
+					mode_type = "bayer";
+					pixel_phase = "rggb";
+					csi_pixel_bit_depth = "10";
+					readout_orientation = "90";
+					line_length = "9024";
+					inherent_gain = "1";
+					mclk_multiplier = "80";
+					pix_clk_hz = "840000000";
+
+					gain_factor = "16";
+					framerate_factor = "1000000";
+					exposure_factor = "1000000";
+					min_gain_val = "16"; /* 1.00x */
+					max_gain_val = "356"; /* 22x */
+					step_gain_val = "1";
+					default_gain = "16"; /* 1.00x */
+					min_hdr_ratio = "1";
+					max_hdr_ratio = "1";
+					min_framerate = "2000000"; /* 2.0 fps */
+					max_framerate = "30000000"; /* 30.0 fps */
+					step_framerate = "1";
+					default_framerate = "30000000"; /* 30.0 fps */
+					min_exp_time = "11"; /* us */
+					max_exp_time = "500000"; /* us */
+					step_exp_time = "1";
+					default_exp_time = "2495"; /* us */
+
+					embedded_metadata_height = "2";
+				};
+				mode1 { /* IMX477_MODE_1920X1080 */
+					mclk_khz = "24000";
+					num_lanes = "2";
+					tegra_sinterface = "serial_c";
+					phy_mode = "DPHY";
+					discontinuous_clk = "no";
+					dpcm_enable = "false";
+					cil_settletime = "0";
 
-		/**
-		* 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
-		*
-		* isp_peak_byte_per_pixel = <>;
-		* Max byte per pixel for the ISP ISO case
-		*
-		* isp_bw_margin_pct = <>;
-		* Isp bandwidth margin in percentage
-		*/
+					active_w = "1920";
+					active_h = "1080";
+					mode_type = "bayer";
+					pixel_phase = "rggb";
+					csi_pixel_bit_depth = "10";
+					readout_orientation = "90";
+					line_length = "9024";
+					inherent_gain = "1";
+					mclk_multiplier = "80";
+					pix_clk_hz = "840000000";
+
+					gain_factor = "16";
+					framerate_factor = "1000000";
+					exposure_factor = "1000000";
+					min_gain_val = "16"; /* 1.00x */
+					max_gain_val = "356"; /* 22x */
+					step_gain_val = "1";
+					default_gain = "16"; /* 1.00x */
+					min_hdr_ratio = "1";
+					max_hdr_ratio = "1";
+					min_framerate = "2000000"; /* 2.0 fps */
+					max_framerate = "60000000"; /* 60.0 fps */
+					step_framerate = "1";
+					default_framerate = "60000000"; /* 60.0 fps */
+					min_exp_time = "11"; /* us */
+					max_exp_time = "500000"; /* us */
+					step_exp_time = "1";
+					default_exp_time = "2495"; /* us */
+
+					embedded_metadata_height = "2";
+				};
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					port@0 {
+						reg = <0>;
+						rbpcv3_imx477_out1: endpoint {
+							port-index = <2>;
+							bus-width = <2>;
+							remote-endpoint = <&rbpcv3_imx477_csi_in1>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
+/ {
+	tcp: tegra-camera-platform {
+		compatible = "nvidia, tegra-camera-platform";
 		num_csi_lanes = <4>;
 		max_lane_speed = <1500000>;
 		min_bits_per_pixel = <10>;
@@ -441,30 +708,26 @@
 		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 vendor.
-		 */
 		modules {
-			module0 {
-				badge = "jakku_front_IMX477";
+			cam_module0: module0 {
+				badge = "jakku_front_RBP194";
 				position = "front";
 				orientation = "1";
-				drivernode0 {
+				status = "okay";
+				cam_module0_drivernode0: drivernode0 {
+					status = "okay";
 					pcl_id = "v4l2_sensor";
 					devname = "imx477 9-001a";
 					proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/rbpcv3_imx477_a@1a";
 				};
 			};
-			module1 {
-				badge = "jakku_rear_IMX477";
+			cam_module1: module1 {
+				badge = "jakku_rear_RBP194";
 				position = "rear";
 				orientation = "1";
-				drivernode0 {
+				status = "okay";
+				cam_module1_drivernode0: drivernode0 {
+					status = "okay";
 					pcl_id = "v4l2_sensor";
 					devname = "imx477 10-001a";
 					proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@1/rbpcv3_imx477_c@1a";
diff --git a/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-p3509-0000-a00.dtsi b/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-p3509-0000-a00.dtsi
index b99d72a..633e8c5 100644
--- a/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-p3509-0000-a00.dtsi
+++ b/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-p3509-0000-a00.dtsi
@@ -17,7 +17,6 @@
 #include "tegra194-audio-p3668.dtsi"
 #include "tegra194-super-module-e2614-p3509.dtsi"
 #include "tegra194-camera-jakku-rbpcv3-imx477.dtsi"
-#include "tegra194-camera-jakku-rbpcv2-imx219.dtsi"
 / {
 	gpio-keys {
 		compatible = "gpio-keys";
-- 
2.24.3 (Apple Git-128)
ISP modification recipe

isp-config.bb

FILESEXTRAPATHS:append := ":${THISDIR}/${PN}"

inherit systemd allarch

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI += " \
    file://camera_overrides.isp \
"

FILES:${PN} = " \
    /var/nvidia/nvcam/settings/camera_overrides.isp \
"

S = "${WORKDIR}"

RDEPENDS:${PN} = " bash systemd"

do_install:append() {
    install -d ${D}${localstatedir}/nvidia/nvcam/settings
    install -m 0644 ${WORKDIR}/camera_overrides.isp ${D}${localstatedir}/nvidia/nvcam/settings/camera_overrides.isp
}

You can get the camera_overrides.isp from ridgerun :slight_smile:

1 Like

I just found the kernel patch for the jetson nano in my local dev folder from last year, that might help you

0004-add-imx477.patch.txt (55.1 KB)