Skip to content

Camera

Testing our MIPI cameras

export DISPLAY=:0

gst-launch-1.0 imxv4l2videosrc device=/dev/video0 ! imxeglvivsink

You can find more examples in the GStreamer section.

Adding a parallel camera

To add a parallel camera support to the kernel: As usual, make sure the driver for your device (camera) is included in the kernel configuration (use menuconfig), and define in the device tree the pins and driver to be used. The device tree for VAR-SOM-MX6 is arch/arm/boot/dts/imx6qdl-var-som.dtsi The device tree for DART-MX6 is arch/arm/boot/dts/imx6qdl-var-dart.dtsi For example:

diff --git a/arch/arm/boot/dts/imx6qdl-var-dart.dtsi b/arch/arm/boot/dts/imx6qdl-var-dart.dtsi
index 7afa15e7813b..975c30233e87 100644
--- a/arch/arm/boot/dts/imx6qdl-var-dart.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-var-dart.dtsi
@@ -171,21 +171,28 @@
        brightness-levels = <0 4 8 16 32 64 128 248>;
        default-brightness-level = <7>;
        status = "okay";
    };

    v4l2_cap_0 {
        compatible = "fsl,imx6q-v4l2-capture";
        ipu_id = <0>;
-       csi_id = <1>;
+       csi_id = <0>;
        mclk_source = <0>;
        status = "okay";
    };

+   v4l2_cap_1 {
+       compatible = "fsl,imx6q-v4l2-capture";
+       ipu_id = <1>;
+       csi_id = <1>;
+       mclk_source = <0>;
+       status = "okay";
+   };


    v4l2_out {
        compatible = "fsl,mxc_v4l2_output";
        status = "okay";
    };
 };

@@ -222,17 +229,17 @@

    ov564x_mipi: ov564x_mipi@3c {
        compatible = "ovti,ov564x_mipi";
        reg = <0x3c>;
        clocks = <&clks 200>;
        clock-names = "csi_mclk";
        pwn-gpios = <&gpio3 13 1>;
        rst-gpios = <&gpio4 10 0>;
-       csi_id = <1>;
+       csi_id = <0>;
        mclk = <24000000>;
        mclk_source = <0>;
    };
 };

 &i2c2 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
@@ -266,16 +273,30 @@
    pinctrl-0 = <&pinctrl_i2c3_3>;
    status = "okay";

    /* DS1307 RTC module */
    rtc@0x68 {
        compatible = "dallas,ds1307";
        reg = <0x68>;
    };
+
+   ov564x: ov564x@3c {
+       compatible = "ovti,ov564x";
+       reg = <0x3c>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ipu2>;
+       clocks = <&clks 200>;
+       clock-names = "csi_mclk";
+       pwn-gpios = <&gpio3 4 0>;
+       rst-gpios = <&gpio3 5 0>;
+       csi_id = <1>;
+       mclk = <24000000>;
+       mclk_source=<0>;
+   };
 };

 &iomuxc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hog>;

    imx6qdl-var-som-mx6 {

@@ -395,16 +416,35 @@
                MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19   0x10
                MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20   0x10
                MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21   0x10
                MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22   0x10
                MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23   0x10
            >;
        };

