overlays: Add overlay for the OV64A40 Arducam Camera Module
authorJacopo Mondi <jacopo.mondi@ideasonboard.com>
Thu, 20 Jul 2023 11:18:34 +0000 (13:18 +0200)
committerDom Cobley <popcornmix@gmail.com>
Mon, 19 Feb 2024 11:35:20 +0000 (11:35 +0000)
Arducam have integrated an Omnivision OV64A40 with a ROHM BU64754 VCM
with a Raspberry Pi compatible cable pinout.

Provide an overlay to support the module.

Also add support to the camera mux overlays.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
arch/arm/boot/dts/overlays/Makefile
arch/arm/boot/dts/overlays/README
arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts
arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts
arch/arm/boot/dts/overlays/ov64a40-overlay.dts [new file with mode: 0644]
arch/arm/boot/dts/overlays/ov64a40.dtsi [new file with mode: 0644]

index d825a65..fc97bdb 100644 (file)
@@ -175,6 +175,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
        mz61581.dtbo \
        ov2311.dtbo \
        ov5647.dtbo \
+       ov64a40.dtbo \
        ov7251.dtbo \
        ov9281.dtbo \
        papirus.dtbo \
index 8937cb4..c1128fc 100644 (file)
@@ -817,6 +817,7 @@ Params: cam0-arducam-64mp       Select Arducam64MP for camera on port 0
         cam0-imx708             Select IMX708 for camera on port 0
         cam0-ov2311             Select OV2311 for camera on port 0
         cam0-ov5647             Select OV5647 for camera on port 0
+        cam0-ov64a40            Select OV64A40 for camera on port 0
         cam0-ov7251             Select OV7251 for camera on port 0
         cam0-ov9281             Select OV9281 for camera on port 0
         cam0-imx290-clk-freq    Set clock frequency for an IMX290 on port 0
@@ -829,6 +830,7 @@ Params: cam0-arducam-64mp       Select Arducam64MP for camera on port 0
         cam1-imx708             Select IMX708 for camera on port 1
         cam1-ov2311             Select OV2311 for camera on port 1
         cam1-ov5647             Select OV5647 for camera on port 1
+        cam1-ov64a40            Select OV64A40 for camera on port 1
         cam1-ov7251             Select OV7251 for camera on port 1
         cam1-ov9281             Select OV9281 for camera on port 1
         cam1-imx290-clk-freq    Set clock frequency for an IMX290 on port 1
@@ -850,6 +852,7 @@ Params: cam0-arducam-64mp       Select Arducam64MP for camera on port 0
         cam0-imx708             Select IMX708 for camera on port 0
         cam0-ov2311             Select OV2311 for camera on port 0
         cam0-ov5647             Select OV5647 for camera on port 0
+        cam0-ov64a40            Select OV64A40 for camera on port 0
         cam0-ov7251             Select OV7251 for camera on port 0
         cam0-ov9281             Select OV9281 for camera on port 0
         cam0-imx290-clk-freq    Set clock frequency for an IMX290 on port 0
@@ -862,6 +865,7 @@ Params: cam0-arducam-64mp       Select Arducam64MP for camera on port 0
         cam1-imx708             Select IMX708 for camera on port 1
         cam1-ov2311             Select OV2311 for camera on port 1
         cam1-ov5647             Select OV5647 for camera on port 1
+        cam1-ov64a40            Select OV64A40 for camera on port 1
         cam1-ov7251             Select OV7251 for camera on port 1
         cam1-ov9281             Select OV9281 for camera on port 1
         cam1-imx290-clk-freq    Set clock frequency for an IMX290 on port 1
@@ -874,6 +878,7 @@ Params: cam0-arducam-64mp       Select Arducam64MP for camera on port 0
         cam2-imx708             Select IMX708 for camera on port 2
         cam2-ov2311             Select OV2311 for camera on port 2
         cam2-ov5647             Select OV5647 for camera on port 2
+        cam2-ov64a40            Select OV64A40 for camera on port 2
         cam2-ov7251             Select OV7251 for camera on port 2
         cam2-ov9281             Select OV9281 for camera on port 2
         cam2-imx290-clk-freq    Set clock frequency for an IMX290 on port 2
@@ -886,6 +891,7 @@ Params: cam0-arducam-64mp       Select Arducam64MP for camera on port 0
         cam3-imx708             Select IMX708 for camera on port 3
         cam3-ov2311             Select OV2311 for camera on port 3
         cam3-ov5647             Select OV5647 for camera on port 3
+        cam3-ov64a40            Select OV64A40 for camera on port 3
         cam3-ov7251             Select OV7251 for camera on port 3
         cam3-ov9281             Select OV9281 for camera on port 3
         cam3-imx290-clk-freq    Set clock frequency for an IMX290 on port 3
