Interfacing IMX377 sensor directly to I2C/CSI

Greetings,

We are currently developing an application that will use 3 IMX377 camera sensors connected directly to Jetson, without the tca9564 and pca9570 ICs.

For this purpose we are using the J140 daughterboard from Auvidea (https://auvidea.com/product/70730/).

I am trying to create the proper dts files for said configuration but I cannot find an example that uses I2C and CSI ports directly. I am reading the sensor programming guide but I still have trouble interfacing with the camera.

I would be grateful if you could you give me some pointers or examples on how to do that ?

Cheers,
Pavlos

Check the ov5693 on the board E3326. tegra210-camera-e3326-a00.dtsi

Hello again,

I have checked the file you proposed and developed the corresponding dtsi files for the IMX377 sensor.

Using i2cdetect command I can see that the device is detected on the I2C bus. However I still can’t get a frame or connect to the camera for that matter.

I do not have a lot of experience with regards to Linux kernel programming and device tree and I am currently learning on the go.

This is the output of the v4l2-compliance command.

Driver Info:
	Driver name   : tegra-video
	Card type     : vi-output, imx377 6-001a
	Bus info      : platform:54080000.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: 1 Private Controls: 10

	Format ioctls:
		test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
		test VIDIOC_G/S_PARM: OK (Not Supported)
		test VIDIOC_G_FBUF: OK (Not Supported)
		test VIDIOC_G_FMT: OK
		test VIDIOC_TRY_FMT: OK
		fail: v4l2-test-formats.cpp(418): expected EINVAL, but got 16 when getting format for buftype 1
		fail: v4l2-test-formats.cpp(952): Video Capture is valid, but no S_FMT was implemented
		test VIDIOC_S_FMT: FAIL
		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:
		fail: v4l2-test-buffers.cpp(446): ret && ret != EINVAL
		test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: FAIL
		fail: v4l2-test-buffers.cpp(571): q.has_expbuf(node)
		test VIDIOC_EXPBUF: FAIL

Test input 0:

Total: 42, Succeeded: 38, Failed: 4, Warnings: 0

I am pretty sure I have messed up something in the dtsi files but need a little guidance to find out where exactly.

This is the tegra210-camera-imx377-a00.dtsi file.

{
	host1x {
		vi {
			num-channels = <1>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					liimx377_vi_in0: endpoint {
						csi-port = <0>;
						bus-width = <4>;
						remote-endpoint = <&liimx377_csi_out0>;
					};
				};
			};
		};
		nvcsi {
			num-channels = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						liimx377_csi_in0: endpoint@0 {
							csi-port = <0>;
							bus-width = <4>;
							remote-endpoint = <&liimx377_imx377_out0>;
						};
					};
					port@1 {
						reg = <1>;
						liimx377_csi_out0: endpoint@1 {
							remote-endpoint = <&liimx377_vi_in0>;
						};
					};
				};
			};
		};
		i2c@546c0000 {

			status = "okay";
			#address-cells = <1>;
			#size-cells = <0>;
			imx377_a@1a {
				compatible = "nvidia,imx377";
				reg = <0x1a>;

				/* Physical dimensions of sensor */
				physical_w = "15.0";
				physical_h = "12.5";

				sensor_model ="imx377";
				/* Define any required hw resources needed by driver */
				/* ie. clocks, io pins, power sources */

				/* Defines number of frames to be dropped by driver internally after applying */
				/* sensor crop settings. Some sensors send corrupt frames after applying */
				/* crop co-ordinates */
				post_crop_frame_drop = "0";

				/* Convert Gain to unit of dB (decibel) befor passing to kernel driver */
				use_decibel_gain = "false";

				/* if true, delay gain setting by one frame to be in sync with exposure */
				delayed_gain = "true";

				/* enable CID_SENSOR_MODE_ID for sensor modes selection */
				use_sensor_mode_id = "true";

				/**
				* 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
				*
				* dynamic_pixel_bit_depth = "";
				* sensor dynamic bit depth for sensor mode
				*
				* csi_pixel_bit_depth = "";
				* sensor output bit depth for sensor mode
				*
				* mode_type="";
				* Sensor mode type, For eg: yuv, Rgb, bayer, bayer_wdr_pwl
				*
				* pixel_phase="";
				* Pixel phase for sensor mode, For eg: rggb, vyuy, rgb888
				*
				* 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
				* if use_decibel_gain = "true", please set the gain as decibel
				*
				* 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)
				*
				* embedded_metadata_height = "";
				* Sensor embedded metadata height in units of rows.
				* If sensor does not support embedded metadata value should be 0.
				*/
				mode0 {/*mode IMX377_MODE_4104X3046_CROP_30FPS*/
					mclk_khz = "24000";
					num_lanes = "4";
					tegra_sinterface = "serial_a";
					discontinuous_clk = "yes";
					dpcm_enable = "false";
					cil_settletime = "0";
					dynamic_pixel_bit_depth = "12";
					csi_pixel_bit_depth = "12";
					mode_type = "bayer";
					pixel_phase = "rggb";

					active_w = "4104";
					active_h = "3046";
					readout_orientation = "0";
					line_length = "6000";
					inherent_gain = "1";
					mclk_multiplier = "100";
					pix_clk_hz = "576000000";

					min_gain_val = "0"; 
					max_gain_val = "1957"; 
					min_hdr_ratio = "1";
					max_hdr_ratio = "1";
					min_framerate = "1.5";
					max_framerate = "30";
					min_exp_time = "83";
					max_exp_time = "66600";
					embedded_metadata_height = "2";
				};
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						liimx377_imx377_out0: endpoint {
							csi-port = <0>;
							bus-width = <4>;
							remote-endpoint = <&liimx377_csi_in0>;
						};
					};
				};
			};
		};
	};

	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
		*
		* 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 = <4>;
		max_lane_speed = <1500000>;
		min_bits_per_pixel = <10>;
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		isp_peak_byte_per_pixel = <5>;
		isp_bw_margin_pct = <25>;

		/**
		 * 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 = "imx377_front_liimx377";
				position = "front";
				orientation = "1";
				drivernode0 {
					/* Declare PCL support driver (classically known as guid)  */
					pcl_id = "v4l2_sensor";
					/* Driver v4l2 device name */
					devname = "imx377 6-001a";
					/* Declare the device-tree hierarchy to driver instance */
					proc-device-tree = "/proc/device-tree/host1x/i2c@546c0000/imx377_a@1a";
				};
			};
		};
	};
};