+       pinctrl_ipu2: ipu2grp { /* parallel camera */
+           fsl,pins = <
+               MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12        0x0000b0b1
+               MX6QDL_PAD_EIM_A18__IPU2_CSI1_DATA13        0x0000b0b1
+               MX6QDL_PAD_EIM_A19__IPU2_CSI1_DATA14        0x0000b0b1
+               MX6QDL_PAD_EIM_A20__IPU2_CSI1_DATA15        0x0000b0b1
+               MX6QDL_PAD_EIM_A21__IPU2_CSI1_DATA16        0x0000b0b1
+               MX6QDL_PAD_EIM_A22__IPU2_CSI1_DATA17        0x0000b0b1
+               MX6QDL_PAD_EIM_A23__IPU2_CSI1_DATA18        0x0000b0b1
+               MX6QDL_PAD_EIM_A24__IPU2_CSI1_DATA19        0x0000b0b1
+               MX6QDL_PAD_EIM_DA10__IPU2_CSI1_DATA_EN      0x80000000
+               MX6QDL_PAD_EIM_A16__IPU2_CSI1_PIXCLK        0x0000b0b1
+               MX6QDL_PAD_EIM_DA11__IPU2_CSI1_HSYNC        0x0000b0b1
+               MX6QDL_PAD_EIM_DA12__IPU2_CSI1_VSYNC        0x0000b0b1
+               MX6QDL_PAD_EIM_DA4__GPIO3_IO04          0x80000000
+               MX6QDL_PAD_EIM_DA5__GPIO3_IO05          0x80000000
+           >;
+       };
+
        pinctrl_pwm1_1: pwm1grp {
            fsl,pins = <
                MX6QDL_PAD_DISP0_DAT9__PWM2_OUT     0x1b0b1
            >;
        };

        /* Linux Console */
        pinctrl_uart1_1: uart1grp-1 { /* RX/TX only */
@@ -593,17 +633,17 @@
    fsl,phy_reg_vlev = <0x0294>;
    fsl,phy_reg_cksymtx = <0x800d>;
    status = "okay";
 };

 &mipi_csi {
    status = "okay";
    ipu_id = <0>;
-   csi_id = <1>;
+   csi_id = <0>;
    v_channel = <0>;
    lanes = <2>;
 };

 &pcie {
    reset-gpio    = <&gpio4 11 0>;  /* gpio pin num of power good signal */
    wake-up-gpio  = <&gpio4 31 1>;  /* gpio pin num of incoming wakeup signal */
    disable-gpio  = <&gpio5 5 0>;   /* gpio pin num of outgoing rfkill/endpoint disable signal */
diff --git a/arch/arm/boot/dts/imx6qdl-var-som.dtsi b/arch/arm/boot/dts/imx6qdl-var-som.dtsi
index 043b9332af05..0edad80b22c5 100644
--- a/arch/arm/boot/dts/imx6qdl-var-som.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-var-som.dtsi
@@ -159,30 +159,38 @@
        compatible = "pwm-backlight";
        pwms = <&pwm2 0 50000>;
        brightness-levels = <0 4 8 16 32 64 128 248>;
        default-brightness-level = <7>;
        status = "okay";
    };

    v4l2_cap_0 {
        compatible = "fsl,imx6q-v4l2-capture";
        ipu_id = <0>;
        csi_id = <1>;
        mclk_source = <0>;
        status = "okay";
    };

+   v4l2_cap_1 {
+       compatible = "fsl,imx6q-v4l2-capture";
+       ipu_id = <0>;
+       csi_id = <0>;
+       mclk_source = <0>;
+       status = "okay";
+   };
+
    v4l2_out {
        compatible = "fsl,mxc_v4l2_output";
        status = "okay";
    };
 };

 &audmux {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_audmux_2>;
    status = "okay";
 };

 &cpu0 {
    arm-supply = <&sw1a_reg>;
    soc-supply = <&sw1c_reg>;
@@ -297,30 +305,44 @@
        >;
    };
 };

 &i2c3 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c3_3>;
    status = "okay";

    /* DS1307 RTC module */
    rtc@0x68 {
        compatible = "dallas,ds1307";
        reg = <0x68>;
    };
