Framos driver on custom board

Hi all, me again…

I’m trying to bring up the Framos 662 sensor on our custom board, but for some reason I can’t get the linking to work.

We’ve got the following kernel modules installed

Module               
vvcam_isp         
vvcam_dwe           
vvcam_video
imx8_media_dev        
imx662     
galcore

I can see the sensor gets registered as a subdevice in dmesg

    5.079145] enter imx662_probe
[    5.082765] enter imx662_power_on
[    5.130659] enter imx662_set_exp exposure received: 500 control: 1
[    5.137490] enter imx662_set_exp exposure register: 1213 integration_time_line: 37
[    5.150900] enter imx662_set_gain: gain received: 0 control: 1
[    5.156776] imx662_set_gain: gain register: 0
[    5.163500] enter imx662_set_black_level black level: 50
[    5.171183] enter imx662_set_black_level black level: 50
[    5.176531] enter imx662_set_data_rate data rate received: 7
[    5.176539] imx662_change_data_rate++
[    5.178324] imx662_change_data_rate: Setting data rate to value: 7
[    5.192957] imx662_adjust_hmax_register:++
[    5.203877] imx662_adjust_hmax_register:  one line : 13333
[    5.209390] enter imx662_set_sync_mode sync mode 0
[    5.214799] enter imx662_configure_triggering_pins
[    5.221074] enter imx662_set_fps fps received: 60
[    5.225811] enter imx662_set_fps vmax register: 1250 line_time 13333
[    5.235112] enter imx662_set_test_pattern
[    5.241948] imx662_probe camera mipi imx662, is found
[    6.263408] imx8_media_dev: module is from the staging directory, the quality is unknown, you have been warned.
[    6.276655] mx8-img-md: Registered sensor subdevice: imx662 2-001a (1)
[    6.301027] mx8-img-md: created link [imx662 2-001a] => [mxc-mipi-csi2.0]

Media controller shows


Media controller API version 5.15.148

Media device information
------------------------
driver          vvcam-video
model           viv_media
serial
bus info
hw revision     0x0
driver version  5.15.148

Device topology
- entity 1: viv_v4l20 (1 pad, 1 link)
            type Node subtype V4L flags 0
            device node name /dev/video2
        pad0: Sink
                <- "vvcam-isp.0":0 [ENABLED]

- entity 5: vvcam-isp.0 (1 pad, 1 link)
            type Node subtype V4L flags 0
            device node name /dev/v4l-subdev0
        pad0: Source
                -> "viv_v4l20":0 [ENABLED]

- entity 7: vvcam-dwe.0 (2 pads, 0 link)
            type Node subtype V4L flags 0
            device node name /dev/v4l-subdev1
        pad0: Source
        pad1: Sink

and

root@meercam-worker-framos-test:~ # v4l2-ctl --list-devices
 ():
        /dev/v4l-subdev0
        /dev/v4l-subdev1

VIV (platform:viv0):
        /dev/video2

vsi_v4l2dec (platform:vsi_v4l2dec):
        /dev/video1

vsi_v4l2enc (platform:vsi_v4l2enc):
        /dev/video0

viv_media (platform:vvcam-video):
        /dev/media0

I wondered if anyone has an example dmesg with this camera successfully loading?
I am curious to see if I’ve got one or more of the following:

  • Some kernel config I am missing?
  • An additional kernel module missing?
  • Something wrong in the dts?!!?

My dts looks like this ( apologies for the old fragment syntax, I haven’t yet converted… )

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/imx8mp-clock.h>
#include <dt-bindings/gpio/gpio.h>

