From fe30939a0e61559cfc5a7b5d188c6802fe56e6ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= <megi@xff.cz>
Date: Wed, 8 Jul 2020 00:58:16 +0200
Subject: [PATCH 168/463] arm64: dts: sun50i-a64-pinephone: Add Type-C support
 for all PP variants 1.0-1.2

There are differences in GPIO and how VBUS is handled. Describe them
in DTS. Thankfully we can support both unmodded and modded variants
of 1.0 and 1.1 boards with one DTS. No need for more subvariants.

Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
 .../allwinner/sun50i-a64-pinephone-1.0.dts    | 86 +++++++++++++++++++
 .../allwinner/sun50i-a64-pinephone-1.1.dts    | 86 +++++++++++++++++++
 .../allwinner/sun50i-a64-pinephone-1.2.dts    | 60 +++++++++++++
 .../dts/allwinner/sun50i-a64-pinephone.dtsi   | 68 ++++++++++++++-
 4 files changed, 299 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
index 219f720b8b7d9..498ae493d176d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.0.dts
@@ -8,6 +8,92 @@
 / {
 	model = "Pine64 PinePhone Developer Batch (1.0)";
 	compatible = "pine64,pinephone-1.0", "pine64,pinephone", "allwinner,sun50i-a64";
+
+	reg_vbus: usb0-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb0-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
+		enable-active-high;
+		vin-supply = <&reg_drivevbus>;
+	};
+};
+
+&axp803 {
+	x-powers,drive-vbus-en;
+};
+
+&i2c0 {
+	hdmi-bridge@28 {
+		compatible = "analogix,anx7688";
+		reg = <0x28>;
+
+		interrupt-parent = <&r_pio>;
+		interrupts = <0 11 IRQ_TYPE_EDGE_FALLING>; /* PL11 */
+
+		enable-gpios = <&pio 3 10 GPIO_ACTIVE_LOW>; /* PD10 */
+		reset-gpios = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /* PL9 */
+
+		cabledet-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+
+		avdd10-supply = <&reg_anx1v0>;
+		dvdd10-supply = <&reg_anx1v0>;
+		/* This is for the HW hack variant, but will also work for non-modified version. */
+		avdd18-supply = <&reg_ldo_io1>;
+		dvdd18-supply = <&reg_ldo_io1>;
+		avdd33-supply = <&reg_dldo1>;
+		vconn-supply = <&reg_vconn5v0>;
+		hdmi_vt-supply = <&reg_dldo1>;
+
+		source-caps = <
+			PDO_FIXED(5000, 500, PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE)
+		>;
+
+		sink-caps = <
+			PDO_FIXED(5000, 3000, PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE)
+		>;
+
+		/*
+		 * ANX7688 can't enable/disable USB-5V <-> DCIN switch by
+		 * itself, and PMIC's N_VBUSEN is not connected anywhere either,
+		 * so we need to configure everything in software:
+		 *
+		 * - get the VBUS status from ANX7688 via I2C
+		 * - configure PMIC to let it know vbus drive status (via
+		 *   reg_drivevbus)
+		 * - enable VBUS switch and USB-5V regulator (via reg_vbus
+		 *   and reg_usb_5v)
+		 */
+		vbus-supply = <&reg_vbus>;
+		vbus_in-supply = <&usb_power_supply>;
+
+		port {
+			typec0_dr_sw: endpoint {
+				remote-endpoint = <&usb0_drd_sw>;
+			};
+		};
+	};
+};
+
+/*
+ * The N_VBUSEN pin is disconnected, but we need to inform the PMIC about
+ * the VBUS status anyway. To avoid the pin from floating and to inform
+ * the PMIC, about VBUS status, we couple reg_drivevbus with reg_vbus.
+ */
+&reg_drivevbus {
+	vin-supply = <&reg_usb_5v>;
+	status = "okay";
+};
+
+&usbphy {
+	usb-role-switch;
+
+	port {
+		usb0_drd_sw: endpoint {
+			remote-endpoint = <&typec0_dr_sw>;
+		};
+	};
 };
 
 &codec_analog {
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
index 723af64a9ceee..73275308f484f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
@@ -8,6 +8,20 @@
 / {
 	model = "Pine64 PinePhone Braveheart (1.1)";
 	compatible = "pine64,pinephone-1.1", "pine64,pinephone", "allwinner,sun50i-a64";
+
+	reg_vbus: usb0-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb0-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
+		enable-active-high;
+		vin-supply = <&reg_drivevbus>;
+	};
+};
+
+&axp803 {
+	x-powers,drive-vbus-en;
 };
 
 &backlight {
@@ -33,7 +47,79 @@ &codec_analog {
 	allwinner,internal-bias-resistor;
 };
 
+&i2c0 {
+	hdmi-bridge@28 {
+		compatible = "analogix,anx7688";
+		reg = <0x28>;
+
+		interrupt-parent = <&r_pio>;
+		interrupts = <0 11 IRQ_TYPE_EDGE_FALLING>; /* PL11 */
+
+		enable-gpios = <&pio 3 10 GPIO_ACTIVE_LOW>; /* PD10 */
+		reset-gpios = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /* PL9 */
+
+		cabledet-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+
+		avdd10-supply = <&reg_anx1v0>;
+		dvdd10-supply = <&reg_anx1v0>;
+		/* This is for the HW hack variant, but will also work for non-modified version. */
+		avdd18-supply = <&reg_ldo_io1>;
+		dvdd18-supply = <&reg_ldo_io1>;
+		avdd33-supply = <&reg_dldo1>;
+		vconn-supply = <&reg_vconn5v0>;
+		hdmi_vt-supply = <&reg_dldo1>;
+
+		source-caps = <
+			PDO_FIXED(5000, 500, PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE)
+		>;
+
+		sink-caps = <
+			PDO_FIXED(5000, 3000, PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE)
+		>;
+
+		/*
+		 * ANX7688 can't enable/disable USB-5V <-> DCIN switch by
+		 * itself, and PMIC's N_VBUSEN is not connected anywhere either,
+		 * so we need to configure everything in software:
+		 *
+		 * - get the VBUS status from ANX7688 via I2C
+		 * - configure PMIC to let it know vbus drive status (via
+		 *   reg_drivevbus)
+		 * - enable VBUS switch and USB-5V regulator (via reg_vbus
+		 *   and reg_usb_5v)
+		 */
+		vbus-supply = <&reg_vbus>;
+		vbus_in-supply = <&usb_power_supply>;
+
+		port {
+			typec0_dr_sw: endpoint {
+				remote-endpoint = <&usb0_drd_sw>;
+			};
+		};
+	};
+};
+
+/*
+ * The N_VBUSEN pin is disconnected, but we need to inform the PMIC about
+ * the VBUS status anyway. To avoid the pin from floating and to inform
+ * the PMIC, about VBUS status, we couple reg_drivevbus with reg_vbus.
+ */
+&reg_drivevbus {
+	vin-supply = <&reg_usb_5v>;
+	status = "okay";
+};
+
 &sgm3140 {
 	enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
 	flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
 };
+
+&usbphy {
+	usb-role-switch;
+
+	port {
+		usb0_drd_sw: endpoint {
+			remote-endpoint = <&typec0_dr_sw>;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
index 4e7e237cb46aa..40127186606f2 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
@@ -48,7 +48,67 @@ &mmc1 {
 	mmc-pwrseq = <&wifi_pwrseq>;
 };
 
+&i2c0 {
+	hdmi-bridge@28 {
+		compatible = "analogix,anx7688";
+		reg = <0x28>;
+
+		interrupt-parent = <&r_pio>;
+		interrupts = <0 11 IRQ_TYPE_EDGE_FALLING>; /* PL11 */
+
+		enable-gpios = <&pio 3 10 GPIO_ACTIVE_LOW>; /* PD10 */
+		reset-gpios = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
+
+		cabledet-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+
+		avdd10-supply = <&reg_anx1v0>;
+		dvdd10-supply = <&reg_anx1v0>;
+		avdd18-supply = <&reg_ldo_io1>;
+		dvdd18-supply = <&reg_ldo_io1>;
+		avdd33-supply = <&reg_dcdc1>;
+		vconn-supply = <&reg_vconn5v0>;
+		hdmi_vt-supply = <&reg_dldo1>;
+
+		source-caps = <
+			PDO_FIXED(5000, 500, PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE)
+		>;
+
+		sink-caps = <
+			PDO_FIXED(5000, 3000, PDO_FIXED_DATA_SWAP | PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE)
+		>;
+
+		/*
+		 * ANX7688 will enable/disable USB-5V <-> DCIN switch by itself
+		 * via VBUS_CTRL pin. The driver just has to enable the USB-5V
+		 * so that the switch has power.
+		 */
+		vbus-supply = <&reg_usb_5v>;
+		vbus_in-supply = <&usb_power_supply>;
+
+		port {
+			typec0_dr_sw: endpoint {
+				remote-endpoint = <&usb0_drd_sw>;
+			};
+		};
+	};
+};
+
+&reg_anx1v0 {
+	gpio = <&pio 3 11 GPIO_ACTIVE_HIGH>; /* PD11 */
+	enable-active-high;
+};
+
 &sgm3140 {
 	enable-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
 	flash-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>; /* PC3 */
 };
+
+&usbphy {
+	usb-role-switch;
+
+	port {
+		usb0_drd_sw: endpoint {
+			remote-endpoint = <&typec0_dr_sw>;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index 44b18d5a9d939..d126c9e9a605c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -10,6 +10,7 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/usb/pd.h>
 
 / {
 	chassis-type = "handset";
@@ -70,6 +71,24 @@ led2: led-2 {
 		};
 	};
 
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	reg_anx1v0: anx1v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "anx1v0";
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <1000000>;
+	};
+
 	multi-led {
 		compatible = "leds-group-multicolor";
 		color = <LED_COLOR_ID_RGB>;
@@ -85,6 +104,24 @@ reg_ps: ps-regulator {
 		regulator-boot-on;
 	};
 
+	reg_usb_5v: usb-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "usb-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&pio 3 8 GPIO_ACTIVE_HIGH>; /* PD8 */
+		enable-active-high;
+	};
+
+	reg_vbat_bb: vbat-bb {
+		compatible = "regulator-fixed";
+		regulator-name = "vbat-bb";
+		regulator-min-microvolt = <3500000>;
+		regulator-max-microvolt = <3500000>;
+		gpio = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */
+		enable-active-high;
+	};
+
 	reg_vbat_wifi: vbat-wifi {
 		compatible = "regulator-fixed";
 		regulator-min-microvolt = <3300000>;
@@ -92,6 +129,16 @@ reg_vbat_wifi: vbat-wifi {
 		regulator-name = "vbat-wifi";
 	};
 
+	/* This is a charge pump for CC1 and CC2 pins on USB-C connector. */
+	reg_vconn5v0: vconn5v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vconn5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&pio 3 9 GPIO_ACTIVE_HIGH>; /* PD9 */
+		enable-active-high;
+	};
+
 	sgm3140: led-controller {
 		compatible = "sgmicro,sgm3140";
 		vin-supply = <&reg_dcdc1>;
@@ -207,6 +254,21 @@ &ehci1 {
 	status = "okay";
 };
 
+&hdmi {
+	hvcc-supply = <&reg_dldo1>;
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&sound_hdmi {
+	status = "okay";
+};
+
 &i2c_csi {
 	gc2145: front-camera@3c {
 		compatible = "galaxycore,gc2145";
@@ -309,6 +371,10 @@ &i2c2 {
 	status = "okay";
 };
 
+&i2s2 {
+	status = "okay";
+};
+
 &lradc {
 	vref-supply = <&reg_aldo3>;
 	wakeup-source;
@@ -602,7 +668,7 @@ &uart3 {
 };
 
 &usb_otg {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
 	status = "okay";
 };
 
-- 
2.46.0

