meson64-6.19: radxa-zero2: fusb302 (minimal by me + full impl by Neil/Christian)

- I submitted the basic enablement, got feedback on ML, reworked it to the minimal, valid, description
- Picked and rebased Neil/Christian's original full implementation from 2024 on top of it
  - See https://gitlab.com/superna9999/linux/-/tree/topic/amlogic/radxa-zero2/fusb302
  - This includes a driver for the CH482D chip (under `CONFIG_TYPEC_MUX_GPIO_SWITCH`, enabled here)
  - Quick search revealed two CH482D's are also present `rockchip/rk3566-radxa-cm3-io.dts` but thus far undescribed
    - see https://dl.radxa.com/cm3/io_board/radxa_cm3_io_board_v1.32_schematic.pdf pages 7 and 13
    - maybe we can work with them to help test driver and bindings?
- See https://lore.kernel.org/linux-amlogic/20260114-arm64-dts-amlogic-radxa-zero2-additions-v1-0-8b5cdf328fde@pardini.net/
- See https://lore.kernel.org/linux-amlogic/20260115-arm64-dts-amlogic-radxa-zero2-additions-v2-1-948bb0479a45@pardini.net/
This commit is contained in:
Ricardo Pardini 2026-01-14 04:03:19 +01:00
parent 332e43bc8c
commit 160688703e
2 changed files with 517 additions and 0 deletions

View File

@ -3102,6 +3102,7 @@ CONFIG_TYPEC_STUSB160X=m
CONFIG_TYPEC_WUSB3801=m
CONFIG_TYPEC_MUX_FSA4480=m
CONFIG_TYPEC_MUX_PI3USB30532=m
CONFIG_TYPEC_MUX_GPIO_SWITCH=m
CONFIG_TYPEC_DP_ALTMODE=m
CONFIG_MMC=y
CONFIG_PWRSEQ_SD8787=m

View File