/ {
        /* ------------------------------------------------------------------ *
         *  Fragment 0 – fixed regulators (unchanged)                         *
         * ------------------------------------------------------------------ */
        fragment@0 {
                target-path = "/";
                __overlay__ {
                        reg_cam1: regulator-cam1 {
                                compatible          = "regulator-fixed";
                                regulator-name      = "cam_pvdd1";
                                regulator-min-microvolt = <3300000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
                                gpio                = <&gpio1 0 GPIO_ACTIVE_HIGH>;
                                enable-active-high;
                                regulator-always-on;
                        };

                        reg_cam2: regulator-cam2 {
                                compatible          = "regulator-fixed";
                                regulator-name      = "cam_pvdd2";
                                regulator-min-microvolt = <3300000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
                                gpio                = <&gpio1 1 GPIO_ACTIVE_HIGH>;
                                enable-active-high;
                                regulator-always-on;
                        };
                };
        };

        /* ------------------------------------------------------------------ *
         *  Fragment 1 – cameradev                                             *
         * ------------------------------------------------------------------ */
        fragment@1 {
                target = <&cameradev>;
                __overlay__ {
                        status = "okay";
                };
        };

    /* ------------------------------------------------------------------ *
         *  Fragment 2 – IMX662 @ I²C2 (bus-address 0x1b)                      *
         * ------------------------------------------------------------------ */
        fragment@2 {
                target = <&i2c2>;
                __overlay__ {
                        status = "okay";
                        clock-frequency = <100000>;

                        imx662_mipi@1a {
                                assigned-clocks       = <&clk IMX8MP_CLK_IPP_DO_CLKO2>;
                                assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
                                assigned-clock-rates   = <24000000>;
                                clocks                 = <&clk IMX8MP_CLK_IPP_DO_CLKO2>;
                                clock-names            = "csi_mclk";

                                compatible    = "framos,imx662";
                                reg           = <0x1a>;
                                csi_id        = <0>;
                                mipi_csi;

                                rst-gpios            = <&gpio1 6 GPIO_ACTIVE_LOW>;   /* Meercam SODIMM 212 */
                                cam_pvdd-supply      = <&reg_cam2>;

                                status = "okay";

                                port {
                                        imx662_mipi_0_ep: endpoint {
                                                data-lanes           = <1 2 3 4>;
                                                clock-lanes          = <0>;
                                                max-pixel-frequency  = /bits/ 64 <500000000>;
                                                remote-endpoint      = <&mipi_csi0_ep>;
                                        };
                                };
                        };
                };
        };



        /* ------------------------------------------------------------------ *
         *  Fragment 2 – IMX662 @ I²C3 (bus-address 0x1a)                      *
         * ------------------------------------------------------------------ */
        fragment@3 {
                target = <&i2c3>;
                __overlay__ {
                        status = "okay";
                        clock-frequency = <100000>;

                        imx662_mipi1@1a {
                                /* ---- clocks ---- */
                                assigned-clocks       = <&clk IMX8MP_CLK_IPP_DO_CLKO2>;
                                assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
                                assigned-clock-rates   = <24000000>;
                                clocks                 = <&clk IMX8MP_CLK_IPP_DO_CLKO2>;
                                clock-names            = "csi_mclk";

                                /* ---- identity ---- */
                                compatible    = "framos,imx662";
                                reg           = <0x1a>;
                                csi_id        = <1>;
                                mipi_csi;

                                /* ---- GPIO / supplies ---- */
                                rst-gpios            = <&gpio1 5 GPIO_ACTIVE_LOW>;   /* Meercam SODIMM 210 */
                                cam_pvdd-supply      = <&reg_cam1>;

                                status = "okay";

                                /* ---- endpoint ---- */
                                port {
                                        imx662_mipi_1_ep: endpoint {
                                                data-lanes           = <1 2 3 4>;
                                                clock-lanes          = <0>;
                                                max-pixel-frequency  = /bits/ 64 <500000000>;
                                                remote-endpoint      = <&mipi_csi1_ep>;
                                        };
                                };
                        };
                };
        };

        /* ------------------------------------------------------------------ *
         *  Fragment 4 – disable ISI_0                                         *
         * ------------------------------------------------------------------ */
        fragment@4 {
                target = <&isi_0>;
                __overlay__ {
                        status = "disabled";
                };
        };

        /* ------------------------------------------------------------------ *
         *  Fragment 5 – disable ISI_1                                         *
         * ------------------------------------------------------------------ */
        fragment@5 {
                target = <&isi_1>;
                __overlay__ {
                        status = "disabled";
                };
        };

        /* ------------------------------------------------------------------ *
         *  Fragment 6 – enable ISP_0                                          *
         * ------------------------------------------------------------------ */
        fragment@6 {
                target = <&isp_0>;
                __overlay__ {
                        status = "okay";
                };
        };

    /* ------------------------------------------------------------------ *
         *  Fragment 7 – enable ISP_1                                          *
         * ------------------------------------------------------------------ */
        fragment@7 {
                target = <&isp_1>;
                __overlay__ {
                        status = "okay";
                };
        };

        /* ------------------------------------------------------------------ *
         *  Fragment 8 – enable Dewarp                                         *
         * ------------------------------------------------------------------ */
        fragment@8 {
                target = <&dewarp>;
                __overlay__ {
                        status = "okay";
                };
        };

        /* ------------------------------------------------------------------ *
         *  Fragment 9 – MIPI-CSI 0 endpoint                                   *
         * ------------------------------------------------------------------ */
        fragment@9 {
                target = <&mipi_csi_0>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "okay";

                        port@0 {
                                reg = <0>;
                                mipi_csi0_ep: endpoint {
                                        data-lanes          = <1 2 3 4>;      /* number of lanes */
                                        csis-hs-settle      = <13>;
                                        csis-clk-settle     = <2>;
                                        csis-wclk;
                                        remote-endpoint     = <&imx662_mipi_0_ep>;
                                };
                        };
                };
        };

        /* ------------------------------------------------------------------ *
         *  Fragment 10 – MIPI-CSI 1 endpoint                                   *
         * ------------------------------------------------------------------ */
        fragment@10 {
                target = <&mipi_csi_1>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "okay";

                        port@1 {
                                reg = <1>;
                                mipi_csi1_ep: endpoint {
                                        data-lanes          = <1 2 3 4>;      /* number of lanes */
                                        csis-hs-settle      = <13>;
                                        csis-clk-settle     = <2>;
                                        csis-wclk;
                                        remote-endpoint     = <&imx662_mipi_1_ep>;
                                };
                        };
                };
        };
};

