OV10635 image sensor on TX2

Dear all,

We have just designed a custom hardware that use 3 OV10635 image sensors. For long distance and we use MAX9271 to serialize and MAX9288 to deserialize and convert data from 10 bit DVP to MIPI signal.
Now I use latest Jetpack 3.1 to flash OS to our board.

We’re facing many problems.

  1. When I try to use i2cdetect to see if there is any device on i2c bus, this is result:
-- [   25.618804] tegra-i2c 3160000.i2c: no acknowledge from address 0x5
-- [   25.625860] tegra-i2c 3160000.i2c: no acknowledge from address 0x6
-- [   25.632777] tegra-i2c 3160000.i2c: no acknowledge from address 0x7
-- [   25.639724] tegra-i2c 3160000.i2c: no acknowledge from address 0x8
-- [   25.646651] tegra-i2c 3160000.i2c: no acknowledge from address 0x9
-- [   25.653576] tegra-i2c 3160000.i2c: no acknowledge from address 0xa
-- [   25.660506] tegra-i2c 3160000.i2c: no acknowledge from address 0xb

Even though, last time with OS from driver package (28.1) I can detect some devices. Im not sure is there any difference between flashing with Jetpack 3.1 and flashing with driver package.

  1. I downloaded latest kernel version on download center then added ov10635 driver, modified device tree and rebuilt according to Sensor Driver Programming Guide:
    Using Main Platform Device Tree File
    • Now, “hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts”:
#include <t18x-common-platforms/tegra186-quill-common-p3310-1000-a00.dtsi>
     #include <t18x-common-platforms/tegra186-quill-power-tree-p3310-1000-a00-00.dtsi>
     /*#include <t18x-common-platforms/tegra186-quill-camera-modules.dtsi>*/
     #include <t18x-common-platforms/tegra186-hanyang-camera-modules.dtsi>
     #include <t18x-common-modules/tegra186-display-e3320-1000-a00.dtsi>

     /* comms dtsi file should be included after gpio dtsi file */
     #include <t18x-common-platforms/tegra186-quill-comms.dtsi>
     #include <t18x-common-plugin-manager/tegra186-quill-p3310-1000-a00-plugin-manager.dtsi>
     #include <t18x-common-modules/tegra186-super-module-e2614-p2597-1000-a00.dtsi>
     #include <t18x-common-plugin-manager/tegra186-quill-display-plugin-manager.dtsi>
     #include <t18x-common-prod/tegra186-priv-quill-p3310-1000-a00-prod.dtsi>
     /*#include <t18x-common-plugin-manager/tegra186-quill-camera-plugin-manager.dtsi>*/

     #include <dt-bindings/linux/driver-info.h>
     ............
  • “t18x-common-platforms/tegra186-hanyang-camera-modules.dtsi”:
/*
 * Copyright (c) 2016-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; version 2 of the License.
 *
 * 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.
 *
 */

#define CAM0_RST_L	TEGRA_MAIN_GPIO(R, 5)
#define CAM0_PWDN	TEGRA_MAIN_GPIO(R, 0)
#define CAM1_RST_L	TEGRA_MAIN_GPIO(R, 1)
#define CAM1_PWDN	TEGRA_MAIN_GPIO(L, 6)

/ {
	tegra-camera-platform {
		/**
		* tpg_max_iso = <>;
		* Max iso bw for 6 streams of tpg
		* streams * nvcsi_freq * PG_bitrate / RG10 * BPP
		* 6 * 102Mhz * 32 bits/ 10 bits * 2 Bps
		* = 3916.8 MBps
		*/
		tpg_max_iso = <3916800>;
	};

	/* set camera gpio direction to output */
	gpio@2200000 {
		camera-control-output-low {
			gpio-hog;
			output-low;
			gpios = <CAM0_RST_L 0 CAM0_PWDN 0
				 CAM1_RST_L 0 CAM1_PWDN 0>;
			label = "cam0-rst", "cam0-pwdn",
				"cam1-rst", "cam1-pwdn";
		};
	};

	/* all cameras are disabled by default */
	host1x {
		vi_base: vi@15700000 {
			num-channels = <1>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				vi_port0: port@0 { /*CSI A*/
					status = "okay";
					reg = <0>;
					e3326_vi_in0: endpoint {
						status = "disabled";
						csi-port = <0>;
						bus-width = <4>;
						remote-endpoint = <&e3326_csi_out0>;
					};
				};
				vi_port1: port@1 {
					status = "disabled";
					vi_in1: endpoint {
						status = "disabled";
					};
				};
				vi_port2: port@2 {
					status = "disabled";
					vi_in2: endpoint {
						status = "disabled";
					};
				};
			};
		};
		csi_base: nvcsi@150c0000 {
			num-channels = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			csi_chan0: channel@0 {
				status = "okay";
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					csi_chan0_port0: port@0 {
						status = "okay";
						reg = <0>;
						e3326_csi_in0: endpoint@0 {
							status = "disabled";
							csi-port = <0>;
							bus-width = <4>;
							remote-endpoint = <&e3326_ov10635_out0>;
						};
					};
					csi_chan0_port1: port@1 {
						status = "okay";
						reg = <1>;
						e3326_csi_out0: endpoint@1 {
							status = "disabled";
							remote-endpoint = <&e3326_vi_in0>;
						};
					};
				};
			};
			csi_chan1: channel@1 {
				status = "disabled";
				ports {
					csi_chan1_port0: port@0 {
						status = "disabled";
						csi_in1: endpoint@2 {
							status = "disabled";
						};
					};
					csi_chan1_port1: port@1 {
						status = "disabled";
						csi_out1: endpoint@3 {
							status = "disabled";
						};
					};
				};
			};
			csi_chan2: channel@2 {
				status = "disabled";
				ports {
					csi_chan2_port0: port@0 {
						status = "disabled";
						csi_in2: endpoint@4 {
							status = "disabled";
						};
					};
					csi_chan2_port1: port@1 {
						status = "disabled";
						csi_out2: endpoint@5 {
							status = "disabled";
						};
					};
				};
			};
		};
	};

	i2c@3180000 {
		e3326_cam0: ov10635_c@40 {
			status = "okay";
			compatible = "nvidia,ov10635";
			
			/* I2C device address */
			reg = <0x40>;

			/* V4L2 device node location */
			devnode = "video0";
			
			ports {
				#address-cells = <1>;
				#size-cells = <0>;

				port@0 {
					reg = <0>;
					e3326_ov10635_out0: endpoint {
						csi-port = <0>;
						bus-width = <4>;
						remote-endpoint = <&e3326_csi_in0>;
					};
				};
			};
		};
		e3323_cam0: ov23850_a@10 {
			status = "disabled";
		};
		e3323_vcm0: lc898212@72 {
			status = "disabled";
		};
	};

	i2c@c240000 {
		e3323_cam1: ov23850_c@40 {
			status = "disabled";
		};
		e3323_vcm1: lc898212@72 {
			status = "disabled";
		};
	};

	tcp: tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";
		modules {
			cam_module0: module0 {
				status = "disabled";
				badge = "e3326_left_ov10635";
				position = "rear";
				orientation = "1";
				cam_module0_drivernode0: drivernode0 {
					status = "okay";
					/* Declare PCL support driver (classically known as guid)  */
					pcl_id = "v4l2_sensor";
					/* Driver v4l2 device name */
					devname = "ov10635 1-0040";
					/* Declare the device-tree hierarchy to driver instance */
					proc-device-tree = "/proc/device-tree/i2c@3180000/ov10635_c@40";
				};
				cam_module0_drivernode1: drivernode1 {
					status = "okay";
					pcl_id = "v4l2_focuser_stub";
				};
			};
			cam_module1: module1 {
				status = "disabled";
				cam_module1_drivernode0: drivernode0 {
					status = "disabled";
				};
				cam_module1_drivernode1: drivernode1 {
					status = "disabled";
					pcl_id = "v4l2_focuser_stub";
				};
			};
			cam_module2: module2 {
				status = "disabled";
				cam_module2_drivernode0: drivernode0 {
					status = "disabled";
				};
				cam_module2_drivernode1: drivernode1 {
					status = "disabled";
					pcl_id = "v4l2_focuser_stub";
				};
			};
		};
	};
};
 + Add this line to /boot/etxlinux/extlinux.conf to load my custom dtb