This is the tegra210-jetson-cv-camera-imx377-a00.dtsi file

#include "tegra210-camera-imx377-a00.dtsi"

#define CAM0_RST_L		TEGRA_GPIO(S, 7)
#define CAM0_PWDN       TEGRA_GPIO(T, 0)

/* camera control gpio definitions */

{
	host1x {
		i2c@546c0000 {
			imx377_a@1a {
				/* Define any required hw resources needed by driver */
				/* ie. clocks, io pins, power sources */
				#compatible = "nvidia,imx377";
				#reg = <0x1a>;
				#address-cells = <1>;
				#size-cells = <0>;
				skip_mux_detect = "yes";
				vcc-supply = <&en_vdd_cam>;
				vcc_lp = "vcc";
				clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_3>;
				clock-names = "clk_out_3";
				clock-frequency = <24000000>;
				mclk = "clk_out_3";
				reset-gpios = <&gpio CAM0_RST_L GPIO_ACTIVE_HIGH>;
			};
		};
	};

	gpio@6000d000 {
		camera-control-output-low {
			gpio-hog;
			output-low;
			gpios = <
				CAM0_RST_L 0
				CAM0_PWDN 0
				>;
			label = "cam0-rst", "cam0-pwdn";
		};
	};
};

I have changed the Reset and Power-Down pins as they our different for our board.

In addition I have altered the tegra210-jetson-cv-base-p2597-2180-a00.dts file with the following lines.

//#include "jetson-platforms/tegra210-jetson-cv-camera-modules.dtsi"
#include "jetson-platforms/tegra210-jetson-cv-camera-imx377-a00.dtsi"
//#include "jetson-plugin-manager/tegra210-jetson-cv-eeprom-manager.dtsi"
//#include "jetson-plugin-manager/tegra210-jetson-cv-camera-plugin-manager.dtsi"
//#include "jetson-plugin-manager/tegra210-jetson-cv-plugin-manager.dtsi"

Any ideas ?

Did you use v4l2-ctl to get frame? Any kernel error message.

https://elinux.org/Jetson_TX2/28.1_Camera_BringUp

Hello,

Apologies for the late reply I was busy with another project.

So here is the output from various commands.

v4l2-ctl --list-devices
VIDIOC_QUERYCAP: failed: Inappropriate ioctl for device
VIDIOC_QUERYCAP: failed: Inappropriate ioctl for device
vi-output, imx377 6-001a (platform:54080000.vi:0):
	/dev/video0
	/dev/v4l-subdev1
	/dev/v4l-subdev0
