[MIPI-CSI2]cam_i2cmux: i2c@2 duplicates my i2c@0 entry

Hi all,

We are currently working with two camera modules from two different vendors on the XavierNX devkit.

  • The first camera is an ADI ToF sensor. In particular, ADI had to use two CSI entries and two i2c entries in the device tree (even if only one camera is being used). Note that physically, the camera is linked to the XavierNX through a single 2 lane CSI-2 link.
  • The second camera is a RBPC-HQ (with the IMX477). We’re using the dtsi gently provided by RidgeRun.

We fused both device trees to support the two cameras simultaneously. In particular, in the cam_i2cmux, we had something like:

		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@0 {
			reg = <0>;
			#address-cells = <1>;
			#size-cells = <0>;
			adi_tof_cam0@64 {
				compatible = "adi,addi9036";
				reg = <0x64>;
				sensor_model = "MN34906BL";
				physical_w = "2.688";
				use_decibel_gain = "true";
				devnode = "video0";
				delayed_gain = "true";
				use_sensor_mode_id = "true";
				physical_h = "3.584";
				mode0 {				
					mclk_khz = "45000";
					num_lanes = "2";
					tegra_sinterface = "serial_e";
					phy_mode = "DPHY";
					discontinuous_clk = "no";
					dpcm_enable = "false";
					cil_settletime = "0";
					active_w = "640";
					active_h = "480";
					mode_type = "bayer";
					pixel_phase = "bggr";
					csi_pixel_bit_depth = "12";
					pix_clk_hz = "73728000";
					line_length = "640";
					inherent_gain = "1";
					min_hdr_ratio = "1";
					max_hdr_ratio = "1";
					min_gain_val = "0";         /* 0dB */
					max_gain_val = "0";       /* 48dB */
					step_gain_val = "1";        /* 0.3 */
					default_gain = "0";
					min_framerate = "5000000";
					max_framerate = "30000000";
					step_framerate = "1";
					default_framerate = "30000000";
					embedded_metadata_height = "0";
				};
				ports {
					#address-cells = <0x1>;
					#size-cells = <0x0>;

					port@0 {
						reg = <0x0>;
						adi9036_out0: endpoint {
							port-index = <0>;
							remote-endpoint = <&addi9036_csi_in0>;
							bus-width = <2>;
							vc-id = <0>;
						};
					};
				};
			};

			eeprom@56 {
				reg = <0x56>;
				compatible = "atmel,24c1024";
				pagesize = <32>;
			};	
		};
		i2c@1 {
			reg = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			adi_tof_cam1@64 {
				compatible = "adi,addi9036";
				reg = <0x64>;
				sensor_model = "MN34906BL";
				physical_w = "2.688";
				use_decibel_gain = "true";
				devnode = "video0";
				delayed_gain = "true";
				use_sensor_mode_id = "true";
				physical_h = "3.584";

				mode0 {				
					mclk_khz = "45000";
					num_lanes = "2";
					tegra_sinterface = "serial_e";
					phy_mode = "DPHY";
					discontinuous_clk = "no";
					dpcm_enable = "false";
					cil_settletime = "0";
					active_w = "640";
					active_h = "480";
					mode_type = "bayer";
					pixel_phase = "bggr";
					csi_pixel_bit_depth = "12";
					pix_clk_hz = "73728000";
					line_length = "640";
					inherent_gain = "1";
					min_hdr_ratio = "1";
					max_hdr_ratio = "1";
					min_gain_val = "0";         /* 0dB */
					max_gain_val = "0";       /* 48dB */
					step_gain_val = "1";        /* 0.3 */
					default_gain = "0";
					min_framerate = "5000000";
					max_framerate = "30000000";
					step_framerate = "1";
					default_framerate = "30000000";
					embedded_metadata_height = "0";
				};

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

					port@0 {
						reg = <0x0>;
						adi9036_out1: endpoint {
							port-index = <0>;
							remote-endpoint = <&addi9036_csi_in1>;
							bus-width = <2>;
							vc-id = <1>;
						};
					};
				};
			};		
			eeprom@56 {
				reg = <0x56>;
				compatible = "atmel,24c1024";
				pagesize = <32>;
			};	
		};
		i2c@2 {
			reg = <2>;
			#address-cells = <1>;
			#size-cells = <0>;
			imx477_cam1: rbpcv3_imx477_c@1a {
				compatible = "ridgerun,imx477";
				reg = <0x1a>;
				reset-gpios = <&tegra_main_gpio CAM1_PWDN GPIO_ACTIVE_HIGH>;
				devnode = "video2";
				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";
					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>;
						};
					};
				};
			};
		};		
	};

Using this device tree, the ADI camera works fine but the IMX477 sensor is not detected during i2c probe. Here is a list of detected i2c devices