FDT /boot/tegra186-quill-p3310-1000-c03-00-base.dtb

Then OS stuck here:

[    0.000000] Booting Linux on physical CPU 0x100
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 4.4.38 (hy@hy-Lenovo-ideapad-Y700-15ISK) (gcc version 4.8.2 (GCC) ) #3 SMP PREEMPT Wed Aug 2 12:42:17 KST 2017
[    0.000000] Boot CPU: AArch64 Processor [411fd073]
[    0.000000] earlycon: Early serial console at MMIO32 0x3100000 (options '')
[    0.000000] bootconsole [uart0] enabled
[    0.000000] Reserved memory: initialized node ramoops_carveout, compatible id nvidia,ramoops
[    0.000000] Reserved memory: initialized node vpr-carveout, compatible id nvidia,vpr-carveout
[    0.000000] cma: Reserved 64 MiB at 0x00000000fbc00000
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.0 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] PERCPU: Embedded 17 pages/cpu @ffffffc1f5c18000 s31232 r8192 d30208 u69632
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 2018947
[    0.000000] Kernel command line: root=/dev/mmcblk0p1 rw rootwait console=ttyS0,115200n8 console=tty0 OS=l4t fbcon=map:0 net.ifnames=0 memtype=0 video=tegrafb no_console_suspend=1 earlycon=uart8250,mmio32,0x03100000 nvdumper_reserved=0x2772e0000 gpt tegraid=18.1.2.0.0 tegra_keep_boot_clocks maxcpus=6 androidboot.serialno=0321017053548 bl_prof_dataptr=0x10000@0x277240000 sdhci_tegra.en_boot_part_access=1 root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes)
[    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes)
[    0.000000] Memory: 7283632K/8204288K available (10840K kernel code, 1768K rwdata, 5668K rodata, 1156K init, 679K bss, 166992K reserved, 753664K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vmalloc : 0xffffff8000000000 - 0xffffffbdbfff0000   (   246 GB)
[    0.000000]     vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000   (     8 GB maximum)
[    0.000000]               0xffffffbdc2000000 - 0xffffffbdc9d7c400   (   125 MB actual)
[    0.000000]     fixed   : 0xffffffbffa7fd000 - 0xffffffbffac00000   (  4108 KB)
[    0.000000]     PCI I/O : 0xffffffbffae00000 - 0xffffffbffbe00000   (    16 MB)
[    0.000000]     modules : 0xffffffbffc000000 - 0xffffffc000000000   (    64 MB)
[    0.000000]     memory  : 0xffffffc000000000 - 0xffffffc1f5f10000   (  8031 MB)
[    0.000000]       .init : 0xffffffc0010a0000 - 0xffffffc0011c1000   (  1156 KB)
[    0.000000]       .text : 0xffffffc000080000 - 0xffffffc0010a0000   ( 16512 KB)
[    0.000000]       .data : 0xffffffc0011e2000 - 0xffffffc00139c000   (  1768 KB)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=6, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] 	Build-time adjustment of leaf fanout to 64.
[    0.000000] 	RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=6.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=64, nr_cpu_ids=6
[    0.000000] NR_IRQS:64 nr_irqs:64 0
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] Architected cp15 timer(s) running at 31.25MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xe6a171046, max_idle_ns: 881590405314 ns
[    0.000002] sched_clock: 56 bits at 31MHz, resolution 32ns, wraps every 4398046511088ns
[    0.009512] Console: colour dummy device 80x25
[    0.014170] console [tty0] enabled
[    0.017726] bootconsole [uart0] disabled

Thanks

@forever
From the r28.1 we don’t suggestion to use FDT as point the boot dtb.
Please follow below step to flash the DTB instead of modify the extlinux.conf

  1. copy the dtb file to the …/Linuxfor_tegra_64_tx2/kernel/dtb/
  2. sudo ./flash -r -k kernel-dtb jetson-tx2 mmcblk0p1

Thanks for your comment. It should be faster for me.

I figure out that I have to let this line

#include "t18x-common-platforms/tegra186-quill-camera-e3322-a00.dtsi"

to make it boot to OS properly.

Now my dtsi file

/*
 * Copyright (c) 2016-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; version 2 of the License.
 *
 * 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.
 *
 */

#include "t18x-common-platforms/tegra186-quill-camera-e3322-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-li-mipi-adpt-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-imx274-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-vivid.dtsi"

#define CAM0_RST_L	TEGRA_MAIN_GPIO(R, 5)
#define CAM0_PWDN	TEGRA_MAIN_GPIO(R, 0)
#define CAM1_RST_L	TEGRA_MAIN_GPIO(R, 1)
#define CAM1_PWDN	TEGRA_MAIN_GPIO(L, 6)

/ {
	tegra-camera-platform {
		/**
		* tpg_max_iso = <>;
		* Max iso bw for 6 streams of tpg
		* streams * nvcsi_freq * PG_bitrate / RG10 * BPP
		* 6 * 102Mhz * 32 bits/ 10 bits * 2 Bps
		* = 3916.8 MBps
		*/
		tpg_max_iso = <3916800>;
	};

	/* set camera gpio direction to output */
	gpio@2200000 {
		camera-control-output-low {
			gpio-hog;
			output-low;
			gpios = <CAM0_RST_L 0 CAM0_PWDN 0
				 CAM1_RST_L 0 CAM1_PWDN 0>;
			label = "cam0-rst", "cam0-pwdn",
				"cam1-rst", "cam1-pwdn";
		};
	};

	/* all cameras are disabled by default */
	host1x {
		vi_base: vi@15700000 {
			num-channels = <1>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				vi_port0: port@0 { /*CSI A*/
					status = "okay";
					reg = <0>;
					e3326_vi_in0: endpoint {
						status = "okay";
						csi-port = <0>;
						bus-width = <4>;
						remote-endpoint = <&e3326_csi_out0>;
					};
				};
				vi_port1: port@1 {
					status = "disabled";
					vi_in1: endpoint {
						status = "disabled";
					};
				};
				vi_port2: port@2 {
					status = "disabled";
					vi_in2: endpoint {
						status = "disabled";
					};
				};
			};
		};
		csi_base: nvcsi@150c0000 {
			num-channels = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			csi_chan0: channel@0 {
				status = "okay";
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					csi_chan0_port0: port@0 {
						status = "okay";
						reg = <0>;
						e3326_csi_in0: endpoint@0 {
							status = "okay";
							csi-port = <0>;
							bus-width = <4>;
							remote-endpoint = <&e3326_ov10635_out0>;
						};
					};
					csi_chan0_port1: port@1 {
						status = "okay";
						reg = <1>;
						e3326_csi_out0: endpoint@1 {
							status = "okay";
							remote-endpoint = <&e3326_vi_in0>;
						};
					};
				};
			};
			csi_chan1: channel@1 {
				status = "disabled";
				ports {
					csi_chan1_port0: port@0 {
						status = "disabled";
						csi_in1: endpoint@2 {
							status = "disabled";
						};
					};
					csi_chan1_port1: port@1 {
						status = "disabled";
						csi_out1: endpoint@3 {
							status = "disabled";
						};
					};
				};
			};
			csi_chan2: channel@2 {
				status = "disabled";
				ports {
					csi_chan2_port0: port@0 {
						status = "disabled";
						csi_in2: endpoint@4 {
							status = "disabled";
						};
					};
					csi_chan2_port1: port@1 {
						status = "disabled";
						csi_out2: endpoint@5 {
							status = "disabled";
						};
					};
				};
			};
		};
	};

	i2c@3180000 {
		e3326_cam0: ov10635_c@40 {
			status = "okay";
			compatible = "nvidia,ov10635";
			
			/* I2C device address */
			reg = <0x40>;

			/* V4L2 device node location */
			devnode = "video0";
			
			/* 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>;
					e3326_ov10635_out0: endpoint {
						csi-port = <0>;
						bus-width = <4>;
						remote-endpoint = <&e3326_csi_in0>;
					};
				};
			};
		};
		e3323_cam0: ov23850_a@10 {
			status = "disabled";
		};
		e3323_vcm0: lc898212@72 {
			status = "disabled";
		};
	};

	i2c@c240000 {
		e3323_cam1: ov23850_c@40 {
			status = "disabled";
		};
		e3323_vcm1: lc898212@72 {
			status = "disabled";
		};
	};

	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 = <160000>;
		isp_peak_byte_per_pixel = <5>;
		isp_bw_margin_pct = <25>;
		modules {
			cam_module0: module0 {
				status = "okay";
				badge = "e3326_left_ov10635";
				position = "rear";
				orientation = "1";
				cam_module0_drivernode0: drivernode0 {
					status = "okay";
					/* Declare PCL support driver (classically known as guid)  */
					pcl_id = "v4l2_sensor";
					/* Driver v4l2 device name */
					devname = "ov10635 1-0040";
					/* Declare the device-tree hierarchy to driver instance */
					proc-device-tree = "/proc/device-tree/i2c@3180000/ov10635_c@40";
				};
				cam_module0_drivernode1: drivernode1 {
					status = "okay";
					pcl_id = "v4l2_focuser_stub";
					proc-device-tree = "/proc/device-tree/e3326_focuser_ov10635@P5V27C/";
				};
			};
			cam_module1: module1 {
				status = "disabled";
				cam_module1_drivernode0: drivernode0 {
					status = "disabled";
				};
				cam_module1_drivernode1: drivernode1 {
					status = "disabled";
					pcl_id = "v4l2_focuser_stub";
				};
			};
			cam_module2: module2 {
				status = "disabled";
				cam_module2_drivernode0: drivernode0 {
					status = "disabled";
				};
				cam_module2_drivernode1: drivernode1 {
					status = "disabled";
					pcl_id = "v4l2_focuser_stub";
				};
			};
		};
	};
};

