Skip to contentSkip to conversation

usb: typec: add Qualcomm PMI8998 USB Type-C role-switch support

PATCH In review taygoth 7 participants 23 messages May 18 – Jul 28 1 message not in the archive

Subsystems (6)
lore
Share & tools
lore

taygoth

author
#0 lore raw

cover usb: typec: add Qualcomm PMI8998 USB Type-C role-switch support

This series adds USB Type-C role-switch support for the PMI8998 PMIC used on SDM845 phones (OnePlus 6/6T, Xiaomi Poco F1, SHIFT 6mq), which have been locked to USB peripheral mode under mainline kernels until now.

The PMI8998 SMB2 charger block integrates a Type-C detection unit at SPMI offset 0x1300 that performs CC sensing, debounce and Rp/Rd resolution entirely in hardware. The state is exposed through the TYPE_C_STATUS_4 register and reported via a single consolidated "type-c-change" interrupt. The new driver reads that status on every interrupt and pushes the negotiated role to a usb_role_switch consumer (dwc3), enabling automatic peripheral/host switching on cable change. Because the hardware handles the Type-C state machine natively, no software TCPM port manager is required.

The Type-C block shares the SMB2 USBIN region with the already mainlined qcom_pmi8998-charger driver. The two coexist on the shared SPMI regmap without write conflict: the typec driver only reads TYPE_C_STATUS_* and touches the IRQ enable bits at offsets 0x130b-0x130f and 0x1367-0x1368.

The PMI8998 USB OTG VBUS boost converter at offset 0x1100 has the same CMD_OTG / OTG_CFG / OTG_CURRENT_LIMIT register layout as PM8150B, so the existing drivers/regulator/qcom_usb_vbus-regulator can drive it through a compatible cascade -- only the DT binding needs the new compatible string added.

Power Delivery is not implemented. The PMI8998 PDPHY block at offset 0x1700 is register-identical to PM8150B and could be wired through the existing drivers/usb/typec/tcpm/qcom code in a follow-up if PD negotiation becomes a requirement.

Tested-on: OnePlus 6T (sdm845-oneplus-fajita) running Mobian 6.12-sdm845. A USB flash drive, USB ethernet adapter, USB WiFi adapter (TP-Link Archer T2) and a self-powered USB-C dock with downstream ethernet all enumerate through xHCI after the role transitions from peripheral to host. Repeat plug/unplug cycles drive the role through device -> none -> host -> none -> device cleanly with no IRQ stalls or stale role-switch state.

Series mirror:
https://github.com/taygoth/linux/tree/pmi8998-typec

taygoth (6):
dt-bindings: regulator: qcom,usb-vbus-regulator: add PMI8998
dt-bindings: usb: add Qualcomm PMI8998 Type-C controller
usb: typec: add Qualcomm PMI8998 role-switch driver
arm64: dts: qcom: pmi8998: add USB Type-C and VBUS regulator nodes
arm64: dts: qcom: sdm845-oneplus-common: enable USB Type-C role
switching
MAINTAINERS: add entry for Qualcomm PMI8998 USB Type-C driver

 .../regulator/qcom,usb-vbus-regulator.yaml    |   1 +
 .../bindings/usb/qcom,pmi8998-typec.yaml      |  97 ++++++++
 MAINTAINERS                                   |   8 +
 arch/arm64/boot/dts/qcom/pmi8998.dtsi         |  19 ++
 .../boot/dts/qcom/sdm845-oneplus-common.dtsi  |  43 +++-
 drivers/usb/typec/Kconfig                     |  17 ++
 drivers/usb/typec/Makefile                    |   1 +
 drivers/usb/typec/qcom_pmi8998_typec.c        | 213 ++++++++++++++++++
 8 files changed, 392 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml
 create mode 100644 drivers/usb/typec/qcom_pmi8998_typec.c

base-commit: 5200f5f493f79f14bbdc349e402a40dfb32f23c8

Signature · 1 line
2.47.3
author
#1 lore raw

PATCH 1/6 dt-bindings: regulator: qcom,usb-vbus-regulator: add PMI8998

The Qualcomm PMI8998 PMIC integrates a USB OTG VBUS boost converter inside its SMB2 charger block at offset 0x1100. The OTG control register layout (CMD_OTG at +0x40, OTG_CURRENT_LIMIT_CFG at +0x52, OTG_CFG at +0x53) matches the PM8150B SMB5 block, so the existing qcom_usb_vbus-regulator driver can drive it without code changes via compatible cascade.

Verified by inspecting the downstream qpnp-smb2 driver and reading live register values on a OnePlus 6T (sdm845-oneplus-fajita) running mainline Linux.

---
 .../devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml   | 1 +
 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml +1 -0
index fcefc722ee2a..9e2e2c8f9539 100644
@@ -28,6 +28,7 @@ properties:
               - qcom,pm6150-vbus-reg
               - qcom,pm7250b-vbus-reg
               - qcom,pmi632-vbus-reg
+              - qcom,pmi8998-vbus-reg
           - const: qcom,pm8150b-vbus-reg
 
   reg:
Signature · 1 line
2.47.3
Reviewed-by on v1 1/6
#2 lore raw

Re: [PATCH 1/6] dt-bindings: regulator: qcom,usb-vbus-regulator: add PMI8998

Quoted 21 lines · taygoth

The Qualcomm PMI8998 PMIC integrates a USB OTG VBUS boost converter inside its SMB2 charger block at offset 0x1100. The OTG control register layout (CMD_OTG at +0x40, OTG_CURRENT_LIMIT_CFG at +0x52, OTG_CFG at +0x53) matches the PM8150B SMB5 block, so the existing qcom_usb_vbus-regulator driver can drive it without code changes via compatible cascade.

Verified by inspecting the downstream qpnp-smb2 driver and reading live register values on a OnePlus 6T (sdm845-oneplus-fajita) running mainline Linux.

---
  .../devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml   | 1 +
  1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml +0 -0
index fcefc722ee2a..9e2e2c8f9539 100644

Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml properties: · line 34