sudo i2cdetect -l
i2c-3	i2c       	3190000.i2c                     	I2C adapter
i2c-1	i2c       	c240000.i2c                     	I2C adapter
i2c-11	i2c       	i2c-2-mux (chan_id 2)          I2C adapter
i2c-8	i2c       	31e0000.i2c                     	I2C adapter
i2c-6	i2c       	31c0000.i2c                     	I2C adapter
i2c-4	i2c       	Tegra BPMP I2C adapter     I2C adapter
i2c-2	i2c       	3180000.i2c                     	I2C adapter
i2c-0	i2c       	3160000.i2c                     	I2C adapter
i2c-9	i2c       	i2c-2-mux (chan_id 0)         I2C adapter
i2c-10	i2c       	i2c-2-mux (chan_id 1)         I2C adapter
i2c-7	i2c       	c250000.i2c                     	I2C adapter
i2c-5	i2c       	31b0000.i2c                     	I2C adapter

The ADI i2c parts are working normally

sudo i2cdetect -r -y 9  # ADDI IR
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- UU UU -- -- -- -- -- -- -- -- 
60: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- 73 -- -- -- --   

sudo i2cdetect -r -y 10 # ADDI TOF
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

However, the IMX477 i2c response (on i2c bus 11) seems incorrect:

sudo i2cdetect -r -y 11
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- 56 57 -- -- -- -- -- -- -- -- 
60: -- -- -- -- 64 -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- 73 -- -- -- --  

In fact, this is a copy of i2c bus 9 (named i2c@0 on the device tree cam-i2c-mux), and I can’t understand why.
Is their any overwrite ? is i2c bus 11 reserved for something ?

Thanks,
K

The CAM_I2C_MUX only have one GPIO pin, So can only support two bus I think.

https://www.kernel.org/doc/html/v5.9/i2c/muxes/i2c-mux-gpio.html

Thanks for your reply @ShaneCCC ! Now I understand, I even see the single GPIO Pin
mux-gpios = <&tegra_aon_gpio CAM_I2C_MUX GPIO_ACTIVE_HIGH>;
If I may ask, is it possible to bypass CAM_I2C_MUX and rely on a dedicated i2c ?

You can try move the imx477 to i2c-mux parent cam_i2c aka i2c@3180000

I moved the IMX477 parts to i2c@3180000 as the following, without success

	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@0 {
               // ADI ToF
		};
		i2c@1 {
               // ADI IR
		};
	};
	i2c@3180000 {
		#address-cells = <1>;
		#size-cells = <0>;	
		status = "okay";
		i2c@2 {
			reg = <2>;
			#address-cells = <1>;
			#size-cells = <0>;
			imx477_cam1: rbpcv3_imx477_c@1a {
				compatible = "ridgerun,imx477";
				reg = <0x1a>;
				reset-gpios = <&tegra_main_gpio CAM1_PWDN GPIO_ACTIVE_HIGH>;
				devnode = "video2";
				physical_w = "7.564";
				physical_h = "5.476";
				sensor_model = "imx477";
				use_sensor_mode_id = "true";
				mode0 { 
                    /* IMX477_MODE_4032X3040 */
				};
				mode1 {
                    /* IMX477_MODE_1920X1080 */
				};
				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>;
						};
					};
				};
			};
		};		
	};

I also modified the tegra-camera-platform entries:

				drivernode2 {
					status = "okay";
					pcl_id = "v4l2_sensor";
					devname = "imx477 2-001a";
					proc-device-tree = "/proc/device-tree/i2c@3180000/i2c@2/rbpcv3_imx477_c@1a";
				};

Am I Missing other entries on i2c@3180000 ??

Need remove the i2c@2 have imx477 directly in i2c3180000 scope.

Thanks for your assistance @ShaneCCC ! Both devices are now detected

v4l2-ctl --list-devices
vi-output, addi9036 9-0064 (platform:15c10000.vi:0):
	/dev/video0
	/dev/video1

vi-output, imx477 2-001a (platform:15c10000.vi:2):
	/dev/video2

I am able to get frames for the ADDI camera, but video capture from the IMX477 fails with both gstreamer and v4l2. dmesg reports the following error:

[  672.878957] tegra-i2c 3180000.i2c: no acknowledge from address 0x1a
[  672.879178] regmap_util_write_table_8:regmap_util_write_table:-121
[  672.879286] imx477 2-001a: Error writing mode

However, 0x1a is accessible from i2cdetect

sudo i2cdetect -r -y 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- UU UU -- -- -- -- -- -- -- -- 
60: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- 73 -- -- -- --                         

Any idea where this problem may come from ?

Could you check if i2c tools(i2cget/i2ctransfer) can access imx477 continuously.

I2CGet reported that address 0x1a was not responding …

I changed the dts entries related to csi lane speed, and now the IMX477 responds ! I’m capable of getting frames from both cameras now, but not at the same time !

Now i’m working on simultaneous video capture on both cameras.

Thanks a lot for you assistance,
Kamel

1 Like

Check below link to check if any changes can fix your problem.

https://elinux.org/Jetson/L4T/r32.5.x_patches

Thanks for you assistance,
The problems cam from a bad i2c configuration and we can successfully capture frames simultaneously now.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.