My image camera sensor driver:

/*
 * ov10635.c - ov10635 sensor driver
 *
 * Copyright (c) 2016, 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 <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/camera_common.h>
#include <media/ov10635.h>

#include "ov10635_mode_tbls.h"

#define OV10635_SC_CHIP_ID_HIGH_ADDR	0x300A
#define OV10635_SC_CHIP_ID_LOW_ADDR	0x300B
#define OV10635_SC_SCCB_ID_ADDR		0x300C



/* Register definitions */
#define	OV10635_VFLIP			0x381c
#define	 OV10635_VFLIP_ON		(0x3 << 6)
#define	 OV10635_VFLIP_SUBSAMPLE	0x1
#define	OV10635_HMIRROR			0x381d
#define	 OV10635_HMIRROR_ON		0x3

/* IDs */
#define OV10635_VERSION_REG		0xa635

#define OV10635_DEFAULT_MODE		OV10635_MODE_1280x720
#define OV10635_DEFAULT_WIDTH		1280
#define OV10635_DEFAULT_HEIGHT		720
#define OV10635_DEFAULT_DATAFMT		MEDIA_BUS_FMT_UYVY8_1X16
#define OV10635_DEFAULT_CLK_FREQ	26000000

#define OV10635_DEFAULT_I2C_ADDRESS		(0x30 >> 1)

#define CAM1_RSTN 148 //219	/* TEGRA_GPIO_PBB3 */
#define CAM1_PWDN 151 //221	/* TEGRA_GPIO_PBB5 */

struct ov10635 {
	struct camera_common_power_rail	power;
	int				num_ctrls;
	bool				master;
	int				cam_sid_gpio;
	int				mcu_boot_gpio;
	int				mcu_reset_gpio;
	struct v4l2_ctrl_handler	ctrl_handler;
	struct i2c_client		*i2c_client;
	struct v4l2_subdev		*subdev;
	struct media_pad		pad;

	s32				group_hold_prev;
	bool				group_hold_en;
	struct regmap			*regmap;
	struct camera_common_data	*s_data;
	struct camera_common_pdata	*pdata;
	struct v4l2_ctrl		*ctrls[];
};

static const struct regmap_config sensor_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
	.cache_type = REGCACHE_RBTREE,
};

static int ov10635_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
static int ov10635_s_ctrl(struct v4l2_ctrl *ctrl);

static const struct v4l2_ctrl_ops ov10635_ctrl_ops = {
	.g_volatile_ctrl = ov10635_g_volatile_ctrl,
	.s_ctrl		= ov10635_s_ctrl,
};

static struct v4l2_ctrl_config ctrl_config_list[] = {
/* Do not change the name field for the controls! */
	{
		.ops = &ov10635_ctrl_ops,
		.id = V4L2_CID_VFLIP,
		.name = "VFlip",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.flags = V4L2_CTRL_FLAG_SLIDER,
		.min = 0,
		.max = 1,
		.def = 0,
		.step = 1,
	},
	{
		.ops = &ov10635_ctrl_ops,
		.id = V4L2_CID_HFLIP,
		.name = "HFlip",
		.type = V4L2_CTRL_TYPE_INTEGER,
		.flags = V4L2_CTRL_FLAG_SLIDER,
		.min = 0,
		.max = 1,
		.def = 0,
		.step = 1,
	},
};

static inline int ov10635_read_reg(struct camera_common_data *s_data,
				u16 addr, u8 *val)
{
	struct ov10635 *priv = (struct ov10635 *)s_data->priv;
	unsigned int temp_val;
	int err;

	err = regmap_read(priv->regmap, addr, &temp_val);
	if (!err)
		*val = temp_val;

	return err;
}

static int ov10635_write_reg(struct camera_common_data *s_data,
		u16 addr, u8 val)
{
	int err;
	struct ov10635 *priv = (struct ov10635 *)s_data->priv;

	err = regmap_write(priv->regmap, addr, val);
	if (err)
		pr_err("[vunguyen] %s:i2c write failed, %x = %x\n",
			__func__, addr, val);

	return err;
}

/* Read a register, alter its bits, write it back */
static int ov10635_rmw_reg(struct camera_common_data *s_data, u16 addr, u8 set, u8 unset)

{
	int err;
	u8 val = 0;

	err = ov10635_read_reg(s_data, addr, &val);
	if (err)
		pr_err("[vunguyen] %s:i2c read failed, %x = %x\n",
			__func__, addr, val);

	val |= set;
	val &= ~unset;

	err = ov10635_write_reg(s_data, addr, val);
	if (err)
		pr_err("[vunguyen] %s:i2c write failed, %x = %x\n",
			__func__, addr, val);
			
	return err;
}

static int ov10635_write_table(struct ov10635 *priv,
				const ov10635_reg table[])
{
	return regmap_util_write_table_8(priv->regmap,
					 table,
					 NULL, 0,
					 OV10635_TABLE_WAIT_MS,
					 OV10635_TABLE_END);
}

static int ov10635_reset_sensor(void)
{
	int err;
	pr_err("[vunguyen] %s !! [+]\n", __func__);

	err = gpio_request(CAM1_RSTN, "CAM0_RST");
	if (err) {
		pr_err("[vunguyen] %s %d ERROR !!!\n", __func__, __LINE__);
	}

	gpio_direction_output(CAM1_RSTN, 1);
	gpio_set_value(CAM1_RSTN, 1);
	msleep(600);

	gpio_set_value(CAM1_RSTN, 0);
	msleep(600);
	
	gpio_set_value(CAM1_RSTN, 1);

	pr_err("[vunguyen] %s [-]\n", __func__);

	return 0;
}


static int ov10635_power_on(struct camera_common_data *s_data)
{
	int err = 0;
	struct ov10635 *priv = (struct ov10635 *)s_data->priv;
	struct camera_common_power_rail *pw = &priv->power;

	dev_dbg(&priv->i2c_client->dev, "%s: power on\n", __func__);

	if (priv->pdata->power_on) {
		err = priv->pdata->power_on(pw);
		if (err)
			pr_err("%s failed.\n", __func__);
		else
			pw->state = SWITCH_ON;
		return err;
	}

	usleep_range(5350, 5360);
	pw->state = SWITCH_ON;
	return 0;
}