@@ -3222,6 +3228,25 @@ Params: rotation                Mounting rotation of the camera sensor (0 or
         vcm                     Configure a VCM focus drive on the sensor.
 
 
+Name:   ov64a40
+Info:   Arducam OV64A40 camera module.
+        Uses Unicam 1, which is the standard camera connector on most Pi
+        variants.
+Load:   dtoverlay=ov64a40,<param>=<val>
+Params: rotation                Mounting rotation of the camera sensor (0 or
+                                180, default 0)
+        orientation             Sensor orientation (0 = front, 1 = rear,
+                                2 = external, default external)
+        media-controller        Configure use of Media Controller API for
+                                configuring the sensor (default on)
+        cam0                    Adopt the default configuration for CAM0 on a
+                                Compute Module (CSI0, i2c_vc, and cam0_reg).
+        vcm                     Select lens driver state. Default is enabled,
+                                but vcm=off will disable.
+        link-frequency          Allowable link frequency values to use in Hz:
+                                456000000 (default), 360000000
+
+
 Name:   ov7251
 Info:   Omnivision OV7251 camera module.
         Uses Unicam 1, which is the standard camera connector on most Pi
index 8471ad0..c5cfbdc 100644 (file)
                                        #undef cam_node
                                        #undef cam_endpoint
                                        #undef cam1_clk
+
+                                       #define cam_node ov64a40_0
+                                       #define cam_endpoint ov64a40_0_ep
+                                       #define vcm_node ov64a40_0_vcm
+                                       #define cam1_clk clk_24mhz
+                                       #include "ov64a40.dtsi"
+                                       #undef cam_node
+                                       #undef cam_endpoint
+                                       #undef vcm_node
+                                       #undef cam1_clk
                                };
 
                                i2c@1 {
                                        #undef cam_node
                                        #undef cam_endpoint
                                        #undef cam1_clk
+
+                                       #define cam_node ov64a40_1
+                                       #define cam_endpoint ov64a40_1_ep
+                                       #define vcm_node ov64a40_1_vcm
+                                       #define cam1_clk clk_24mhz
+                                       #include "ov64a40.dtsi"
+                                       #undef cam_node
+                                       #undef cam_endpoint
+                                       #undef vcm_node
+                                       #undef cam1_clk
                                };
                        };
                };
                cam0-ov2311 = <&mux_in0>, "remote-endpoint:0=",<&ov2311_0_ep>,
                              <&ov2311_0_ep>, "remote-endpoint:0=",<&mux_in0>,
                              <&ov2311_0>, "status=okay";
+               cam0-ov64a40 = <&mux_in0>, "remote-endpoint:0=",<&ov64a40_0_ep>,
+                             <&ov64a40_0_ep>, "remote-endpoint:0=",<&mux_in0>,
+                             <&mux_in0>, "clock-noncontinuous?",
+                             <&ov64a40_0>, "status=okay",
+                             <&ov64a40_0_vcm>, "status=okay",
+                             <&ov64a40_0>,"lens-focus:0=", <&ov64a40_0_vcm>;
 
                cam1-arducam-64mp = <&mux_in1>, "remote-endpoint:0=",<&arducam_64mp_1_ep>,
                                    <&arducam_64mp_1_ep>, "remote-endpoint:0=",<&mux_in1>,
                cam1-ov2311 = <&mux_in1>, "remote-endpoint:0=",<&ov2311_1_ep>,
                              <&ov2311_1_ep>, "remote-endpoint:0=",<&mux_in1>,
                              <&ov2311_1>, "status=okay";
+               cam1-ov64a40 = <&mux_in1>, "remote-endpoint:0=",<&ov64a40_1_ep>,
+                             <&ov64a40_1_ep>, "remote-endpoint:0=",<&mux_in1>,
+                             <&mux_in1>, "clock-noncontinuous?",
+                             <&ov64a40_1>, "status=okay",
+                             <&ov64a40_1_vcm>, "status=okay",
+                             <&ov64a40_1>,"lens-focus:0=", <&ov64a40_1_vcm>;
 
                cam0-imx290-clk-freq = <&clk_imx290>,"clock-frequency:0",
                                       <&imx290_0>,"clock-frequency:0";
index bdb1aeb..1dcc63e 100644 (file)
                                        #undef cam_node
                                        #undef cam_endpoint
                                        #undef cam1_clk
