ORIN NX无法生成/dev/video设备

您好,我使用36.3版本镜像,自己需要添加CSI摄像头的驱动,我新增了一个设备树,里面添加了video设备,但加载后实际并没有产生/dev/video设备,请问是我设备树哪里配置的不对么,如下是我设备树的源文件
tegra234-camera-gmsl-isx019.txt (27.3 KB)

hello tiancai1234,

please refer to developer guide, Verifying the V4L2 Sensor Driver and also Debugging Tips for troubleshooting.

您好,我使用36.2版本,同样的设备树的方法,是可以生成/dev/video*节点的,但是36.3同样的方法不行,请问这两个版本有什么大的区别么

hello tiancai1234,

please debug into it. you may share some error logs for cross checking.

这是我加载驱动之后的dmesg
err.log (71.3 KB)

这是36.2正常的日志
dmesg.txt (61.5 KB)

hello tiancai1234

is ISX019 your camera sensor? it should have video node registered as there’re several logs Detected ISX019 sensor.

the issue should be on sensor side, during kernel initialization stage, it’s step for camera device registration to setup a video device node to linux kernel. sensor probing only run once during kernel initialization stage of system boot-up.
for a typical camera application running cycle, the driver will Power On the sensor, Start Sensor Streaming, sending relevant v4l2 controls, and finally power off the sensor.
so…
if there’s a error returns, it’ll not register a video node, (/dev/video0).

detect应该是我没有插摄像头设备,但是我看36.2也有这个打印,不插摄像头也能生成/dev/video节点

hello tiancai1234

please check my previous update, if there’s a error returns, it’ll not register a video node, (/dev/video0).
let’s try have camera connected before power-on for confirmation.

经过调试,发现我的驱动中的prob函数里面的未执行isx019_subdev_internal_ops,这个是生成/dev/video节点的部分

static int isx019_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct device_node *node = dev->of_node;
	struct tegracam_device *tc_dev;
	struct isx019 *priv;
	int err;

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

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

	priv = devm_kzalloc(dev, sizeof(struct isx019), GFP_KERNEL);
	if (!priv) {
		dev_err(dev, "unable to allocate memory!\n");
		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, "isx019", sizeof(tc_dev->name));
	tc_dev->dev_regmap_config = &sensor_regmap_config;
	tc_dev->sensor_ops = &isx019_common_ops;
	tc_dev->v4l2sd_internal_ops = &isx019_subdev_internal_ops;
	tc_dev->tcctrl_ops = &isx019_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);

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

	/* Register sensor to deserializer dev */
	err = max9286_sdev_register(priv->dser_dev, &priv->g_ctx);
	if (err) {
		dev_err(&client->dev, "gmsl deserializer register failed\n");
		return err;
	}
	/*
	 * gmsl serdes setup
	 *
	 * Sensor power on/off should be the right place for serdes
	 * setup/reset. But the problem is, the total required delay
	 * in serdes setup/reset exceeds the frame wait timeout, looks to
	 * be related to multiple channel open and close sequence
	 * issue (#BUG 200477330).
	 * Once this bug is fixed, these may be moved to power on/off.
	 * The delays in serdes is as per guidelines and can't be reduced,
	 * so it is placed in probe/remove, though for that, deserializer
	 * would be powered on always post boot, until 1.2v is supplied
	 * to deserializer from CVB.
	 */
	err = isx019_gmsl_serdes_setup(priv);
	if (err) {
		dev_err(&client->dev,
			"%s gmsl serdes setup failed\n", __func__);
		return err;
	}

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


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

	return 0;
}


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

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

	return 0;
}

static const struct v4l2_subdev_internal_ops isx019_subdev_internal_ops = {
	.open = isx019_open,
};


hello tiancai1234,

you should have to use tegracam_ctrl_ops to define those standard operations.
and… it’s tegracam_ctrls.c to call CID controls to operate with your sensor driver.
for instance,
you should have below to define all the operations in your sensor driver.

static struct tegracam_ctrl_ops imx185_ctrl_ops = { 
        .set_gain = imx185_set_gain,
        .set_exposure = imx185_set_exposure,

here’s tegracam_set_ctrls for controlling standard IOCTLs.

static int tegracam_set_ctrls(struct tegracam_ctrl_handler *handler,
                        struct v4l2_ctrl *ctrl)
{
...
        case TEGRA_CAMERA_CID_GAIN:
                if (*ctrl->p_new.p_s64 == ctrlprops->max_gain_val + 1) 
                        return 0;
                err = ops->set_gain(tc_dev, *ctrl->p_new.p_s64);
                break;
        case TEGRA_CAMERA_CID_FRAME_RATE:
                err = ops->set_frame_rate(tc_dev, *ctrl->p_new.p_s64);
                break;

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