Custom camera can not registered device tree on jetson Tx2

Hello,

I have a working custom camera( MIPI-CSI2: 2Lane) connected to the Jetson TX2 camera expansion header.

pixel format is RAW10, framerate are 30fps/60fps, and the resolution are 2608x1960 and 1304x980.

I’ve built a device tree and a driver for camera based on the Sensor Driver Programming Guide.

I failed to be loaded device driver. ( it’s not appears a /dev/video0 entry)

  1. how to debugging device tree and device driver?
    It is hard to find where the device tree failed to load from.
    How do I enable debugging messages in kernel code?

  2. I modified from OV5693 code. but custom camera sensor doesn’t eeprom.
    I modified tegra186-quill-camera-plugin-manager.dtsi
    as Sensor Driver Programming Guide document.
    "Using Plugin Manager
    If your camera module has onboard EEPROM and has a valid camera ID programmed, Plugin Manager can
    be used. If your device module does not meet this requirement, use the main platform device tree instead by
    following the directions in Using Main Platform Device Tree File. "

    Shouldn’t the Plug-in manager.dtsi file be used for sensors without EEPROM?

    here is modified tegra186-quill-camera-plugin-manager.dtsi.

/* s5k5e8 camera board */
		fragment-e3327@0 {
			ids = "3327-*";
			/* Camera 0: Module */

			override@0 {
				target = <&e3327_cam0>;
				_overlay_ {
					status = "okay";
				};
			};

				
			override@1 {
				target = <&cam_module0>;
				_overlay_ {
					status = "okay";
					badge = "3327_front_s5k5e8";
					position = "rear";
					orientation = "1";
				};
			};
			override@2 {
				target = <&cam_module0_drivernode0>;
				_overlay_ {
					status = "okay";
					pcl_id = "v4l2_sensor";
					devname = "s5k5e8 2-0020";
					proc-device-tree = "/proc/device-tree/i2c@3180000/s5k5e8_c@20";
				};
			};
			/* Camera 0: VI */
			override@3 {
				target = <&vi_base>;
				_overlay_ {
					num-channels=<1>;
				};
			};			
			override@4 {
				target = <&vi_port0>;
				_overlay_ {
					status = "okay";
				};
			};
			override@5 {
				target = <&e3327_vi_in0>;
				_overlay_ {
					status = "okay";
					port-index = <0>;
					bus-width = <2>;
					remote-endpoint = <&e3327_csi_out0>;
				};
			};
			/* Camera 0: CSI */
			override@6 {
				target = <&csi_chan0>;
				_overlay_ {
					status = "okay";
				};
			};
			override@7 {
				target = <&csi_chan0_port0>;
				_overlay_ {
					status = "okay";
				};
			};
			override@8 {
				target = <&e3327_csi_in0>;
				_overlay_ {
					status = "okay";
					port-index = <0>;
					bus-width = <2>;
					remote-endpoint = <&e3327_s5k5e8_out0>;
				};
			};
			override@9 {
				target = <&csi_chan0_port1>;
				_overlay_ {
					status = "okay";
				};
			};
			override@10 {
				target = <&e3327_csi_out0>;
				_overlay_ {
					status = "okay";
					remote-endpoint = <&e3327_vi_in0>;
				};
			};
			/* tegra-camera-platform settings */
			override@11 {
				target = <&tcp>;
				_overlay_ {
					num_csi_lanes = <2>;
					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>;
				};
			};

			/* GPIO */
			override@12 {
				target = <&{/gpio@2200000}>;
				_overlay_ {
					camera-control-input {
						status = "disabled";
					};
					camera-control-output-low {
						gpio-hog;
		    		                gpios = <CAM1_RST_L 0 CAM0_PWDN 0>;
		                        	label = "cam0-rst", "cam0-pwdn";
                    				output-low;
						status = "okay";
					};
					camera-control-output-high {
						status = "disabled";
					};
				};
			};
		};
 here is device tree custom camera sensor  
/ {
	host1x {
		vi@15700000 {
			num-channels = <1>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					e3327_vi_in0: endpoint {
						port-index = <2>;
						bus-width = <2>;
						remote-endpoint = <&e3327_csi_out0>;
					};
				};
			};
		};

		nvcsi@150c0000 {
			num-channels = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						e3327_csi_in0: endpoint@0 {
							port-index = <2>;
							bus-width = <2>;
							remote-endpoint = <&e3327_s5k5e8_out0>;
						};
					};
					port@1 {
						reg = <1>;
						e3327_csi_out0: endpoint@1 {
							remote-endpoint = <&e3327_vi_in0>;
						};
					};
				};
			};
		};
	};

	i2c@3180000 {
		s5k5e8_c@20 {
			compatible = "nvidia,s5k5e8";
			/* I2C device address */
			reg = <0x20>;

			/* V4L2 device node location */
			devnode = "video0";

			/* Physical dimensions of sensor */
			physical_w = "4.675";
			physical_h = "3.633";

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

			/* Sensor output flip settings */
			vertical-flip = "true";

			mode0 { // S5K5E8_MODE_2608X1960
				mclk_khz = "24000";
				num_lanes = "2";
				tegra_sinterface = "serial_c";
				phy_mode = "DPHY";
				discontinuous_clk = "no";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "2608";
				active_h = "1960";
				mode_type = "bayer";
				pixel_phase = "grbg";
				csi_pixel_bit_depth = "10";
				readout_orientation = "90";
				line_length = "2856";
				inherent_gain = "1";
				mclk_multiplier = "7";
				pix_clk_hz = "170000000";

				gain_factor = "10";
				min_gain_val = "1";/* 1DB*/
				max_gain_val = "16";/* 16DB*/
				step_gain_val = "1";
				default_gain = "10";
				min_hdr_ratio = "";
				max_hdr_ratio = "";
				framerate_factor = "1000000";
				min_framerate = "2000000";/*1.816577 */
				max_framerate = "30000000";/*30*/
				step_framerate = "1";
				default_framerate = "30000000";
				exposure_factor = "1000000";
				min_exp_time = "34";/* us */
				max_exp_time = "279384";/* us */
				step_exp_time = "1";
				default_exp_time = "33334";/* us */
				embedded_metadata_height = "0";
			};

			mode1 { //S5K5E8_MODE_1304X980
				mclk_khz = "24000";
				num_lanes = "2";
				tegra_sinterface = "serial_c";
				phy_mode = "DPHY";
				discontinuous_clk = "no";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "1340";
				active_h = "980";
				mode_type = "bayer";
				pixel_phase = "grbg";
				csi_pixel_bit_depth = "10";
				readout_orientation = "90";
				line_length = "2856";
				inherent_gain = "1";
				mclk_multiplier = "7";
				pix_clk_hz = "170000000";

				gain_factor = "10";
				min_gain_val = "1";/* 1DB*/
				max_gain_val = "16";/* 16DB*/
				step_gain_val = "1";
				default_gain = "10";
				min_hdr_ratio = "";
				max_hdr_ratio = "";
				framerate_factor = "1000000";
				min_framerate = "1816577";/*1.816577 */
				max_framerate = "60000000";/*30*/
				step_framerate = "1";
				default_framerate = "60000000";
				exposure_factor = "1000000";
				min_exp_time = "34";/* us */
				max_exp_time = "279384";/* us */
				step_exp_time = "1";
				default_exp_time = "33334";/* us */
				embedded_metadata_height = "0";
			};


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

				port@0 {
					reg = <0>;
					e3327_s5k5e8_out0: endpoint {
						port-index = <2>;
						bus-width = <2>;
						remote-endpoint = <&e3327_csi_in0>;
					};
				};
			};
		};
	};


	tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";
		num_csi_lanes = <2>;
		max_lane_speed = <1500000>;
		min_bits_per_pixel = <10>;
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		max_pixel_rate = <170000>;
		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 = "e3327_front_s5k5e8";
				position = "rear";
				orientation = "1";
				drivernode0 {
					/* Declare PCL support driver (classically known as guid)  */
					pcl_id = "v4l2_sensor";
					/* Driver v4l2 device name */
					devname = "s5k5e8 2-0020";
					/* Declare the device-tree hierarchy to driver instance */
					proc-device-tree = "/proc/device-tree/i2c@3180000/s5k5e8_c@20";
				};
			};
		};
	};
};
 here is custom device driver code  in <b>/drivers/media/i2c</b>   