Quoted 7 lines
Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml +1 -0
@@ -28,6 +28,7 @@ properties:
                - qcom,pm6150-vbus-reg
                - qcom,pm7250b-vbus-reg
                - qcom,pmi632-vbus-reg
+              - qcom,pmi8998-vbus-reg
            - const: qcom,pm8150b-vbus-reg
 
    reg:

---
bod

#3 lore raw

Re: [PATCH 1/6] dt-bindings: regulator: qcom,usb-vbus-regulator: add PMI8998

In reply to taygoth
Quoted 7 lines · taygoth

The Qualcomm PMI8998 PMIC integrates a USB OTG VBUS boost converter inside its SMB2 charger block at offset 0x1100. The OTG control register layout (CMD_OTG at +0x40, OTG_CURRENT_LIMIT_CFG at +0x52, OTG_CFG at +0x53) matches the PM8150B SMB5 block, so the existing qcom_usb_vbus-regulator driver can drive it without code changes via compatible cascade.

Quoted 5 lines

Verified by inspecting the downstream qpnp-smb2 driver and reading live register values on a OnePlus 6T (sdm845-oneplus-fajita) running mainline Linux.

Incomplete identity. Please use real names. We do not accept anonymous contributions.

Best regards,
Krzysztof

author
#4 lore raw

PATCH 2/6 dt-bindings: usb: add Qualcomm PMI8998 Type-C controller

In reply to taygoth

The PMI8998 PMIC integrates a USB Type-C detection block in its SMB2 charger USBIN region at offset 0x1300. The block performs CC sensing, debounce and Rp/Rd resolution in hardware and reports role changes through a single consolidated "type-c-change" interrupt.

This is architecturally distinct from the qcom,pmic-typec binding (PM8150B / PMI632 family) which exposes a granular 8-16 IRQ topology fanned out per Type-C event for a software TCPM state machine. PMI8998 has neither the per-event IRQs nor a register layout compatible with the TCPM code path, so this binding describes a separate hardware- managed role-switch controller.

---
 .../bindings/usb/qcom,pmi8998-typec.yaml      | 97 +++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml
Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml new file +97 -0
new file mode 100644
index 000000000000..f2814f5ce3de
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/qcom,pmi8998-typec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PMI8998 USB Type-C role-switch controller
+
+maintainers:
+  - Maxim Furman <[email protected]>
+
+description:
+  The PMI8998 PMIC integrates a USB Type-C detection block inside its SMB2
+  charger USBIN region at offset 0x1300. CC sensing, debounce and Rp/Rd
+  resolution are performed in hardware, and the negotiated role is reported
+  through a single consolidated "type-c-change" interrupt.
+
+  This block is distinct from the TCPM-based qcom,pmic-typec controllers
+  (PM8150B, PMI632, etc.) — PMI8998 lacks the granular per-event interrupt
+  topology those parts expose and the driver therefore translates the
+  hardware-decided role directly into a usb_role_switch_set_role() call
+  rather than running a software TCPM state machine. Power Delivery is not
+  supported by this binding.
+
+properties:
+  compatible:
+    const: qcom,pmi8998-typec
+
+  reg:
+    maxItems: 1
+    description: Type-C SPMI register base offset (typically 0x1300).
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-names:
+    items:
+      - const: type-c-change
+
+  vdd-vbus-supply:
+    description:
+      VBUS source regulator enabled when the controller transitions to
+      USB host mode so bus-powered downstream peripherals can be powered.
+
+  connector:
+    type: object
+    $ref: /schemas/connector/usb-connector.yaml#
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - connector
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    pmic {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        typec@1300 {
+            compatible = "qcom,pmi8998-typec";
+            reg = <0x1300>;
+
+            interrupts = <0x2 0x13 0x7 IRQ_TYPE_EDGE_BOTH>;
+            interrupt-names = "type-c-change";
+
+            vdd-vbus-supply = <&pmi8998_vbus>;
+
+            connector {
+                compatible = "usb-c-connector";
+                label = "USB-C";
+                power-role = "dual";
+                data-role = "dual";
+                try-power-role = "sink";
+
+                ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    port@0 {
+                        reg = <0>;
+                        pmi8998_hs_in: endpoint {
+                            remote-endpoint = <&usb_1_dwc3_hs>;
+                        };
+                    };
+                };
+            };
+        };
+    };
+...
Signature · 1 line
2.47.3
#5 lore raw

Re: [PATCH 2/6] dt-bindings: usb: add Qualcomm PMI8998 Type-C controller

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] The `qcom,spmi-pmic.yaml` parent schema unconditionally enforces the old `qcom,pmic-typec.yaml`…

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The qcom,spmi-pmic.yaml parent schema unconditionally enforces the old qcom,pmic-typec.yaml on all typec@ nodes, which will cause dtbs_check validation failures for the newly introduced qcom,pmi8998-typec hardware node. --

commit 1c9db8c5249c49002058f3167b19c898d414957d
Author: taygoth <[email protected]>
dt-bindings: usb: add Qualcomm PMI8998 Type-C controller

This commit adds a new devicetree binding for the Qualcomm PMI8998 USB Type-C role-switch controller. It describes a hardware block distinct from the TCPM-based qcom,pmic-typec controllers, using a single consolidated interrupt instead of granular per-event IRQs.

Quoted 5 lines
Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml new file +0 -0
new file mode 100644
index 0000000000000..f2814f5ce3de7

[ ... ]

Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml line 68