dmesg | grep -i imx377
[    2.960713] [IMX377]: probing v4l2 sensor.
v4l2-ctl --list-formats-ext -d /dev/video0
ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'RGGB'
	Name        : 8-bit Bayer RGRG/GBGB
		Size: Discrete 4104x3046
			Interval: Discrete 0.033s (30.000 fps)

	Index       : 1
	Type        : Video Capture
	Pixel Format: 'RG10'
	Name        : 10-bit Bayer RGRG/GBGB
		Size: Discrete 4104x3046
			Interval: Discrete 0.033s (30.000 fps)

	Index       : 2
	Type        : Video Capture
	Pixel Format: 'BG10'
	Name        : 10-bit Bayer BGBG/GRGR
		Size: Discrete 4104x3046
			Interval: Discrete 0.033s (30.000 fps)

	Index       : 3
	Type        : Video Capture
	Pixel Format: 'XBGP'
	Name        : 10-bit Bayer BGGR(10-10-10-2)

	Index       : 4
	Type        : Video Capture
	Pixel Format: 'XRGP'
	Name        : 10-bit Bayer RGGB(10-10-10-2)
		Size: Discrete 4104x3046
			Interval: Discrete 0.033s (30.000 fps)

	Index       : 5
	Type        : Video Capture
	Pixel Format: 'RG12'
	Name        : 12-bit Bayer RGRG/GBGB
		Size: Discrete 4104x3046
			Interval: Discrete 0.033s (30.000 fps)
gst-launch-1.0 nvcamerasrc ! nvvidconv ! xvimagesink
Setting pipeline to PAUSED ...

Available Sensor modes : 
4104 x 3046 FR=30.000000 CF=0x1009208a10 SensorModeType=4 CSIPixelBitDepth=12 DynPixelBitDepth=12
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock

NvCameraSrc: Trying To Set Default Camera Resolution. Selected sensorModeIndex = 0 WxH = 4104x3046 FrameRate = 30.000000 ...

ERROR: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: Output window was closed
Additional debug info:
xvimagesink.c(555): gst_xv_image_sink_handle_xevents (): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0
Execution ended after 0:01:21.267099892
Setting pipeline to PAUSED ...
Setting pipeline to READY ...

For the last one it gets stuck displaying a green window.

Are you use 28.2?
Enable the debug print and use below command to debug the sensor driver first.

cd /sys/kernel/debug/dynamic_debug/
echo file csi2_fops.c +p > control

v4l2-ctl -d /dev/video0 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=100 --stream-to=test.raw

Hello,

I followed your instructions and this is what I get as debug output with respect to the imx377 sensor when running the command.When I run the command nothing happens.

drivers/media/i2c/imx377.c:792 [imx377]imx377_open =_ "%s:\012"
drivers/media/i2c/imx377.c:611 [imx377]imx377_calculate_shr =_ "%s: shr: %u framelength: %d\012"
drivers/media/i2c/imx377.c:372 [imx377]imx377_s_stream =_ "%s++\012"
drivers/media/i2c/imx377.c:379 [imx377]imx377_s_stream =_ "%s mode[%d]\012"
drivers/media/i2c/imx377.c:414 [imx377]imx377_s_stream =_ "%s: error setting stream\012"
drivers/media/i2c/imx377.c:509 [imx377]imx377_set_group_hold =_ "%s: Group hold control error\012"
drivers/media/i2c/imx377.c:530 [imx377]imx377_set_gain =_ "%s: val: %d\012"
drivers/media/i2c/imx377.c:555 [imx377]imx377_set_gain =_ "%s: GAIN control error\012"
drivers/media/i2c/imx377.c:623 [imx377]imx377_set_coarse_time =_ "%s: val: %d\012"
drivers/media/i2c/imx377.c:643 [imx377]imx377_set_coarse_time =_ "%s: COARSE_TIME control error\012"
drivers/media/i2c/imx377.c:291 [imx377]imx377_power_off =_ "%s: power off\012"
drivers/media/i2c/imx377.c:257 [imx377]imx377_power_on =_ "%s: power on\012"
drivers/media/i2c/imx377.c:693 [imx377]imx377_ctrls_init =_ "%s++\012"
drivers/media/i2c/imx377.c:884 [imx377]imx377_probe =_ "%s: name %s\012"
drivers/media/i2c/imx377.c:914 [imx377]imx377_probe =_ "Detected IMX377 sensor\012"
drivers/media/i2c/imx377.c:568 [imx377]imx377_set_frame_length =_ "%s: val: %u\012"
drivers/media/i2c/imx377.c:591 [imx377]imx377_set_frame_length =_ "%s: framelength: %u\012"