static const u32 ctrl_cid_list[] = {
	TEGRA_CAMERA_CID_GAIN,
	TEGRA_CAMERA_CID_EXPOSURE,
	TEGRA_CAMERA_CID_FRAME_RATE,
	TEGRA_CAMERA_CID_GROUP_HOLD,
};

struct s5k5e8 {
//	struct camera_common_eeprom_data eeprom[S5K5E8_EEPROM_NUM_BLOCKS];
//	u8				eeprom_buf[S5K5E8_EEPROM_SIZE];
//	u8				otp_buf[S5K5E8_OTP_SIZE];
	struct i2c_client		*i2c_client;
	struct v4l2_subdev		*subdev;
	u8				fuse_id[S5K5E8_FUSE_ID_SIZE];
	const char			*devname;
	struct dentry			*debugfs_dir;
	struct mutex			streaming_lock;
	bool				streaming;

	s32				group_hold_prev;
	u32				frame_length;
	bool				group_hold_en;
	struct camera_common_i2c	i2c_dev;
	struct camera_common_data	*s_data;
	struct tegracam_device		*tc_dev;
};

static struct regmap_config s5k5e8_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
};

static inline void s5k5e8_get_frame_length_regs(s5k5e8_reg *regs,
				u32 frame_length)
{
	regs->addr = S5K5E8_FRAME_LENGTH_ADDR_MSB;       //0x0340
	regs->val = (frame_length >> 8) & 0xff;
	(regs + 1)->addr = S5K5E8_FRAME_LENGTH_ADDR_LSB; //0x0341 
	(regs + 1)->val = (frame_length) & 0xff;
}

static inline void s5k5e8_get_coarse_time_regs(s5k5e8_reg *regs,
				u32 coarse_time)
{
	regs->addr = S5K5E8_COARSE_TIME_ADDR_MSB;          //0x0202 
	regs->val = (coarse_time >> 8) & 0xff;
	(regs + 1)->addr = S5K5E8_COARSE_TIME_ADDR_LSB;    //0x0203 
	(regs + 1)->val = (coarse_time ) & 0xff;
}

static inline void s5k5e8_get_gain_regs(s5k5e8_reg *regs,
				u16 gain)
{
	regs->addr = S5K5E8_GAIN_ADDR_MSB;              //0x0204
	regs->val = (gain >> 8) & 0xff;

	(regs + 1)->addr = S5K5E8_GAIN_ADDR_LSB;		//0x0205
	(regs + 1)->val = (gain) & 0xff;
}

static int test_mode;
module_param(test_mode, int, 0644);                  //0644 ???

static inline int s5k5e8_read_reg(struct camera_common_data *s_data,
				u16 addr, u8 *val)
{
	int err = 0;
	u32 reg_val = 0;

	err = regmap_read(s_data->regmap, addr, &reg_val);
	*val = reg_val & 0xFF;

	return err;
}

static int s5k5e8_write_reg(struct camera_common_data *s_data, u16 addr, u8 val)
{
	int err;
	struct device *dev = s_data->dev;

	err = regmap_write(s_data->regmap, addr, val);

	if (err)
		dev_err(dev, "%s: i2c write failed, 0x%x = %x\n",
			__func__, addr, val);

	return err;
}

static int s5k5e8_write_table(struct s5k5e8 *priv,
			      const s5k5e8_reg table[])
{
	struct camera_common_data *s_data = priv->s_data;

	return regmap_util_write_table_8(s_data->regmap,
					 table,
					 NULL, 0,
					 S5K5E8_TABLE_WAIT_MS,
					 S5K5E8_TABLE_END);
}

static void s5k5e8_gpio_set(struct camera_common_data *s_data,
			    unsigned int gpio, int val)
{
	struct camera_common_pdata *pdata = s_data->pdata;

	if (pdata && pdata->use_cam_gpio)
		cam_gpio_ctrl(s_data->dev, gpio, val, 1);
	else {
		if (gpio_cansleep(gpio))
			gpio_set_value_cansleep(gpio, val);
		else
			gpio_set_value(gpio, val);
	}
}

static int s5k5e8_power_on(struct camera_common_data *s_data)
{
	int err = 0;
	struct camera_common_power_rail *pw = s_data->power;
	struct camera_common_pdata *pdata = s_data->pdata;
	struct device *dev = s_data->dev;


	dev_dbg(dev, "%s: power on\n", __func__);

	if (pdata && pdata->power_on) {
		err = pdata->power_on(pw);
		if (err)
			dev_err(dev, "%s failed.\n", __func__);
		else
			pw->state = SWITCH_ON;
		return err;
	}
	/* sleeps calls in the sequence below are for internal device
	 * signal propagation as specified by sensor vendor
	 */

	if (pw->avdd)
		err = regulator_enable(pw->avdd);
	if (err)
		goto s5k5e8_avdd_fail;

	if (pw->iovdd)
		err = regulator_enable(pw->iovdd);
	if (err)
		goto s5k5e8_iovdd_fail;

	usleep_range(1, 2);
	if (gpio_is_valid(pw->pwdn_gpio))
		s5k5e8_gpio_set(s_data, pw->pwdn_gpio, 1);

	/*
	 * datasheet 2.9: reset requires ~2ms settling time
	 * a power on reset is generated after core power becomes stable
	 */
	usleep_range(2000, 2010);

	if (gpio_is_valid(pw->reset_gpio))
		s5k5e8_gpio_set(s_data, pw->reset_gpio, 1);

	/* datasheet fig 2-9: t3 */
	usleep_range(2000, 2010);

	pw->state = SWITCH_ON;


	return 0;

s5k5e8_iovdd_fail:
	regulator_disable(pw->avdd);

s5k5e8_avdd_fail:
	dev_err(dev, "%s failed.\n", __func__);
	return -ENODEV;
}