+
+                                       #define cam_node ov64a40_0
+                                       #define cam_endpoint ov64a40_0_ep
+                                       #define vcm_node ov64a40_0_vcm
+                                       #define cam1_clk clk_24mhz
+                                       #include "ov64a40.dtsi"
+                                       #undef cam_node
+                                       #undef cam_endpoint
+                                       #undef vcm_node
+                                       #undef cam1_clk
                                };
 
                                i2c@1 {
                                        #undef cam_node
                                        #undef cam_endpoint
                                        #undef cam1_clk
+
+                                       #define cam_node ov64a40_1
+                                       #define cam_endpoint ov64a40_1_ep
+                                       #define vcm_node ov64a40_1_vcm
+                                       #define cam1_clk clk_24mhz
+                                       #include "ov64a40.dtsi"
+                                       #undef cam_node
+                                       #undef cam_endpoint
+                                       #undef vcm_node
+                                       #undef cam1_clk
                                };
 
                                i2c@2 {
                                        #undef cam_node
                                        #undef cam_endpoint
                                        #undef cam1_clk
+
+                                       #define cam_node ov64a40_2
+                                       #define cam_endpoint ov64a40_2_ep
+                                       #define vcm_node ov64a40_2_vcm
+                                       #define cam1_clk clk_24mhz
+                                       #include "ov64a40.dtsi"
+                                       #undef cam_node
+                                       #undef cam_endpoint
+                                       #undef vcm_node
+                                       #undef cam1_clk
                                };
 
                                i2c@3 {
                                        #undef cam_node
                                        #undef cam_endpoint
                                        #undef cam1_clk
+
+                                       #define cam_node ov64a40_3
+                                       #define cam_endpoint ov64a40_3_ep
+                                       #define vcm_node ov64a40_3_vcm
+                                       #define cam1_clk clk_24mhz
+                                       #include "ov64a40.dtsi"
+                                       #undef cam_node
+                                       #undef cam_endpoint
+                                       #undef vcm_node
+                                       #undef cam1_clk
                                };
                        };
                };
                cam0-ov2311 = <&mux_in0>, "remote-endpoint:0=",<&ov2311_0_ep>,
                              <&ov2311_0_ep>, "remote-endpoint:0=",<&mux_in0>,
                              <&ov2311_0>, "status=okay";
+               cam0-ov64a40 = <&mux_in0>, "remote-endpoint:0=",<&ov64a40_0_ep>,
+                             <&ov64a40_0_ep>, "remote-endpoint:0=",<&mux_in0>,
+                             <&mux_in0>, "clock-noncontinuous?",
+                             <&ov64a40_0>, "status=okay",
+                             <&ov64a40_0_vcm>, "status=okay",
+                             <&ov64a40_0>,"lens-focus:0=", <&ov64a40_0_vcm>;
 
                cam1-arducam-64mp = <&mux_in1>, "remote-endpoint:0=",<&arducam_64mp_1_ep>,
                                    <&arducam_64mp_1_ep>, "remote-endpoint:0=",<&mux_in1>,
                cam1-ov2311 = <&mux_in1>, "remote-endpoint:0=",<&ov2311_1_ep>,
                              <&ov2311_1_ep>, "remote-endpoint:0=",<&mux_in1>,
                              <&ov2311_1>, "status=okay";
+               cam1-ov64a40 = <&mux_in1>, "remote-endpoint:0=",<&ov64a40_1_ep>,
+                             <&ov64a40_1_ep>, "remote-endpoint:0=",<&mux_in1>,
+                             <&mux_in1>, "clock-noncontinuous?",
+                             <&ov64a40_1>, "status=okay",
+                             <&ov64a40_1_vcm>, "status=okay",
+                             <&ov64a40_1>,"lens-focus:0=", <&ov64a40_1_vcm>;
 
                cam2-arducam-64mp = <&mux_in2>, "remote-endpoint:0=",<&arducam_64mp_2_ep>,
                                    <&arducam_64mp_2_ep>, "remote-endpoint:0=",<&mux_in2>,
                cam2-ov2311 = <&mux_in2>, "remote-endpoint:0=",<&ov2311_2_ep>,
                              <&ov2311_2_ep>, "remote-endpoint:0=",<&mux_in2>,
                              <&ov2311_2>, "status=okay";
+               cam2-ov64a40 = <&mux_in2>, "remote-endpoint:0=",<&ov64a40_2_ep>,
+                             <&ov64a40_2_ep>, "remote-endpoint:0=",<&mux_in2>,
+                             <&mux_in2>, "clock-noncontinuous?",
+                             <&ov64a40_2>, "status=okay",
+                             <&ov64a40_2_vcm>, "status=okay",
+                             <&ov64a40_2>,"lens-focus:0=", <&ov64a40_2_vcm>;
 
                cam3-arducam-64mp = <&mux_in3>, "remote-endpoint:0=",<&arducam_64mp_3_ep>,
                                    <&arducam_64mp_3_ep>, "remote-endpoint:0=",<&mux_in3>,
                cam3-ov2311 = <&mux_in3>, "remote-endpoint:0=",<&ov2311_3_ep>,
                              <&ov2311_3_ep>, "remote-endpoint:0=",<&mux_in3>,
                              <&ov2311_3>, "status=okay";