@ -0,0 +1,516 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ricardo Pardini <ricardo@pardini.net>
Date: Wed, 14 Jan 2026 02:49:48 +0100
Subject: arm64: dts: amlogic: add the type-c controller on Radxa Zero 2
The Radxa Zero2 has an FUSB302 controller on i2c3 at address 0x22 and
INT# wired to GPIOA-13; include a minimal connector.
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
---
arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts | 34 ++++++++++
1 file changed, 34 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
index 111111111111..222222222222 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
@@ -364,12 +364,46 @@ hdmi_tx_tmds_out: endpoint {
};
};
+/* Also exposed on the 40-pin header: SDA pin 3, SCL pin 5 */
+&i2c3 {
+ pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ fusb0: typec-portc@22 {
+ compatible = "fcs,fusb302";
+ reg = <0x22>;
+
+ pinctrl-0 = <&fusb302_irq_pins>;
+ pinctrl-names = "default";
+ interrupt-parent = <&gpio_intc>;
+ interrupts = <74 IRQ_TYPE_LEVEL_LOW>;
+
+ vbus-supply = <&ao_5v>;
+
+ connector {
+ compatible = "usb-c-connector";
+ };
+ };
+};
+
&ir {
status = "disabled";
pinctrl-0 = <&remote_input_ao_pins>;
pinctrl-names = "default";
};
+&periphs_pinctrl {
+ fusb302_irq_pins: fusb302-irq {
+ mux {
+ groups = "GPIOA_13";
+ function = "gpio_periphs";
+ bias-pull-up;
+ output-disable;
+ };
+ };
+};
+
&pwm_ab {
pinctrl-0 = <&pwm_a_e_pins>;
pinctrl-names = "default";
--
Armbian
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Tue, 31 Jan 2023 04:02:59 +0000
Subject: dt-bindings: add wch vendor prefix
Add vendor prefix for Nanjing Qinheng Microelectronics Co., Ltd
operating as WinChipHead (wch).
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 111111111111..222222222222 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1789,6 +1789,8 @@ patternProperties:
description: Wandbord (Technexion)
"^waveshare,.*":
description: Waveshare Electronics
+ "^wch,.*":
+ description: Nanjing Qinheng Microelectronics Co., Ltd (WinChipHead)
"^wd,.*":
description: Western Digital Corp.
"^we,.*":
--
Armbian
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Mon, 30 Jan 2023 15:50:30 +0000
Subject: dt-bindings: usb: add USB superspeed GPIO based switch
Introduce a binding for the CH482D GPIO-based switch hardware used for
switching USB SuperSpeed lanes from the USB Type-C plug orientation
signal provided by the Type-C Port Manager.
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
Documentation/devicetree/bindings/usb/gpio-superspeed-switch.yaml | 120 ++++++++++
1 file changed, 120 insertions(+)
diff --git a/Documentation/devicetree/bindings/usb/gpio-superspeed-switch.yaml b/Documentation/devicetree/bindings/usb/gpio-superspeed-switch.yaml
new file mode 100644
index 000000000000..111111111111
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/gpio-superspeed-switch.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/gpio-superspeed-switch.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: GPIO-based SuperSpeed switch
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+
+description:
+ In USB Type-C applications the USB SuperSpeed lanes must be switched depending
+ on the orientation of the Type-C plug. This binding describes a family of
+ hardware solutions which analog switches pairs of differential high-speed
+ lanes using a GPIO signal.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - wcn,ch482d
+ - const: gpio-superspeed-switch
+
+ enable-gpios:
+ description: Switch enable GPIO
+
+ select-gpios:
+ description: Orientation select
+
+ vcc-supply:
+ description: power supply
+
+ orientation-switch:
+ description: Flag the port as possible handler of orientation switching
+ type: boolean
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Super Speed output lanes
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Super Speed input lanes
+
+required:
+ - compatible
+ - select-gpios
+ - orientation-switch
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ tcpm {
+ connector {
+ compatible = "usb-c-connector";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ tcpm_hs_out: endpoint {
+ remote-endpoint = <&usb_hs_phy_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ tcpm_ss_out: endpoint {
+ remote-endpoint = <&usb_ss_switch_in>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ tcpm_sbu_out: endpoint {
+ remote-endpoint = <&sbu_mux_in>;
+ };
+ };
+ };
+ };
+ };
+
+ superspeed-mux {
+ compatible = "wcn,ch482d", "gpio-superspeed-switch";
+
+ select-gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ usb_ss_switch_out: endpoint {
+ remote-endpoint = <&tcpm_ss_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ usb_ss_switch_in: endpoint {
+ remote-endpoint = <&usb_ss_phy_in>;
+ };
+ };
+ };
+ };
+...
--
Armbian
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Mon, 30 Jan 2023 15:37:29 +0000
Subject: usb: typec: mux: Add generic GPIO based SuperSpeed switch driver
Add a simple driver to register a GPIO Based SuperSpeed lanes
switch device used to flip the lanes depending on the Type-C
plug orientation.
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
drivers/usb/typec/mux/Kconfig | 6 +
drivers/usb/typec/mux/Makefile | 1 +
drivers/usb/typec/mux/gpio-superspeed-switch.c | 119 ++++++++++
3 files changed, 126 insertions(+)
diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
index 111111111111..222222222222 100644
--- a/drivers/usb/typec/mux/Kconfig
+++ b/drivers/usb/typec/mux/Kconfig
@@ -95,4 +95,10 @@ config TYPEC_MUX_WCD939X_USBSS
common USB Type-C connector.
If compiled as a module, the module will be named wcd939x-usbss.
+config TYPEC_MUX_GPIO_SWITCH
+ tristate "GPIO based USB Type-C SuperSpeed switch"
+ help
+ Say Y or M if your system uses a GPIO based analog switch mux for
+ flipping the SuperSpeed lanes connected to a Type-C port.
+
endmenu
diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile
index 111111111111..222222222222 100644
--- a/drivers/usb/typec/mux/Makefile
+++ b/drivers/usb/typec/mux/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_TYPEC_MUX_PS883X) += ps883x.o
obj-$(CONFIG_TYPEC_MUX_PTN36502) += ptn36502.o
obj-$(CONFIG_TYPEC_MUX_TUSB1046) += tusb1046.o
obj-$(CONFIG_TYPEC_MUX_WCD939X_USBSS) += wcd939x-usbss.o
+obj-$(CONFIG_TYPEC_MUX_GPIO_SWITCH) += gpio-superspeed-switch.o
diff --git a/drivers/usb/typec/mux/gpio-superspeed-switch.c b/drivers/usb/typec/mux/gpio-superspeed-switch.c
new file mode 100644
index 000000000000..111111111111
--- /dev/null
+++ b/drivers/usb/typec/mux/gpio-superspeed-switch.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/gpio/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/usb/typec_mux.h>
+
+struct gpio_ss_switch {
+ struct gpio_desc *enable_gpio;
+ struct gpio_desc *select_gpio;
+
+ struct typec_switch_dev *sw;
+
+ bool enabled;
+ bool swapped;
+};
+
+static int gpio_ss_switch_set(struct typec_switch_dev *sw,
+ enum typec_orientation orientation)
+{
+ struct gpio_ss_switch *gpio_ss_switch = typec_switch_get_drvdata(sw);
+ bool enabled;
+ bool swapped;
+
+ enabled = gpio_ss_switch->enabled;
+ swapped = gpio_ss_switch->swapped;
+
+ switch (orientation) {
+ case TYPEC_ORIENTATION_NONE:
+ enabled = false;
+ break;
+ case TYPEC_ORIENTATION_NORMAL:
+ swapped = false;
+ break;
+ case TYPEC_ORIENTATION_REVERSE:
+ swapped = true;
+ break;
+ }
+
+ if (enabled != gpio_ss_switch->enabled)
+ gpiod_set_value_cansleep(gpio_ss_switch->enable_gpio, enabled);
+
+ if (swapped != gpio_ss_switch->swapped)
+ gpiod_set_value_cansleep(gpio_ss_switch->select_gpio, swapped);
+
+ gpio_ss_switch->enabled = enabled;
+ gpio_ss_switch->swapped = swapped;
+
+ return 0;
+}
+
+static int gpio_ss_switch_probe(struct platform_device *pdev)
+{
+ struct typec_switch_desc sw_desc = { };
+ struct device *dev = &pdev->dev;
+ struct gpio_ss_switch *gpio_ss_switch;
+
+ gpio_ss_switch = devm_kzalloc(dev, sizeof(*gpio_ss_switch), GFP_KERNEL);
+ if (!gpio_ss_switch)
+ return -ENOMEM;
+
+ gpio_ss_switch->enable_gpio = devm_gpiod_get_optional(dev, "enable",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(gpio_ss_switch->enable_gpio))
+ return dev_err_probe(dev, PTR_ERR(gpio_ss_switch->enable_gpio),
+ "unable to acquire enable gpio\n");
+
+ gpio_ss_switch->select_gpio = devm_gpiod_get(dev, "select", GPIOD_OUT_LOW);
+ if (IS_ERR(gpio_ss_switch->select_gpio))
+ return dev_err_probe(dev, PTR_ERR(gpio_ss_switch->select_gpio),
+ "unable to acquire select gpio\n");
+
+ sw_desc.drvdata = gpio_ss_switch;
+ sw_desc.fwnode = dev_fwnode(dev);
+ sw_desc.set = gpio_ss_switch_set;
+
+ gpio_ss_switch->sw = typec_switch_register(dev, &sw_desc);
+ if (IS_ERR(gpio_ss_switch->sw))
+ return dev_err_probe(dev, PTR_ERR(gpio_ss_switch->sw),
+ "failed to register gpio_ss_switch switch\n");
+
+ platform_set_drvdata(pdev, gpio_ss_switch);
+
+ return 0;
+}
+
+static void gpio_ss_switch_remove(struct platform_device *pdev)
+{
+ struct gpio_ss_switch *gpio_ss_switch = platform_get_drvdata(pdev);
+
+ gpiod_set_value_cansleep(gpio_ss_switch->enable_gpio, 0);
+
+ typec_switch_unregister(gpio_ss_switch->sw);
+}
+
+static const struct of_device_id gpio_ss_switch_match[] = {
+ { .compatible = "gpio-superspeed-switch" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, gpio_ss_switch_match);
+
+static struct platform_driver gpio_ss_switch_driver = {
+ .probe = gpio_ss_switch_probe,
+ .remove = gpio_ss_switch_remove,
+ .driver = {
+ .name = "gpio_ss_switch",
+ .of_match_table = gpio_ss_switch_match,
+ },
+};
+module_platform_driver(gpio_ss_switch_driver);
+
+MODULE_DESCRIPTION("GPIO based USB TYPE-C SuperSpeed switch driver");
+MODULE_LICENSE("GPL");
--
Armbian
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Mon, 30 Jan 2023 06:21:27 +0100
Subject: arm64: dts: meson: radxa-zero2: add FUSB302 support
Add support for the FUSB302 TYPE-C connector
- rpardini: reworked on top of minimal submission to ML
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
---
arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts | 51 ++++++++++
1 file changed, 51 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
index 111111111111..222222222222 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-radxa-zero2.dts
@@ -12,8 +12,10 @@
#include "meson-g12b-a311d.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+#include <dt-bindings/usb/pd.h>
/ {
compatible = "radxa,zero2", "amlogic,a311d", "amlogic,g12b";
@@ -84,6 +86,26 @@ sdio_pwrseq: sdio-pwrseq {
clock-names = "ext_clock";
};
+ superspeed-switch {
+ compatible = "wcn,ch482d", "gpio-superspeed-switch";
+
+ select-gpios = <&gpio GPIOC_7 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+ orientation-switch;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ usb_ss_switch_out: endpoint {
+ remote-endpoint = <&usb_con_ss>;
+ };
+ };
+ };
+ };
+
ao_5v: regulator-ao-5v {
compatible = "regulator-fixed";
regulator-name = "AO_5V";
@@ -92,6 +114,14 @@ ao_5v: regulator-ao-5v {
regulator-always-on;
};
+ typec2_vbus: regulator-typec2-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "TYPEC2_VBUS";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&ao_5v>;
+ };
+
vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC_1V8";
@@ -383,6 +413,22 @@ fusb0: typec-portc@22 {
connector {
compatible = "usb-c-connector";
+ label = "USB-C";
+ data-role = "host";
+ power-role = "source";
+ source-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ usb_con_ss: endpoint {
+ remote-endpoint = <&usb_ss_switch_out>;
+ };
+ };
+ };
};
};
};
@@ -539,3 +585,8 @@ &uart_AO {
&usb {
status = "okay";
};
+
+&usb3_pcie_phy {
+ status = "okay";
+ phy-supply = <&typec2_vbus>;
+};
--
Armbian