From 15808e7f0b3e320c52e71cab722f2dbb137a6d95 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Thu, 22 Dec 2022 14:12:54 +0000
Subject: [PATCH] dtoverlays: Add overlays for the IMX708 image sensor

New overlay to support the Sony IMX708 image sensor.
This includes a VCM for lens control.
Also adds support to the camera mux overlays.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
 arch/arm/boot/dts/overlays/Makefile           |   1 +
 arch/arm/boot/dts/overlays/README             |  23 ++++
 .../dts/overlays/camera-mux-2port-overlay.dts |  32 ++++++
 .../dts/overlays/camera-mux-4port-overlay.dts |  64 +++++++++++
 arch/arm/boot/dts/overlays/imx708-overlay.dts | 104 ++++++++++++++++++
 arch/arm/boot/dts/overlays/imx708.dtsi        |  35 ++++++
 6 files changed, 259 insertions(+)
 create mode 100644 arch/arm/boot/dts/overlays/imx708-overlay.dts
 create mode 100644 arch/arm/boot/dts/overlays/imx708.dtsi

--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -122,6 +122,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
 	imx462.dtbo \
 	imx477.dtbo \
 	imx519.dtbo \
+	imx708.dtbo \
 	iqaudio-codec.dtbo \
 	iqaudio-dac.dtbo \
 	iqaudio-dacplus.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -716,6 +716,7 @@ Params: cam0-imx219             Select I
         cam0-imx258             Select IMX258 for camera on port 0
         cam0-imx290             Select IMX290 for camera on port 0
         cam0-imx477             Select IMX477 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-ov7251             Select OV7251 for camera on port 0
@@ -725,6 +726,7 @@ Params: cam0-imx219             Select I
         cam1-imx258             Select IMX258 for camera on port 1
         cam1-imx290             Select IMX290 for camera on port 1
         cam1-imx477             Select IMX477 for camera on port 1
+        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-ov7251             Select OV7251 for camera on port 1
@@ -741,6 +743,7 @@ Params: cam0-imx219             Select I
         cam0-imx258             Select IMX258 for camera on port 0
         cam0-imx290             Select IMX290 for camera on port 0
         cam0-imx477             Select IMX477 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-ov7251             Select OV7251 for camera on port 0
@@ -750,6 +753,7 @@ Params: cam0-imx219             Select I
         cam1-imx258             Select IMX258 for camera on port 1
         cam1-imx290             Select IMX290 for camera on port 1
         cam1-imx477             Select IMX477 for camera on port 1
+        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-ov7251             Select OV7251 for camera on port 1
@@ -759,6 +763,7 @@ Params: cam0-imx219             Select I
         cam2-imx258             Select IMX258 for camera on port 2
         cam2-imx290             Select IMX290 for camera on port 2
         cam2-imx477             Select IMX477 for camera on port 2
+        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-ov7251             Select OV7251 for camera on port 2
@@ -768,6 +773,7 @@ Params: cam0-imx219             Select I
         cam3-imx258             Select IMX258 for camera on port 3
         cam3-imx290             Select IMX290 for camera on port 3
         cam3-imx477             Select IMX477 for camera on port 3
+        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-ov7251             Select OV7251 for camera on port 3
@@ -2345,6 +2351,23 @@ Params: rotation                Mounting
         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).
+
+
+Name:   imx708
+Info:   Sony IMX708 camera module.
+        Uses Unicam 1, which is the standard camera connector on most Pi
+        variants.
+Load:   dtoverlay=imx708,<param>=<val>
+Params: rotation                Mounting rotation of the camera sensor (0 or
+                                180, default 180)
+        orientation             Sensor orientation (0 = front, 1 = rear,
+                                2 = external, default external)
+        vcm                     Select lens driver state. Default is enabled,
+                                but vcm=off will disable.
+        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).
 
 
--- a/arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts
+++ b/arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts
@@ -112,6 +112,16 @@
 					#undef cam_endpoint
 					#undef cam1_clk
 
+					#define cam_node imx708_0
+					#define cam_endpoint imx708_0_ep
+					#define vcm_node imx708_0_vcm
+					#define cam1_clk clk_24mhz
+					#include "imx708.dtsi"
+					#undef cam_node
+					#undef cam_endpoint
+					#undef vcm_node
+					#undef cam1_clk
+
 					#define cam_node ov5647_0
 					#define cam_endpoint ov5647_0_ep
 					#define cam1_clk clk_25mhz