static int s5k5e8_power_off(struct camera_common_data *s_data)
{
	int err = 0;
	struct camera_common_power_rail *pw = s_data->power;
	struct device *dev = s_data->dev;
	struct camera_common_pdata *pdata = s_data->pdata;

	dev_dbg(dev, "%s: power off\n", __func__);

	if (pdata && pdata->power_off) {
		err = pdata->power_off(pw);
		if (!err) {
			goto power_off_done;
		} else {
			dev_err(dev, "%s failed.\n", __func__);
			return err;
		}
	}

	/* sleeps calls in the sequence below are for internal device
	 * signal propagation as specified by sensor vendor
	 */
	usleep_range(21, 25);
	if (gpio_is_valid(pw->pwdn_gpio))
		s5k5e8_gpio_set(s_data, pw->pwdn_gpio, 0);
	usleep_range(1, 2);
	if (gpio_is_valid(pw->reset_gpio))
		s5k5e8_gpio_set(s_data, pw->reset_gpio, 0);

	/* datasheet 2.9: reset requires ~2ms settling time*/
	usleep_range(2000, 2010);

	if (pw->iovdd)
		regulator_disable(pw->iovdd);
	if (pw->avdd)
		regulator_disable(pw->avdd);

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

static int s5k5e8_power_put(struct tegracam_device *tc_dev)
{
	struct camera_common_data *s_data = tc_dev->s_data;
	struct camera_common_power_rail *pw = s_data->power;
	struct camera_common_pdata *pdata = s_data->pdata;
	struct device *dev = tc_dev->dev;

	if (unlikely(!pw))
		return -EFAULT;

	if (pdata && pdata->use_cam_gpio)
		cam_gpio_deregister(dev, pw->pwdn_gpio);
	else {
		if (gpio_is_valid(pw->pwdn_gpio))
			gpio_free(pw->pwdn_gpio);
		if (gpio_is_valid(pw->reset_gpio))
			gpio_free(pw->reset_gpio);
	}

	return 0;
}

static int s5k5e8_power_get(struct tegracam_device *tc_dev)
{
	struct camera_common_data *s_data = tc_dev->s_data;
	struct camera_common_power_rail *pw = s_data->power;
	struct camera_common_pdata *pdata = s_data->pdata;
	struct device *dev = tc_dev->dev;
	const char *mclk_name;
	const char *parentclk_name;
	struct clk *parent;
	int err = 0, ret = 0;

	if (!pdata) {
		dev_err(dev, "pdata missing\n");
		return -EFAULT;
	}

	mclk_name = pdata->mclk_name ?
		    pdata->mclk_name : "cam_mclk1";
	pw->mclk = devm_clk_get(dev, mclk_name);
	if (IS_ERR(pw->mclk)) {
		dev_err(dev, "unable to get clock %s\n", mclk_name);
		return PTR_ERR(pw->mclk);
	}
	parentclk_name = pdata->parentclk_name;
	if (parentclk_name) {
		parent = devm_clk_get(dev, parentclk_name);
		if (IS_ERR(parent)) {
			dev_err(dev, "unable to get parent clcok %s",
				parentclk_name);
		} else
			clk_set_parent(pw->mclk, parent);
	}

	/* analog 2.8v */
	err |= camera_common_regulator_get(dev,
			&pw->avdd, pdata->regulators.avdd);
	/* IO 1.8v */
	err |= camera_common_regulator_get(dev,
			&pw->iovdd, pdata->regulators.iovdd);

	if (!err) {
		pw->reset_gpio = pdata->reset_gpio;
		pw->pwdn_gpio = pdata->pwdn_gpio;
	}
	if (pdata->use_cam_gpio) {
		err = cam_gpio_register(dev, pw->pwdn_gpio);
		if (err)
			dev_err(dev, "%s ERR can't register cam gpio %u!\n",
				 __func__, pw->pwdn_gpio);
	} else {
		if (gpio_is_valid(pw->pwdn_gpio)) {
			ret = gpio_request(pw->pwdn_gpio, "cam_pwdn_gpio");
			if (ret < 0) {
				dev_dbg(dev, "%s can't request pwdn_gpio %d\n",
					__func__, ret);
			}
			gpio_direction_output(pw->pwdn_gpio, 1);
		}
		if (gpio_is_valid(pw->reset_gpio)) {
			ret = gpio_request(pw->reset_gpio, "cam_reset_gpio");
			if (ret < 0) {
				dev_dbg(dev, "%s can't request reset_gpio %d\n",
					__func__, ret);
			}
			gpio_direction_output(pw->reset_gpio, 1);
		}
	}

	pw->state = SWITCH_OFF;
	return err;
}

static int s5k5e8_set_gain(struct tegracam_device *tc_dev, s64 val);
static int s5k5e8_set_frame_rate(struct tegracam_device *tc_dev, s64 val);
//static int s5k5e8_set_exposure(struct tegracam_device *tc_dev, s64 val);
//static int s5k5e8_set_exposure_short(struct tegracam_device *tc_dev, s64 val);

static const struct of_device_id s5k5e8_of_match[] = {
	{
		.compatible = "nvidia,s5k5e8",	},
	{ },
};

static int s5k5e8_set_group_hold(struct tegracam_device *tc_dev, bool val)
{
	int err;
	struct s5k5e8 *priv = tc_dev->priv;
	int gh_prev = switch_ctrl_qmenu[priv->group_hold_prev];
	struct device *dev = tc_dev->dev;

	if (priv->group_hold_en == true && gh_prev == SWITCH_OFF) {
		camera_common_i2c_aggregate(&priv->i2c_dev, true);
		/* enter group hold */
		err = s5k5e8_write_reg(priv->s_data,
				       S5K5E8_GROUP_HOLD_ADDR, val);      //0x0104
		if (err)
			goto fail;

		priv->group_hold_prev = 1;

		dev_dbg(dev, "%s: enter group hold\n", __func__);
	} else if (priv->group_hold_en == false && gh_prev == SWITCH_ON) {
		/* leave group hold */
		err = s5k5e8_write_reg(priv->s_data,
				       S5K5E8_GROUP_HOLD_ADDR, 0x00);
		if (err)
			goto fail;

		err = s5k5e8_write_reg(priv->s_data,
				       S5K5E8_GROUP_HOLD_ADDR, 0x00);
		if (err)
			goto fail;

		camera_common_i2c_aggregate(&priv->i2c_dev, false);

		priv->group_hold_prev = 0;

		dev_dbg(dev, "%s: leave group hold\n", __func__);
	}

	return 0;

fail:
	dev_dbg(dev, "%s: Group hold control error\n", __func__);
	return err;
}

static int s5k5e8_set_gain(struct tegracam_device *tc_dev, s64 val)
{
	struct camera_common_data *s_data = tc_dev->s_data;
	struct s5k5e8 *priv = (struct s5k5e8 *)tc_dev->priv;
	struct device *dev = tc_dev->dev;
	const struct sensor_mode_properties *mode =
		&s_data->sensor_props.sensor_modes[s_data->mode_prop_idx];
	s5k5e8_reg reg_list[2];
	int err;
	u16 gain;
	int i;

	if (!priv->group_hold_prev)
		s5k5e8_set_group_hold(tc_dev, 1);

	/* translate value */
	gain = (u16) (((val * 16) +
			(mode->control_properties.gain_factor / 2)) /
			mode->control_properties.gain_factor);
	s5k5e8_get_gain_regs(reg_list, gain);
	dev_dbg(dev, "%s: gain %d val: %lld\n", __func__, gain, val);

	for (i = 0; i < 2; i++) {
		err = s5k5e8_write_reg(s_data, reg_list[i].addr,
			 reg_list[i].val);
		if (err)
			goto fail;
	}

	return 0;

fail:
	dev_dbg(dev, "%s: GAIN control error\n", __func__);
	return err;
}

static int s5k5e8_set_frame_rate(struct tegracam_device *tc_dev, s64 val)
{
	struct camera_common_data *s_data = tc_dev->s_data;
	struct device *dev = tc_dev->dev;
	struct s5k5e8 *priv = tc_dev->priv;
	const struct sensor_mode_properties *mode =
		&s_data->sensor_props.sensor_modes[s_data->mode_prop_idx];
	s5k5e8_reg reg_list[2];
	int err;
	u32 frame_length;
	int i;

	if (!priv->group_hold_prev)
		s5k5e8_set_group_hold(tc_dev, 1);

	frame_length =  mode->signal_properties.pixel_clock.val *
		mode->control_properties.framerate_factor /
		mode->image_properties.line_length / val;

	s5k5e8_get_frame_length_regs(reg_list, frame_length);
	dev_dbg(dev, "%s: val: %d\n", __func__, frame_length);

	for (i = 0; i < 2; i++) {
		err = s5k5e8_write_reg(s_data, reg_list[i].addr,
			 reg_list[i].val);
		if (err)
			goto fail;
	}

	priv->frame_length = frame_length;

	return 0;

fail:
	dev_dbg(dev, "%s: FRAME_LENGTH control error\n", __func__);
	return err;
}


static int s5k5e8_set_exposure(struct tegracam_device *tc_dev, s64 val)
{
	struct camera_common_data *s_data = tc_dev->s_data;
	struct device *dev = tc_dev->dev;
	struct s5k5e8 *priv = tc_dev->priv;
	const s32 max_coarse_time = priv->frame_length - S5K5E8_MAX_COARSE_DIFF;
	const struct sensor_mode_properties *mode =
		&s_data->sensor_props.sensor_modes[s_data->mode_prop_idx];
	s5k5e8_reg reg_list[2];
	int err;
	u32 coarse_time;
	int i;

	if (!priv->group_hold_prev)
		s5k5e8_set_group_hold(tc_dev, 1);

	coarse_time = (u32)(((mode->signal_properties.pixel_clock.val*val)
			/mode->image_properties.line_length)/
			mode->control_properties.exposure_factor);
	if (coarse_time < S5K5E8_MIN_EXPOSURE_COARSE)
		coarse_time = S5K5E8_MIN_EXPOSURE_COARSE;
	else if (coarse_time > max_coarse_time)
		coarse_time = max_coarse_time;
	s5k5e8_get_coarse_time_regs(reg_list, coarse_time);
	dev_dbg(dev, "%s: val: %d\n", __func__, coarse_time);

	for (i = 0; i < 2; i++) {
		err = s5k5e8_write_reg(s_data, reg_list[i].addr,
			 reg_list[i].val);
		if (err)
			goto fail;
	}

	return 0;

fail:
	dev_dbg(dev, "%s: COARSE_TIME control error\n", __func__);
	return err;
}


MODULE_DEVICE_TABLE(of, s5k5e8_of_match);

static struct camera_common_pdata *s5k5e8_parse_dt(struct tegracam_device
							*tc_dev)
{
	struct device *dev = tc_dev->dev;
	struct device_node *node = 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;

	dev_err(dev, "s5k5e8 enter_parse_dt\n");
	if (!node){
		
		return NULL;
	}	
	match = of_match_device(s5k5e8_of_match, dev);
	if (!match) {
		dev_err(dev, "Failed to find matching dt id\n");
		return NULL;
	}

	board_priv_pdata = devm_kzalloc(dev,
			   sizeof(*board_priv_pdata), GFP_KERNEL);
	if (!board_priv_pdata)
		return NULL;

	err = camera_common_parse_clocks(dev,
					 board_priv_pdata);
	if (err) {
		dev_err(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;
		}
		gpio = 0;
	}
	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(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(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(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(dev, board_priv_pdata);
	return ret;
}

static int s5k5e8_set_mode(struct tegracam_device *tc_dev)
{
	struct s5k5e8 *priv = (struct s5k5e8 *)tegracam_get_privdata(tc_dev);
	struct camera_common_data *s_data = tc_dev->s_data;
	int err;

	err = s5k5e8_write_table(priv, mode_table[s_data->mode_prop_idx]);
	if (err)
		return err;

	return 0;
}

static int s5k5e8_start_streaming(struct tegracam_device *tc_dev)
{
	struct s5k5e8 *priv = (struct s5k5e8 *)tegracam_get_privdata(tc_dev);
	struct camera_common_data *s_data = tc_dev->s_data;
//	struct camera_common_pdata *pdata = s_data->pdata;
	struct device *dev = s_data->dev;
	int err;
//	u8 val;

	mutex_lock(&priv->streaming_lock);
	err = s5k5e8_write_table(priv, mode_table[S5K5E8_MODE_START_STREAM]);
	if (err) {
		mutex_unlock(&priv->streaming_lock);
		goto exit;
	} else {
		priv->streaming = true;
		mutex_unlock(&priv->streaming_lock);
	}
/*
	if (pdata->v_flip) {
		s5k5e8_read_reg(s_data, S5K5E8_TIMING_REG20, &val);
		s5k5e8_write_reg(s_data, S5K5E8_TIMING_REG20,
				 val | VERTICAL_FLIP);
	}
	if (pdata->h_mirror) {
		s5k5e8_read_reg(s_data, S5K5E8_TIMING_REG21, &val);
		s5k5e8_write_reg(s_data, S5K5E8_TIMING_REG21,
				 val | HORIZONTAL_MIRROR_MASK);
	} else {
		s5k5e8_read_reg(s_data, OV5693_TIMING_REG21, &val);
		s5k5e8_write_reg(s_data, OV5693_TIMING_REG21,
				 val & (~HORIZONTAL_MIRROR_MASK));
	}
*/
	if (test_mode)
		err = s5k5e8_write_table(priv,
			mode_table[S5K5E8_MODE_TEST_PATTERN]);

	return 0;

exit:
	dev_err(dev, "%s: error starting stream\n", __func__);
	return err;
}

static int s5k5e8_stop_streaming(struct tegracam_device *tc_dev)
{
	struct camera_common_data *s_data = tc_dev->s_data;
	struct s5k5e8 *priv = (struct s5k5e8 *)tegracam_get_privdata(tc_dev);
	struct device *dev = s_data->dev;
	u32 frame_time;
	int err;

	mutex_lock(&priv->streaming_lock);
	err = s5k5e8_write_table(priv,
		mode_table[S5K5E8_MODE_STOP_STREAM]);
	if (err) {
		mutex_unlock(&priv->streaming_lock);
		goto exit;
	} else {
		priv->streaming = false;
		mutex_unlock(&priv->streaming_lock);
	}

	/*
	 * Wait for one frame to make sure sensor is set to
	 * software standby in V-blank
	 *
	 * frame_time = frame length rows * Tline
	 * Tline = line length / pixel clock (in MHz)
	 */
	frame_time = priv->frame_length *
		S5K5E8_DEFAULT_LINE_LENGTH / S5K5E8_DEFAULT_PIXEL_CLOCK;

	usleep_range(frame_time, frame_time + 1000);

	return 0;

exit:
	dev_err(dev, "%s: error stopping stream\n", __func__);
	return err;
}

static struct camera_common_sensor_ops s5k5e8_common_ops = {
	.numfrmfmts = ARRAY_SIZE(s5k5e8_frmfmt),
	.frmfmt_table = s5k5e8_frmfmt,
	.power_on = s5k5e8_power_on,
	.power_off = s5k5e8_power_off,
	.write_reg = s5k5e8_write_reg,
	.read_reg = s5k5e8_read_reg,
	.parse_dt = s5k5e8_parse_dt,
	.power_get = s5k5e8_power_get,
	.power_put = s5k5e8_power_put,
	.set_mode = s5k5e8_set_mode,
	.start_streaming = s5k5e8_start_streaming,
	.stop_streaming = s5k5e8_stop_streaming,
};

static int s5k5e8_debugfs_streaming_show(void *data, u64 *val)
{
	struct s5k5e8 *priv = data;

	mutex_lock(&priv->streaming_lock);
	*val = priv->streaming;
	mutex_unlock(&priv->streaming_lock);

	return 0;
}

static int s5k5e8_debugfs_streaming_write(void *data, u64 val)
{
	int err = 0;
	struct s5k5e8 *priv = data;
	struct i2c_client *client = priv->i2c_client;
	bool enable = (val != 0);
	int mode_index = enable ?
		(S5K5E8_MODE_START_STREAM) : (S5K5E8_MODE_STOP_STREAM);

	dev_info(&client->dev, "%s: %s sensor\n",
			__func__, (enable ? "enabling" : "disabling"));

	mutex_lock(&priv->streaming_lock);

	err = s5k5e8_write_table(priv, mode_table[mode_index]);
	if (err) {
		dev_err(&client->dev, "%s: error setting sensor streaming\n",
			__func__);
		goto done;
	}

	priv->streaming = enable;

done:
	mutex_unlock(&priv->streaming_lock);

	return err;
}

DEFINE_SIMPLE_ATTRIBUTE(s5k5e8_debugfs_streaming_fops,
	s5k5e8_debugfs_streaming_show,
	s5k5e8_debugfs_streaming_write,
	"%lld\n");

static void s5k5e8_debugfs_remove(struct s5k5e8 *priv);

static int s5k5e8_debugfs_create(struct s5k5e8 *priv)
{
	int err = 0;
	struct i2c_client *client = priv->i2c_client;
	const char *devnode;
	char debugfs_dir[16];

	err = of_property_read_string(client->dev.of_node, "devnode", &devnode);
	if (err) {
		dev_err(&client->dev, "devnode not in DT\n");
		return err;
	}
	snprintf(debugfs_dir, sizeof(debugfs_dir), "camera-%s", devnode);

	priv->debugfs_dir = debugfs_create_dir(debugfs_dir, NULL);
	if (priv->debugfs_dir == NULL)
		return -ENOMEM;

	if (!debugfs_create_file("streaming", 0644, priv->debugfs_dir, priv,
			&s5k5e8_debugfs_streaming_fops))
		goto error;

	return 0;

error:
	s5k5e8_debugfs_remove(priv);

	return -ENOMEM;
}

static struct tegracam_ctrl_ops s5k5e8_ctrl_ops = {
	.numctrls = ARRAY_SIZE(ctrl_cid_list),
	.ctrl_cid_list = ctrl_cid_list,
//	.string_ctrl_size = {S5K5E8_EEPROM_STR_SIZE,
//				S5K5E8_FUSE_ID_STR_SIZE,
//				S5K5E8_OTP_STR_SIZE},
	.set_gain = s5k5e8_set_gain,
	.set_exposure = s5k5e8_set_exposure,
//	.set_exposure_short = s5k5e8_set_exposure_short,
	.set_frame_rate = s5k5e8_set_frame_rate,
	.set_group_hold = s5k5e8_set_group_hold,
//	.fill_string_ctrl = s5k5e8_fill_string_ctrl,
};

static int s5k5e8_board_setup(struct s5k5e8 *priv)
{
	struct camera_common_data *s_data = priv->s_data;
	struct device *dev = s_data->dev;
//	bool eeprom_ctrl = 0;
	int err = 0;

	dev_dbg(dev, "%s++\n", __func__);

	/* eeprom interface */
/*
	err = s5k5e8_eeprom_device_init(priv);
	if (err && s_data->pdata->has_eeprom)
		dev_err(dev,
			"Failed to allocate eeprom reg map: %d\n", err);
	eeprom_ctrl = !err;
*/
	err = camera_common_mclk_enable(s_data);
	if (err) {
		dev_err(dev,
			"Error %d turning on mclk\n", err);
		return err;
	}

	err = s5k5e8_power_on(s_data);
	if (err) {
		dev_err(dev,
			"Error %d during power on sensor\n", err);
		return err;
	}
	

// error:
//	s5k5e8_power_off(s_data);
//	camera_common_mclk_disable(s_data);
	return err;
}

static void s5k5e8_debugfs_remove(struct s5k5e8 *priv)
{
	debugfs_remove_recursive(priv->debugfs_dir);
	priv->debugfs_dir = NULL;
}

static int s5k5e8_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 s5k5e8_subdev_internal_ops = {
	.open = s5k5e8_open,
};

static int s5k5e8_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct device_node *node = client->dev.of_node;
	struct tegracam_device *tc_dev;
	struct s5k5e8 *priv;
	int err;
	const struct of_device_id *match;

	dev_info(dev, "probing v4l2 sensor.\n");

	match = of_match_device(s5k5e8_of_match, dev);
	if (!match) {
		dev_err(dev, "No device match found\n");
		return -ENODEV;
	}

	if (!IS_ENABLED(CONFIG_OF) || !node)
		return -EINVAL;

	priv = devm_kzalloc(dev,
			    sizeof(struct s5k5e8), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	tc_dev = devm_kzalloc(dev,
			    sizeof(struct tegracam_device), GFP_KERNEL);
	if (!tc_dev)
		return -ENOMEM;

	priv->i2c_client = tc_dev->client = client;
	tc_dev->dev = dev;
	strncpy(tc_dev->name, "s5k5e8", sizeof(tc_dev->name));
	tc_dev->dev_regmap_config = &s5k5e8_regmap_config;
	tc_dev->sensor_ops = &s5k5e8_common_ops;
	tc_dev->v4l2sd_internal_ops = &s5k5e8_subdev_internal_ops;
	tc_dev->tcctrl_ops = &s5k5e8_ctrl_ops;

	err = tegracam_device_register(tc_dev);
	if (err) {
		dev_err(dev, "tegra camera driver registration failed\n");
		return err;
	}

	priv->tc_dev = tc_dev;
	priv->s_data = tc_dev->s_data;
	priv->subdev = &tc_dev->s_data->subdev;
	tegracam_set_privdata(tc_dev, (void *)priv);
	mutex_init(&priv->streaming_lock);

	err = s5k5e8_board_setup(priv);
		if (err) {
			dev_err(dev, "board setup failed\n");
			return err;
	}

	err = tegracam_v4l2subdev_register(tc_dev, true);
	if (err) {
		dev_err(dev, "tegra camera subdev registration failed\n");
		return err;
	}

	err = s5k5e8_debugfs_create(priv);
	if (err) {
		dev_err(dev, "error creating debugfs interface");
		s5k5e8_debugfs_remove(priv);
		return err;
	}

	dev_dbg(dev, "Detected S5K5E8 sensor\n");

	return 0;
}

static int
s5k5e8_remove(struct i2c_client *client)
{
	struct camera_common_data *s_data = to_camera_common_data(&client->dev);
	struct s5k5e8 *priv = (struct s5k5e8 *)s_data->priv;

	s5k5e8_debugfs_remove(priv);

	tegracam_v4l2subdev_unregister(priv->tc_dev);
	s5k5e8_power_put(priv->tc_dev);
	tegracam_device_unregister(priv->tc_dev);

	mutex_destroy(&priv->streaming_lock);

	return 0;
}

static const struct i2c_device_id s5k5e8_id[] = {
	{ "s5k5e8", 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, s5k5e8_id);

static struct i2c_driver s5k5e8_i2c_driver = {
	.driver = {
		.name = "s5k5e8",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(s5k5e8_of_match),
	},
	.probe = s5k5e8_probe,
	.remove = s5k5e8_remove,
	.id_table = s5k5e8_id,
};
module_i2c_driver(s5k5e8_i2c_driver);

MODULE_DESCRIPTION("Media Controller driver for Samsung S5K5E8");
MODULE_AUTHOR("NVIDIA Corporation");
MODULE_LICENSE("GPL v2");

You should disable the plugin manager if your sensor board didn’t have EEPROM for auto detect.

https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fcamera_sensor_prog.html%23wwpID0E01F0HA

As you mentioned, I modified it with reference to “Using the main Platform device tree file” in “camera sensor programming guide”.
However, the device “/ dev / video0” is not registered.

Compared dmesg by connecting ov5693 camera board and custom board.
ov5693 has confirmed the following message.
[b]ov5693 2-0036: probing v4l2 sensor.
ov5693 2-0036: tegracam sensor driver: ov5693_v2.0.6

tegra-vi4 15700000.vi: initialized
tegra-vi4 15700000.vi: subdev 150c0000.nvcsi–1 bound
tegra-vi4 15700000.vi: subdev ov5693 2-0036 bound[/b]

On the custom board, only the following message is shown.
tegra-vi4 15700000.vi: initialized
tegra-vi4 15700000.vi: ep of_device is not enabled / host1x / vi @ 15700000 / ports / port @ 0 / endpoint

If only dtsi is registered correctly, will “dev / video0” be enabled?
Or should the device driver code run without problems?

Looks like the device tree have problem cause the VI driver failed. Below was my try.

diff --git a/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts b/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
index f498a54..ded1d73 100644
--- a/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
+++ b/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
@@ -15,7 +15,9 @@

 #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-quill-camera-e3326-a00.dtsi>

 #include <t18x-common-modules/tegra186-display-e3320-1000-a00.dtsi>

 /* comms dtsi file should be included after gpio dtsi file */
@@ -24,7 +26,7 @@
 #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>

 / {
        model = "quill";
diff --git a/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dts b/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dts
index c244a9c..85c0dc6 100644
--- a/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dts
+++ b/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dts
@@ -15,6 +15,7 @@
  */

 #include "tegra186-quill-p3310-1000-a00-00-base.dts"
+#include <t18x-common-platforms/tegra186-quill-camera-modules.dtsi>

 / {
        nvidia,dtsfilename = __FILE__;

Please, Check the modified progress.
I don’t understand where can i modified VI driver is correct.

I wrote the process of my modification.

  1. Locate the following file:
    hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dsi
  2. In the DTSI, remove the following line:
    //#include <t18x-common-plugin-manager/tegra186-quill-camera-plugin-manager.dtsi>
#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-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>
  1. Locate the following file:
    hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-camera-modules.dtsi
  2. In the DTSI, add the following line: (custom camera sensor )
    #include “t18x-common-platforms/tegra186-quill-camera-s5k5e8-a00.dtsi”
#include "t18x-common-platforms/tegra186-quill-camera-e3326-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-e3323-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-e3331-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-e3333-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-e3322-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-imx185-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-imx274-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-imx274-dual.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-imx390-a00.dtsi"
#include "t18x-common-platforms/tegra186-quill-camera-vivid.dtsi"

#include "t18x-common-platforms/tegra186-quill-camera-s5k5e8-a00.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)
  1. Locate the following file:
    hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-module/
  2. Add file tegra186-camera-s5k5e8-a00.dtsi file modified from tegra186-camera-e3326-a00.dtsi file

Custom camera connection uses the same CAM_CSI_C port as the OV5693 and uses MIPI CIS-2 2lane.
no focus driver and flash.

/ {
	host1x {
		vi@15700000 {
			num-channels = <1>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					e3327_vi_in0: endpoint {
						port-index = <2>;
						bus-width = <2>;
						remote-endpoint = <&e3327_csi_out0>;
					};
				};
			};
		};

		nvcsi@150c0000 {
			num-channels = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						e3327_csi_in0: endpoint@0 {
							port-index = <2>;
							bus-width = <2>;
							remote-endpoint = <&e3327_s5k5e8_out0>;
						};
					};
					port@1 {
						reg = <1>;
						e3327_csi_out0: endpoint@1 {
							remote-endpoint = <&e3327_vi_in0>;
						};
					};
				};
			};
		};
	};

	i2c@3180000 {
		s5k5e8_c@20 {
			compatible = "nvidia,s5k5e8";
			/* I2C device address */
			reg = <0x20>;

			/* V4L2 device node location */
			devnode = "video0";

			/* Physical dimensions of sensor */
			physical_w = "4.675";
			physical_h = "3.633";

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

			/* Sensor output flip settings */
			vertical-flip = "true";


			mode0 { // S5K5E8_MODE_2608X1960
				mclk_khz = "24000";
				num_lanes = "2";
				tegra_sinterface = "serial_c";
				phy_mode = "DPHY";
				discontinuous_clk = "no";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "2608";
				active_h = "1960";
				mode_type = "bayer";
				pixel_phase = "grbg";
				csi_pixel_bit_depth = "10";
				readout_orientation = "90";
				line_length = "2856";
				inherent_gain = "1";
				mclk_multiplier = "7";
				pix_clk_hz = "170000000";

				gain_factor = "10";
				min_gain_val = "1";/* 1DB*/
				max_gain_val = "16";/* 16DB*/
				step_gain_val = "1";
				default_gain = "10";
				min_hdr_ratio = "";
				max_hdr_ratio = "";
				framerate_factor = "1000000";
				min_framerate = "2000000";/*1.816577 */
				max_framerate = "30000000";/*30*/
				step_framerate = "1";
				default_framerate = "30000000";
				exposure_factor = "1000000";
				min_exp_time = "34";/* us */
				max_exp_time = "279384";/* us */
				step_exp_time = "1";
				default_exp_time = "33334";/* us */
				embedded_metadata_height = "0";
			};

			mode1 { //S5K5E8_MODE_1304X980
				mclk_khz = "24000";
				num_lanes = "2";
				tegra_sinterface = "serial_c";
				phy_mode = "DPHY";
				discontinuous_clk = "no";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "1340";
				active_h = "980";
				mode_type = "bayer";
				pixel_phase = "grbg";
				csi_pixel_bit_depth = "10";
				readout_orientation = "90";
				line_length = "2856";
				inherent_gain = "1";
				mclk_multiplier = "7";
				pix_clk_hz = "170000000";

				gain_factor = "10";
				min_gain_val = "1";/* 1DB*/
				max_gain_val = "16";/* 16DB*/
				step_gain_val = "1";
				default_gain = "10";
				min_hdr_ratio = "";
				max_hdr_ratio = "";
				framerate_factor = "1000000";
				min_framerate = "1816577";/*1.816577 */
				max_framerate = "60000000";/*30*/
				step_framerate = "1";
				default_framerate = "60000000";
				exposure_factor = "1000000";
				min_exp_time = "34";/* us */
				max_exp_time = "279384";/* us */
				step_exp_time = "1";
				default_exp_time = "33334";/* us */
				embedded_metadata_height = "0";
			};


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

				port@0 {
					reg = <0>;
					e3327_s5k5e8_out0: endpoint {
						port-index = <2>;
						bus-width = <2>;
						remote-endpoint = <&e3327_csi_in0>;
					};
				};
			};
		};
	};


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

		num_csi_lanes = <2>;
		max_lane_speed = <1000000>;     
		min_bits_per_pixel = <10>;
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		max_pixel_rate = <100000>;
		isp_peak_byte_per_pixel = <5>;
		isp_bw_margin_pct = <25>;


		modules {
			module0 {
				badge = "e3327_front_s5k5e8";
				position = "front";
				orientation = "1";
				drivernode0 {
					/* Declare PCL support driver (classically known as guid)  */
					pcl_id = "v4l2_sensor";
					/* Driver v4l2 device name */
					devname = "s5k5e8 2-0020";
					/* Declare the device-tree hierarchy to driver instance */
					proc-device-tree = "/proc/device-tree/i2c@3180000/s5k5e8_c@20";
				};
			};
		};
	};
};

