Getting /dev/video to show up without Platform Manager

I’m trying to implement a custom v4l2 driver following the Package Developer Guide “Sensor Driver Programming Guide” chapter. My device is recognized and probed on boot as expected, but I’m having trouble figuring out how to get /dev/video0 to show up for the device.

Experimentation with the devboard camera module on the Jetpack 2.3 24.2 sample filesystem shows this for when the ov5693 link is created:

[    8.467938] vi vi: vi_probe: ++
[    8.476586] vi vi: initialized
[    8.483313] vi vi: parsing node /host1x/vi
[    8.490723] vi vi: handling endpoint /host1x/vi/ports/port@0/endpoint
[    8.500500] vi vi: handling endpoint /host1x/vi/ports/port@1/endpoint
[    8.510172] vi vi: handling endpoint /host1x/vi/ports/port@2/endpoint
[    8.519688] vi vi: handling endpoint /host1x/vi/ports/port@3/endpoint
[    8.529088] vi vi: handling endpoint /host1x/vi/ports/port@4/endpoint
[    8.538315] vi vi: handling endpoint /host1x/vi/ports/port@5/endpoint
[    8.547503] vi vi: parsing node /host1x/i2c@546c0000/ov5693_c@36
[    8.556223] vi vi: handling endpoint /host1x/i2c@546c0000/ov5693_c@36/ports/port@0/endpoint
[    8.567381] vi vi: subdev ov5693 6-0036 bound
[    8.574501] vi vi: notify complete, all subdevs registered
[    8.582753] vi vi: creating links for entity ov5693 6-0036
[    8.591027] vi vi: processing endpoint /host1x/i2c@546c0000/ov5693_c@36/ports/port@0/endpoint
[    8.602423] vi vi: skipping channel port /host1x/i2c@546c0000/ov5693_c@36:0
[    8.612285] vi vi: creating links for channels
[    8.619617] vi vi: processing endpoint /host1x/vi/ports/port@0/endpoint
[    8.629167] vi vi: creating link for channel vi-output-2
[    8.637371] vi vi: creating ov5693 6-0036:0 -> vi-output-2:0 link

I’ve noticed that when I remove PluginManager support from the device tree as described in the “Device Registration” section of the programming guide that the ov5693 isn’t loaded at all and all that I can find for vi vi is:

[    7.456232] vi vi: vi_probe: ++
[    7.539544] vi vi: initialized
[    7.545952] vi vi: Failed to find num of channels, set TPG mode
[    7.555098] vi vi: Set TPG mode to 2

If I’m not using PluginManager how do I make the /dev/video0 link get created? My probe function registers the device as a media entity and does everything that the ov5693 driver does.

I thought I found the issue. The vi node in my dtb didn’t have num-channels defined.

I defined it to 1 just like the removed files did and now it doesn’t boot. Hmmmm.

I suppose that you are creating a driver for a MIPI camera, on which i2c bus are you using the camera? did you change the device tree to use the correct i2c bus?

Which camera are you trying to enable?

Maybe you can add your changes to the device tree?

The camera is on i2c bus 6 using CSI-A. I’m reasonably sure I have the correct i2c bus because probe is being called and i2cdetect shows that the camera address is in use by a driver.

My dtsi is also definitely being compiled in. I decompiled the blob with dtc just to make sure.

Here’s my dtsi based on how ov5693_c@36 is defined.

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