static int ov10635_power_off(struct camera_common_data *s_data)
{
	int err = 0;
	struct ov10635 *priv = (struct ov10635 *)s_data->priv;
	struct camera_common_power_rail *pw = &priv->power;

	dev_dbg(&priv->i2c_client->dev, "%s: power off\n", __func__);
	ov10635_write_table(priv, mode_table[OV10635_MODE_STOP_STREAM]);

	if (priv->pdata->power_off) {
		err = priv->pdata->power_off(pw);
		if (err)
			pr_err("%s failed.\n", __func__);
		else
			goto power_off_done;
	}

	return err;

power_off_done:
	pw->state = SWITCH_OFF;
	return 0;
}

static int ov10635_power_put(struct ov10635 *priv)
{
	return 0;
}

static int ov10635_power_get(struct ov10635 *priv)
{
	struct camera_common_power_rail *pw = &priv->power;
	const char *mclk_name;
	int err = 0;

	//mclk_name = priv->pdata->mclk_name ?
	//	    priv->pdata->mclk_name : "cam_mclk1";
	mclk_name = "default_mclk";
	pw->mclk = devm_clk_get(&priv->i2c_client->dev, mclk_name);
	if (IS_ERR(pw->mclk)) {
		dev_err(&priv->i2c_client->dev,
			"unable to get clock %s\n", mclk_name);
		return PTR_ERR(pw->mclk);
	}

	/* ananlog 2.7v */
	//pw->avdd = devm_regulator_get(&priv->i2c_client->dev, "vana");
	pw->avdd = regulator_get(NULL, "vana");
	if (IS_ERR(pw->avdd)) {
		err = PTR_ERR(pw->avdd);
		pw->avdd = NULL;
		dev_err(&priv->i2c_client->dev, "Failed to get regulator vana\n");
		return err;
	}

	/* digital 1.2v */
	//pw->dvdd = devm_regulator_get(&priv->i2c_client->dev, "vdig");
	pw->dvdd = regulator_get(NULL, "vdig");
	if (IS_ERR(pw->dvdd)) {
		err = PTR_ERR(pw->dvdd);
		pw->dvdd = NULL;
		dev_err(&priv->i2c_client->dev, "Failed to get regulator vdig\n");
		return err;
	}

	/* IO 1.8v */
	//pw->iovdd = devm_regulator_get(&priv->i2c_client->dev, "vif");
	pw->iovdd = regulator_get(NULL, "vif");
	if (IS_ERR(pw->iovdd)) {
		err = PTR_ERR(pw->iovdd);
		pw->iovdd = NULL;
		dev_err(&priv->i2c_client->dev, "Failed to get regulator vif\n");
		return err;
	}
	
	pw->state = SWITCH_OFF;
	return err;
}

static int ov10635_verify_chip_id(struct ov10635 *priv)
{
	struct i2c_client *client = priv->i2c_client;
	struct camera_common_data *s_data = priv->s_data;
	u8 chip_id_hi, chip_id_lo;
	u16 chip_id;
	int err;

	err = camera_common_s_power(priv->subdev, true);
	if (err)
		return -ENODEV;

	err = ov10635_read_reg(s_data, OV10635_SC_CHIP_ID_HIGH_ADDR,
			       &chip_id_hi);
	if (err) {
		dev_err(&client->dev, "Failed to read chip ID\n");
		return err;
	}
	err = ov10635_read_reg(s_data, OV10635_SC_CHIP_ID_LOW_ADDR,
			       &chip_id_lo);
	if (err) {
		dev_err(&client->dev, "Failed to read chip ID\n");
		return err;
	}

	chip_id = (chip_id_hi << 8) | chip_id_lo;
	if (chip_id != OV10635_VERSION_REG) {
		dev_err(&client->dev, "Read unknown chip ID 0x%04x\n", chip_id);
		return -EINVAL;
	}

	err = camera_common_s_power(priv->subdev, false);
	if (err)
		return -ENODEV;

	return 0;
}

static int ov10635_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct camera_common_data *s_data = to_camera_common_data(client);
	int err;
	
	err =  ov10635_write_reg(s_data, 0x0100, enable);
	if (err)
		goto exit;

	return 0;
exit:
	dev_dbg(&client->dev, "%s: error setting stream\n", __func__);
	return err;
}

static int ov10635_g_input_status(struct v4l2_subdev *sd, u32 *status)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct camera_common_data *s_data = to_camera_common_data(client);
	struct ov10635 *priv = (struct ov10635 *)s_data->priv;
	struct camera_common_power_rail *pw = &priv->power;

	*status = pw->state == SWITCH_ON;
	return 0;
}

static struct v4l2_subdev_video_ops ov10635_subdev_video_ops = {
	.s_stream	= ov10635_s_stream,
	.g_mbus_config	= camera_common_g_mbus_config,
	.g_input_status = ov10635_g_input_status,
};

static struct v4l2_subdev_core_ops ov10635_subdev_core_ops = {
	.s_power	= camera_common_s_power,
};

static int ov10635_get_fmt(struct v4l2_subdev *sd,
		struct v4l2_subdev_pad_config *cfg,
		struct v4l2_subdev_format *format)
{
	return camera_common_g_fmt(sd, &format->format);
}

static int ov10635_set_fmt(struct v4l2_subdev *sd,
		struct v4l2_subdev_pad_config *cfg,
		struct v4l2_subdev_format *format)
{
	int ret;

	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
		ret = camera_common_try_fmt(sd, &format->format);
	else
		ret = camera_common_s_fmt(sd, &format->format);

	return ret;
}

static struct v4l2_subdev_pad_ops ov10635_subdev_pad_ops = {
	.set_fmt = ov10635_set_fmt,
	.get_fmt = ov10635_get_fmt,
	.enum_mbus_code = camera_common_enum_mbus_code,
	.enum_frame_size	= camera_common_enum_framesizes,
	.enum_frame_interval	= camera_common_enum_frameintervals,
};

static struct v4l2_subdev_ops ov10635_subdev_ops = {
	.core	= &ov10635_subdev_core_ops,
	.video	= &ov10635_subdev_video_ops,
	.pad	= &ov10635_subdev_pad_ops,
};

static struct of_device_id ov10635_of_match[] = {
	{ .compatible = "nvidia,ov10635", },
	{ },
};

static struct camera_common_sensor_ops ov10635_common_ops = {
	.power_on = ov10635_power_on,
	.power_off = ov10635_power_off,
	.write_reg = ov10635_write_reg,
	.read_reg = ov10635_read_reg,
};

static int ov10635_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
	struct ov10635 *priv =
		container_of(ctrl->handler, struct ov10635, ctrl_handler);
	int err = 0;

	if (priv->power.state == SWITCH_OFF)
		return 0;

	switch (ctrl->id) {
	default:
			pr_err("%s: unknown ctrl id.\n", __func__);
			return -EINVAL;
	}

	return err;
}

static int ov10635_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct ov10635 *priv =
		container_of(ctrl->handler, struct ov10635, ctrl_handler);
	int err = 0;

	if (priv->power.state == SWITCH_OFF)
		return 0;

	switch (ctrl->id) {
	case V4L2_CID_VFLIP:
		if (ctrl->val)
			return ov10635_rmw_reg(priv->s_data, OV10635_VFLIP, OV10635_VFLIP_ON, 0);
		else
			return ov10635_rmw_reg(priv->s_data, OV10635_VFLIP, 0, OV10635_VFLIP_ON);
		break;
	case V4L2_CID_HFLIP:
		if (ctrl->val)
			return ov10635_rmw_reg(priv->s_data, OV10635_HMIRROR, OV10635_HMIRROR_ON, 0);
		else
			return ov10635_rmw_reg(priv->s_data, OV10635_HMIRROR, 0, OV10635_HMIRROR_ON);
		break;
	default:
		pr_err("%s: unknown ctrl id.\n", __func__);
		return -EINVAL;
	}

	return err;
}