Looks like didn’t get any error in kernel message. Did the v4l2-ctl run done normally?

Hello again,

I finally figured out how to make the camera work.

Initially I had to include PCA9570 in the device tree.

Next step is to alter the IMX377 driver with respect to handling the Reset Gpio, which also need a pull-up to be added on the custom board.

After these changes I managed to get the IMX377 camera sensor working on the Auvidea board.

Next step is to configure the device-tree to work with 3 cameras connected to different i2c and csi ports.

One thing I would like to confirm with you is how to select the CSI port for each camera.

When I write “imx377_a@1a” in the DTSI file, that means that it will use CSI port A and the I2C address is 0x1a, correct ? So essentially I will add the additional ports and configure respective i2c channels ?

Is there an example where 3 cameras are used on different I2C and CSI ports ?

For multiple camera you can check the e3333 and L4T document the chapter “sensor programing guide” for your reference.

Hello again,

First of all thank you for your support so far.

Checking the various examples and forum threads I have managed to connect 2 of the 3 cameras.

The first camera is connected to I2C 1 @7000c400 and uses CSI AB
The second camera is connected to I2C 6 @546c000 and uses CSI CD
The third camera is connected to I2C 2 @7000c500 and uses CSI EF

While I am able to pass the v4l2 compliance tests and get video stream fro the first two cameras, I have a problem when trying to use the third one.

Running the i2detect command I can see that it detects the camera properly.

Here are the DT files I am using.

tegra210-jetson-cv-camera-imx377-a00.dtsi

#include "tegra210-camera-imx377-a00.dtsi"

#define CAM0_RST_L	TEGRA_GPIO(T, 0) // 0
#define CAM1_RST_L	TEGRA_GPIO(S, 4) // 1
#define CAM2_RST_L	TEGRA_GPIO(S, 5) // 2
#define CAMERA_I2C_MUX_BUS(x) (0x1E + x)

/ {
	host1x {
		i2c@546c0000 {
			imx377_c@1a {
				clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_3>;
				clock-names = "clk_out_3";
				clock-frequency = <24000000>;
				mclk = "clk_out_3";
				reset-gpios = <&gpio CAM1_RST_L GPIO_ACTIVE_HIGH>;

				vana-supply = <&en_vdd_cam_hv_2v8>;
				vif-supply = <&en_vdd_cam>;
				vdig-supply = <&en_vdd_cam_1v2>;
			};
		};
	};
	i2c@7000c500 {
		imx377_e@1a {
			clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_3>;
			clock-names = "clk_out_3";
			clock-frequency = <24000000>;
			mclk = "clk_out_3";
			reset-gpios = <&gpio CAM2_RST_L GPIO_ACTIVE_HIGH>;

			vana-supply = <&en_vdd_cam_hv_2v8>;
			vif-supply = <&en_vdd_cam>;
			vdig-supply = <&en_vdd_cam_1v2>;
		};
	};
	i2c@7000c400 {
		imx377_a@1a {
			clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_3>;
			clock-names = "clk_out_3";
			clock-frequency = <24000000>;
			mclk = "clk_out_3";
			reset-gpios = <&gpio CAM0_RST_L GPIO_ACTIVE_HIGH>;

			vana-supply = <&en_vdd_cam_hv_2v8>;
			vif-supply = <&en_vdd_cam>;
			vdig-supply = <&en_vdd_cam_1v2>;
		};
	};
};

tegra210-camera-imx377-a00.dtsi

#include <dt-bindings/media/camera.h>
#include <dt-bindings/platform/t210/t210.h>

