diff --git a/config/kernel/linux-rockchip64-current.config b/config/kernel/linux-rockchip64-current.config index ded95bec46..d05dce0a6e 100644 --- a/config/kernel/linux-rockchip64-current.config +++ b/config/kernel/linux-rockchip64-current.config @@ -7355,6 +7355,7 @@ CONFIG_EXTCON_PTN5150=m # CONFIG_EXTCON_SM5502 is not set CONFIG_EXTCON_USB_GPIO=y # CONFIG_EXTCON_USBC_CROS_EC is not set +CONFIG_EXTCON_USBC_VIRTUAL_PD=y # CONFIG_MEMORY is not set CONFIG_IIO=y CONFIG_IIO_BUFFER=y diff --git a/patch/kernel/rockchip64-current/board-nanopc-t4-add-typec-dp.patch b/patch/kernel/rockchip64-current/board-nanopc-t4-add-typec-dp.patch new file mode 100644 index 0000000000..d3f8c65f60 --- /dev/null +++ b/patch/kernel/rockchip64-current/board-nanopc-t4-add-typec-dp.patch @@ -0,0 +1,183 @@ +From 5b697589bfd64a14ef1c991cffb5179ccb6cf880 Mon Sep 17 00:00:00 2001 +From: tonymac32 +Date: Wed, 17 Feb 2021 00:54:00 -0500 +Subject: [PATCH] Patching something + +Signed-off-by: tonymac32 +--- + .../boot/dts/rockchip/rk3399-nanopc-t4.dts | 83 +++++++++++++++++++ + .../boot/dts/rockchip/rk3399-nanopi4.dtsi | 27 +++--- + 2 files changed, 98 insertions(+), 12 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts +index e0d75617b..bbe200ab6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts +@@ -66,6 +66,12 @@ fan: pwm-fan { + }; + }; + ++&cdn_dp { ++ status = "okay"; ++ extcon = <&fusb0>; ++ phys = <&tcphy0_dp>; ++}; ++ + &cpu_thermal { + trips { + cpu_warm: cpu_warm { +@@ -94,6 +100,50 @@ map3 { + }; + }; + ++&fusb0 { ++ ++ connector { ++ compatible = "usb-c-connector"; ++ label = "USB-C"; ++ power-role = "dual"; ++ data-role = "dual"; ++ try-power-role = "sink"; ++ source-pdos = ; ++ sink-pdos = ; ++ op-sink-microwatt = <5000000>; ++ ++ extcon-cables = <1 2 5 6 9 10 12 44>; ++ typec-altmodes = <0xff01 1 0x001c0000 1>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ port@0 { ++ reg = <0>; ++ usb_con_hs: endpoint { ++ remote-endpoint = ++ <&u2phy0_typec_hs>; ++ }; ++ }; ++ port@1 { ++ reg = <1>; ++ ++ usb_con_ss: endpoint { ++ remote-endpoint = ++ <&tcphy0_typec_ss>; ++ }; ++ }; ++ port@2 { ++ reg = <2>; ++ usb_con_dp: endpoint { ++ remote-endpoint = ++ <&tcphy0_typec_dp>; ++ }; ++ }; ++ }; ++ }; ++}; ++ + &pcie0 { + num-lanes = <4>; + vpcie3v3-supply = <&vcc3v3_sys>; +@@ -113,14 +163,47 @@ &sdhci { + mmc-hs400-enhanced-strobe; + }; + ++&tcphy0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&tcphy0_dp { ++ port { ++ tcphy0_typec_dp: endpoint { ++ remote-endpoint = <&usb_con_dp>; ++ }; ++ }; ++}; ++ ++&tcphy0_usb3 { ++ port { ++ tcphy0_typec_ss: endpoint { ++ remote-endpoint = <&usb_con_ss>; ++ }; ++ }; ++}; ++ + &u2phy0_host { + phy-supply = <&vcc5v0_host0>; + }; + ++&u2phy0_otg { ++ port { ++ u2phy0_typec_hs: endpoint { ++ remote-endpoint = <&usb_con_hs>; ++ }; ++ }; ++}; ++ + &u2phy1_host { + phy-supply = <&vcc5v0_host0>; + }; + ++&usbdrd_dwc3_0 { ++ extcon = <&fusb0>; ++}; ++ + &vcc5v0_sys { + vin-supply = <&vcc12v0_sys>; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi +index 86e802fd8..9c2e8c8ae 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi +@@ -13,6 +13,7 @@ + + /dts-v1/; + #include ++#include + #include "rk3399.dtsi" + #include "rk3399-opp.dtsi" + +@@ -706,26 +707,28 @@ &tsadc { + + &u2phy0 { + status = "okay"; +-}; ++ extcon = <&fusb0>; + +-&u2phy0_host { +- status = "okay"; +-}; ++ u2phy0_otg: otg-port { ++ status = "okay"; ++ }; + +-&u2phy0_otg { +- status = "okay"; ++ u2phy0_host: host-port { ++ status = "okay"; ++ }; + }; + + &u2phy1 { + status = "okay"; +-}; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; + +-&u2phy1_host { +- status = "okay"; +-}; ++ u2phy1_host: host-port { ++ status = "okay"; ++ }; + +-&u2phy1_otg { +- status = "okay"; + }; + + &uart0 { +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rockchip64-current/board-rockpi4c-add-minidp.patch.WIP b/patch/kernel/rockchip64-current/board-rockpi4c-add-minidp.patch.WIP new file mode 100644 index 0000000000..6e403f0fc9 --- /dev/null +++ b/patch/kernel/rockchip64-current/board-rockpi4c-add-minidp.patch.WIP @@ -0,0 +1,28 @@ +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts +index 4c7ebb1c5d2d..19a648add355 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts +@@ -11,6 +11,22 @@ + / { + model = "Radxa ROCK Pi 4C"; + compatible = "radxa,rockpi4c", "radxa,rockpi4", "rockchip,rk3399"; ++ ++ virtual_pd: virtual-pd { ++ compatible = "linux,extcon-usbc-virtual-pd"; ++ det-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_LOW>; /* DP_HPD */ ++ vpd-data-role = "display-port"; ++ vpd-super-speed; ++ }; ++}; ++ ++&cdn_dp { ++ extcon = <&virtual_pd>; ++ status = "okay"; ++}; ++ ++&tcphy0 { ++ extcon = <&virtual_pd>; + }; + + &sdio0 { + diff --git a/patch/kernel/rockchip64-current/general-add-miniDP-dt-doc.patch b/patch/kernel/rockchip64-current/general-add-miniDP-dt-doc.patch new file mode 100644 index 0000000000..58b1a9a7ab --- /dev/null +++ b/patch/kernel/rockchip64-current/general-add-miniDP-dt-doc.patch @@ -0,0 +1,73 @@ +diff --git a/Documentation/devicetree/bindings/extcon/extcon-usbc-virtual-pd.yaml b/Documentation/devicetree/bindings/extcon/extcon-usbc-virtual-pd.yaml +new file mode 100644 +index 000000000000..8110fbe2ddc2 +--- /dev/null ++++ b/Documentation/devicetree/bindings/extcon/extcon-usbc-virtual-pd.yaml +@@ -0,0 +1,66 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/extcon/extcon-usbc-virtual-pd.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Type-C Virtual PD extcon ++ ++maintainers: ++ - Jagan Teki ++ ++description: | ++ USB Type-C protocol supports various modes of operations includes PD, ++ USB3, and Altmode. If the platform design supports a Type-C connector ++ then configuring these modes can be done via enumeration. ++ ++ However, there are some platforms that design these modes as separate ++ protocol connectors like design Display Port from on-chip USB3 controller. ++ So we can access Type-C Altmode Display Port via onboard Display Port ++ connector instead of a Type-C connector. These kinds of platforms require ++ an explicit extcon driver in order to handle Power Delivery and ++ Port Detection. ++ ++properties: ++ compatible: ++ const: linux,extcon-usbc-virtual-pd ++ ++ det-gpios: ++ description: Detect GPIO pin. Pin can be Display Port Detect or USB ID. ++ maxItems: 1 ++ ++ vpd-polarity: ++ description: USB Type-C Polarity. false for Normal and true for Flip. ++ type: boolean ++ ++ vpd-super-speed: ++ description: USB Super Speed. false for USB2 and true for USB3. ++ type: boolean ++ ++ vpd-data-role: ++ description: USB Data roles for Virtual Type-C. ++ $ref: /schemas/types.yaml#definitions/string ++ ++ enum: ++ - host ++ - device ++ - display-port ++ ++required: ++ - compatible ++ - det-gpios ++ - vpd-data-role ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ ++ virtual_pd: virtual-pd { ++ compatible = "linux,extcon-usbc-virtual-pd"; ++ det-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_LOW>; ++ vpd-data-role = "display-port"; ++ vpd-super-speed; ++ }; + diff --git a/patch/kernel/rockchip64-current/general-add-miniDP-virtual-extcon.patch b/patch/kernel/rockchip64-current/general-add-miniDP-virtual-extcon.patch new file mode 100644 index 0000000000..57773aa277 --- /dev/null +++ b/patch/kernel/rockchip64-current/general-add-miniDP-virtual-extcon.patch @@ -0,0 +1,337 @@ +diff --git a/MAINTAINERS b/MAINTAINERS +index 68f21d46614c..aeb161b19dae 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -6466,6 +6466,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git + F: Documentation/filesystems/ext4/ + F: fs/ext4/ + ++EXTCON DRIVER FOR TYPE-C VIRTUAL PD ++M: Jagan Teki ++S: Maintained ++F: Documentation/devicetree/bindings/extcon/extcon-usbc-virtual-pd.yaml ++F: drivers/extcon/extcon-usbc-virtual-pd.c ++ + Extended Verification Module (EVM) + M: Mimi Zohar + L: linux-integrity@vger.kernel.org +diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig +index aac507bff135..edd6c3c52699 100644 +--- a/drivers/extcon/Kconfig ++++ b/drivers/extcon/Kconfig +@@ -186,4 +186,14 @@ config EXTCON_USBC_CROS_EC + Say Y here to enable USB Type C cable detection extcon support when + using Chrome OS EC based USB Type-C ports. + ++config EXTCON_USBC_VIRTUAL_PD ++ tristate "Virtual Type-C PD EXTCON support" ++ depends on GPIOLIB || COMPILE_TEST ++ help ++ Say Y here to enable Virtual Type-C PD extcon driver support, if ++ hardware platform designed Type-C modes separately. ++ ++ Example, of designing Display Port separately from Type-C Altmode ++ instead of accessing Altmode Display Port in Type-C connector. ++ + endif +diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile +index 52096fd8a216..c35191eef0e1 100644 +--- a/drivers/extcon/Makefile ++++ b/drivers/extcon/Makefile +@@ -25,3 +25,4 @@ obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o + obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o + obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o + obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o ++obj-$(CONFIG_EXTCON_USBC_VIRTUAL_PD) += extcon-usbc-virtual-pd.o +diff --git a/drivers/extcon/extcon-usbc-virtual-pd.c b/drivers/extcon/extcon-usbc-virtual-pd.c +new file mode 100644 +index 000000000000..e0713670e33d +--- /dev/null ++++ b/drivers/extcon/extcon-usbc-virtual-pd.c +@@ -0,0 +1,285 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Type-C Virtual PD Extcon driver ++ * ++ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (c) 2019 Radxa Limited ++ * Copyright (c) 2019 Amarula Solutions(India) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static const unsigned int vpd_cable[] = { ++ EXTCON_USB, ++ EXTCON_USB_HOST, ++ EXTCON_DISP_DP, ++ EXTCON_NONE, ++}; ++ ++enum vpd_data_role { ++ DR_NONE, ++ DR_HOST, ++ DR_DEVICE, ++ DR_DISPLAY_PORT, ++}; ++ ++enum vpd_polarity { ++ POLARITY_NORMAL, ++ POLARITY_FLIP, ++}; ++ ++enum vpd_usb_ss { ++ USB_SS_USB2, ++ USB_SS_USB3, ++}; ++ ++struct vpd_extcon { ++ struct device *dev; ++ struct extcon_dev *extcon; ++ struct gpio_desc *det_gpio; ++ ++ u8 polarity; ++ u8 usb_ss; ++ enum vpd_data_role data_role; ++ ++ int irq; ++ bool enable_irq; ++ struct work_struct work; ++ struct delayed_work irq_work; ++}; ++ ++static void vpd_extcon_irq_work(struct work_struct *work) ++{ ++ struct vpd_extcon *vpd = container_of(work, struct vpd_extcon, irq_work.work); ++ bool host_connected = false, device_connected = false, dp_connected = false; ++ union extcon_property_value property; ++ int det; ++ ++ det = vpd->det_gpio ? gpiod_get_raw_value(vpd->det_gpio) : 0; ++ if (det) { ++ device_connected = (vpd->data_role == DR_DEVICE) ? true : false; ++ host_connected = (vpd->data_role == DR_HOST) ? true : false; ++ dp_connected = (vpd->data_role == DR_DISPLAY_PORT) ? true : false; ++ } ++ ++ extcon_set_state(vpd->extcon, EXTCON_USB, host_connected); ++ extcon_set_state(vpd->extcon, EXTCON_USB_HOST, device_connected); ++ extcon_set_state(vpd->extcon, EXTCON_DISP_DP, dp_connected); ++ ++ property.intval = vpd->polarity; ++ extcon_set_property(vpd->extcon, EXTCON_USB, ++ EXTCON_PROP_USB_TYPEC_POLARITY, property); ++ extcon_set_property(vpd->extcon, EXTCON_USB_HOST, ++ EXTCON_PROP_USB_TYPEC_POLARITY, property); ++ extcon_set_property(vpd->extcon, EXTCON_DISP_DP, ++ EXTCON_PROP_USB_TYPEC_POLARITY, property); ++ ++ property.intval = vpd->usb_ss; ++ extcon_set_property(vpd->extcon, EXTCON_USB, ++ EXTCON_PROP_USB_SS, property); ++ extcon_set_property(vpd->extcon, EXTCON_USB_HOST, ++ EXTCON_PROP_USB_SS, property); ++ extcon_set_property(vpd->extcon, EXTCON_DISP_DP, ++ EXTCON_PROP_USB_SS, property); ++ ++ extcon_sync(vpd->extcon, EXTCON_USB); ++ extcon_sync(vpd->extcon, EXTCON_USB_HOST); ++ extcon_sync(vpd->extcon, EXTCON_DISP_DP); ++} ++ ++static irqreturn_t vpd_extcon_irq_handler(int irq, void *dev_id) ++{ ++ struct vpd_extcon *vpd = dev_id; ++ ++ schedule_delayed_work(&vpd->irq_work, msecs_to_jiffies(10)); ++ ++ return IRQ_HANDLED; ++} ++ ++static enum vpd_data_role vpd_extcon_data_role(struct vpd_extcon *vpd) ++{ ++ const char *const data_roles[] = { ++ [DR_NONE] = "NONE", ++ [DR_HOST] = "host", ++ [DR_DEVICE] = "device", ++ [DR_DISPLAY_PORT] = "display-port", ++ }; ++ struct device *dev = vpd->dev; ++ int ret; ++ const char *dr; ++ ++ ret = device_property_read_string(dev, "vpd-data-role", &dr); ++ if (ret < 0) ++ return DR_NONE; ++ ++ ret = match_string(data_roles, ARRAY_SIZE(data_roles), dr); ++ ++ return (ret < 0) ? DR_NONE : ret; ++} ++ ++static int vpd_extcon_parse_dts(struct vpd_extcon *vpd) ++{ ++ struct device *dev = vpd->dev; ++ bool val = false; ++ int ret; ++ ++ val = device_property_read_bool(dev, "vpd-polarity"); ++ if (val) ++ vpd->polarity = POLARITY_FLIP; ++ else ++ vpd->polarity = POLARITY_NORMAL; ++ ++ val = device_property_read_bool(dev, "vpd-super-speed"); ++ if (val) ++ vpd->usb_ss = USB_SS_USB3; ++ else ++ vpd->usb_ss = USB_SS_USB2; ++ ++ vpd->data_role = vpd_extcon_data_role(vpd); ++ ++ vpd->det_gpio = devm_gpiod_get_optional(dev, "det", GPIOD_OUT_LOW); ++ if (IS_ERR(vpd->det_gpio)) { ++ ret = PTR_ERR(vpd->det_gpio); ++ dev_warn(dev, "failed to get det gpio: %d\n", ret); ++ return ret; ++ } ++ ++ vpd->irq = gpiod_to_irq(vpd->det_gpio); ++ if (vpd->irq < 0) { ++ dev_err(dev, "failed to get irq for gpio: %d\n", vpd->irq); ++ return vpd->irq; ++ } ++ ++ ret = devm_request_threaded_irq(dev, vpd->irq, NULL, ++ vpd_extcon_irq_handler, ++ IRQF_TRIGGER_FALLING | ++ IRQF_TRIGGER_RISING | IRQF_ONESHOT, ++ NULL, vpd); ++ if (ret) ++ dev_err(dev, "failed to request gpio irq\n"); ++ ++ return ret; ++} ++ ++static int vpd_extcon_probe(struct platform_device *pdev) ++{ ++ struct vpd_extcon *vpd; ++ struct device *dev = &pdev->dev; ++ int ret; ++ ++ vpd = devm_kzalloc(dev, sizeof(*vpd), GFP_KERNEL); ++ if (!vpd) ++ return -ENOMEM; ++ ++ vpd->dev = dev; ++ ret = vpd_extcon_parse_dts(vpd); ++ if (ret) ++ return ret; ++ ++ INIT_DELAYED_WORK(&vpd->irq_work, vpd_extcon_irq_work); ++ ++ vpd->extcon = devm_extcon_dev_allocate(dev, vpd_cable); ++ if (IS_ERR(vpd->extcon)) { ++ dev_err(dev, "allocat extcon failed\n"); ++ return PTR_ERR(vpd->extcon); ++ } ++ ++ ret = devm_extcon_dev_register(dev, vpd->extcon); ++ if (ret) { ++ dev_err(dev, "register extcon failed: %d\n", ret); ++ return ret; ++ } ++ ++ extcon_set_property_capability(vpd->extcon, EXTCON_USB, ++ EXTCON_PROP_USB_VBUS); ++ extcon_set_property_capability(vpd->extcon, EXTCON_USB_HOST, ++ EXTCON_PROP_USB_VBUS); ++ ++ extcon_set_property_capability(vpd->extcon, EXTCON_USB, ++ EXTCON_PROP_USB_TYPEC_POLARITY); ++ extcon_set_property_capability(vpd->extcon, EXTCON_USB_HOST, ++ EXTCON_PROP_USB_TYPEC_POLARITY); ++ extcon_set_property_capability(vpd->extcon, EXTCON_USB, ++ EXTCON_PROP_USB_SS); ++ extcon_set_property_capability(vpd->extcon, EXTCON_USB_HOST, ++ EXTCON_PROP_USB_SS); ++ ++ extcon_set_property_capability(vpd->extcon, EXTCON_DISP_DP, ++ EXTCON_PROP_USB_SS); ++ extcon_set_property_capability(vpd->extcon, EXTCON_DISP_DP, ++ EXTCON_PROP_USB_TYPEC_POLARITY); ++ ++ platform_set_drvdata(pdev, vpd); ++ ++ vpd_extcon_irq_work(&vpd->irq_work.work); ++ ++ return 0; ++} ++ ++static int vpd_extcon_remove(struct platform_device *pdev) ++{ ++ struct vpd_extcon *vpd = platform_get_drvdata(pdev); ++ ++ cancel_delayed_work_sync(&vpd->irq_work); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static int vpd_extcon_suspend(struct device *dev) ++{ ++ struct vpd_extcon *vpd = dev_get_drvdata(dev); ++ ++ if (!vpd->enable_irq) { ++ disable_irq_nosync(vpd->irq); ++ vpd->enable_irq = true; ++ } ++ ++ return 0; ++} ++ ++static int vpd_extcon_resume(struct device *dev) ++{ ++ struct vpd_extcon *vpd = dev_get_drvdata(dev); ++ ++ if (vpd->enable_irq) { ++ enable_irq(vpd->irq); ++ vpd->enable_irq = false; ++ } ++ ++ return 0; ++} ++#endif ++ ++static SIMPLE_DEV_PM_OPS(vpd_extcon_pm_ops, ++ vpd_extcon_suspend, vpd_extcon_resume); ++ ++static const struct of_device_id vpd_extcon_dt_match[] = { ++ { .compatible = "linux,extcon-usbc-virtual-pd", }, ++ { /* sentinel */ } ++}; ++ ++static struct platform_driver vpd_extcon_driver = { ++ .probe = vpd_extcon_probe, ++ .remove = vpd_extcon_remove, ++ .driver = { ++ .name = "extcon-usbc-virtual-pd", ++ .pm = &vpd_extcon_pm_ops, ++ .of_match_table = vpd_extcon_dt_match, ++ }, ++}; ++ ++module_platform_driver(vpd_extcon_driver); ++ ++MODULE_AUTHOR("Jagan Teki "); ++MODULE_DESCRIPTION("Type-C Virtual PD extcon driver"); ++MODULE_LICENSE("GPL v2"); +