static int ov10635_ctrls_init(struct ov10635 *priv)
{
	struct i2c_client *client = priv->i2c_client;
	struct v4l2_ctrl *ctrl;
	int num_ctrls;
	int err;
	int i;

	dev_dbg(&client->dev, "%s++\n", __func__);

	num_ctrls = ARRAY_SIZE(ctrl_config_list);
	v4l2_ctrl_handler_init(&priv->ctrl_handler, num_ctrls);

	for (i = 0; i < num_ctrls; i++) {
		ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler,
			&ctrl_config_list[i], NULL);
		if (ctrl == NULL) {
			dev_err(&client->dev, "Failed to init %s ctrl\n",
				ctrl_config_list[i].name);
			continue;
		}

		if (ctrl_config_list[i].type == V4L2_CTRL_TYPE_STRING &&
			ctrl_config_list[i].flags & V4L2_CTRL_FLAG_READ_ONLY) {
			ctrl->p_new.p_char = devm_kzalloc(&client->dev,
				ctrl_config_list[i].max + 1, GFP_KERNEL);
		}
		priv->ctrls[i] = ctrl;
	}

	priv->num_ctrls = num_ctrls;
	priv->subdev->ctrl_handler = &priv->ctrl_handler;
	if (priv->ctrl_handler.error) {
		dev_err(&client->dev, "Error %d adding controls\n",
			priv->ctrl_handler.error);
		err = priv->ctrl_handler.error;
		goto error;
	}

	err = v4l2_ctrl_handler_setup(&priv->ctrl_handler);
	if (err) {
		dev_err(&client->dev,
			"Error %d setting default controls\n", err);
		goto error;
	}

	return 0;

error:
	v4l2_ctrl_handler_free(&priv->ctrl_handler);
	return err;
}

MODULE_DEVICE_TABLE(of, ov10635_of_match);

static struct camera_common_pdata *ov10635_parse_dt(struct i2c_client *client)
{
	struct device_node *node = client->dev.of_node;
	struct camera_common_pdata *board_priv_pdata;
	const struct of_device_id *match;
	int gpio;
	int err;
	struct camera_common_pdata *ret = NULL;

	if (!node)
		return NULL;

	match = of_match_device(ov10635_of_match, &client->dev);
	if (!match) {
		dev_err(&client->dev, "Failed to find matching dt id\n");
		return NULL;
	}

	board_priv_pdata = devm_kzalloc(&client->dev,
			   sizeof(*board_priv_pdata), GFP_KERNEL);
	if (!board_priv_pdata)
		return NULL;

	err = camera_common_parse_clocks(client, board_priv_pdata);
	if (err) {
		dev_err(&client->dev, "Failed to find clocks\n");
		goto error;
	}

	gpio = of_get_named_gpio(node, "pwdn-gpios", 0);
	if (gpio < 0) {
		if (gpio == -EPROBE_DEFER) {
			ret = ERR_PTR(-EPROBE_DEFER);
			goto error;
		}
		dev_err(&client->dev, "pwdn gpios not in DT\n");
		goto error;
	}
	board_priv_pdata->pwdn_gpio = (unsigned int)gpio;

	gpio = of_get_named_gpio(node, "reset-gpios", 0);
	if (gpio < 0) {
		/* reset-gpio is not absolutely needed */
		if (gpio == -EPROBE_DEFER) {
			ret = ERR_PTR(-EPROBE_DEFER);
			goto error;
		}
		dev_dbg(&client->dev, "reset gpios not in DT\n");
		gpio = 0;
	}
	board_priv_pdata->reset_gpio = (unsigned int)gpio;

	board_priv_pdata->use_cam_gpio =
		of_property_read_bool(node, "cam,use-cam-gpio");

	err = of_property_read_string(node, "avdd-reg",
			&board_priv_pdata->regulators.avdd);
	if (err) {
		dev_err(&client->dev, "avdd-reg not in DT\n");
		goto error;
	}
	err = of_property_read_string(node, "iovdd-reg",
			&board_priv_pdata->regulators.iovdd);
	if (err) {
		dev_err(&client->dev, "iovdd-reg not in DT\n");
		goto error;
	}

	board_priv_pdata->has_eeprom =
		of_property_read_bool(node, "has-eeprom");
	board_priv_pdata->v_flip= of_property_read_bool(node, "vertical-flip");
	board_priv_pdata->h_mirror = of_property_read_bool(node,
							 "horizontal-mirror");
	return board_priv_pdata;

error:
	devm_kfree(&client->dev, board_priv_pdata);
	return ret;
}

static int ov10635_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	dev_dbg(&client->dev, "%s:\n", __func__);

	return 0;
}

static const struct v4l2_subdev_internal_ops ov10635_subdev_internal_ops = {
	.open = ov10635_open,
};

static const struct media_entity_operations ov10635_media_ops = {
	.link_validate = v4l2_subdev_link_validate,
};

static int ov10635_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct camera_common_data *common_data;
	struct ov10635 *priv;
	char dev_name[10];
	int err;

	pr_info("[OV10635]: probing v4l2 sensor.\n");
	pr_err("[VuNguyen] %s %d\n", __func__, __LINE__);

	common_data = devm_kzalloc(&client->dev,
			    sizeof(struct camera_common_data), GFP_KERNEL);

	priv = devm_kzalloc(&client->dev,
			sizeof(struct ov10635) + sizeof(struct v4l2_ctrl *) *
			ARRAY_SIZE(ctrl_config_list),
			GFP_KERNEL);
	if (!priv) {
		dev_err(&client->dev, "unable to allocate memory!\n");
		return -ENOMEM;
	}
	pr_err("[VuNguyen] %s %d\n", __func__, __LINE__);
	priv->regmap = devm_regmap_init_i2c(client, &sensor_regmap_config);
	if (IS_ERR(priv->regmap)) {
		dev_err(&client->dev,
			"regmap init failed: %ld\n", PTR_ERR(priv->regmap));
		return -ENODEV;
	}
	pr_err("[VuNguyen] %s %d\n", __func__, __LINE__);
	
	priv->pdata = ov10635_parse_dt(client);
	if (PTR_ERR(priv->pdata) == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	if (!priv->pdata) {
		dev_err(&client->dev, "unable to get platform data\n");
		return -EFAULT;
	}

	common_data->ops		= &ov10635_common_ops;
	common_data->ctrl_handler	= &priv->ctrl_handler;
	common_data->i2c_client		= client;
	common_data->frmfmt		= ov10635_frmfmt;
	common_data->colorfmt		= camera_common_find_datafmt(
					  OV10635_DEFAULT_DATAFMT);
	common_data->power		= &priv->power;
	common_data->ctrls		= priv->ctrls;
	common_data->priv		= (void *)priv;
	common_data->numctrls		= ARRAY_SIZE(ctrl_config_list);
	common_data->numfmts		= ARRAY_SIZE(ov10635_frmfmt);
	common_data->def_mode		= OV10635_DEFAULT_MODE;
	common_data->def_width		= OV10635_DEFAULT_WIDTH;
	common_data->def_height		= OV10635_DEFAULT_HEIGHT;
	common_data->def_clk_freq	= OV10635_DEFAULT_CLK_FREQ;
	common_data->fmt_width		= common_data->def_width;
	common_data->fmt_height		= common_data->def_height;

	priv->i2c_client		= client;
	priv->s_data			= common_data;
	priv->subdev			= &common_data->subdev;
	priv->subdev->dev		= &client->dev;
	priv->group_hold_prev		= 0;

	err = ov10635_power_get(priv);
	if (err)
		return err;

	/*
	 * If our device tree node is given MCU GPIOs, then we are expected to
	 * reset the MCU.
	 */
	if (gpio_is_valid(priv->mcu_boot_gpio) &&
	    gpio_is_valid(priv->mcu_reset_gpio)) {
		dev_info(&client->dev, "Resetting MCU\n");
		gpio_set_value(priv->mcu_boot_gpio, 0);
		gpio_set_value(priv->mcu_reset_gpio, 0);
		msleep_range(1);
		gpio_set_value(priv->mcu_reset_gpio, 1);
	}
	pr_err("[VuNguyen] %s %d\n", __func__, __LINE__);
	err = camera_common_parse_ports(client, common_data);
	if (err) {
		dev_err(&client->dev, "Failed to find port info\n");
		return err;
	}
	sprintf(dev_name, "ov10635_%c", common_data->csi_port + 'a');
	dev_dbg(&client->dev, "%s: name %s\n", __func__, dev_name);
	camera_common_create_debugfs(common_data, dev_name);
	pr_err("[VuNguyen] %s %d\n", __func__, __LINE__);
	ov10635_reset_sensor();

	v4l2_i2c_subdev_init(&common_data->subdev, client,
			     &ov10635_subdev_ops);

	err = ov10635_ctrls_init(priv);
	if (err)
		return err;

	err = ov10635_verify_chip_id(priv);
	if (err)
		return err;
	
	/*Write default registers*/	
	err = ov10635_write_table(priv, mode_table[OV10635_MODE_1280x720]);
	if (err)
		return err;
		
	pr_err("[VuNguyen] %s %d\n", __func__, __LINE__);
	priv->subdev->internal_ops = &ov10635_subdev_internal_ops;
	priv->subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
		     V4L2_SUBDEV_FL_HAS_EVENTS;

#if defined(CONFIG_MEDIA_CONTROLLER)
	priv->pad.flags = MEDIA_PAD_FL_SOURCE;
	priv->subdev->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
	priv->subdev->entity.ops = &ov10635_media_ops;
	err = media_entity_init(&priv->subdev->entity, 1, &priv->pad, 0);
	if (err < 0) {
		dev_err(&client->dev, "unable to init media entity\n");
		return err;
	}
#endif
	pr_err("[VuNguyen] %s %d\n", __func__, __LINE__);
	err = v4l2_async_register_subdev(priv->subdev);
	if (err)
		return err;

	dev_info(&client->dev, "Detected OV10635 sensor\n");

	return 0;
}

