From c00d40f80f267c7b548549ad599c1ba808d7dad0 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Date: Tue, 2 Jun 2026 15:37:25 +0100
Subject: [PATCH] dtoverlays: camera-mux-N-port: Allow multiple simultaneous
 instances

The overlays had a cam0 override that changed the CSI2 and I2C
interfaces, but it didn't create unique nodes for the clocks and
mux nodes meaning that loading two instances simultaneously didn't
work.

Update them to create unique nodes, and add overrides to set the
GPIOs controlling the muxes.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
 arch/arm/boot/dts/overlays/README             |  4 ++++
 .../dts/overlays/camera-mux-2port-overlay.dts | 21 ++++++++++++-----
 .../dts/overlays/camera-mux-4port-overlay.dts | 23 ++++++++++++++-----
 3 files changed, 36 insertions(+), 12 deletions(-)

--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -945,6 +945,7 @@ Params: cam0-arducam-64mp       Select A
         cam1-sync-sink          Set camera on port 1 as vsync sink
 
         cam0                    Connect the mux to CAM0 port (default is CAM1)
+        gpio-sel                Set the GPIO used to control the mux
 
 
 Name:   camera-mux-4port
@@ -1014,6 +1015,9 @@ Params: cam0-arducam-64mp       Select A
         cam3-sync-sink          Set camera on port 3 as vsync sink
 
         cam0                    Connect the mux to CAM0 port (default is CAM1)
+        gpio-sel                Set the GPIO used to control the mux select line
+        gpio-en1                Set the GPIO used to control the mux en1 line
+        gpio-en2                Set the GPIO used to control the mux en2 line
 
 
 Name:   cap1106
--- a/arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts
+++ b/arch/arm/boot/dts/overlays/camera-mux-2port-overlay.dts
@@ -339,15 +339,17 @@
 	fragment@203 {
 		target-path="/";
 		__overlay__ {
-			mux: mux-controller {
+			mux: mux-controller@1 {
 				compatible = "gpio-mux";
+				reg = <1>;
 				#mux-control-cells = <0>;
 
 				mux-gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;
 			};
 
-			video-mux {
+			videomux: video-mux@1 {
 				compatible = "video-mux";
+				reg = <1>;
 				mux-controls = <&mux>;
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -378,7 +380,7 @@
 				};
 			};
 
-			clk_24mhz: clk_24mhz {
+			clk_24mhz: clk_24mhz_1 {
 				compatible = "fixed-clock";
 				#clock-cells = <0>;
 
@@ -386,7 +388,7 @@
 				status = "okay";
 			};
 
-			clk_25mhz: clk_25mhz {
+			clk_25mhz: clk_25mhz_1 {
 				compatible = "fixed-clock";
 				#clock-cells = <0>;
 
@@ -394,7 +396,7 @@
 				status = "okay";
 			};
 
-			clk_imx290: clk_imx290 {
+			clk_imx290: clk_imx290_1 {
 				compatible = "fixed-clock";
 				#clock-cells = <0>;
 
@@ -535,11 +537,18 @@
 				       <&imx290_1>,"clock-frequency:0";
 
 		cam0 = <&i2c_frag>, "target:0=",<&i2c_csi_dsi0>,
-		       <&csi_frag>, "target:0=",<&csi0>;
+		       <&csi_frag>, "target:0=",<&csi0>,
+		       <&mux>, "reg:0=0",
+		       <&videomux>, "reg:0=0",
+		       <&clk_24mhz>, "name=clk_24mhz_0",
+		       <&clk_25mhz>, "name=clk_25mhz_0",
+		       <&clk_imx290>, "name=clk_imx290_0";
 
 		cam0-sync-source = <&imx477_0>, "trigger-mode:0=1";
 		cam0-sync-sink = <&imx477_0>, "trigger-mode:0=2";
 		cam1-sync-source = <&imx477_1>, "trigger-mode:0=1";
 		cam1-sync-sink = <&imx477_1>, "trigger-mode:0=2";
+
+		gpio-sel = <&mux>, "mux-gpios:4";
 	};
 };
--- a/arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts
+++ b/arch/arm/boot/dts/overlays/camera-mux-4port-overlay.dts
@@ -617,8 +617,9 @@
 	fragment@203 {
 		target-path="/";
 		__overlay__ {
-			mux: mux-controller {
+			mux: mux-controller@1 {
 				compatible = "gpio-mux";
+				reg = <1>;
 				#mux-control-cells = <0>;
 
 				/* SEL, En2, En1 */
@@ -627,8 +628,9 @@
 					    <&gpio 17 GPIO_ACTIVE_HIGH>;
 			};
 
-			video-mux {
+			videomux: video-mux@1 {
 				compatible = "video-mux";
+				reg = <1>;
 				mux-controls = <&mux>;
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -684,7 +686,7 @@
 				};
 			};
 
-			clk_24mhz: clk_24mhz {
+			clk_24mhz: clk_24mhz_1 {
 				compatible = "fixed-clock";
 				#clock-cells = <0>;
 
@@ -692,7 +694,7 @@
 				status = "okay";
 			};
 
-			clk_25mhz: clk_25mhz {
+			clk_25mhz: clk_25mhz_1 {
 				compatible = "fixed-clock";
 				#clock-cells = <0>;
 
@@ -700,7 +702,7 @@
 				status = "okay";
 			};
 
-			clk_imx290: clk_imx290 {
+			clk_imx290: clk_imx290_1 {
 				compatible = "fixed-clock";
 				#clock-cells = <0>;
 
@@ -940,7 +942,12 @@
 				       <&imx290_3>,"clock-frequency:0";
 
 		cam0 = <&i2c_frag>, "target:0=",<&i2c_csi_dsi0>,
-		       <&csi_frag>, "target:0=",<&csi0>;
+		       <&csi_frag>, "target:0=",<&csi0>,
+		       <&mux>, "reg:0=0",
+		       <&videomux>, "reg:0=0",
+		       <&clk_24mhz>, "name=clk_24mhz_0",
+		       <&clk_25mhz>, "name=clk_25mhz_0",
+		       <&clk_imx290>, "name=clk_imx290_0";
 
 		cam0-sync-source = <&imx477_0>, "trigger-mode:0=1";
 		cam0-sync-sink = <&imx477_0>, "trigger-mode:0=2";
@@ -950,5 +957,9 @@
 		cam2-sync-sink = <&imx477_2>, "trigger-mode:0=2";
 		cam3-sync-source = <&imx477_3>, "trigger-mode:0=1";
 		cam3-sync-sink = <&imx477_3>, "trigger-mode:0=2";
+
+		gpio-sel = <&mux>, "mux-gpios:4";
+		gpio-en2 = <&mux>, "mux-gpios:16";
+		gpio-en1 = <&mux>, "mux-gpios:28";
 	};
 };