please check reply.

the device “/dev/video0” is not registered yet.

Can I ask you advice about something?

Should be like below.

diff --git a/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts b/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
index f498a54..ded1d73 100644
--- a/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
+++ b/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
@@ -15,7 +15,9 @@

 #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-quill-camera-imx274-dual.dtsi>   /* <b>Replace to your sensor dts</b> */

 #include <t18x-common-modules/tegra186-display-e3320-1000-a00.dtsi>

 /* comms dtsi file should be included after gpio dtsi file */
@@ -24,7 +26,7 @@
 #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 <t18x-common-plugin-manager/tegra186-quill-camera-plugin-manager.dtsi>

 / {
        model = "quill";
diff --git a/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dts b/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dts
index c244a9c..85c0dc6 100644
--- a/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dts
+++ b/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dts
@@ -15,6 +15,7 @@
  */

 #include "tegra186-quill-p3310-1000-a00-00-base.dts"
+#include <t18x-common-platforms/tegra186-quill-camera-modules.dtsi>

 / {
        nvidia,dtsfilename = __FILE__;

Thank you for advise.

As you recommend it.
but it has compile error.

these label are custom camera sensor node in tegra186-camera-s5k5e8-a00.dtsi.

/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-modules/tegra186-display-e3320-1000-a00.dtsi>
<b>#include <t18x-common-modules/tegra186-camera-s5k5e8-a00.dtsi></b>     <b>/* add my sensor dts*/</b>


/* 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>

device tree compiled
jpchae@ubuntu:~/kernel_32.1/public_sources$ make -C kernel/kernel-4.9/ ARCH=arm64 O=$KERNEL_OUT CROSS_COMPILE=${CROSS_COMPILE} -j2 dtbs

error message As shown below.

make: Entering directory '/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9'
make[1]: Entering directory '/home/jpchae/kernel_32.1/public_sources/build'
  CHK     scripts/mod/devicetable-offsets.h
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-ape-cam.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-edp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-dsi-hdmi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-dsi-hdmi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-dsi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-c03-00.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-a00-00.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base-mods-display.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-imx274.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-imx185_v1.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-a00-00-imx274.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-c03-00-imx274.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-ape-cam.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-imx185_v1.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-dsi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c00-00-auo-1080p-edp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-e3313-1000-a00-00-e2598.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3489-1000-a00-00-ucm1.dtb
ERROR (phandle_references): Reference to non-existent node or label "e3327_vi_in0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_csi_out0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_csi_in0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_s5k5e8_out0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_csi_out0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_vi_in0"

ERROR: Input tree has errors, aborting (use -f to force output)
/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9/arch/arm64/boot/dts/Makefile:120: recipe for target 'arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3489-1000-a00-00-ucm1.dtb' failed
make[2]: *** [arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3489-1000-a00-00-ucm1.dtb] Error 2
make[2]: *** Waiting for unfinished jobs....
arch/arm64/Makefile:154: recipe for target 'dtbs' failed
make[1]: *** [dtbs] Error 2
make[1]: Leaving directory '/home/jpchae/kernel_32.1/public_sources/build'
Makefile:171: recipe for target 'sub-make' failed
make: *** [sub-make] Error 2
make: Leaving directory '/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9'

please give me advise.

You need to remove this line.

-#include <t18x-common-platforms/tegra186-quill-camera-modules.dtsi>

Thanks ShaneCCC,

I remove the line.
//#include <t18x-common-platforms/tegra186-quill-camera-modules.dtsi>

but bug is not fixed.

error message As shown below.

I didn’t modified in kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dtb

jpchae@ubuntu:~/kernel_32.1/public_sources$ make -C kernel/kernel-4.9/ ARCH=arm64 O=$KERNEL_OUT CROSS_COMPILE=${CROSS_COMPILE} -j2 dtbs 
make: Entering directory '/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9'
make[1]: Entering directory '/home/jpchae/kernel_32.1/public_sources/build'
  CHK     scripts/mod/devicetable-offsets.h
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-ape-cam.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-edp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-dsi-hdmi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-dsi-hdmi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-dsi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-c03-00.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-a00-00.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base-mods-display.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-imx274.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-imx185_v1.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dtb
ERROR (phandle_references): Reference to non-existent node or label "cam_module0_drivernode1"

ERROR (phandle_references): Reference to non-existent node or label "cam_module1_drivernode1"

ERROR (phandle_references): Reference to non-existent node or label "vi_base"

ERROR: Input tree has errors, aborting (use -f to force output)
/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9/arch/arm64/boot/dts/Makefile:120: recipe for target 'arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dtb' failed
make[2]: *** [arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-lc898212.dtb] Error 2
make[2]: *** Waiting for unfinished jobs....
arch/arm64/Makefile:154: recipe for target 'dtbs' failed
make[1]: *** [dtbs] Error 2
make[1]: Leaving directory '/home/jpchae/kernel_32.1/public_sources/build'
Makefile:171: recipe for target 'sub-make' failed
make: *** [sub-make] Error 2
make: Leaving directory '/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9'

Modify the Makefile to remove tegra186-quill-p3310-1000-a00-00-lc898212.dtb you don’t need to compile this one.

Thanks ShaneCCC,

Modified Makefile in " /hardware/nvidia/platform/t18x/quill/kerne-dts/Makefile "

Removed all references below tegra186-quill-p3310-1000-a00-00-lc898212.dtb from the Makefile.

old-dtb := $(dtb-y)
old-dtbo := $(dtbo-y)
dtb-y :=
dtbo-y :=
makefile-path := platform/t18x/quill/kernel-dts

dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-base.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-ape-cam.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-edp.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-dsi-hdmi-dp.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-c03-00-dsi-hdmi-dp.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-dsi-dp.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-hdmi-primary-p3310-1000-c03-00.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-hdmi-primary-p3310-1000-a00-00.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-base-mods-display.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-imx274.dtb
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-imx185_v1.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-00-lc898212.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-hdmi-primary-p3310-1000-a00-00-imx274.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-hdmi-primary-p3310-1000-c03-00-imx274.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-c03-00-ape-cam.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-c03-00-base.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-c03-00-imx185_v1.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-c03-00-dsi-dp.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-c00-00-auo-1080p-edp.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-e3313-1000-a00-00-e2598.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3489-1000-a00-00-ucm1.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3489-1000-a00-00-ucm2.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3489-1000-a00-00-e2598.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3489-0888-a00-00-base.dtb
#dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3489-0888-a00-00-e2598.dtb

dtbo-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-a00-overlay.dtbo
dtb-$(CONFIG_ARCH_TEGRA_18x_SOC) += tegra186-quill-p3310-1000-as-0888.dtb

ifneq ($(dtb-y),)
dtb-y := $(addprefix $(makefile-path)/,$(dtb-y))
dtbo-y := $(addprefix $(makefile-path)/,$(dtbo-y))
dts-include += $(makefile-path)
endif

dtb-y += $(old-dtb)
dtbo-y += $(old-dtbo)

but error is not fixed yet.

I think my custom camera device tree dtsi file is something wrong.

because error labels are defined in my custom file.<t18x-common-modules/tegra186-camera-s5k5e8-a00.dtsi>

jpchae@ubuntu:~/kernel_32.1/public_sources$ make -C kernel/kernel-4.9/ ARCH=arm64 O=$KERNEL_OUT CROSS_COMPILE=${CROSS_COMPILE} -j2 dtbs 
make: Entering directory '/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9'
make[1]: Entering directory '/home/jpchae/kernel_32.1/public_sources/build'
  CHK     scripts/mod/devicetable-offsets.h
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-ape-cam.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-edp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-dsi-hdmi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-dsi-hdmi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-dsi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-c03-00.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-a00-00.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base-mods-display.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-imx274.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-imx185_v1.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-a00-00-imx274.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-hdmi-primary-p3310-1000-c03-00-imx274.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-ape-cam.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-base.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-imx185_v1.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-dsi-dp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c00-00-auo-1080p-edp.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-e3313-1000-a00-00-e2598.dtb
  DTC     arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-as-0888.dtb
ERROR (phandle_references): Reference to non-existent node or label "e3327_vi_in0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_csi_out0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_csi_in0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_s5k5e8_out0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_csi_out0"

ERROR (phandle_references): Reference to non-existent node or label "e3327_vi_in0"

ERROR: Input tree has errors, aborting (use -f to force output)
/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9/arch/arm64/boot/dts/Makefile:120: recipe for target 'arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-as-0888.dtb' failed
make[2]: *** [arch/arm64/boot/dts/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/_ddot_/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-as-0888.dtb] Error 2
make[2]: *** Waiting for unfinished jobs....
arch/arm64/Makefile:154: recipe for target 'dtbs' failed
make[1]: *** [dtbs] Error 2
make[1]: Leaving directory '/home/jpchae/kernel_32.1/public_sources/build'
Makefile:171: recipe for target 'sub-make' failed
make: *** [sub-make] Error 2
make: Leaving directory '/home/jpchae/kernel_32.1/public_sources/kernel/kernel-4.9'

I attached my custom camera sensor dtsi.

please let me know my error code.

/ {
	host1x {
		vi@15700000 {
			num-channels = <1>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					status = "okay";
					reg = <0>;
					e3327_vi_in0: endpoint {
						port-index = <2>;
						bus-width = <2>;
						remote-endpoint = <&e3327_csi_out0>;
					};
				};
			};
		};

		nvcsi@150c0000 {
			num-channels = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						status = "okay";
						reg = <0>;
						e3327_csi_in0: endpoint@0 {
							port-index = <2>;
							bus-width = <2>;
							remote-endpoint = <&e3327_s5k5e8_out0>;
						};
					};
					port@1 {
						status = "okay";
						reg = <1>;
						e3327_csi_out0: endpoint@1 {
							remote-endpoint = <&e3327_vi_in0>;
						};
					};
				};
			};
		};
	};

	i2c@3180000 {
		s5k5e8_c@20 {
			compatible = "nvidia,s5k5e8";
			/* I2C device address */
			reg = <0x20>;
			status = "okay";
			/* V4L2 device node location */
			devnode = "video0";

			/* Physical dimensions of sensor */
			physical_w = "4.675";
			physical_h = "3.633";

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

			/* Sensor output flip settings */
			vertical-flip = "true";

			mode0 { // S5K5E8_MODE_2608X1960
				mclk_khz = "24000";
				num_lanes = "2";
				tegra_sinterface = "serial_c";
				phy_mode = "DPHY";
				discontinuous_clk = "no";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "2608";
				active_h = "1960";
				mode_type = "bayer";
				pixel_phase = "grbg";
				csi_pixel_bit_depth = "10";
				readout_orientation = "90";
				line_length = "2856";
				inherent_gain = "1";
				mclk_multiplier = "7";
				pix_clk_hz = "170000000";

				gain_factor = "10";
				min_gain_val = "1";/* 1DB*/
				max_gain_val = "16";/* 16DB*/
				step_gain_val = "1";
				default_gain = "10";
				min_hdr_ratio = "";
				max_hdr_ratio = "";
				framerate_factor = "1000000";
				min_framerate = "2000000";/*1.816577 */
				max_framerate = "30000000";/*30*/
				step_framerate = "1";
				default_framerate = "30000000";
				exposure_factor = "1000000";
				min_exp_time = "34";/* us */
				max_exp_time = "279384";/* us */
				step_exp_time = "1";
				default_exp_time = "33334";/* us */
				embedded_metadata_height = "0";
			};

			mode1 { //S5K5E8_MODE_1304X980
				mclk_khz = "24000";
				num_lanes = "2";
				tegra_sinterface = "serial_c";
				phy_mode = "DPHY";
				discontinuous_clk = "no";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "1340";
				active_h = "980";
				mode_type = "bayer";
				pixel_phase = "grbg";
				csi_pixel_bit_depth = "10";
				readout_orientation = "90";
				line_length = "2856";
				inherent_gain = "1";
				mclk_multiplier = "7";
				pix_clk_hz = "170000000";

				gain_factor = "10";
				min_gain_val = "1";/* 1DB*/
				max_gain_val = "16";/* 16DB*/
				step_gain_val = "1";
				default_gain = "10";
				min_hdr_ratio = "";
				max_hdr_ratio = "";
				framerate_factor = "1000000";
				min_framerate = "1816577";/*1.816577 */
				max_framerate = "60000000";/*30*/
				step_framerate = "1";
				default_framerate = "60000000";
				exposure_factor = "1000000";
				min_exp_time = "34";/* us */
				max_exp_time = "279384";/* us */
				step_exp_time = "1";
				default_exp_time = "33334";/* us */
				embedded_metadata_height = "0";
			};


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

				port@0 {
					reg = <0>;
					e3327_s5k5e8_out0: endpoint {
						port-index = <2>;
						bus-width = <2>;
						remote-endpoint = <&e3327_csi_in0>;
					};
				};
			};
		};
	};


	tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";
		num_csi_lanes = <2>;
		max_lane_speed = <1000000>;     //1500000 --> 1000000
		min_bits_per_pixel = <10>;
		vi_peak_byte_per_pixel = <2>;
		vi_bw_margin_pct = <25>;
		max_pixel_rate = <100000>;
		isp_peak_byte_per_pixel = <5>;
		isp_bw_margin_pct = <25>;

		modules {
			module0 {
				badge = "e3327_front_s5k5e8";
				position = "front";
				orientation = "1";
				drivernode0 {
					status = "okay";
					/* Declare PCL support driver (classically known as guid)  */
					pcl_id = "v4l2_sensor";
					/* Driver v4l2 device name */
					devname = "s5k5e8 2-0020";
					/* Declare the device-tree hierarchy to driver instance */
					proc-device-tree = "/proc/device-tree/i2c@3180000/s5k5e8_c@20";
				};
			};
		};
	};
};