static int
ov10635_remove(struct i2c_client *client)
{
	struct camera_common_data *s_data = to_camera_common_data(client);
	struct ov10635 *priv = (struct ov10635 *)s_data->priv;

	v4l2_async_unregister_subdev(priv->subdev);
#if defined(CONFIG_MEDIA_CONTROLLER)
	media_entity_cleanup(&priv->subdev->entity);
#endif
	v4l2_ctrl_handler_free(&priv->ctrl_handler);
	ov10635_power_put(priv);
	camera_common_remove_debugfs(s_data);

	return 0;
}

static const struct i2c_device_id ov10635_id[] = {
	{ "ov10635", 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, ov10635_id);

static struct i2c_driver ov10635_i2c_driver = {
	.driver = {
		.name = "ov10635",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(ov10635_of_match),
	},
	.probe = ov10635_probe,
	.remove = ov10635_remove,
	.id_table = ov10635_id,
};

module_i2c_driver(ov10635_i2c_driver);

MODULE_DESCRIPTION("SoC Camera driver for Omnivison OV10635");
MODULE_AUTHOR("NVIDIA Corporation");
MODULE_LICENSE("GPL v2");

But look like it can not invoke “ov10635_probe” function.

Please check the /proc/device-tree/tegra-camera-platform/ is change exactly as your modify.

My result:

more /proc/device-tree/i2c@3180000/ov10635_c@40/compatible
nvidia,ov10635

I think dtb file is modified exactly.

Please check

ls /proc/device-tree/tegra-camera-platform/modules/

cat /proc/device-tree/tegra-camera-platform/modules/module*/drivernode0/proc-device-tree

There are results:

ls /proc/device-tree/tegra-camera-platform/modules/
module0  module1  module2  module3  module4  module5  name
/proc/device-tree/tegra-camera-platform/modules/module0/drivernode0/proc-device-tree
::::::::::::::
/proc/device-tree/i2c@3180000/ov10635_c@40
::::::::::::::
/proc/device-tree/tegra-camera-platform/modules/module1/drivernode0/proc-device-tree
::::::::::::::
/proc/device-tree/i2c@3180000/tca9548@77/i2c@1/imx219_b@10
::::::::::::::
/proc/device-tree/tegra-camera-platform/modules/module2/drivernode0/proc-device-tree
::::::::::::::
/proc/device-tree/i2c@3180000/tca9548@77/i2c@2/imx219_c@10
::::::::::::::
/proc/device-tree/tegra-camera-platform/modules/module3/drivernode0/proc-device-tree
::::::::::::::
/proc/device-tree/i2c@3180000/tca9548@77/i2c@3/imx219_d@10
::::::::::::::
/proc/device-tree/tegra-camera-platform/modules/module4/drivernode0/proc-device-tree
::::::::::::::
/proc/device-tree/i2c@3180000/tca9548@77/i2c@4/imx219_e@10
::::::::::::::
/proc/device-tree/tegra-camera-platform/modules/module5/drivernode0/proc-device-tree
::::::::::::::
/proc/device-tree/i2c@3180000/tca9548@77/i2c@5/imx219_f@10

Thanks

Looks like your DT no quite correct to include the imx219 while disable the plugin manager.

Because I have to include this file

#include "t18x-common-platforms/tegra186-quill-camera-e3322-a00.dtsi"

in my camera dts.

If I didn’t include, system will be hang at here:

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x100
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 4.4.38 (vu@vu-desktop) (gcc version 4.8.2 (GCC) ) #2 SMP PREEMPT Tue Aug 8 10:35:22 KST 2017
[    0.000000] Boot CPU: AArch64 Processor [411fd073]
[    0.000000] earlycon: Early serial console at MMIO32 0x3100000 (options '')
[    0.000000] bootconsole [uart0] enabled
[    0.000000] Reserved memory: initialized node ramoops_carveout, compatible id nvidia,ramoops
[    0.000000] cma: Reserved 64 MiB at 0x00000000fc000000
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.0 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] PERCPU: Embedded 17 pages/cpu @ffffffc1f5d3f000 s31232 r8192 d30208 u69632
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 2018947
[    0.000000] Kernel command line: root=/dev/mmcblk0p1 rw rootwait console=ttyS0,115200n8 console=tty0 OS=l4t fbcon=map:0 net.ifnames=0 memtype=0 video=tegrafb no_console_suspend=1 earlycon=uart8250,mmio32,0x03100000 nvdumper_reserved=0x2772e0000 gpt tegraid=18.1.2.0.0 tegra_keep_boot_clocks maxcpus=6 androidboot.serialno=0321017053548 bl_prof_dataptr=0x10000@0x277240000 sdhci_tegra.en_boot_part_access=1 root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes)
[    0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes)
[    0.000000] Memory: 7972912K/8204288K available (10844K kernel code, 1767K rwdata, 5656K rodata, 1156K init, 679K bss, 165840K reserved, 65536K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vmalloc : 0xffffff8000000000 - 0xffffffbdbfff0000   (   246 GB)
[    0.000000]     vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000   (     8 GB maximum)
[    0.000000]               0xffffffbdc2000000 - 0xffffffbdc9d7c400   (   125 MB actual)
[    0.000000]     fixed   : 0xffffffbffa7fd000 - 0xffffffbffac00000   (  4108 KB)
[    0.000000]     PCI I/O : 0xffffffbffae00000 - 0xffffffbffbe00000   (    16 MB)
[    0.000000]     modules : 0xffffffbffc000000 - 0xffffffc000000000   (    64 MB)
[    0.000000]     memory  : 0xffffffc000000000 - 0xffffffc1f5f10000   (  8031 MB)
[    0.000000]       .init : 0xffffffc00109e000 - 0xffffffc0011bf000   (  1156 KB)
[    0.000000]       .text : 0xffffffc000080000 - 0xffffffc00109e000   ( 16504 KB)
[    0.000000]       .data : 0xffffffc0011e0000 - 0xffffffc001399c98   (  1768 KB)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=6, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] 	Build-time adjustment of leaf fanout to 64.
[    0.000000] 	RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=6.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=64, nr_cpu_ids=6
[    0.000000] NR_IRQS:64 nr_irqs:64 0
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] Architected cp15 timer(s) running at 31.25MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xe6a171046, max_idle_ns: 881590405314 ns
[    0.000002] sched_clock: 56 bits at 31MHz, resolution 32ns, wraps every 4398046511088ns
[    0.009630] Console: colour dummy device 80x25
[    0.014285] console [tty0] enabled
[    0.017840] bootconsole [uart0] disabled

Thanks

Update:
In this file “t18x-common-platforms/tegra186-quill-camera-e3322-a00.dtsi” I commented this line

/*#include <t18x-common-modules/tegra186-camera-e3322-a00.dtsi>*/

Now my camera driver is probed but still does something wrong in the driver.
May need your help in the further problem.

Hi ShaneCCC,