@@ -182,6 +192,16 @@
 					#undef cam_endpoint
 					#undef cam1_clk
 
+					#define cam_node imx708_1
+					#define cam_endpoint imx708_1_ep
+					#define vcm_node imx708_1_vcm
+					#define cam1_clk clk_24mhz
+					#include "imx708.dtsi"
+					#undef cam_node
+					#undef cam_endpoint
+					#undef vcm_node
+					#undef cam1_clk
+
 					#define cam_node ov5647_1
 					#define cam_endpoint ov5647_1_ep
 					#define cam1_clk clk_25mhz
@@ -353,6 +373,12 @@
 			      <&imx477_0_ep>, "remote-endpoint:0=",<&mux_in0>,
 			      <&mux_in0>, "clock-noncontinuous?",
 			      <&imx477_0>, "status=okay";
+		cam0-imx708 = <&mux_in0>, "remote-endpoint:0=",<&imx708_0_ep>,
+			      <&imx708_0_ep>, "remote-endpoint:0=",<&mux_in0>,
+			      <&mux_in0>, "clock-noncontinuous?",
+			      <&imx708_0>, "status=okay",
+			      <&imx708_0_vcm>, "status=okay",
+			      <&imx708_0>,"lens-focus:0=", <&imx708_0_vcm>;
 		cam0-ov5647 = <&mux_in0>, "remote-endpoint:0=",<&ov5647_0_ep>,
 			      <&ov5647_0_ep>, "remote-endpoint:0=",<&mux_in0>,
 			      <&ov5647_0>, "status=okay";
@@ -381,6 +407,12 @@
 			      <&imx477_1_ep>, "remote-endpoint:0=",<&mux_in1>,
 			      <&mux_in1>, "clock-noncontinuous?",
 			      <&imx477_1>, "status=okay";
+		cam1-imx708 = <&mux_in1>, "remote-endpoint:0=",<&imx708_1_ep>,
+			      <&imx708_1_ep>, "remote-endpoint:0=",<&mux_in1>,
+			      <&mux_in1>, "clock-noncontinuous?",
+			      <&imx708_1>, "status=okay",
+			      <&imx708_1_vcm>, "status=okay",
+			      <&imx708_1>,"lens-focus:0=", <&imx708_1_vcm>;
 		cam1-ov5647 = <&mux_in1>, "remote-endpoint:0=",<&ov5647_1_ep>,
 			      <&ov5647_1_ep>, "remote-endpoint:0=",<&mux_in1>,
 			      <&ov5647_1>, "status=okay";
--- a/arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts
+++ b/arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts
@@ -170,6 +170,16 @@
 					#undef cam_endpoint
 					#undef cam1_clk
 
+					#define cam_node imx708_0
+					#define cam_endpoint imx708_0_ep
+					#define vcm_node imx708_0_vcm
+					#define cam1_clk clk_24mhz
+					#include "imx708.dtsi"
+					#undef cam_node
+					#undef cam_endpoint
+					#undef vcm_node
+					#undef cam1_clk
+
 					#define cam_node ov5647_0
 					#define cam_endpoint ov5647_0_ep
 					#define cam1_clk clk_25mhz
@@ -240,6 +250,16 @@
 					#undef cam_endpoint
 					#undef cam1_clk
 
+					#define cam_node imx708_1
+					#define cam_endpoint imx708_1_ep
+					#define vcm_node imx708_1_vcm
+					#define cam1_clk clk_24mhz
+					#include "imx708.dtsi"
+					#undef cam_node
+					#undef cam_endpoint
+					#undef vcm_node
+					#undef cam1_clk
+
 					#define cam_node ov5647_1
 					#define cam_endpoint ov5647_1_ep
 					#define cam1_clk clk_25mhz
@@ -310,6 +330,16 @@
 					#undef cam_endpoint
 					#undef cam1_clk
 