Quoted 10 lines
Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml new file +10 -0
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    pmic {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        typec@1300 {
+            compatible = "qcom,pmi8998-typec";

Will this node cause dtbs_check validation failures when instantiated under the PMIC?

In Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml, the patternProperties rule for ^typec@[0-9a-f]+$ has a hardcoded reference to /schemas/usb/qcom,pmic-typec.yaml#.

Because this new qcom,pmi8998-typec schema defines only 1 interrupt instead of the 8 to 16 required by the older binding, it will fail validation against the parent PMIC schema.

Should the parent qcom,spmi-pmic.yaml schema be updated alongside this change to permit this new hardware block?

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
#6 lore raw

Re: [PATCH 2/6] dt-bindings: usb: add Qualcomm PMI8998 Type-C controller

In reply to taygoth
Quoted 57 lines · taygoth

The PMI8998 PMIC integrates a USB Type-C detection block in its SMB2 charger USBIN region at offset 0x1300. The block performs CC sensing, debounce and Rp/Rd resolution in hardware and reports role changes through a single consolidated "type-c-change" interrupt.

This is architecturally distinct from the qcom,pmic-typec binding (PM8150B / PMI632 family) which exposes a granular 8-16 IRQ topology fanned out per Type-C event for a software TCPM state machine. PMI8998 has neither the per-event IRQs nor a register layout compatible with the TCPM code path, so this binding describes a separate hardware- managed role-switch controller.

---
 .../bindings/usb/qcom,pmi8998-typec.yaml      | 97 +++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml
Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml new file +33 -0
new file mode 100644
index 000000000000..f2814f5ce3de
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/qcom,pmi8998-typec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PMI8998 USB Type-C role-switch controller
+
+maintainers:
+  - Maxim Furman <[email protected]>
+
+description:
+  The PMI8998 PMIC integrates a USB Type-C detection block inside its SMB2
+  charger USBIN region at offset 0x1300. CC sensing, debounce and Rp/Rd
+  resolution are performed in hardware, and the negotiated role is reported
+  through a single consolidated "type-c-change" interrupt.
+
+  This block is distinct from the TCPM-based qcom,pmic-typec controllers
+  (PM8150B, PMI632, etc.) — PMI8998 lacks the granular per-event interrupt
+  topology those parts expose and the driver therefore translates the
+  hardware-decided role directly into a usb_role_switch_set_role() call
+  rather than running a software TCPM state machine. Power Delivery is not
+  supported by this binding.
+
+properties:
+  compatible:
+    const: qcom,pmi8998-typec
+
+  reg:
+    maxItems: 1
+    description: Type-C SPMI register base offset (typically 0x1300).
+
+  interrupts:

Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml line 43

Quoted 10 lines
Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml new file +10 -0
+    maxItems: 1
+
+  interrupt-names:
+    items:
+      - const: type-c-change
+
+  vdd-vbus-supply:
+    description:
+      VBUS source regulator enabled when the controller transitions to
+      USB host mode so bus-powered downstream peripherals can be powered.

We probably need to fix this for PM8150B too... This should be connector's vbus-supply instead. I'll send a patch for the existing devices.

Quoted 57 lines
Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml new file +54 -0
+
+  connector:
+    type: object
+    $ref: /schemas/connector/usb-connector.yaml#
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - connector
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    pmic {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        typec@1300 {
+            compatible = "qcom,pmi8998-typec";
+            reg = <0x1300>;
+
+            interrupts = <0x2 0x13 0x7 IRQ_TYPE_EDGE_BOTH>;
+            interrupt-names = "type-c-change";
+
+            vdd-vbus-supply = <&pmi8998_vbus>;
+
+            connector {
+                compatible = "usb-c-connector";
+                label = "USB-C";
+                power-role = "dual";
+                data-role = "dual";
+                try-power-role = "sink";
+
+                ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    port@0 {
+                        reg = <0>;
+                        pmi8998_hs_in: endpoint {
+                            remote-endpoint = <&usb_1_dwc3_hs>;
+                        };
+                    };
+                };
+            };
+        };
+    };
+...
Signature · 1 line
2.47.3
Signature · 2 lines
With best wishes
Dmitry
author
#7 lore raw

PATCH 3/6 usb: typec: add Qualcomm PMI8998 role-switch driver

In reply to taygoth

The Qualcomm PMI8998 PMIC integrates a USB Type-C detection block in its SMB2 charger USBIN region at offset 0x1300. The block performs CC sensing, debounce and Rp/Rd resolution in silicon and reports role changes through a single consolidated "type-c-change" interrupt.

This driver reads TYPE_C_STATUS_4 on probe and on every interrupt, decodes the hardware-detected role (host / device / none) and pushes it to a usb_role_switch consumer (typically dwc3) so the controller can flip between peripheral and host on cable orientation change. An optional VBUS supply regulator is toggled on USB_ROLE_HOST transitions so bus-powered downstream peripherals can be powered.

No software TCPM state machine is used because the hardware handles the Type-C protocol natively, and the PMI8998 interrupt topology does not expose the granular per-event signals the TCPM code path expects. Power Delivery is not implemented in this driver; the PMI8998 PDPHY block at offset 0x1700 (register-identical to PM8150B) can be wired up by a separate driver later if PD negotiation is required.

This enables USB host mode on the OnePlus 6 (enchilada), OnePlus 6T (fajita), Xiaomi Poco F1 (beryllium), SHIFT 6mq (axolotl) and other SDM845-based phones that use the PMI8998 as their second PMIC.

---
 drivers/usb/typec/Kconfig              |  17 ++
 drivers/usb/typec/Makefile             |   1 +
 drivers/usb/typec/qcom_pmi8998_typec.c | 213 +++++++++++++++++++++++++
 3 files changed, 231 insertions(+)
 create mode 100644 drivers/usb/typec/qcom_pmi8998_typec.c
drivers/usb/typec/Kconfig +17 -0
index 2f80c2792dbd..1912ca3f6e0a 100644
@@ -100,6 +100,23 @@ config TYPEC_STUSB160X
 	  If you choose to build this driver as a dynamically linked module, the
 	  module will be called stusb160x.ko.
 
+config TYPEC_QCOM_PMI8998
+	tristate "Qualcomm PMI8998 USB Type-C role-switch driver"
+	depends on ARCH_QCOM || COMPILE_TEST
+	depends on SPMI
+	select USB_ROLE_SWITCH
+	help
+	  Say Y or M here to enable the role-switch driver for the USB
+	  Type-C detection block integrated in the Qualcomm PMI8998 PMIC.
+	  This is the part used on SDM845 phones such as the OnePlus 6/6T,
+	  Xiaomi Poco F1 and SHIFT 6mq. The driver reports the
+	  hardware-detected role through the USB role switch class so the
+	  USB DRD controller (e.g. dwc3) can flip between peripheral and
+	  host on cable orientation change.
+
+	  If you choose to build this driver as a dynamically linked module,
+	  the module will be called qcom_pmi8998_typec.ko.
+
 config TYPEC_WUSB3801
 	tristate "Willsemi WUSB3801 Type-C port controller driver"
 	depends on I2C
drivers/usb/typec/Makefile +1 -0
index 8a6a1c663eb6..568f8ee68c9d 100644
@@ -10,5 +10,6 @@ obj-$(CONFIG_TYPEC_ANX7411)	+= anx7411.o
 obj-$(CONFIG_TYPEC_HD3SS3220)	+= hd3ss3220.o
 obj-$(CONFIG_TYPEC_STUSB160X) 	+= stusb160x.o
 obj-$(CONFIG_TYPEC_RT1719)	+= rt1719.o
+obj-$(CONFIG_TYPEC_QCOM_PMI8998)	+= qcom_pmi8998_typec.o
 obj-$(CONFIG_TYPEC_WUSB3801)	+= wusb3801.o
 obj-$(CONFIG_TYPEC)		+= mux/
drivers/usb/typec/qcom_pmi8998_typec.c new file +213 -0

213 lines not on this page · raw message

Signature · 1 line
2.47.3
#8 lore raw

Re: [PATCH 3/6] usb: typec: add Qualcomm PMI8998 role-switch driver

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [High] Race condition and Use-After-Free during driver removal due to mixed devm and manual cleanup.…

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Race condition and Use-After-Free during driver removal due to mixed devm and manual cleanup.
- [Medium] VBUS regulator enable count leak on probe error path.
- [Medium] Silently ignored return value of hardware initialization in probe().
--

commit 2be57d2a22cd876c2f33d5adcda09af34cd9c497
Author: taygoth <[email protected]>

usb: typec: add Qualcomm PMI8998 role-switch driver

This commit introduces a new USB Type-C role-switch driver for the Qualcomm PMI8998 PMIC. It translates the hardware-detected role into a consumer switch state, and enables an optional VBUS supply regulator when acting as a USB host.

Quoted 5 lines
drivers/usb/typec/qcom_pmi8998_typec.c new file +0 -0
new file mode 100644
index 0000000000000..77662b4f1b0c6

[ ... ]

Quoted 2 lines
drivers/usb/typec/qcom_pmi8998_typec.c new file +2 -0
+static int pmi8998_typec_probe(struct platform_device *pdev)
+{

[ ... ]

drivers/usb/typec/qcom_pmi8998_typec.c line 171

Quoted 3 lines
drivers/usb/typec/qcom_pmi8998_typec.c new file +3 -0
+	platform_set_drvdata(pdev, typec);
+
+	pmi8998_typec_apply(typec);

Should the return value of pmi8998_typec_apply() be checked here?

If operations like regmap_read() or regulator_enable() fail inside apply(), the probe will silently succeed with an unsynchronized hardware state.

drivers/usb/typec/qcom_pmi8998_typec.c line 182

Quoted 11 lines
drivers/usb/typec/qcom_pmi8998_typec.c new file +11 -0
+
+	ret = devm_request_threaded_irq(dev, typec->irq, NULL,
+					pmi8998_typec_isr, IRQF_ONESHOT,
+					dev_name(dev), typec);
+	if (ret)
+		goto err_role_put;
+
+	return 0;
+
+err_role_put:
+	usb_role_switch_put(typec->role_sw);

If pmi8998_typec_apply() above evaluates to USB_ROLE_HOST, it will enable the vbus regulator and set typec->vbus_enabled to true.

If the interrupt request then fails, does this error path leak the regulator enable count by missing a regulator_disable() call?

drivers/usb/typec/qcom_pmi8998_typec.c line 192

Quoted 10 lines
drivers/usb/typec/qcom_pmi8998_typec.c new file +10 -0
+	return ret;
+}
+
+static void pmi8998_typec_remove(struct platform_device *pdev)
+{
+	struct pmi8998_typec *typec = platform_get_drvdata(pdev);
+
+	if (typec->vbus_enabled)
+		regulator_disable(typec->vbus);
+	usb_role_switch_put(typec->role_sw);

Because the interrupt was requested using devm_request_threaded_irq(), it will not be freed until after pmi8998_typec_remove() returns.

If a hardware interrupt fires right after we disable the regulator and put the role switch:

pmi8998_typec_remove()

    regulator_disable(typec->vbus);
    usb_role_switch_put(typec->role_sw);

-> interrupt fires
pmi8998_typec_isr()

    pmi8998_typec_apply()

Could the ISR attempt to use the freed typec->role_sw or perform an unbalanced regulator_disable() since typec->vbus_enabled is never set to false in remove()?

Quoted 1 line

+}

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
#9 lore raw

Re: [PATCH 3/6] usb: typec: add Qualcomm PMI8998 role-switch driver

In reply to taygoth
Quoted 11 lines · taygoth

The Qualcomm PMI8998 PMIC integrates a USB Type-C detection block in its SMB2 charger USBIN region at offset 0x1300. The block performs CC sensing, debounce and Rp/Rd resolution in silicon and reports role changes through a single consolidated "type-c-change" interrupt.

This driver reads TYPE_C_STATUS_4 on probe and on every interrupt, decodes the hardware-detected role (host / device / none) and pushes it to a usb_role_switch consumer (typically dwc3) so the controller can flip between peripheral and host on cable orientation change. An optional VBUS supply regulator is toggled on USB_ROLE_HOST transitions so bus-powered downstream peripherals can be powered.

This is an interesting implementation, but...

Quoted 7 lines

No software TCPM state machine is used because the hardware handles the Type-C protocol natively, and the PMI8998 interrupt topology does not expose the granular per-event signals the TCPM code path expects. Power Delivery is not implemented in this driver; the PMI8998 PDPHY block at offset 0x1700 (register-identical to PM8150B) can be wired up by a separate driver later if PD negotiation is required.

I think TCPM / PD-PHY is (more or less) a sensible requirement. Without it you can't negotiate higher power modes or AltModes support (which means no DP).

Also, this (read-only) implementation doesn't leave space for the active events, like role negotiation.

Anyway, could you please be more specific, which events or which controls do you need?

Quoted 6 lines

This enables USB host mode on the OnePlus 6 (enchilada), OnePlus 6T (fajita), Xiaomi Poco F1 (beryllium), SHIFT 6mq (axolotl) and other SDM845-based phones that use the PMI8998 as their second PMIC.

Please correct your Git configuration to use your full name in the From metadata and in the SoB.

Quoted 8 lines
---
 drivers/usb/typec/Kconfig              |  17 ++
 drivers/usb/typec/Makefile             |   1 +
 drivers/usb/typec/qcom_pmi8998_typec.c | 213 +++++++++++++++++++++++++
 3 files changed, 231 insertions(+)
 create mode 100644 drivers/usb/typec/qcom_pmi8998_typec.c
Signature · 2 lines
With best wishes
Dmitry
#10 lore raw

Re: [PATCH 3/6] usb: typec: add Qualcomm PMI8998 role-switch driver

Quoted 9 lines · Dmitry Baryshkov
Quoted 6 lines

No software TCPM state machine is used because the hardware handles the Type-C protocol natively, and the PMI8998 interrupt topology does not expose the granular per-event signals the TCPM code path expects. Power Delivery is not implemented in this driver; the PMI8998 PDPHY block at offset 0x1700 (register-identical to PM8150B) can be wired up by a separate driver later if PD negotiation is required.

I think TCPM / PD-PHY is (more or less) a sensible requirement. Without it you can't negotiate higher power modes or AltModes support (which means no DP).

If the PDPHY is register compatible as stated then the PD part is very close.

Looking at the pmi8998 STATUS_REG_4

- VBUS_STATUS
- ORIENTATION
- ATTACHED

are all driven. So I believe it would be possible to bring the pmi8998 into - along side the pmi8998 logic.

@Maxim have you looked at that as an option ?

I believe Casey and Luca? both worked on that.

For preference I think we should try to land pmi8998 into the existing TCPM logic though, as another TypeC port handler within the existing logic.

The important signals above, appear to be driven.

---
bod

#11 lore raw

Re: [PATCH 3/6] usb: typec: add Qualcomm PMI8998 role-switch driver

Quoted 1 line · Bryan O'Donoghue

along side the pmi8998 logic.

*pm8150b

---
bod

#12 lore raw

Re: [PATCH 3/6] usb: typec: add Qualcomm PMI8998 role-switch driver

In reply to taygoth
Quoted 19 lines · taygoth

The Qualcomm PMI8998 PMIC integrates a USB Type-C detection block in its SMB2 charger USBIN region at offset 0x1300. The block performs CC sensing, debounce and Rp/Rd resolution in silicon and reports role changes through a single consolidated "type-c-change" interrupt.

This driver reads TYPE_C_STATUS_4 on probe and on every interrupt, decodes the hardware-detected role (host / device / none) and pushes it to a usb_role_switch consumer (typically dwc3) so the controller can flip between peripheral and host on cable orientation change. An optional VBUS supply regulator is toggled on USB_ROLE_HOST transitions so bus-powered downstream peripherals can be powered.

No software TCPM state machine is used because the hardware handles the Type-C protocol natively, and the PMI8998 interrupt topology does not expose the granular per-event signals the TCPM code path expects. Power Delivery is not implemented in this driver; the PMI8998 PDPHY block at offset 0x1700 (register-identical to PM8150B) can be wired up by a separate driver later if PD negotiation is required.

Quoted 5 lines

This enables USB host mode on the OnePlus 6 (enchilada), OnePlus 6T (fajita), Xiaomi Poco F1 (beryllium), SHIFT 6mq (axolotl) and other SDM845-based phones that use the PMI8998 as their second PMIC.

Incomplete identity.

Quoted 6 lines
---
 drivers/usb/typec/Kconfig              |  17 ++
 drivers/usb/typec/Makefile             |   1 +
 drivers/usb/typec/qcom_pmi8998_typec.c | 213 +++++++++++++++++++++++++
 3 files changed, 231 insertions(+)
 create mode 100644 drivers/usb/typec/qcom_pmi8998_typec.c

Do not mix up subsystems which take entire sets in one patchset. USB patches should be split.

Best regards,
Krzysztof

author
#13 lore raw

PATCH 4/6 arm64: dts: qcom: pmi8998: add USB Type-C and VBUS regulator nodes

In reply to taygoth

The PMI8998 PMIC includes a USB Type-C detection block at SPMI offset 0x1300 and a USB OTG VBUS boost converter at offset 0x1100. Both are left disabled here so that only boards which wire up the connector and USB role-switch enable them.

The VBUS regulator falls back to the qcom,pm8150b-vbus-reg compatible because the OTG register layout (CMD_OTG, OTG_CFG, OTG_CURRENT_LIMIT) is identical to the PM8150B SMB5 block.

---
 arch/arm64/boot/dts/qcom/pmi8998.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
arch/arm64/boot/dts/qcom/pmi8998.dtsi +19 -0
index cd3f0790fd42..08a5f58c9b85 100644
@@ -29,6 +29,25 @@ pmi8998_charger: charger@1000 {
 			status = "disabled";
 		};
 
+		pmi8998_vbus: vbus-reg@1100 {
+			compatible = "qcom,pmi8998-vbus-reg",
+				     "qcom,pm8150b-vbus-reg";
+			reg = <0x1100>;
+			status = "disabled";
+		};
+
+		pmi8998_typec: typec@1300 {
+			compatible = "qcom,pmi8998-typec";
+			reg = <0x1300>;
+
+			interrupts = <0x2 0x13 0x7 IRQ_TYPE_EDGE_BOTH>;
+			interrupt-names = "type-c-change";
+
+			vdd-vbus-supply = <&pmi8998_vbus>;
+
+			status = "disabled";
+		};
+
 		pmi8998_gpios: gpio@c000 {
 			compatible = "qcom,pmi8998-gpio", "qcom,spmi-gpio";
 			reg = <0xc000>;
Signature · 1 line
2.47.3
#14 lore raw

Re: [PATCH 4/6] arm64: dts: qcom: pmi8998: add USB Type-C and VBUS regulator nodes

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [Medium] Devicetree schema validation failure for VBUS regulator node due to incorrect name and missing…

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Devicetree schema validation failure for VBUS regulator node due to incorrect name and missing properties.
- [Medium] Devicetree schema validation failure for Type-C node due to schema routing conflict and missing required subnode. --

commit d114c820eb701d590cfd5b3e5e83a32def5c8605
Author: taygoth <[email protected]>

arm64: dts: qcom: pmi8998: add USB Type-C and VBUS regulator nodes

This commit adds disabled nodes for the PMI8998 PMIC USB Type-C detection block and the USB OTG VBUS boost converter. The VBUS regulator falls back to the pm8150b-vbus-reg compatible due to identical register layouts.

arch/arm64/boot/dts/qcom/pmi8998.dtsi pmi8998_charger: charger@1000 { · line 32

Quoted 7 lines
arch/arm64/boot/dts/qcom/pmi8998.dtsi +1 -0
@@ -29,6 +29,25 @@ pmi8998_charger: charger@1000 {
 			status = "disabled";
 		};
 
+		pmi8998_vbus: vbus-reg@1100 {

Will this node name cause a devicetree schema validation failure during dtbs_check?

It looks like Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml enforces the node name pattern ^usb-vbus-regulator@[0-9a-f]+$ and has
additionalProperties: false.

arch/arm64/boot/dts/qcom/pmi8998.dtsi pmi8998_charger: charger@1000 { · line 35

Quoted 3 lines
arch/arm64/boot/dts/qcom/pmi8998.dtsi +3 -0
+			compatible = "qcom,pmi8998-vbus-reg",
+				     "qcom,pm8150b-vbus-reg";
+			reg = <0x1100>;

Are we missing the regulator-min-microamp and regulator-max-microamp properties here?

The qcom,usb-vbus-regulator.yaml schema strictly requires them, which might trigger warnings for all boards including pmi8998.dtsi even if the status is disabled.

arch/arm64/boot/dts/qcom/pmi8998.dtsi pmi8998_charger: charger@1000 { · line 39

Quoted 4 lines
arch/arm64/boot/dts/qcom/pmi8998.dtsi +4 -0
+			status = "disabled";
+		};
+
+		pmi8998_typec: typec@1300 {

Does naming this node typec@1300 create a schema routing conflict?

The pattern ^typec@[0-9a-f]+$ in qcom,spmi-pmic.yaml hardcodes a reference to /schemas/usb/qcom,pmic-typec.yaml#. Since qcom,pmi8998-typec has its own binding and isn't permitted in qcom,pmic-typec.yaml, dtbs_check might evaluate it against the wrong schema and reject the compatible string.

arch/arm64/boot/dts/qcom/pmi8998.dtsi pmi8998_charger: charger@1000 { · line 46

Quoted 7 lines
arch/arm64/boot/dts/qcom/pmi8998.dtsi +7 -0
+			compatible = "qcom,pmi8998-typec";
+			reg = <0x1300>;
+
+			interrupts = <0x2 0x13 0x7 IRQ_TYPE_EDGE_BOTH>;
+			interrupt-names = "type-c-change";
+
+			vdd-vbus-supply = <&pmi8998_vbus>;

Does this node also need the connector subnode? It appears to be explicitly listed as required in qcom,pmi8998-typec.yaml.

Quoted 3 lines
arch/arm64/boot/dts/qcom/pmi8998.dtsi +3 -0
+
+			status = "disabled";
+		};

[ ... ]

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4
author
#15 lore raw

PATCH 5/6 arm64: dts: qcom: sdm845-oneplus-common: enable USB Type-C role switching

In reply to taygoth

Enable the PMI8998 Type-C controller and USB OTG VBUS regulator so the OnePlus 6 and OnePlus 6T can dynamically switch between USB peripheral and host roles depending on the connected cable, instead of being locked to peripheral mode at boot.

The dwc3 controller is moved from dr_mode = "peripheral" to "otg" and gains a usb-role-switch property. The existing usb_1_dwc3_hs endpoint declared in sdm845.dtsi has its remote-endpoint pointed at the new pmi8998 Type-C connector subnode. The maximum-speed override is no longer required because role switching infrastructure handles speed negotiation through the usb-c-connector.

The VBUS regulator current limits (500 mA - 1.5 A) match the boost converter capability noted in the downstream qpnp-smb2 charger config.

---
 .../boot/dts/qcom/sdm845-oneplus-common.dtsi  | 43 ++++++++++++++++---
 1 file changed, 36 insertions(+), 7 deletions(-)
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +36 -7
index 6b7378cf4d49..42badc71ba6a 100644
@@ -606,6 +606,36 @@ &pmi8998_charger {
 	status = "okay";
 };
 
+&pmi8998_vbus {
+	regulator-min-microamp = <500000>;
+	regulator-max-microamp = <1500000>;
+	status = "okay";
+};
+
+&pmi8998_typec {
+	status = "okay";
+
+	connector {
+		compatible = "usb-c-connector";
+		label = "USB-C";
+		power-role = "dual";
+		data-role = "dual";
+		try-power-role = "sink";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				pmi8998_hs_in: endpoint {
+					remote-endpoint = <&usb_1_dwc3_hs>;
+				};
+			};
+		};
+	};
+};
+
 &pmi8998_flash {
 	status = "okay";
 
@@ -890,19 +920,18 @@ &usb_1 {
 };
 
 &usb_1_dwc3 {
-	/*
-	 * We don't have the capability to switch modes yet.
-	 */
-	dr_mode = "peripheral";
-
-	/* fastest mode for USB 2 */
-	maximum-speed = "high-speed";
+	dr_mode = "otg";
+	usb-role-switch;
 
 	/* Remove USB3 phy as it's unused on this device. */
 	phys = <&usb_1_hsphy>;
 	phy-names = "usb2-phy";
 };
 
+&usb_1_dwc3_hs {
+	remote-endpoint = <&pmi8998_hs_in>;
+};
+
 &usb_1_hsphy {
 	status = "okay";
 
Signature · 1 line
2.47.3
#16 lore raw

Re: [PATCH 5/6] arm64: dts: qcom: sdm845-oneplus-common: enable USB Type-C role switching

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] Removing `maximum-speed = "high-speed"` misconfigures the DWC3 controller to default to SuperSpeed…

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Removing maximum-speed = "high-speed" misconfigures the DWC3 controller to default to SuperSpeed on a physically High-Speed-only board, leading to false capabilities advertisement and potential AXI bus hangs.
- [High] The vdd-vbus-supply property is missing from the &pmi8998_typec node, which completely breaks VBUS power delivery in USB host mode.
--

commit fd2e287ee85d01cae64bd27f78d0a7b1a4d6ea65
Author: taygoth <[email protected]>

arm64: dts: qcom: sdm845-oneplus-common: enable USB Type-C role switching

This commit enables the PMI8998 Type-C controller and configures the dwc3 controller for OTG mode on the OnePlus 6/6T. It removes the maximum-speed property and maps the USB endpoints for role switching.

Quoted 3 lines
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +0 -0

[ ... ]

arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi &pmi8998_charger { · line 616

Quoted 8 lines

+&pmi8998_vbus {

arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +7 -0
+	regulator-min-microamp = <500000>;
+	regulator-max-microamp = <1500000>;
+	status = "okay";
+};
+
+&pmi8998_typec {
+	status = "okay";

Does this node need a vdd-vbus-supply property?

The qcom,pmi8998-typec driver looks up the VBUS regulator using devm_regulator_get_optional(dev, "vdd-vbus"). Without a vdd-vbus-supply property pointing to &pmi8998_vbus, the lookup returns -ENODEV and the driver proceeds with a NULL vbus.

Will this result in the driver silently skipping the VBUS regulator enablement during USB_ROLE_HOST transitions, leaving bus-powered downstream peripherals without power?

Quoted 3 lines
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +3 -0
+
+	connector {
+		compatible = "usb-c-connector";

[ ... ]

arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi &usb_1 { · line 924

Quoted 13 lines
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +2 -7
@@ -890,19 +920,18 @@ &usb_1 {
 };
 
 &usb_1_dwc3 {
-	/*
-	 * We don't have the capability to switch modes yet.
-	 */
-	dr_mode = "peripheral";
-
-	/* fastest mode for USB 2 */
-	maximum-speed = "high-speed";
+	dr_mode = "otg";
+	usb-role-switch;

Is it safe to remove the maximum-speed property here?

The commit message notes that the role switching infrastructure handles speed negotiation through the usb-c-connector. However, Type-C CC pins typically only negotiate power delivery and data roles, not the underlying USB protocol speed limits.

If maximum-speed is omitted, the DWC3 core driver falls back to reading the controller's internal hardware parameters (GHWPARAMS3). Since the SDM845 IP is SuperSpeed-capable, it will default to USB_SPEED_SUPER.

Because the board only wires High-Speed lines and drops the SuperSpeed PHY (phys = <&usb_1_hsphy>), will the xHCI driver register a SuperSpeed root hub and attempt Rx.Detect polling? Could attempting to access the PIPE interface of an unclocked QMP PHY trigger an AXI bus hang?

Quoted 3 lines
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +0 -0
 	/* Remove USB3 phy as it's unused on this device. */
 	phys = <&usb_1_hsphy>;

[ ... ]

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=5
author
#17 lore raw

PATCH 6/6 MAINTAINERS: add entry for Qualcomm PMI8998 USB Type-C driver

In reply to taygoth

Add a MAINTAINERS entry covering the new qcom_pmi8998_typec driver and its device-tree binding.

---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
index c2c6d79275c6..d2861fdef012 100644
@@ -22120,6 +22120,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/usb/qcom,pmic-*.yaml
 F:	drivers/usb/typec/tcpm/qcom/
 
+QUALCOMM PMI8998 USB TYPE-C ROLE-SWITCH DRIVER
+M:	Maxim Furman <[email protected]>
+L:	[email protected]
+L:	[email protected]
+S:	Maintained
+F:	Documentation/devicetree/bindings/usb/qcom,pmi8998-typec.yaml
+F:	drivers/usb/typec/qcom_pmi8998_typec.c
+
 QUALCOMM VENUS VIDEO ACCELERATOR DRIVER
 M:	Vikash Garodia <[email protected]>
 M:	Dikshita Agarwal <[email protected]>
Signature · 1 line
2.47.3
#18 lore raw
In reply to taygoth
Quoted 4 lines · taygoth

Power Delivery is not implemented. The PMI8998 PDPHY block at offset 0x1700 is register-identical to PM8150B and could be wired through the existing drivers/usb/typec/tcpm/qcom code in a follow-up if PD negotiation becomes a requirement.

So in this case why not implement your code as a new instance of of type-c phy in the existing TCPM driver ?

---
bod

A message that is not in the archive (sent off-list or not yet received): CAFPzRonyVt9Kd+Sc0ooNz8By6b-Zr_jHr0sBXv-M25dQ0w9Cjg@mail.gmail.com

#20 lore raw
Quoted 10 lines · Максим Фурман

Three shapes for adding a second port handler to the existing driver:
  (a) extracted ops -- pmic_typec_port_ops with chip-specific get_cc / get_vbus / set_mode / set_vconn / start_toggling, refactor PM8150B code into the ops, add parallel PMI8998 implementation
  (b) parallel port file -- keep PM8150B code untouched, add a sibling source file with the same tcpc_dev callback surface
  (c) per-chip register table + per-chip decode helpers in the same file

Bryan, do you have a preference? I'd rather match your taste than guess, since you'll be maintaining the merged result.

Taste - loaded with honey, chilli and salt please chef and add the whole clove of garlic....

My feeling is sibling file but please use your own taste/discretion.

---
bod

#21 lore raw
Quoted 7 lines · Bryan O'Donoghue
Quoted 6 lines · Максим Фурман

Three shapes for adding a second port handler to the existing driver:
  (a) extracted ops -- pmic_typec_port_ops with chip-specific get_cc / get_vbus / set_mode / set_vconn / start_toggling, refactor PM8150B code into the ops, add parallel PMI8998 implementation
  (b) parallel port file -- keep PM8150B code untouched, add a sibling source file with the same tcpc_dev callback surface

2c, my preference would be this option.

Quoted 12 lines
Quoted 4 lines

  (c) per-chip register table + per-chip decode helpers in the same file

Bryan, do you have a preference? I'd rather match your taste than guess, since you'll be maintaining the merged result.

Taste - loaded with honey, chilli and salt please chef and add the whole clove of garlic....

My feeling is sibling file but please use your own taste/discretion.

---
bod

Signature · 2 lines
With best wishes
Dmitry
#22 lore raw
In reply to taygoth
Quoted 27 lines · taygoth

This series adds USB Type-C role-switch support for the PMI8998 PMIC used on SDM845 phones (OnePlus 6/6T, Xiaomi Poco F1, SHIFT 6mq), which have been locked to USB peripheral mode under mainline kernels until now.

The PMI8998 SMB2 charger block integrates a Type-C detection unit at SPMI offset 0x1300 that performs CC sensing, debounce and Rp/Rd resolution entirely in hardware. The state is exposed through the TYPE_C_STATUS_4 register and reported via a single consolidated "type-c-change" interrupt. The new driver reads that status on every interrupt and pushes the negotiated role to a usb_role_switch consumer (dwc3), enabling automatic peripheral/host switching on cable change. Because the hardware handles the Type-C state machine natively, no software TCPM port manager is required.

The Type-C block shares the SMB2 USBIN region with the already mainlined qcom_pmi8998-charger driver. The two coexist on the shared SPMI regmap without write conflict: the typec driver only reads TYPE_C_STATUS_* and touches the IRQ enable bits at offsets 0x130b-0x130f and 0x1367-0x1368.

The PMI8998 USB OTG VBUS boost converter at offset 0x1100 has the same CMD_OTG / OTG_CFG / OTG_CURRENT_LIMIT register layout as PM8150B, so the existing drivers/regulator/qcom_usb_vbus-regulator can drive it through a compatible cascade -- only the DT binding needs the new compatible string added.

Quoted 7 lines

Power Delivery is not implemented. The PMI8998 PDPHY block at offset 0x1700 is register-identical to PM8150B and could be wired through the existing drivers/usb/typec/tcpm/qcom code in a follow-up if PD negotiation becomes a requirement.

Tested-on: OnePlus 6T (sdm845-oneplus-fajita) running Mobian 6.12-sdm845.

FWIW 6.12 has been released 2 years ago and the sdm845 fork contains a lot of unrelated changes. Please give this a test on linux-next/master

Konrad

#23 lore raw
In reply to taygoth
Quoted 32 lines · taygoth

This series adds USB Type-C role-switch support for the PMI8998 PMIC used on SDM845 phones (OnePlus 6/6T, Xiaomi Poco F1, SHIFT 6mq), which have been locked to USB peripheral mode under mainline kernels until now.

The PMI8998 SMB2 charger block integrates a Type-C detection unit at SPMI offset 0x1300 that performs CC sensing, debounce and Rp/Rd resolution entirely in hardware. The state is exposed through the TYPE_C_STATUS_4 register and reported via a single consolidated "type-c-change" interrupt. The new driver reads that status on every interrupt and pushes the negotiated role to a usb_role_switch consumer (dwc3), enabling automatic peripheral/host switching on cable change. Because the hardware handles the Type-C state machine natively, no software TCPM port manager is required.

The Type-C block shares the SMB2 USBIN region with the already mainlined qcom_pmi8998-charger driver. The two coexist on the shared SPMI regmap without write conflict: the typec driver only reads TYPE_C_STATUS_* and touches the IRQ enable bits at offsets 0x130b-0x130f and 0x1367-0x1368.

The PMI8998 USB OTG VBUS boost converter at offset 0x1100 has the same CMD_OTG / OTG_CFG / OTG_CURRENT_LIMIT register layout as PM8150B, so the existing drivers/regulator/qcom_usb_vbus-regulator can drive it through a compatible cascade -- only the DT binding needs the new compatible string added.

Power Delivery is not implemented. The PMI8998 PDPHY block at offset 0x1700 is register-identical to PM8150B and could be wired through the existing drivers/usb/typec/tcpm/qcom code in a follow-up if PD negotiation becomes a requirement.

Quoted 8 lines

Tested-on: OnePlus 6T (sdm845-oneplus-fajita) running Mobian 6.12-sdm845. A USB flash drive, USB ethernet adapter, USB WiFi adapter (TP-Link Archer T2) and a self-powered USB-C dock with downstream ethernet all enumerate through xHCI after the role transitions from peripheral to host. Repeat plug/unplug cycles drive the role through device -> none -> host -> none -> device cleanly with no IRQ stalls or stale role-switch state.

Hello Максим,

1st, let me say happy to hear about progress here, I missed this message - due to huge traffic in linux-arm-msm*.

2nd, I have locally version which does work with DisplayPort (SHIFT 6MQ), does work with dockstation USB (e.g. perperials are recognized and does work), but doesn't provide power to the usb devices (haven't figureout, and it's more clanker work than mine here).

3rd, added Sam into +Cc, as he's interested in the pmi8998 too, plus there are others doing some experiments with pmi8998 in Matrix room https://matrix.to/#/#sdm845:ixit.cz .

What's your current state? Would you be interested joining the room and chat? or
we can do some email exchange of trees and work done :)

David

* there is [email protected], where this type of contribution stand out a bit, possibly for next iteration

[...]