/ {
	host1x {
		vi {
			num-channels = <3>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					liimx377_vi_in0: endpoint {
						csi-port = <0>;
						bus-width = <4>;
						remote-endpoint = <&liimx377_csi_out0>;
					};
				};
				port@1 {
					reg = <1>;
					liimx377_vi_in1: endpoint {
						csi-port = <2>;
						bus-width = <4>;
						remote-endpoint = <&liimx377_csi_out1>;
					};
				};
				port@2 {
					reg = <2>;
					liimx377_vi_in2: endpoint {
						csi-port = <4>;
						bus-width = <4>;
						remote-endpoint = <&liimx377_csi_out2>;
					};
				};
			};
		};
		nvcsi {
			num-channels = <3>;
			#address-cells = <1>;
			#size-cells = <0>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						liimx377_csi_in0: endpoint@0 {
							csi-port = <0>;
							bus-width = <4>;
							remote-endpoint = <&liimx377_imx377_out0>;
						};
					};
					port@1 {
						reg = <1>;
						liimx377_csi_out0: endpoint@1 {
							remote-endpoint = <&liimx377_vi_in0>;
						};
					};
				};
			};
			channel@1 {
				reg = <1>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						liimx377_csi_in1: endpoint@0 {
							csi-port = <2>;
							bus-width = <4>;
							remote-endpoint = <&liimx377_imx377_out1>;
						};
					};
					port@1 {
						reg = <1>;
						liimx377_csi_out1: endpoint@1 {
							remote-endpoint = <&liimx377_vi_in1>;
						};
					};
				};
			};
			channel@2 {
				reg = <2>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						liimx377_csi_in2: endpoint@0 {
							csi-port = <4>;
							bus-width = <4>;
							remote-endpoint = <&liimx377_imx377_out2>;
						};
					};
					port@1 {
						reg = <1>;
						liimx377_csi_out2: endpoint@1 {
							remote-endpoint = <&liimx377_vi_in2>;
						};
					};
				};
			};
		}; 
		i2c@546c0000 {

			status = "okay";
			#address-cells = <1>;
			#size-cells = <0>;
			imx377_c@1a {
				compatible = "nvidia,imx377";
				reg = <0x1a>;
				devnode = "video1";

				physical_w = "15.0";
				physical_h = "12.5";

				sensor_model ="imx377";
				post_crop_frame_drop = "0";
				use_decibel_gain = "false";
				delayed_gain = "true";
				use_sensor_mode_id = "true";

				mode0 {
					mclk_khz = "24000";
					num_lanes = "4";
					tegra_sinterface = "serial_c";
					discontinuous_clk = "yes";
					dpcm_enable = "false";
					cil_settletime = "0";
					dynamic_pixel_bit_depth = "12";
					csi_pixel_bit_depth = "12";
					mode_type = "bayer";
					pixel_phase = "rggb";

					active_w = "4104";
					active_h = "3046";
					readout_orientation = "0";
					line_length = "6000";
					inherent_gain = "1";
					mclk_multiplier = "100";
					pix_clk_hz = "576000000";

					min_gain_val = "0"; 
					max_gain_val = "1957"; 
					min_hdr_ratio = "1";
					max_hdr_ratio = "1";
					min_framerate = "1.5";
					max_framerate = "30";
					min_exp_time = "83";
					max_exp_time = "66600";
					embedded_metadata_height = "2";
				};
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						liimx377_imx377_out1: endpoint {
							csi-port = <2>;
							bus-width = <4>;
							remote-endpoint = <&liimx377_csi_in1>;
						};
					};
				};
			};
		};
	};
	i2c@7000c500 {

		status = "okay";
		#address-cells = <1>;
		#size-cells = <0>;
		imx377_e@1a {
			compatible = "nvidia,imx377";
			reg = <0x1a>;
			devnode = "video2";

			physical_w = "15.0";
			physical_h = "12.5";

			sensor_model ="imx377";
			post_crop_frame_drop = "0";
			use_decibel_gain = "false";
			delayed_gain = "true";
			use_sensor_mode_id = "true";

			mode0 {
				mclk_khz = "24000";
				num_lanes = "4";
				tegra_sinterface = "serial_e";
				discontinuous_clk = "yes";
				dpcm_enable = "false";
				cil_settletime = "0";
				dynamic_pixel_bit_depth = "12";
				csi_pixel_bit_depth = "12";
				mode_type = "bayer";
				pixel_phase = "rggb";

				active_w = "4104";
				active_h = "3046";
				readout_orientation = "0";
				line_length = "6000";
				inherent_gain = "1";
				mclk_multiplier = "100";
				pix_clk_hz = "576000000";

				min_gain_val = "0"; 
				max_gain_val = "1957"; 
				min_hdr_ratio = "1";
				max_hdr_ratio = "1";
				min_framerate = "1.5";
				max_framerate = "30";
				min_exp_time = "83";
				max_exp_time = "66600";
				embedded_metadata_height = "2";
			};
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					liimx377_imx377_out2: endpoint {
						csi-port = <4>;
						bus-width = <4>;
						remote-endpoint = <&liimx377_csi_in2>;
					};
				};
			};
		};
	};
	i2c@7000c400 {

		status = "okay";
		#address-cells = <1>;
		#size-cells = <0>;
		imx377_a@1a {
			compatible = "nvidia,imx377";
			reg = <0x1a>;
			devnode = "video0";

			physical_w = "15.0";
			physical_h = "12.5";

			sensor_model ="imx377";
			post_crop_frame_drop = "0";
			use_decibel_gain = "false";
			delayed_gain = "true";
			use_sensor_mode_id = "true";

			mode0 {
				mclk_khz = "24000";
				num_lanes = "4";
				tegra_sinterface = "serial_a";
				discontinuous_clk = "yes";
				dpcm_enable = "false";
				cil_settletime = "0";
				dynamic_pixel_bit_depth = "12";
				csi_pixel_bit_depth = "12";
				mode_type = "bayer";
				pixel_phase = "rggb";

				active_w = "4104";
				active_h = "3046";
				readout_orientation = "0";
				line_length = "6000";
				inherent_gain = "1";
				mclk_multiplier = "100";
				pix_clk_hz = "576000000";

				min_gain_val = "0"; 
				max_gain_val = "1957"; 
				min_hdr_ratio = "1";
				max_hdr_ratio = "1";
				min_framerate = "1.5";
				max_framerate = "30";
				min_exp_time = "83";
				max_exp_time = "66600";
				embedded_metadata_height = "2";
			};
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					liimx377_imx377_out0: endpoint {
						csi-port = <0>;
						bus-width = <4>;
						remote-endpoint = <&liimx377_csi_in0>;
					};
				};
			};
		};
	};

	tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";

		num_csi_lanes = <12>;
		max_lane_speed = <1500000>;
		min_bits_per_pixel = <10>;
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		isp_peak_byte_per_pixel = <5>;
		isp_bw_margin_pct = <25>;

		modules {
			module0 {
				badge = "imx377_left_liimx377";
				position = "left";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "imx377 1-001a";
					proc-device-tree = "/proc/device-tree/i2c@7000c400/imx377_a@1a";
				};
			};
			module1 {
				badge = "imx377_center_liimx377";
				position = "center";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "imx377 6-001a";
					proc-device-tree = "/proc/device-tree/host1x/i2c@546c0000/imx377_c@1a";
				};
			};
			module2 {
				badge = "imx377_right_liimx377";
				position = "right";
				orientation = "1";
				drivernode0 {
					pcl_id = "v4l2_sensor";
					devname = "imx377 2-001a";
					proc-device-tree = "/proc/device-tree/i2c@7000c500/imx377_e@1a";
				};
			};
		};
	};
};

