From e7dc94fcdc76623a82c1b3f20469270020c5f9fe Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Thu, 20 Jul 2023 13:18:34 +0200 Subject: [PATCH] overlays: Add overlay for the OV64A40 Arducam Camera Module 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 Signed-off-by: Kieran Bingham --- arch/arm/boot/dts/overlays/Makefile | 1 + arch/arm/boot/dts/overlays/README | 25 ++++++ .../boot/dts/overlays/camera-mux-2port-overlay.dts | 32 ++++++++ .../boot/dts/overlays/camera-mux-4port-overlay.dts | 64 +++++++++++++++ arch/arm/boot/dts/overlays/ov64a40-overlay.dts | 91 ++++++++++++++++++++++ arch/arm/boot/dts/overlays/ov64a40.dtsi | 34 ++++++++ 6 files changed, 247 insertions(+) create mode 100644 arch/arm/boot/dts/overlays/ov64a40-overlay.dts create mode 100644 arch/arm/boot/dts/overlays/ov64a40.dtsi diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile index d825a65..fc97bdb 100644 --- a/arch/arm/boot/dts/overlays/Makefile +++ b/arch/arm/boot/dts/overlays/Makefile @@ -175,6 +175,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ mz61581.dtbo \ ov2311.dtbo \ ov5647.dtbo \ + ov64a40.dtbo \ ov7251.dtbo \ ov9281.dtbo \ papirus.dtbo \ diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index 8937cb4..c1128fc 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -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,= +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 diff --git a/arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts b/arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts index 8471ad0..c5cfbdc 100644 --- a/arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts +++ b/arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts @@ -189,6 +189,16 @@ #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 { @@ -289,6 +299,16 @@ #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 }; }; }; @@ -450,6 +470,12 @@ 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>, @@ -496,6 +522,12 @@ 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"; diff --git a/arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts b/arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts index bdb1aeb..1dcc63e 100644 --- a/arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts +++ b/arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts @@ -247,6 +247,16 @@ #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 { @@ -347,6 +357,16 @@ #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 { @@ -447,6 +467,16 @@ #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 { @@ -547,6 +577,16 @@ #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 }; }; }; @@ -725,6 +765,12 @@ 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>, @@ -771,6 +817,12 @@ 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>, @@ -817,6 +869,12 @@ 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>, @@ -863,6 +921,12 @@ 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 index 0000000..b6f8586 --- /dev/null +++ b/arch/arm/boot/dts/overlays/ov64a40-overlay.dts @@ -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 index 0000000..471b383 --- /dev/null +++ b/arch/arm/boot/dts/overlays/ov64a40.dtsi @@ -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>; +}; -- 2.7.4