/ {
    host1x {
        vi {
            num-channels = <0x1>;
            ports {
                #address-cells = <0x1>;
                #size-cells = <0x0>;

                port@0 { // CSI A
                    reg = <0x0>;
                    status = "okay";
                    daxc02_vi_in0: endpoint {
                        status = "okay";
                        csi-port = <0x0>;
                        bus-width = <0x4>;
                        remote-endpoint = <&daxc02_out0>;
                    };
                };
            };
        };
        i2c@546c0000 {
            #address-cells = <1>;
            #size-cells = <0>;

            daxc02@0e {
                compatible = "nova,daxc02";

                /* I2C device address */
                reg = <0x0e>;

                /* Physical dimensions of sensor */
                physical_w = "10";
                physical_h = "10";

                /* Sensor Model */
                sensor_model ="mt9m021";

                /* input clock for the device in MHz*/
                mclk = "cam_mclk1";

                /* Define any required hw resources needed by driver */
                /* ie. clocks, io pins, power sources */
                vana-supply = <&max77620_ldo3>;  // analog 2.8v
                vif-supply = <&en_vdd_cam>;    // interface 1.8v
                vdig-supply = <&en_vdd_cam_1v2>; // digital 1.2v

                avdd-reg = "vana";
                iovdd-reg = "vif";
                dvdd-reg = "vdig";

                /* kernel device node */
                devnode = "video0";

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

                /* when set true analog gain value expressed in decibels." */
                use_decibel_gain = "false";

                mode0 {
                    mclk_khz = "24000";
                    num_lanes = "4";
                    tegra_sinterface = "serial_c";
                    discontinuous_clk = "no";
                    dpcm_enable = "false";
                    cil_settletime = "0";

                    active_w = "1280";
                    active_h = "960";
                    pixel_t = "bayer_rggb12";
                    readout_orientation = "0";
                    line_length = "2688";
                    inherent_gain = "1";
                    mclk_multiplier = "3.094";
                    pix_clk_hz = "74250000";

                    min_gain_val = "1.0";
                    max_gain_val = "3.0";
                    min_hdr_ratio = "";
                    max_hdr_ratio = "";
                    min_framerate = "1";
                    max_framerate = "60";
                    min_exp_time = "1";
                    max_exp_time = "672";
                    embedded_metadata_height = "0";
                };
                ports {
                    #address-cells = <0x1>;
                    #size-cells = <0x0>;

                    port@0 {
                        reg = <0x0>;
                        daxc02_out0: endpoint {
                            csi-port = <0x0>;
                            bus-width = <0x4>;
                            remote-endpoint = <&daxc02_vi_in0>;
                        };
                    };
                };
            };
        };
    };

    tegra-camera-platform {
        compatible = "nvidia, tegra-camera-platform";
        modules {
            module0 {
                badge = "daxc02_master_mt9m021";
                position = "front";
                orientation = "1";
                drivernode0 {
                    pcl_id = "v4l2_sensor";
                    proc-device-tree = "/proc/device-tree/host1x/i2c@546c0000/daxc02@0e";
                };
            };
        };
    };

    regulators {
        /* VDD_SYS_EN */
        en_vdd_cam: regulator@5 {
            regulator-boot-on;
            regulator-always-on;
        };

        /* CAM_VDD_2V8_EN */
        en_vdd_cam_hv_2v8: regulator@206 {
            regulator-boot-on;
            regulator-always-on;
        };

        /* CAM_VDD_1V8_EN */
        en_vdd_cam_1v8: regulator@211 {
            regulator-boot-on;
            regulator-always-on;
        };

        /* CAM_VDD_1V2_EN */
        en_vdd_cam_1v2: regulator@209 {
            regulator-boot-on;
            regulator-always-on;
        };
    };
};

Actually looking through the dtb might have indicated a problem. It looks like when I tried to overwrite tegra-camera-platform -> module0 it merged it with the ov5693. I’ll try making it module6 instead, which doesn’t have anything defined.

Here’s the output in question:

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

    modules {

        module0 {
                badge = "daxc02_master_mt9m021";
                position = "front";
                orientation = [31 00];
                status = "disabled";
                linux,phandle = <0xc5>;
                phandle = <0xc5>;

                drivernode0 {
                        pcl_id = "v4l2_sensor";
                        devname = "ov5693 6-0036";
                        proc-device-tree = "/proc/device-tree/host1x/i2c@546c0000/daxc02@0e";
                        status = "disabled";
                        linux,phandle = <0xc6>;
                        phandle = <0xc6>;
                };

                drivernode1 {
                        pcl_id = "v4l2_focuser_stub";
                        devname = "lc898212 6-0072";
                        proc-device-tree = [00];
                        status = "disabled";
                        linux,phandle = <0xc7>;
                        phandle = <0xc7>;
                };
        };