For all three cameras I am using TEGRA210_CLK_CLK_OUT_3. Should a different clock be used for each camera ?
On other forum posts I read that the CAMERA_MCLK2 is not connected and I am wondering if this is the reason that I cannot work with 3 cameras.

All in all, is a setup with 3 cameras on different CSI, I2C supported on the Jetson TX1 platform or not ?
So far I have been unable to find an example that uses such a setup.

We are closing in on a deadline for our product prototype and I need to be sure that Jetson TX1 can work with 3 cameras on different ports, otherwise I should look at other platforms.

Thank you advance for your assistance.

There’s no problem to support multiple camera up to 6 sensors.
Did you see the video node /dev/video2.
The position is incorrect. There’s no left and right define. Please check the sensor programing guide.

Hello again,

You are correct concerning camera naming. I altered the configuration to use top, bottom and center.

I see 3 video devices : dev/video0, dev/video1 and dev/video2.

While I am able to get video from devices 0 and 1 the same does not apply to device 2, both gstreamer and argus_camera programs hang.

Checking this thread https://devtalk.nvidia.com/default/topic/936727/about-csi-camera-master-clock/?offset=10

I came to the conclusion that there could be an issue with the camera clock, is this correct ?

As seen in my code above, I use clk_out_3 as a source clock for all 3 cameras but I am not sure which pin outputs the clock to each of the three cameras.

@pavlos
There’s no problem for connect to the same clock source.
Your problem more like HW problem.

Finally we have resolved the issue.

It is a hardware problem on the Auvidea J140 board. We added an external multiplexer for the clock and now everything works fine.

Thank you for your help.