+					#define cam_node imx708_2
+					#define cam_endpoint imx708_2_ep
+					#define vcm_node imx708_2_vcm
+					#define cam1_clk clk_24mhz
+					#include "imx708.dtsi"
+					#undef cam_node
+					#undef cam_endpoint
+					#undef vcm_node
+					#undef cam1_clk
+
 					#define cam_node ov5647_2
 					#define cam_endpoint ov5647_2_ep
 					#define cam1_clk clk_25mhz
@@ -380,6 +410,16 @@
 					#undef cam_endpoint
 					#undef cam1_clk
 
+					#define cam_node imx708_3
+					#define cam_endpoint imx708_3_ep
+					#define vcm_node imx708_3_vcm
+					#define cam1_clk clk_24mhz
+					#include "imx708.dtsi"
+					#undef cam_node
+					#undef cam_endpoint
+					#undef vcm_node
+					#undef cam1_clk
+
 					#define cam_node ov5647_3
 					#define cam_endpoint ov5647_3_ep
 					#define cam1_clk clk_25mhz
@@ -568,6 +608,12 @@
 			      <&imx477_0_ep>, "remote-endpoint:0=",<&mux_in0>,
 			      <&mux_in0>, "clock-noncontinuous?",
 			      <&imx477_0>, "status=okay";
+		cam0-imx708 = <&mux_in0>, "remote-endpoint:0=",<&imx708_0_ep>,
+			      <&imx708_0_ep>, "remote-endpoint:0=",<&mux_in0>,
+			      <&mux_in0>, "clock-noncontinuous?",
+			      <&imx708_0>, "status=okay",
+			      <&imx708_0_vcm>, "status=okay",
+			      <&imx708_0>,"lens-focus:0=", <&imx708_0_vcm>;
 		cam0-ov5647 = <&mux_in0>, "remote-endpoint:0=",<&ov5647_0_ep>,
 			      <&ov5647_0_ep>, "remote-endpoint:0=",<&mux_in0>,
 			      <&ov5647_0>, "status=okay";
@@ -596,6 +642,12 @@
 			      <&imx477_1_ep>, "remote-endpoint:0=",<&mux_in1>,
 			      <&mux_in1>, "clock-noncontinuous?",
 			      <&imx477_1>, "status=okay";
+		cam1-imx708 = <&mux_in1>, "remote-endpoint:0=",<&imx708_1_ep>,
+			      <&imx708_1_ep>, "remote-endpoint:0=",<&mux_in1>,
+			      <&mux_in1>, "clock-noncontinuous?",
+			      <&imx708_1>, "status=okay",
+			      <&imx708_1_vcm>, "status=okay",
+			      <&imx708_1>,"lens-focus:0=", <&imx708_1_vcm>;
 		cam1-ov5647 = <&mux_in1>, "remote-endpoint:0=",<&ov5647_1_ep>,
 			      <&ov5647_1_ep>, "remote-endpoint:0=",<&mux_in1>,
 			      <&ov5647_1>, "status=okay";
@@ -624,6 +676,12 @@
 			      <&imx477_2_ep>, "remote-endpoint:0=",<&mux_in2>,
 			      <&mux_in2>, "clock-noncontinuous?",
 			      <&imx477_2>, "status=okay";
+		cam2-imx708 = <&mux_in2>, "remote-endpoint:0=",<&imx708_2_ep>,
+			      <&imx708_2_ep>, "remote-endpoint:0=",<&mux_in2>,
+			      <&mux_in2>, "clock-noncontinuous?",
+			      <&imx708_2>, "status=okay",
+			      <&imx708_2_vcm>, "status=okay",
+			      <&imx708_2>,"lens-focus:0=", <&imx708_2_vcm>;
 		cam2-ov5647 = <&mux_in2>, "remote-endpoint:0=",<&ov5647_2_ep>,
 			      <&ov5647_2_ep>, "remote-endpoint:0=",<&mux_in2>,
 			      <&ov5647_2>, "status=okay";
@@ -652,6 +710,12 @@
 			      <&imx477_3_ep>, "remote-endpoint:0=",<&mux_in3>,
 			      <&mux_in3>, "clock-noncontinuous?",
 			      <&imx477_3>, "status=okay";