Because I use MAX9288 as deserialize so I have to set the configuration for MAX9288 first and then set configuration for OV10635 camera image sensor. Both are set through I2C commands.

I had created struct for OV10635 as this

struct ov10635 {
	struct camera_common_power_rail	power;
	int				num_ctrls;
	bool				master;
	int				cam_sid_gpio;
	int				mcu_boot_gpio;
	int				mcu_reset_gpio;
	struct v4l2_ctrl_handler	ctrl_handler;
	struct i2c_client		*i2c_client;
	struct v4l2_subdev		*subdev;
	struct media_pad		pad;

	s32				group_hold_prev;
	bool				group_hold_en;
	struct regmap			*regmap;
	struct camera_common_data	*s_data;
	struct camera_common_pdata	*pdata;
	struct v4l2_ctrl		*ctrls[];
};

and initialized in probe function

priv->regmap = devm_regmap_init_i2c(client, &sensor_regmap_config);

The address of I2C has been fixed in dtb. How can I send I2C commands to MAX9288 because it has different I2C address?

I used i2cdetect tool to detect some devices on bus. So we have 9 i2c bus as total (from 0 - 8). How can I define which i2c bus that one device should be on it in device tree? I saw some strings like this?

i2c@3180000

Is there any relation to i2c bus number?

Thanks

@forever
You may consider to use the i2c_transfer() in your OV10635 power on function to initial the MAX9288

1 Like

Hi ShaneCCC,

Now I can communicate with MAX9288 by i2c_smbus_read_byte_data() and i2c_smbus_write_byte_data() functions. I verified by reading identifier of MAX9288.

But I can not communicate with serialize (MAX9271) and OV10635 as the same MAX9288 way with different I2C address.

I also can detect only MAX9288 at address 0x48 with “i2cdetect” command. MAX9271 and OV10635 can not be detected.

Do you have any recommendation.

Thanks,
Vu Nguyen

Updated:

Now I can communicate with both MAX9271 and OV10635. Everything almost done but I still can not get data from camera.

There are some testing results :

v4l2-ctl --all
Driver Info (not using libv4l2):
	Driver name   : tegra-video
	Card type     : vi-output, ov10635 2-0030
	Bus info      : platform:15700000.vi:0
	Driver version: 4.4.38
	Capabilities  : 0x84200001
		Video Capture
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps   : 0x04200001
		Video Capture
		Streaming
		Extended Pix Format
Priority: 2
Video input : 0 (Camera 0: no power)
Format Video Capture:
	Width/Height      : 1280/720
	Pixel Format      : 'UYVY'
	Field             : None
	Bytes per Line    : 2560
	Size Image        : 1843200
	Colorspace        : sRGB
	Transfer Function : Default
	YCbCr Encoding    : Default
	Quantization      : Default
	Flags             : 

User Controls

                          hflip (int)    : min=0 max=1 step=1 default=0 value=0 flags=slider
                          vflip (int)    : min=0 max=1 step=1 default=0 value=0 flags=slider

Camera Controls

                    bypass_mode (intmenu): min=0 max=1 default=0 value=0
                override_enable (intmenu): min=0 max=1 default=0 value=0
                   height_align (int)    : min=1 max=16 step=1 default=1 value=1
                     size_align (intmenu): min=0 max=2 default=0 value=0
               write_isp_format (int)    : min=1 max=1 step=1 default=1 value=1
nvidia@tegra-ubuntu:~$ v4l2-compliance -d /dev/video0 
Driver Info:
	Driver name   : tegra-video
	Card type     : vi-output, ov10635 2-0030
	Bus info      : platform:15700000.vi:0
	Driver version: 4.4.38
	Capabilities  : 0x84200001
		Video Capture
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps   : 0x04200001
		Video Capture
		Streaming
		Extended Pix Format

Compliance test for device /dev/video0 (not using libv4l2):

Required ioctls:
	test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
	test second video open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 1 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Test input 0:

	Control ioctls:
		test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
		test VIDIOC_QUERYCTRL: OK
		test VIDIOC_G/S_CTRL: OK
		test VIDIOC_G/S/TRY_EXT_CTRLS: OK
		test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
		test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
		Standard Controls: 4 Private Controls: 5

	Format ioctls:
		test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
		test VIDIOC_G/S_PARM: OK (Not Supported)
		test VIDIOC_G_FBUF: OK (Not Supported)
		fail: v4l2-test-formats.cpp(427): unknown pixelformat 59565955 for buftype 1
		test VIDIOC_G_FMT: FAIL
		test VIDIOC_TRY_FMT: OK (Not Supported)
		test VIDIOC_S_FMT: OK (Not Supported)
		test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
		test Cropping: OK (Not Supported)
		test Composing: OK (Not Supported)
		fail: v4l2-test-formats.cpp(1406): doioctl(node, VIDIOC_S_FMT, &fmt)
		fail: v4l2-test-formats.cpp(1503): doioctl(node, VIDIOC_S_FMT, &fmt)
		test Scaling: FAIL

	Codec ioctls:
		test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
		test VIDIOC_G_ENC_INDEX: OK (Not Supported)
		test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

	Buffer ioctls:
		test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
		fail: v4l2-test-buffers.cpp(571): q.has_expbuf(node)
		test VIDIOC_EXPBUF: FAIL

Test input 0:

Total: 42, Succeeded: 39, Failed: 3, Warnings: 0
gst-launch-1.0 -v v4l2src device="/dev/video0" ! "video/x-raw,width=1280,height=720,format=(string)UYVY" ! xvimagesink -e
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data flow error.
Additional debug info:
gstbasesrc.c(2948): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming task paused, reason not-negotiated (-4)
EOS on shutdown enabled -- waiting for EOS after Error
Waiting for EOS...

Terminal:
[ 1308.941884] ov10635 2-0030: could not find device ctrl.
[ 1308.947168] ov10635 2-0030: could not find device ctrl.
[ 1308.952428] ov10635 2-0030: could not find device ctrl.

As I checked core.c file, it look like support only this kind of format “MEDIA_BUS_FMT_SRGGB10_1X10”.

Do you have any recommendation.

Thanks

Could you try the v4l2-ctl to get data and check the kernel message.

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=test.raw

This is terminal result

[  114.177813] tegra_mipi_cal 3990000.mipical: Mipi cal timeout,val:108971, lanes:300000
[  114.185744] tegra_mipi_cal 3990000.mipical: MIPI_CAL_CTRL                  0x04 0x2a000010
[  114.194256] tegra_mipi_cal 3990000.mipical: CIL_MIPI_CAL_STATUS            0x0c 0x00108971
[  114.202658] tegra_mipi_cal 3990000.mipical: CIL_MIPI_CAL_STATUS_2          0x10 0x00000000
[  114.211034] tegra_mipi_cal 3990000.mipical: CILA_MIPI_CAL_CONFIG           0x18 0x00200000
[  114.219408] tegra_mipi_cal 3990000.mipical: CILB_MIPI_CAL_CONFIG           0x1c 0x00200000
[  114.227751] tegra_mipi_cal 3990000.mipical: CILC_MIPI_CAL_CONFIG           0x20 0x00000000
[  114.236125] tegra_mipi_cal 3990000.mipical: CILD_MIPI_CAL_CONFIG           0x24 0x00000000
[  114.244436] tegra_mipi_cal 3990000.mipical: CILE_MIPI_CAL_CONFIG           0x28 0x00000000
[  114.252792] tegra_mipi_cal 3990000.mipical: CILF_MIPI_CAL_CONFIG           0x2c 0x00000000
[  114.261087] tegra_mipi_cal 3990000.mipical: DSIA_MIPI_CAL_CONFIG           0x3c 0x00000200
[  114.269418] tegra_mipi_cal 3990000.mipical: DSIB_MIPI_CAL_CONFIG           0x40 0x00000200
[  114.277732] tegra_mipi_cal 3990000.mipical: DSIC_MIPI_CAL_CONFIG           0x44 0x00000200
[  114.286047] tegra_mipi_cal 3990000.mipical: DSID_MIPI_CAL_CONFIG           0x48 0x00000200
[  114.294355] tegra_mipi_cal 3990000.mipical: MIPI_BIAS_PAD_CFG0             0x5c 0x00000000
[  114.302662] tegra_mipi_cal 3990000.mipical: MIPI_BIAS_PAD_CFG1             0x60 0x00000000
[  114.310980] tegra_mipi_cal 3990000.mipical: MIPI_BIAS_PAD_CFG2             0x64 0x00010010
[  114.319295] tegra_mipi_cal 3990000.mipical: DSIA_MIPI_CAL_CONFIG_2         0x68 0x00000002
[  114.327596] tegra_mipi_cal 3990000.mipical: DSIB_MIPI_CAL_CONFIG_2         0x6c 0x00000002
[  114.335897] tegra_mipi_cal 3990000.mipical: DSIC_MIPI_CAL_CONFIG_2         0x74 0x00000002
[  114.344189] tegra_mipi_cal 3990000.mipical: DSID_MIPI_CAL_CONFIG_2         0x78 0x00000002
[  115.349819] tegra-vi4 15700000.vi: PXL_SOF syncpt timeout! err = -11
[  116.353821] tegra-vi4 15700000.vi: PXL_SOF syncpt timeout! err = -11
[  117.357780] tegra-vi4 15700000.vi: PXL_SOF syncpt timeout! err = -11
[  118.361788] tegra-vi4 15700000.vi: PXL_SOF syncpt timeout! err = -11
[  119.365752] tegra-vi4 15700000.vi: ATOMP_FE syncpt timeout!