i2cdetect also the driver bound…

Any help would be greatly appreciated…

edit:

It’s worth noting we’ve succesfully tested this with a different camera module NOT using ISP, so I figure there’s something I am missing there.

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Hello! Thanks for the detailed information and for sharing your device tree and module setup. Based on your logs and the output from your media controller, it looks like your IMX662 sensor is being successfully detected and registered as a V4L2 subdevice. However, your media pipeline—according to the media controller output—is incomplete: it seems the sensor subdevice is not actually being linked through to the rest of the processing chain (ISP, DWE, etc.), and the entities (subdevices) are not forming the expected connections. Here are some steps and pointers to help you debug this further:

1. Kernel Module Loading Order

The Vivante VVCAM stack often requires modules to be loaded in a specific order for the media graph to set up properly. As a rule of thumb:

  • Remove all media-related modules, especially the custom ones (VVCAM ISP, DWE, etc.).
  • Insert the camera sensor driver (in your case, imx662) first.
  • Re-insert or load ISP, DWE, and VVCAM modules afterwards.

This ordering allows the drivers to register their entities so that the kernel can establish links in the media graph between them automatically.

More on module handling:

2. Review Your Device Tree

Your device tree fragments look comprehensive, but be sure to:

  • Double-check the compatible string (“framos,imx662”) matches what your driver expects.
  • Ensure all supplies and GPIOs (especially rst-gpios) are right for your board’s hardware design.
  • Review the remote-endpoint entries on both sides (CSI and camera sensor). Typos or mismatched labels will prevent link creation.
  • Data lane mapping (data-lanes = <1 2 3 4>;) should match your hardware wiring and what the driver expects.

3. Media Pipeline Link Creation

The media controller does not show links between the sensor → CSI → ISP → DWE → video node. This normally happens via the drivers during module probe. If links are not being created, possible reasons include:

  • The endpoints don’t reference each other correctly in the device tree.
  • A required driver/module failed to initialize, or isn’t loaded.
  • The sensor or ISP driver is missing formats or operations required for link creation.
  • Device tree fragments or .dtbo not applied at boot (check using dmesg or ls /proc/device-tree/).

Here is a general resource on how cameras are handled in the media pipeline:

4. Required Kernel Configuration

Check that you have all required kernel options enabled. At a minimum, you need:

  • CONFIG_VIDEO_V4L2
  • Drivers for the IMX662, CSI, ISP, DWE, and VVCAM framework (imx8_media_dev)
  • Media controller support, and subdev support

Sometimes, vendor-specific drivers require additional configs. You can check your current config with:

zcat /proc/config.gz | grep V4L

Look for lines related to your sensor, CSI, ISP, and media controller.

5. Module/Driver Probing and Logs

Reboot, ensure all required modules are in place, and check dmesg for errors or warnings from any media/video driver. See if you have any “probe failed” or “could not create link” messages.

6. Test With Video4Linux Tools

When the links are set up correctly, running:

media-ctl -p -d /dev/media0

should show a pipeline linking the sensor to the video device. If not, try manually linking entities (if your stack supports it), but normally this is handled automatically by the drivers.

Summary of Actions

  • Review and, if needed, reorder your module loading.
  • Double-check all device tree endpoint references for typos.
  • Confirm all required kernel config options are enabled.
  • Examine dmesg logs immediately after boot or module reload for any media/driver errors.
  • Use media-ctl to inspect your pipeline.
  • If possible, test using a known-working sensor/device tree setup to rule out hardware issues.

Would you like to share the output of media-ctl -p -d /dev/media0 and any related dmesg logs after following the above steps? I can help further interpret what is happening.

Best regards,
Toradex AI Assistant.

[1] Can't register /dev/videoX
[2] Cameras on Toradex System on Modules | Toradex Developer Center

Okay making progress, at least for me this recipe is broken on this line

There needs to be white space either side of file path else the patch never gets applied.

Okay that was definitely the case, we’ve also had to tweak the imx-isp run.sh script for our environment as we only have busybox installed and that makes the framos driver script fail.

What we’re struggling now with is it appears the clock signal isn’t being generated from the sensor. If anyone has experienced anything similar help would be greatly appreciated.