NvOdmDevice ModuleNotPresent

I ported my driver (GitHub - Daxbot/daxc02: Nvidia Jetson TX1/TX2 Kernel Driver for Leopard Imaging LI-M021C-MIPI) over to the TX2 and everything is almost working. The board we use has two camera modules, one on CSI-A and one on CSI-C. The camera on C works great, no problems at all, but the one on CSI-A quits immediately with:

Setting pipeline to PAUSED ...
Socket read error. Camera Daemon stopped functioning.....
gst_nvcamera_open() failed ret=0
ERROR: Pipeline doesn't want to pause.
Setting pipeline to NULL ...
Freeing pipeline ...

NvCameraDeamon reports the following block of errors:

(NvOdmDevice) Error ModuleNotPresent: V4L2Device not available (in dvs/git/dirty/git-master_linux/camera-partner/imager/src/V4L2Device.cpp, function findDevice(), line 245)
(NvOdmDevice) Error ModuleNotPresent:  (propagating from dvs/git/dirty/git-master_linux/camera-partner/imager/src/V4L2Device.cpp, function initialize(), line 55)
(NvOdmDevice) Error ModuleNotPresent:  (propagating from dvs/git/dirty/git-master_linux/camera-partner/imager/src/devices/V4L2SensorViCsi.cpp, function initialize(), line 103)
NvPclDriverInitializeData: Unable to initialize driver v4l2_sensor
NvPclInitializeDrivers: error: Failed to init camera sub module v4l2_sensor
NvPclStartPlatformDrivers: Failed to start module drivers
NvPclStateControllerOpen: Failed ImagerGUID 1. (error 0xA000E)
NvPclOpen: PCL Open Failed. Error: 0xf
SCF: Error BadParameter: Sensor could not be opened. (in src/services/capture/CaptureServiceDeviceSensor.cpp, function getSourceFromGuid(), line 598)
SCF: Error BadParameter:  (propagating from src/services/capture/CaptureService.cpp, function addSourceByGuid(), line 781)
SCF: Error BadParameter:  (propagating from src/api/CameraDriver.cpp, function addSourceByIndex(), line 276)
SCF: Error BadParameter:  (propagating from src/api/CameraDriver.cpp, function getSource(), line 439)
./debug_daemon.sh: line 7:  2231 Segmentation fault      (core dumped) sudo /usr/sbin/nvcamera-daemon

Recording directly with v4l2-ctl works fine, v4l2-compliance passes.

It seems like a class device tree issue. The part about “Unable to initialize driver v4l2_sensor” and references to modules makes me think it’s my the tegra-camera-platform node that has an issue. But I don’t see anything different between the module that works and the module that doesn’t.

Here’s the DTSI:

What causes the “ModuleNotPresent” error?

Check the devname in the tegra-camera-platform is the match with name show with the command v4l2-ctl --list-devices

I plugged in only one camera on the non-working, and working sides respectively. The working side seems to generate an extra subdev node?

Non-working side:

nvidia@tegra-ubuntu:~$ v4l2-ctl --list-devices --verbose
VIDIOC_QUERYCAP: failed: Inappropriate ioctl for device
VIDIOC_QUERYCAP: failed: Inappropriate ioctl for device
vi-output, daxc02 2-0010 (platform:15700000.vi:0):
	/dev/video0
	/dev/v4l-subdev1
	/dev/v4l-subdev0

VIDIOC_QUERYCAP: ok
nvidia@tegra-ubuntu:~$ dmesg | grep subdev
[    2.573677] THERMAL EST: found 3 subdevs
[    2.573700] [THERMAL EST subdev 0]
[    2.573712] [THERMAL EST subdev 1]
[    2.573722] [THERMAL EST subdev 2]
[    3.858872] tegra-vi4 15700000.vi: subdev 150c0000.nvcsi-0 bound
[    3.858875] tegra-vi4 15700000.vi: subdev daxc02 2-0010 bound
[    3.859141] tegra-vi4 15700000.vi: subdev 150c0000.nvcsi-2 bound

Working side:

nvidia@tegra-ubuntu:~$ v4l2-ctl --list-devices --verbose
VIDIOC_QUERYCAP: failed: Inappropriate ioctl for device
VIDIOC_QUERYCAP: failed: Inappropriate ioctl for device
VIDIOC_QUERYCAP: failed: Inappropriate ioctl for device
vi-output, daxc02 1-0010 (platform:15700000.vi:2):
	/dev/video0
	/dev/v4l-subdev2
	/dev/v4l-subdev1
	/dev/v4l-subdev0

VIDIOC_QUERYCAP: ok
nvidia@tegra-ubuntu:~$ dmesg | grep subdev
[    2.675018] THERMAL EST: found 3 subdevs
[    2.684435] [THERMAL EST subdev 0]
[    2.688595] [THERMAL EST subdev 1]
[    2.692745] [THERMAL EST subdev 2]
[    4.429654] tegra-vi4 15700000.vi: subdev 150c0000.nvcsi-0 bound
[    4.429707] tegra-vi4 15700000.vi: subdev 150c0000.nvcsi-2 bound
[    4.429709] tegra-vi4 15700000.vi: subdev daxc02 1-0010 bound

tegra-camera-platform modules:

modules {
    module0 {
        badge = "daxc02_master_mt9m021";
        position = "rear";
        orientation = "0";
        status = "okay";
        drivernode0 {
            pcl_id = "v4l2_sensor";
            devname = "daxc02 2-0010";
            proc-device-tree = "/proc/device-tree/i2c@3180000/daxc02_a@10";
            status = "okay";
        };
    };
    module1 {
        badge = "daxc02_slave_mt9m021";
        position = "front";
        orientation = "1";
        status = "okay";
        drivernode0 {
            pcl_id = "v4l2_sensor";
            devname = "daxc02 1-0010";
            proc-device-tree = "/proc/device-tree/i2c@c240000/daxc02_c@10";
            status = "okay";
        };
    };
};

Ok this is weird.

on a whim I swapped the modules. I changed module0 to module1, and vice versa. That swapped which camera works. Now “2-0010” will stream fine, and “1-0010” won’t open.

modules {
    module1 {
        badge = "daxc02_master_mt9m021";
        position = "rear";
        orientation = "0";
        status = "okay";
        drivernode0 {
            pcl_id = "v4l2_sensor";
            devname = "daxc02 2-0010";
            proc-device-tree = "/proc/device-tree/i2c@3180000/daxc02_a@10";
            status = "okay";
        };
    };
    module0 {
        badge = "daxc02_slave_mt9m021";
        position = "front";
        orientation = "1";
        status = "okay";
        drivernode0 {
            pcl_id = "v4l2_sensor";
            devname = "daxc02 1-0010";
            proc-device-tree = "/proc/device-tree/i2c@c240000/daxc02_c@10";
            status = "okay";
        };
    };
};

Does that point to something farther along in the pipeline being wrong?

Having a single module under tegra-camera-platform works. So it’s not explicitly module0.

modules {
    module0 {
        badge = "daxc02_slave_mt9m021";
        position = "front";
        orientation = "1";
        status = "okay";
        drivernode0 {
            pcl_id = "v4l2_sensor";
            devname = "daxc02 1-0010";
            proc-device-tree = "/proc/device-tree/i2c@c240000/daxc02_c@10";
            status = "okay";
        };
    };
};

And the other camera, also working

modules {
    module0 {
        badge = "daxc02_master_mt9m021";
        position = "rear";
        orientation = "0";
        status = "okay";
        drivernode0 {
            pcl_id = "v4l2_sensor";
            devname = "daxc02 2-0010";
            proc-device-tree = "/proc/device-tree/i2c@3180000/daxc02_a@10";
            status = "okay";
        };
    };
};

In summary:

  1. The issue only presents with more than one module, and seems to affect the first valid module in the list.

  2. The issue does not care about the explicit numbering or order. Having module0, module1, will cause module0 to not work. Having module1, module2, will cause module 1 not to work.

  3. The issue is not related to the content of the module. Swapping the number module0<->module1 will change which one works or fails.

  4. Inserting a fake module, ex fake module0, then valid module1 and module2, does not seem to help. But I may not have been able to create a convincing enough fake without adding a another definition for a different i2c port.

Didn’t you only have one sensor HW ? You must have two HW module otherwise that could be a problem.

I’ll get another camera to test with then. All but this one are being used on our other robots.

Both cameras plugged in and both working. Apparently you shouldn’t have anything extra in the device tree that isn’t being used.