And the image with size 1843200 KB only green color.

Update:

After correct my dtb, changing “pixel_t” from bayer_bggr to uyvy and try to capture image again

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=test.raw --verbose

This is result :

VIDIOC_QUERYCAP: ok
VIDIOC_REQBUFS: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_STREAMON: failed: Invalid argument

terminal:

[   80.581837] [VuNguyen] ov10635_power_on 435
[   80.590578] [VuNguyen] ov10635_power_off 472
[   94.946954] [VuNguyen] ov10635_power_on 435
[   94.959083] [VuNguyen] ov10635_get_fmt 689
[   94.963229] extract_pixel_format: Need to extend formatuyvy
[   94.968873] ov10635 2-0030: Unsupported pixel format
[   94.973885] ov10635 2-0030: Failed to read image properties
[   94.981304] [VuNguyen] ov10635_power_off 472

So after investigating, I found that extract_pixel_format function in sensor_common.c doesn’t add uyvy type. I modified to support uyvy as below:

static int extract_pixel_format(
	const char *pixel_t, u32 *format)
{
	size_t size = strnlen(pixel_t, OF_MAX_STR_LEN);

	if (strncmp(pixel_t, "bayer_bggr10", size) == 0)
		*format = V4L2_PIX_FMT_SBGGR10;
	else if (strncmp(pixel_t, "bayer_rggb10", size) == 0)
		*format = V4L2_PIX_FMT_SRGGB10;
	else if (strncmp(pixel_t, "bayer_bggr12", size) == 0)
		*format = V4L2_PIX_FMT_SBGGR12;
	else if (strncmp(pixel_t, "bayer_rggb12", size) == 0)
		*format = V4L2_PIX_FMT_SRGGB12;
	else if (strncmp(pixel_t, "bayer_wdr_pwl_rggb12", size) == 0)
		*format = V4L2_PIX_FMT_SRGGB12;
	else if (strncmp(pixel_t, "bayer_xbggr10p", size) == 0)
		*format = V4L2_PIX_FMT_XBGGR10P;
	else if (strncmp(pixel_t, "bayer_xrggb10p", size) == 0)
		*format = V4L2_PIX_FMT_XRGGB10P;
	else if (strncmp(pixel_t, "uyvy", size) == 0)
		*format = V4L2_PIX_FMT_UYVY;
	else {
		pr_err("%s: Need to extend format%s\n", __func__, pixel_t);
		return -EINVAL;
	}

	return 0;
}

Then I take picture again with v4l2-ctl

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=test.raw --verbose

Unsupported pixel format issue disappeared but SOF time out still be there.

[  457.500365] [VuNguyen] ov10635_power_on 435
[  457.513557] [VuNguyen] ov10635_get_fmt 689
[  458.017818] tegra_mipi_cal 3990000.mipical: Mipi cal timeout,val:108971, lanes:300000
[  458.025988] tegra_mipi_cal 3990000.mipical: MIPI_CAL_CTRL                  0x04 0x2a000010
[  458.034632] tegra_mipi_cal 3990000.mipical: CIL_MIPI_CAL_STATUS            0x0c 0x00108971
[  458.043327] tegra_mipi_cal 3990000.mipical: CIL_MIPI_CAL_STATUS_2          0x10 0x00000000
[  458.051868] tegra_mipi_cal 3990000.mipical: CILA_MIPI_CAL_CONFIG           0x18 0x00200000
[  458.060346] tegra_mipi_cal 3990000.mipical: CILB_MIPI_CAL_CONFIG           0x1c 0x00200000
[  458.068715] tegra_mipi_cal 3990000.mipical: CILC_MIPI_CAL_CONFIG           0x20 0x00000000
[  458.077071] tegra_mipi_cal 3990000.mipical: CILD_MIPI_CAL_CONFIG           0x24 0x00000000
[  458.085390] tegra_mipi_cal 3990000.mipical: CILE_MIPI_CAL_CONFIG           0x28 0x00000000
[  458.093740] tegra_mipi_cal 3990000.mipical: CILF_MIPI_CAL_CONFIG           0x2c 0x00000000
[  458.102090] tegra_mipi_cal 3990000.mipical: DSIA_MIPI_CAL_CONFIG           0x3c 0x00000200
[  458.110415] tegra_mipi_cal 3990000.mipical: DSIB_MIPI_CAL_CONFIG           0x40 0x00000200
[  458.118722] tegra_mipi_cal 3990000.mipical: DSIC_MIPI_CAL_CONFIG           0x44 0x00000200
[  458.127026] tegra_mipi_cal 3990000.mipical: DSID_MIPI_CAL_CONFIG           0x48 0x00000200
[  458.135337] tegra_mipi_cal 3990000.mipical: MIPI_BIAS_PAD_CFG0             0x5c 0x00000000
[  458.143645] tegra_mipi_cal 3990000.mipical: MIPI_BIAS_PAD_CFG1             0x60 0x00000000
[  458.151964] tegra_mipi_cal 3990000.mipical: MIPI_BIAS_PAD_CFG2             0x64 0x00010010
[  458.160273] tegra_mipi_cal 3990000.mipical: DSIA_MIPI_CAL_CONFIG_2         0x68 0x00000002
[  458.168575] tegra_mipi_cal 3990000.mipical: DSIB_MIPI_CAL_CONFIG_2         0x6c 0x00000002
[  458.176870] tegra_mipi_cal 3990000.mipical: DSIC_MIPI_CAL_CONFIG_2         0x74 0x00000002
[  458.185165] tegra_mipi_cal 3990000.mipical: DSID_MIPI_CAL_CONFIG_2         0x78 0x00000002
[  458.193487] [VuNguyen] ov10635_s_stream 653, status = 1
[  459.197591] tegra-vi4 15700000.vi: PXL_SOF syncpt timeout! err = -11
[  460.201430] tegra-vi4 15700000.vi: PXL_SOF syncpt timeout! err = -11
[  461.205310] tegra-vi4 15700000.vi: PXL_SOF syncpt timeout! err = -11
[  462.209372] tegra-vi4 15700000.vi: PXL_SOF syncpt timeout! err = -11
[  463.213218] tegra-vi4 15700000.vi: ATOMP_FE syncpt timeout!
[  463.220802] [VuNguyen] ov10635_s_stream 653, status = 0
[  463.227942] tegra-i2c 3180000.i2c: no acknowledge from address 0x30
[  463.276423] [VuNguyen] ov10635_power_off 472

The image has only green color.

Thanks

Hi ShaneCCC,

Currently, I think TX2 kernel does not support YUV camera sensor. Could you please confirm about this and let me know about the time that TX2 kernel can support YUV camera sensor.

Thanks

Could you try to tune this define DEFAULT_THS_SETTLE it’s range is 1 - 0x3f
csi4_registers.h

Hi SaneCCC,

Thank for your recommendation. I will try and update to you soon.