Remove those Makefile except the quill/kernel-dts/Makefile

…/32.3/hardware/nvidia/platform/t18x$ find -name Makefile

./quill-internal/kernel-dts/Makefile
./orca/kernel-dts/Makefile
./quill-dev/kernel-dts/Makefile
./quill/kernel-dts/Makefile
./dragonfly/kernel-dts/Makefile

Hi ShaneCCC,

Thank you for your detail advise.

first of all , I fixed compile error.
I was install 32.3.1 kernel. and modified dtsi code as your advise .

anyway, These location were not found when searching for Makefiles.

I was flash the dtb file on Jeston TX2.
but, it stil not register “dev/video0” yet.

In order for the device driver “dev/video0” to be registered,
does the dtb file and device driver file in kernel work together?

my custom device driver is still debugging.

Does below message still showing?

tegra-vi4 15700000.vi: ep of_device is not enabled / host1x / vi @ 15700000 / ports / port @ 0 / endpoint

Hi ShaneCCC,

It does not display message.

I search dmesg about “tegra-vi4” as shown below.

[ 1.462822] tegra-vi4 15700000.vi: initialized
[ 1.463673] tegra-vi4 15700000.vi: subdev 150c0000.nvcsi–1 bound

How about the sensor probe message?
Below is the reference code that working for me.