+
+   ov564x: ov564x@3c {
+       compatible = "ovti,ov564x";
+       reg = <0x3c>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ipu1_2>;
+       clocks = <&clks 200>;
+       clock-names = "csi_mclk";
+       pwn-gpios = <&gpio3 4 0>;
+       rst-gpios = <&gpio3 5 0>;
+       csi_id = <0>;
+       mclk = <24000000>;
+       mclk_source=<0>;
+   };
 };

 &iomuxc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hog>;

    imx6qdl-var-som-mx6 {

        pinctrl_hog: hoggrp {
            fsl,pins = <
                /* CTW6120 IRQ */
                MX6QDL_PAD_EIM_DA7__GPIO3_IO07      0x80000000
                /* for Bluetooth/wifi enable */
                MX6QDL_PAD_SD3_DAT6__GPIO6_IO18     0x1b0b1
                /* SDMMC2 CD/WP */
@@ -448,30 +470,32 @@

        pinctrl_ipu1_2: ipu1grp-2 { /* parallel camera */
            fsl,pins = <
                MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12     0x80000000
                MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13     0x80000000
                MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14     0x80000000
                MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15     0x80000000
                MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16     0x80000000
                MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17     0x80000000
                MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18     0x80000000
                MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19     0x80000000
                MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN  0x80000000
                MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK    0x80000000
                MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC       0x80000000
                MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC      0x80000000
+               MX6QDL_PAD_EIM_DA4__GPIO3_IO04          0x80000000
+               MX6QDL_PAD_EIM_DA5__GPIO3_IO05          0x80000000
            >;
        };

        pinctrl_pwm2_1: pwm2grp {
            fsl,pins = <
                MX6QDL_PAD_DISP0_DAT9__PWM2_OUT     0x1b0b1
            >;
        };
        /* Linux Console */
        pinctrl_uart1_1: uart1grp-1 { /* RX/TX only */
            fsl,pins = <
                MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA    0x1b0b1
                MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA    0x1b0b1
            >;
        };

Note: This is just an example. You should set everything according to your camera model and hardware design, and make sure the pins are not conflicting with other devices in the device tree.

In addition, you need to patch arch/arm/mach-imx/mach-imx6q.c to set the appropriate GPR bits for connecting the desired CSI to the parallel interface. For example:

diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index ae5c3cd29d04..c4def47886e5 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -229,31 +229,39 @@ put_node:
    of_node_put(np);
 }

 static void __init imx6q_csi_mux_init(void)
 {
    /*
-    * MX6Q SabreSD board:
+    * DART-MX6 board:
+    * IPU2 CSI1 connects to parallel interface.
+    * Set GPR1 bit 20 to 0x1.
+    *
+    * MX6Q SabreSD/VAR-SOM-MX6 boards:
     * IPU1 CSI0 connects to parallel interface.
     * Set GPR1 bit 19 to 0x1.
     *
-    * MX6DL SabreSD board:
+    * MX6DL SabreSD/VAR-SOM-MX6 boards:
     * IPU1 CSI0 connects to parallel interface.
     * Set GPR13 bit 0-2 to 0x4.
     * IPU1 CSI1 connects to MIPI CSI2 virtual channel 1.
     * Set GPR13 bit 3-5 to 0x1.
     */
    struct regmap *gpr;

    gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
    if (!IS_ERR(gpr)) {
-       if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
-           of_machine_is_compatible("fsl,imx6q-sabreauto"))
+       if (of_machine_is_compatible("fsl,imx6q-var-dart") ||
+           of_machine_is_compatible("variscite,imx6q-var-dart"))
+           regmap_update_bits(gpr, IOMUXC_GPR1, 1 << 20, 1 << 20);
+       else if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
+           of_machine_is_compatible("fsl,imx6q-sabreauto") ||
+           of_machine_is_compatible("fsl,imx6q-var-som") ||
+           of_machine_is_compatible("variscite,imx6q-var-som"))
            regmap_update_bits(gpr, IOMUXC_GPR1, 1 << 19, 1 << 19);
        else if (of_machine_is_compatible("fsl,imx6dl-sabresd") ||
-            of_machine_is_compatible("fsl,imx6dl-sabreauto"))
+            of_machine_is_compatible("fsl,imx6dl-sabreauto") ||
+            of_machine_is_compatible("fsl,imx6dl-var-som") ||
+            of_machine_is_compatible("variscite,imx6dl-var-som"))
            regmap_update_bits(gpr, IOMUXC_GPR13, 0x3F, 0x0C);
    } else {
        pr_err("%s(): failed to find fsl,imx6q-iomux-gpr regmap\n",
               __func__);
    }
 }