+		cam3-imx708 = <&mux_in3>, "remote-endpoint:0=",<&imx708_3_ep>,
+			      <&imx708_3_ep>, "remote-endpoint:0=",<&mux_in3>,
+			      <&mux_in3>, "clock-noncontinuous?",
+			      <&imx708_3>, "status=okay",
+			      <&imx708_3_vcm>, "status=okay",
+			      <&imx708_3>,"lens-focus:0=", <&imx708_3_vcm>;
 		cam3-ov5647 = <&mux_in3>, "remote-endpoint:0=",<&ov5647_3_ep>,
 			      <&ov5647_3_ep>, "remote-endpoint:0=",<&mux_in3>,
 			      <&ov5647_3>, "status=okay";
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/imx708-overlay.dts
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Definitions for IMX708 camera module on VC I2C bus
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+/{
+	compatible = "brcm,bcm2835";
+
+	fragment@0 {
+		target = <&i2c0if>;
+		__overlay__ {
+			status = "okay";
+		};
+	};
+
+	clk_frag: fragment@1 {
+		target = <&cam1_clk>;
+		__overlay__ {
+			status = "okay";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	fragment@2 {
+		target = <&i2c0mux>;
+		__overlay__ {
+			status = "okay";
+		};
+	};
+
+	reg_frag: fragment@3 {
+		target = <&cam1_reg>;
+		cam_reg: __overlay__ {
+			startup-delay-us = <70000>;
+			off-on-delay-us = <30000>;
+			regulator-min-microvolt = <2700000>;
+			regulator-max-microvolt = <2700000>;
+		};
+	};
+
+	fragment@4 {
+		target = <&cam_node>;
+		__overlay__ {
+			lens-focus = <&vcm_node>;
+		};
+	};
+
+	i2c_frag: fragment@100 {
+		target = <&i2c_csi_dsi>;
+		__overlay__ {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "okay";
+
+			#include "imx708.dtsi"
+		};
+	};
+
+	csi_frag: fragment@101 {
+		target = <&csi1>;
+		csi: __overlay__ {
+			status = "okay";
+			brcm,media-controller;
+
+			port {
+				csi_ep: endpoint {
+					remote-endpoint = <&cam_endpoint>;
+					clock-lanes = <0>;
+					data-lanes = <1 2>;
+					clock-noncontinuous;
+				};
+			};
+		};
+	};
+
+	__overrides__ {
+		rotation = <&cam_node>,"rotation:0";
+		orientation = <&cam_node>,"orientation:0";
+		media-controller = <&csi>,"brcm,media-controller?";
+		cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>,
+		       <&csi_frag>, "target:0=",<&csi0>,
+		       <&clk_frag>, "target:0=",<&cam0_clk>,
+		       <&reg_frag>, "target:0=",<&cam0_reg>,
+		       <&cam_node>, "clocks:0=",<&cam0_clk>,
+		       <&cam_node>, "VANA1-supply:0=",<&cam0_reg>,
+		       <&vcm_node>, "VDD-supply:0=",<&cam0_reg>;
+		vcm = <&vcm_node>, "status",
+		      <0>, "=4";
+	};
+};
+
+&cam_node {
+	status = "okay";
+};
+
+&cam_endpoint {
+	remote-endpoint = <&csi_ep>;
+};
+
+&vcm_node {
+	status = "okay";
+};
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/imx708.dtsi
@@ -0,0 +1,35 @@
+// Fragment that configures a Sony IMX708
+
+cam_node: imx708@1a {
+	compatible = "sony,imx708";
+	reg = <0x1a>;
+	status = "disabled";
+
+	clocks = <&cam1_clk>;
+	clock-names = "xclk";
+
+	VANA1-supply = <&cam1_reg>;	/* 2.8v */
+	VANA2-supply = <&cam_dummy_reg>;/* 1.8v */
+	VDIG-supply = <&cam_dummy_reg>;	/* 1.1v */
+	VDDL-supply = <&cam_dummy_reg>;	/* 1.8v */
+
+	rotation = <180>;
+	orientation = <2>;
+
+	port {
+		cam_endpoint: endpoint {
+			clock-lanes = <0>;
+			data-lanes = <1 2>;
+			clock-noncontinuous;
+			link-frequencies =
+				/bits/ 64 <450000000>;
+		};
+	};
+};
+
+vcm_node: dw9817@c {
+	compatible = "dongwoon,dw9817-vcm";
+	reg = <0x0c>;
+	status = "disabled";
+	VDD-supply = <&cam1_reg>;
+};