+               cam3-ov64a40 = <&mux_in3>, "remote-endpoint:0=",<&ov64a40_3_ep>,
+                             <&ov64a40_3_ep>, "remote-endpoint:0=",<&mux_in3>,
+                             <&mux_in3>, "clock-noncontinuous?",
+                             <&ov64a40_3>, "status=okay",
+                             <&ov64a40_3_vcm>, "status=okay",
+                             <&ov64a40_3>,"lens-focus:0=", <&ov64a40_3_vcm>;
 
                cam0-imx290-clk-freq = <&clk_imx290>,"clock-frequency:0",
                                       <&imx290_0>,"clock-frequency:0";
diff --git a/arch/arm/boot/dts/overlays/ov64a40-overlay.dts b/arch/arm/boot/dts/overlays/ov64a40-overlay.dts
new file mode 100644 (file)
index 0000000..b6f8586
--- /dev/null
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Definitions for OV64A40 camera module on VC I2C bus
+/dts-v1/;
+/plugin/;
+
+/{
+       compatible = "brcm,bcm2835";
+
+       i2c_frag: fragment@0 {
+               target = <&i2c_csi_dsi>;
+               __overlay__ {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "okay";
+
+                       #include "ov64a40.dtsi"
+               };
+       };
+
+       csi_frag: fragment@1 {
+               target = <&csi1>;
+               csi: __overlay__ {
+                       status = "okay";
+                       brcm,media-controller;
+
+                       port{
+                               csi_ep: endpoint{
+                                       remote-endpoint = <&cam_endpoint>;
+                                       clock-lanes = <0>;
+                                       data-lanes = <1 2>;
+                               };
+                       };
+               };
+       };
+
+       fragment@2 {
+               target = <&i2c0if>;
+               __overlay__ {
+                       status = "okay";
+               };
+       };
+
+       clk_frag: fragment@3 {
+               target = <&cam1_clk>;
+               __overlay__ {
+                       clock-frequency = <24000000>;
+                       status = "okay";
+               };
+       };
+
+       fragment@4 {
+               target = <&i2c0mux>;
+               __overlay__ {
+                       status = "okay";
+               };
+       };
+
+       fragment@5 {
+               target = <&cam_node>;
+               __overlay__ {
+                       lens-focus = <&vcm_node>;
+               };
+       };
+
+       __overrides__ {
+               rotation = <&cam_node>,"rotation:0";
+               orientation = <&cam_node>,"orientation:0";
+               media-controller = <&csi>,"brcm,media-controller?";
+               cam0 = <&i2c_frag>, "target:0=",<&i2c_csi_dsi0>,
+                      <&csi_frag>, "target:0=",<&csi0>,
+                      <&clk_frag>, "target:0=",<&cam0_clk>,
+                      <&cam_node>, "clocks:0=",<&cam0_clk>,
+                      <&cam_node>, "avdd-supply:0=",<&cam0_reg>,
+                      <&vcm_node>, "vdd-supply:0=",<&cam0_reg>;
+               vcm = <&vcm_node>, "status",
+                     <0>, "=5";
+               link-frequency = <&cam_endpoint>,"link-frequencies#0";
+       };
+};
+
+&cam_node {
+       status = "okay";
+};
+
+&cam_endpoint {
+       remote-endpoint = <&csi_ep>;
+};
+
+&vcm_node {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/overlays/ov64a40.dtsi b/arch/arm/boot/dts/overlays/ov64a40.dtsi
new file mode 100644 (file)
index 0000000..471b383
--- /dev/null
@@ -0,0 +1,34 @@
+// Fragment that configures an OV64A40
+
+cam_node: ov64a40@36 {
+       compatible = "ovti,ov64a40";
+       reg = <0x36>;
+       status = "disabled";
+
+       clocks = <&cam1_clk>;
+       clock-names = "xclk";
+
+       avdd-supply = <&cam1_reg>;      /* 2.8v */
+       dovdd-supply = <&cam_dummy_reg>;/* 1.8v */
+       dvdd-supply = <&cam_dummy_reg>; /* 1.1v */
+
+       rotation = <180>;
+       orientation = <2>;
+
+       port {
+               cam_endpoint: endpoint {
+                       bus-type = <4>;
+                       clock-lanes = <0>;
+                       data-lanes = <1 2>;
+                       link-frequencies =
+                               /bits/ 64 <456000000>;
+               };
+       };
+};
+
+vcm_node: bu64754@76 {
+       compatible = "rohm,bu64754";
+       reg = <0x76>;
+       status = "disabled";
+       vdd-supply = <&cam1_reg>;
+};