https://devtalk.nvidia.com/default/topic/1072057/jetson-agx-xavier/xavier-using-raw-csi-without-i2c/post/5433520/#5433520

Hi ShanesCCC,

my custom sensor probe message as shown below

[ 1925.918638] s5k5e8 2-0020: probing v4l2 sensor.
[ 1925.918724] s5k5e8 2-0020: s5k5e8 enter_parse_dt
[ 1925.923633] s5k5e8 2-0020: Failed to find clocks
[ 1925.928327] s5k5e8 2-0020: unable to get platform data
[ 1925.933608] s5k5e8 2-0020: tegra camera driver registration failed
[ 1925.939920] s5k5e8: probe of 2-0020 failed with error -14

I think s5k5e8_parse_dt function is something wrong.

static struct camera_common_pdata *s5k5e8_parse_dt(struct tegracam_device
							*tc_dev)
{

	struct device *dev = tc_dev->dev;
	struct device_node *node = 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;

	dev_err(dev, "s5k5e8 enter_parse_dt\n");
	if (!node){
		
		return NULL;
	}	
	match = of_match_device(s5k5e8_of_match, dev);
	if (!match) {
		dev_err(dev, "Failed to find matching dt id\n");
		return NULL;
	}

	board_priv_pdata = devm_kzalloc(dev,
			   sizeof(*board_priv_pdata), GFP_KERNEL);
	if (!board_priv_pdata)
		return NULL;

	err = camera_common_parse_clocks(dev,
					 board_priv_pdata);
	if (err) {
		dev_err(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;
		}
		gpio = 0;
	}
	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(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(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(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(dev, board_priv_pdata);
	return ret;

}

It’s could be lost the information like below file define.

…/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-camera-e3326-a00.dtsi

#include <t18x-common-modules/tegra186-camera-e3326-a00.dtsi>
#include "dt-bindings/clock/tegra186-clock.h"
 
#define CAM0_RST_L	TEGRA_MAIN_GPIO(R, 5)
#define CAM0_PWDN	TEGRA_MAIN_GPIO(R, 0)
 
/* camera control gpio definitions */

/ {
	i2c@3180000 {
		ov5693_c@36 {
			/* Define any required hw resources needed by driver */
			/* ie. clocks, io pins, power sources */
 			/* mclk-index indicates the index of the */
 			/* mclk-name with in the clock-names array */
 
 			clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH1>,
 					 <&tegra_car TEGRA186_CLK_PLLP_OUT0>;
 			clock-names = "extperiph1", "pllp_grtba";
 			mclk = "extperiph1";
 			clock-frequency = <24000000>;
 			reset-gpios = <&tegra_main_gpio CAM0_RST_L GPIO_ACTIVE_HIGH>;
 			pwdn-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;
 			vana-supply = <&en_vdd_cam_hv_2v8>;
 			vif-supply = <&en_vdd_cam>;
 		};
 	};
 
 	gpio@2200000 {
 		camera-control-output-low {
 			gpio-hog;
 			output-low;
 			gpios = <CAM0_RST_L 0 CAM0_PWDN 0>;
 			label = "cam0-rst", "cam0-pwdn";
 		};
 	};
 };

Hi ShaneCCC,

As your advise.
I’m modify dtsi file " tegra186-quill-p3310-1000-a00-00-base.dts"
add dtsi file <t18x-common-platforms/tegra186-quill-camera-s5k5e8-a00.dtsi>

#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>
<b>#include <t18x-common-platforms/tegra186-quill-camera-s5k5e8-a00.dtsi></b>
#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>

I think s5k5e8_parse_dt function is pass.

but i2c error message as shown below.

Is this a problem with device tree definition? or where should I check?

[  154.329788] s5k5e8 2-0020: probing v4l2 sensor.
[  154.329825] s5k5e8 2-0020: s5k5e8 enter_parse_dt
[  154.335244] s5k5e8 2-0020: tegracam sensor driver:s5k5e8_v2.0.6
[b][  154.345801] tegra-i2c 3180000.i2c: arb lost in communicate to add 0x20
[  154.352488] tegra-i2c 3180000.i2c: Un-recovered Arb lost[/b]
[  154.357908] s5k5e8 2-0020: s5k5e8_write_reg: i2c write failed, 0x204 = 0
[  154.364674] s5k5e8 2-0020: Error -5 in control hdl setup
[  154.370015] s5k5e8 2-0020: Failed to init ctrls s5k5e8
[  154.375169] s5k5e8 2-0020: tegra camera subdev registration failed
[  154.381470] s5k5e8: probe of 2-0020 failed with error -5