linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/18] Add Qualcomm PMIC TPCM support
@ 2023-03-18 12:18 Bryan O'Donoghue
  2023-03-18 12:18 ` [PATCH v4 01/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required Bryan O'Donoghue
                   ` (18 more replies)
  0 siblings, 19 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

v4:
- Per Rob's input the pdphy and type-c appear as stadalone blocks
  inside of the PMIC declaration which is a 1:1 mapping of PMIC hardware.
  The TCPM virtual device is declared at the top-level.
  https://lore.kernel.org/all/YY7p7jviA3ZG05gL@robh.at.kernel.org/

- Squashes the removal of the old driver with the addition of the new. - Heikki, Gunter
  https://lore.kernel.org/all/YYVHcHC1Gm92VxEM@kuha.fi.intel.com/

- Reworked Dmitry's old patch for the QMP to account for file renames and
  very minimal code-drift in the interregnum.

- New yaml checks drive update of PMIC VBUS yaml

- Some housekeeping on the sc7180 yaml side. sc7180 is not supported yet.

- Expands and fixes the examples being added in the PMIC tcpm examples.

Previous set:
https://lore.kernel.org/all/20211105033558.1573552-1-bryan.odonoghue@linaro.org/

Bootable:
https://git.codelinaro.org/bryan.odonoghue/kernel/-/commits/linux-next-23-03-18-pm8150b-tcpm-qcom-wrapper-typec-mux

V3:
Rob Herrings review

- Drops use of remote-endpoint and ports to bind
  tcpm to pdphy and typec replacing with phandle

- Drops pmic-pdphy-* and pmic-typec-* from interrupt names
  as suggested

- Passes make dt_binding_check DT_CHECKER_FLAGS=-m

BOD
- Noticed qcom_pmic_tcpm_pdphy_enable() was missing a
  regulator_disable in case of an error, added.

- qcom_pmic_tcpm_pdphy_probe()
  devm_regulator_get() should come before regmap_get()
  as is the case in qcom_pmic_tcpm_typec_probe()

- Fixes compatible name in qcom,pmic-typec.yaml should
  have read qcom,pm8150b-typec not qcom,pm8150b-usb-typec

- Makes sure compat for core is "qcom,pm8150b-tcpm" in
  docs and driver

- Drops redundant return in void qcom_pmic_tcpm_pdphy_reset_off()

Kernel Robot
- Drops unused variable debounced in qcom_pmic_tcpm_typec_get_cc()

- Drops unsused variable orientation in qcom_pmic_tcpm_typec_set_cc()

Latest bootable series can be found here:
Link: https://git.linaro.org/people/bryan.odonoghue/kernel.git/log/?h=usb-next-04-11-21-pm8150b-tcpm-v3

git diff usb-next-27-10-21-pm8150b-tcpm-v2 -- drivers/usb/typec/tcpm/qcom/
git diff usb-next-27-10-21-pm8150b-tcpm-v2 -- Documentation/devicetree/bindings/usb/qcom,pmic*

Previous set:
Link: https://lore.kernel.org/linux-usb/20211028164941.831918-1-bryan.odonoghue@linaro.org/T/#t

V2 resend:
- Adding omitted devicetree mailing list

V2:

Guenter Roeck's review
- Converts suggested qcom_pmic_tcpm_core.c into one-liners

- Adds comment on how polarity is set in set_polarity()

- Removes optional set_current_limit()

- regmap_read/regmap_write
  Reviwing other pm8150b/spmi drivers I then added in checks for all
  reamap_read()/regmap_write() calls.

- Fixes (type == TCPC_TX_CABLE_RESET || TCPC_TX_HARD_RESET)
  thanks I definitely had the blinkers on there and didn't see that at all

- qcom_pmic_tcpm_pdphy_pd_transmit_payload()
  Treats regmap_read and read value as separate error paths

- qcom_pmic_tcpm_pdphy_set_pd_rx()
  Replaces boolean if/else with !on as suggested

- Returns -ENODEV not -EINVAL on dev_get_regmap() error

- qcom_pmic_tcpm_pdphy_pd_receive()
  Guenter asks: "No error return ?"
  bod: No we are inside an ISR here if we read data we pass that off to TCPM
       if somehow we don't read the data - it is "junk" there's no value IMO
       in pushing an error upwards back to the handler.

Heikki Krogerus' review
- Includes Makefile I missed adding to my git index

- Removes old Kconfig entry for remove driver

Randy Dunlap's review 
- Rewords drivers/usb/typec/tcpm/Kconfig

- Drops tautology "aggregates togther"

- Corrects spelling typos

BOD's own review
- Drops redundant include of regmap.h in qcom_pmic_tcpm_core.c

- Propogates qcom_pmic_tcpm_pdphy_disable() error upwards

- Propogates pmic_pdphy_reset() error upwards

- Drops error prints in qcom_pmic_tcpm_pdphy_pd_transmit_payload()
  I had these in-place during development and don't recall them being
  triggered even once, they are redundant, remove.
 
Differences between the two can be seen by
git diff usb-next-27-10-21-pm8150b-tcpm-v2..usb-next-25-10-21-pm8150b-tcpm -- drivers/usb/typec/tcpm

Latest bootable series can be found here:
Link: https://git.linaro.org/people/bryan.odonoghue/kernel.git/log/?h=usb-next-27-10-21-pm8150b-tcpm-v2

Previous set:
Link: https://lore.kernel.org/all/20211025150906.176686-1-bryan.odonoghue@linaro.org/T/#t

V1:
This series adds a set of yaml and a driver to bind together the type-c and
pdphy silicon in qcom's pm8150b block as a Linux type-c port manager.

As part of that we retire the existing qcom-pmic-typec driver and fully
replicate its functionality inside of the new block with the additional
pdphy stuff along with it.

An additional series will follow this one for the SoC and RB5 dtsi and dts
respectively.

A bootable series can be found here

Link: https://git.linaro.org/people/bryan.odonoghue/kernel.git/log/?h=usb-next-25-10-21-pm8150b-tcpm


Bryan O'Donoghue (17):
  dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required
  dt-bindings: regulator: qcom,usb-vbus-regulator: Mark
    regulator-*-microamp required
  dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add orientation-switch
    as optional
  dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional
  dt-bindings: usb: Add qcom,pmic-typec dt-binding header
  dt-bindings: usb: Add Qualcomm PMIC Type-C controller YAML schema
  dt-bindings: usb: Add qcom,pmic-pdphy dt-binding header
  dt-bindings: usb: Add Qualcomm PMIC PDPHY controller YAML schema
  dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types
  dt-bindings: mfd: qcom,spmi-pmic: Add typec to SPMI device types
  usb: typec: qcom: Add Qualcomm PMIC TCPM support
  arm64: dts: qcom: pm8150b: Add a TCPM description
  arm64: dts: qcom: qrb5165-rb5: Switch on Type-C VBUS boost
  arm64: dts: qcom: qrb5165-rb5: Switch on basic TCPM
  arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for
    usb_1
  arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for
    usb_1_qmpphy

Dmitry Baryshkov (1):
  phy: qcom-qmp: Register as a typec switch for orientation detection

 .../bindings/mfd/qcom,spmi-pmic.yaml          |   8 +
 .../phy/qcom,sc7180-qmp-usb3-dp-phy.yaml      |  10 +
 .../regulator/qcom,usb-vbus-regulator.yaml    |  10 +-
 .../bindings/usb/qcom,pmic-pdphy.yaml         |  89 +++
 .../bindings/usb/qcom,pmic-typec.yaml         |  88 +++
 .../bindings/usb/qcom,pmic-virt-tcpm.yaml     |  88 +++
 MAINTAINERS                                   |  10 +
 arch/arm64/boot/dts/qcom/pm8150b.dtsi         |  70 ++
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts      |  63 +-
 drivers/phy/qualcomm/Kconfig                  |   8 +
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c     |  80 ++-
 drivers/usb/typec/Kconfig                     |  13 -
 drivers/usb/typec/Makefile                    |   1 -
 drivers/usb/typec/qcom-pmic-typec.c           | 261 -------
 drivers/usb/typec/tcpm/Kconfig                |  11 +
 drivers/usb/typec/tcpm/Makefile               |   1 +
 drivers/usb/typec/tcpm/qcom/Makefile          |   6 +
 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c | 605 +++++++++++++++++
 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h |  85 +++
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 637 ++++++++++++++++++
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h | 163 +++++
 .../usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c | 326 +++++++++
 .../dt-bindings/usb/typec/qcom,pmic-pdphy.h   |  18 +
 .../dt-bindings/usb/typec/qcom,pmic-typec.h   |  18 +
 24 files changed, 2388 insertions(+), 281 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml
 delete mode 100644 drivers/usb/typec/qcom-pmic-typec.c
 create mode 100644 drivers/usb/typec/tcpm/qcom/Makefile
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
 create mode 100644 include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
 create mode 100644 include/dt-bindings/usb/typec/qcom,pmic-typec.h

-- 
2.39.2


^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH v4 01/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:41   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 02/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark regulator-*-microamp required Bryan O'Donoghue
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Mark reg as a required property.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
index b1cff3adb21b5..7a3b59f836092 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
@@ -25,6 +25,7 @@ properties:
 
 required:
   - compatible
+  - reg
 
 additionalProperties: false
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 02/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark regulator-*-microamp required
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
  2023-03-18 12:18 ` [PATCH v4 01/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:42   ` Krzysztof Kozlowski
  2023-03-19 11:53   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 03/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add orientation-switch as optional Bryan O'Donoghue
                   ` (16 subsequent siblings)
  18 siblings, 2 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

The VBUS driver needs to know the regulator-min-microamp and
regulator-max-microamp so they should both be marked as required.

regulator.yaml defines those two dependencies so include regulator.yaml.

We need to change from additionalProperties: false to
unevaluatedProperties: false.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../bindings/regulator/qcom,usb-vbus-regulator.yaml      | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
index 7a3b59f836092..f6ecb0f72ad9a 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
@@ -14,6 +14,9 @@ description: |
   regulator will be enabled in situations where the device is required to
   provide power to the connected peripheral.
 
+allOf:
+  - $ref: "regulator.yaml#"
+
 properties:
   compatible:
     enum:
@@ -26,8 +29,10 @@ properties:
 required:
   - compatible
   - reg
+  - regulator-min-microamp
+  - regulator-max-microamp
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
@@ -37,6 +42,8 @@ examples:
         pm8150b_vbus: usb-vbus-regulator@1100 {
             compatible = "qcom,pm8150b-vbus-reg";
             reg = <0x1100>;
+            regulator-min-microamp = <500000>;
+            regulator-max-microamp = <3000000>;
         };
      };
 ...
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 03/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add orientation-switch as optional
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
  2023-03-18 12:18 ` [PATCH v4 01/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required Bryan O'Donoghue
  2023-03-18 12:18 ` [PATCH v4 02/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark regulator-*-microamp required Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:42   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional Bryan O'Donoghue
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

orientation-switch it the standard declaration to inform the Type-C mux
layer that a remote-endpoint is capable of processing orientation change
messages.

Add as an optional since not all versions of the dp-phy currently support
the orientation-switch.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml  | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
index 0ef2c9b9d4669..52886cdb0e506 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
@@ -61,6 +61,10 @@ properties:
   power-domains:
     maxItems: 1
 
+  orientation-switch:
+    description: Flag the port as possible handler of orientation switching
+    type: boolean
+
   resets:
     items:
       - description: reset of phy block.
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (2 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 03/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add orientation-switch as optional Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:45   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 05/18] dt-bindings: usb: Add qcom,pmic-typec dt-binding header Bryan O'Donoghue
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

port is required to instantiate a remote-endpoint which can receive
orientation-switch messages from a Type-C mux.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml           | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
index 52886cdb0e506..1c887e34b1223 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
@@ -65,6 +65,12 @@ properties:
     description: Flag the port as possible handler of orientation switching
     type: boolean
 
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node to link the PHY to a TypeC controller for the purpose of
+      handling altmode muxing and orientation switching.
+
   resets:
     items:
       - description: reset of phy block.
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 05/18] dt-bindings: usb: Add qcom,pmic-typec dt-binding header
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (3 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:50   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 06/18] dt-bindings: usb: Add Qualcomm PMIC Type-C controller YAML schema Bryan O'Donoghue
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Adds a series of defines which are used in the DTS and type-c driver for
identifying interrupts.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../dt-bindings/usb/typec/qcom,pmic-typec.h    | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 include/dt-bindings/usb/typec/qcom,pmic-typec.h

diff --git a/include/dt-bindings/usb/typec/qcom,pmic-typec.h b/include/dt-bindings/usb/typec/qcom,pmic-typec.h
new file mode 100644
index 0000000000000..733e23b6cdbc4
--- /dev/null
+++ b/include/dt-bindings/usb/typec/qcom,pmic-typec.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_TCPM_QCOM_PMIC_TYPEC_H
+#define _DT_BINDINGS_TCPM_QCOM_PMIC_TYPEC_H
+
+#define PMIC_TYPEC_OR_RID_IRQ		0x0
+#define PMIC_TYPEC_VPD_IRQ		0x1
+#define PMIC_TYPEC_CC_STATE_IRQ		0x2
+#define PMIC_TYPEC_VCONN_OC_IRQ		0x3
+#define PMIC_TYPEC_VBUS_IRQ		0x4
+#define PMIC_TYPEC_ATTACH_DETACH_IRQ	0x5
+#define PMIC_TYPEC_LEGACY_CABLE_IRQ	0x6
+#define PMIC_TYPEC_TRY_SNK_SRC_IRQ	0x7
+
+#endif
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 06/18] dt-bindings: usb: Add Qualcomm PMIC Type-C controller YAML schema
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (4 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 05/18] dt-bindings: usb: Add qcom,pmic-typec dt-binding header Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:53   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 07/18] dt-bindings: usb: Add qcom,pmic-pdphy dt-binding header Bryan O'Donoghue
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Add a YAML binding for the Type-C silicon interface inside Qualcomm's
pm8150b hardware block.

The Type-C driver operates with a pdphy driver inside of a high level
single TCPM device.

Based on original work by Wesley.

Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../bindings/usb/qcom,pmic-typec.yaml         | 88 +++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml

diff --git a/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml b/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
new file mode 100644
index 0000000000000..d87bbab88d8be
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/qcom,pmic-typec.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm PMIC based USB type C Detection Driver
+
+maintainers:
+  - Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+description: |
+  Qualcomm PMIC Type C Detect
+
+properties:
+  compatible:
+    enum:
+      - qcom,pm8150b-typec
+
+  reg:
+    maxItems: 1
+    description: Type C base address
+
+  interrupts:
+    items:
+      - description: Bitmask of CC attach, VBUS error, tCCDebounce done and more
+      - description: VCONN Powered Detection
+      - description: CC state change
+      - description: VCONN over-current condition
+      - description: VBUS state change
+      - description: Attach Deteach notification
+      - description: Legacy cable detect
+      - description: Try.Src Try.Snk state change
+
+  interrupt-names:
+    items:
+      - const: or-rid-detect-change
+      - const: vpd-detect
+      - const: cc-state-change
+      - const: vconn-oc
+      - const: vbus-change
+      - const: attach-detach
+      - const: legacy-cable-detect
+      - const: try-snk-src-detect
+
+  vdd-vbus-supply:
+    description: VBUS power supply.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - vdd-vbus-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/usb/typec/qcom,pmic-typec.h>
+    pm8150b {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pm8150b_typec: typec@1500 {
+            compatible = "qcom,pm8150b-typec";
+            reg = <0x1500>;
+            interrupts = <0x2 0x15 PMIC_TYPEC_OR_RID_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x15 PMIC_TYPEC_VPD_IRQ IRQ_TYPE_EDGE_BOTH>,
+                         <0x2 0x15 PMIC_TYPEC_CC_STATE_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x15 PMIC_TYPEC_VCONN_OC_IRQ IRQ_TYPE_EDGE_BOTH>,
+                         <0x2 0x15 PMIC_TYPEC_VBUS_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x15 PMIC_TYPEC_ATTACH_DETACH_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x15 PMIC_TYPEC_LEGACY_CABLE_IRQ IRQ_TYPE_EDGE_BOTH>,
+                         <0x2 0x15 PMIC_TYPEC_TRY_SNK_SRC_IRQ IRQ_TYPE_EDGE_RISING>;
+            interrupt-names = "or-rid-detect-change",
+                              "vpd-detect",
+                              "cc-state-change",
+                              "vconn-oc",
+                              "vbus-change",
+                              "attach-detach",
+                              "legacy-cable-detect",
+                              "try-snk-src-detect";
+            vdd-vbus-supply = <&pm8150b_vbus>;
+        };
+    };
+...
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 07/18] dt-bindings: usb: Add qcom,pmic-pdphy dt-binding header
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (5 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 06/18] dt-bindings: usb: Add Qualcomm PMIC Type-C controller YAML schema Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:50   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 08/18] dt-bindings: usb: Add Qualcomm PMIC PDPHY controller YAML schema Bryan O'Donoghue
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Adds a series of defines which are used in the DTS and pdphy driver for
identifying interrupts.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../dt-bindings/usb/typec/qcom,pmic-pdphy.h    | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 include/dt-bindings/usb/typec/qcom,pmic-pdphy.h

diff --git a/include/dt-bindings/usb/typec/qcom,pmic-pdphy.h b/include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
new file mode 100644
index 0000000000000..7d39985bcc779
--- /dev/null
+++ b/include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_QCOM_PMIC_PDPHY_H
+#define _DT_BINDINGS_QCOM_PMIC_PDPHY_H
+
+#define PMIC_PDPHY_SIG_TX_IRQ		0x0
+#define PMIC_PDPHY_SIG_RX_IRQ		0x1
+#define PMIC_PDPHY_MSG_TX_IRQ		0x2
+#define PMIC_PDPHY_MSG_RX_IRQ		0x3
+#define PMIC_PDPHY_MSG_TX_FAIL_IRQ	0x4
+#define PMIC_PDPHY_MSG_TX_DISCARD_IRQ	0x5
+#define PMIC_PDPHY_MSG_RX_DISCARD_IRQ	0x6
+#define PMIC_PDPHY_FR_SWAP_IRQ		0x7
+
+#endif
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 08/18] dt-bindings: usb: Add Qualcomm PMIC PDPHY controller YAML schema
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (6 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 07/18] dt-bindings: usb: Add qcom,pmic-pdphy dt-binding header Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:55   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM " Bryan O'Donoghue
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Add a YAML binding for the power-delivery PHY silicon interface inside
Qualcomm's pm8150b hardware block.

The pdphy driver operates with a type-c driver inside of a high level
single TCPM device to provide overall TCPM functionality.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../bindings/usb/qcom,pmic-pdphy.yaml         | 89 +++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml

diff --git a/Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml b/Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml
new file mode 100644
index 0000000000000..79318e3da41e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/qcom,pmic-pdphy.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm PMIC based USB PDPHY driver
+
+maintainers:
+  - Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+description: |
+  Qualcomm PMIC Power Delivery PHY driver
+
+properties:
+  compatible:
+    enum:
+      - qcom,pm8150b-pdphy
+
+  reg:
+    maxItems: 1
+    description: PDPHY base address
+
+  interrupts:
+    items:
+      - description: Sig TX - transmitted reset signal
+      - description: Sig RX - received reset signal
+      - description: TX completion
+      - description: RX completion
+      - description: TX fail
+      - description: TX discgard
+      - description: RX discgard
+      - description: Fast Role Swap event
+
+  interrupt-names:
+    items:
+      - const: sig-tx
+      - const: sig-rx
+      - const: msg-tx
+      - const: msg-rx
+      - const: msg-tx-failed
+      - const: msg-tx-discarded
+      - const: msg-rx-discarded
+      - const: fr-swap
+
+  vdd-phy-supply:
+    description: VDD regulator supply to the PHY.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - vdd-phy-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/usb/typec/qcom,pmic-pdphy.h>
+
+    pm8150b {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pm8150b_pdphy: pdphy@1700 {
+            compatible = "qcom,pm8150b-pdphy";
+            reg = <0x1700>;
+            interrupts = <0x2 0x17 PMIC_PDPHY_SIG_TX_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x17 PMIC_PDPHY_SIG_RX_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x17 PMIC_PDPHY_MSG_TX_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x17 PMIC_PDPHY_MSG_RX_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x17 PMIC_PDPHY_MSG_TX_FAIL_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x17 PMIC_PDPHY_MSG_TX_DISCARD_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x17 PMIC_PDPHY_MSG_RX_DISCARD_IRQ IRQ_TYPE_EDGE_RISING>,
+                         <0x2 0x17 PMIC_PDPHY_FR_SWAP_IRQ IRQ_TYPE_EDGE_RISING>;
+            interrupt-names = "sig-tx",
+                              "sig-rx",
+                              "msg-tx",
+                              "msg-rx",
+                              "msg-tx-failed",
+                              "msg-tx-discarded",
+                              "msg-rx-discarded",
+                              "fr-swap";
+            vdd-phy-supply = <&vreg_l2a_3p1>;
+        };
+    };
+...
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (7 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 08/18] dt-bindings: usb: Add Qualcomm PMIC PDPHY controller YAML schema Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:58   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 10/18] dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types Bryan O'Donoghue
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Add a YAML description for the pm8150b-tcpm driver. The pm8150b-tcpm
encapsulates a type-c block and a pdphy block into one block presented to
the TCPM Linux API.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../bindings/usb/qcom,pmic-virt-tcpm.yaml     | 88 +++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml

diff --git a/Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml b/Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml
new file mode 100644
index 0000000000000..576842c8b65b4
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/qcom,pmic-virt-tcpm.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Qualcomm PMIC Virtual TCPM Driver
+
+maintainers:
+  - Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+description: |
+  Qualcomm PMIC Virtual Type-C Port Manager Driver
+  A virtual device which manages Qualcomm PMIC provided Type-C port and
+  Power Delivery in one place.
+
+properties:
+  compatible:
+    const: qcom,pmic-virt-tcpm
+
+  connector:
+    type: object
+    $ref: /schemas/connector/usb-connector.yaml#
+    unevaluatedProperties: false
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      Contains a port which consumes data-role switching messages.
+
+  qcom,pmic-typec:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the typec port hardware driver.
+
+  qcom,pmic-pdphy:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      A phandle to the type-c pdphy hardware driver.
+
+required:
+  - compatible
+  - connector
+  - port
+  - qcom,pmic-typec
+  - qcom,pmic-pdphy
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/usb/pd.h>
+    #include <dt-bindings/usb/typec/qcom,pmic-typec.h>
+    #include <dt-bindings/usb/typec/qcom,pmic-pdphy.h>
+
+    pm8150b_tcpm: pmic-tcpm {
+        compatible = "qcom,pmic-virt-tcpm";
+
+        qcom,pmic-typec = <&pm8150b_typec>;
+        qcom,pmic-pdphy = <&pm8150b_pdphy>;
+
+        port {
+            usb3_role: endpoint {
+                remote-endpoint = <&dwc3_drd_switch>;
+            };
+        };
+
+        connector {
+            compatible = "usb-c-connector";
+
+            power-role = "source";
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                    reg = <0>;
+                    pmic_tcpm_ss_mux: endpoint {
+                        remote-endpoint = <&qmp_ss_mux>;
+                    };
+                };
+            };
+        };
+    };
+
+...
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 10/18] dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (8 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM " Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:58   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 11/18] dt-bindings: mfd: qcom,spmi-pmic: Add typec " Bryan O'Donoghue
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

The PDPHY sits inside of the PMIC SPMI block providing register-level
ability to read/write USB Type-C Power Delivery protocol packets over the
SBU pins.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
index 8f076bb622b15..111aec53caeb5 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
@@ -140,6 +140,10 @@ patternProperties:
     type: object
     $ref: /schemas/power/reset/qcom,pon.yaml#
 
+  "pdphy@[0-9a-f]+$":
+    type: object
+    $ref: /schemas/usb/qcom,pmic-pdphy.yaml#
+
   "^rtc@[0-9a-f]+$":
     type: object
     $ref: /schemas/rtc/qcom-pm8xxx-rtc.yaml#
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 11/18] dt-bindings: mfd: qcom,spmi-pmic: Add typec to SPMI device types
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (9 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 10/18] dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-19 11:59   ` Krzysztof Kozlowski
  2023-03-18 12:18 ` [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support Bryan O'Donoghue
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Add the PMIC Type-C port driver to the list of devices.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
index 111aec53caeb5..44e1dbd5c0f32 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
@@ -152,6 +152,10 @@ patternProperties:
     type: object
     $ref: /schemas/thermal/qcom,spmi-temp-alarm.yaml#
 
+  "^typec@[0-9a-f]+$":
+    type: object
+    $ref: /schemas/usb/qcom,pmic-typec.yaml#
+
   "^usb-detect@[0-9a-f]+$":
     type: object
     $ref: /schemas/extcon/qcom,pm8941-misc.yaml#
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (10 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 11/18] dt-bindings: mfd: qcom,spmi-pmic: Add typec " Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-23 14:36   ` Jianhua Lu
  2023-03-24 14:00   ` Heikki Krogerus
  2023-03-18 12:18 ` [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection Bryan O'Donoghue
                   ` (6 subsequent siblings)
  18 siblings, 2 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

This commit adds a QCOM PMIC TCPM driver with an initial pm8150b
block.

qcom_pmic_virt_tcpm.c : Responsible for registering with TCPM and
                        arbitrates access to the Type-C and PDPHY hardware
                        blocks in one place.
                        This driver presents a virtual device to the Linux
                        TCPM layer.

qcom_pmic_pdphy.c: Rsponsible for interfacing with the PDPHY hardware and
                   processing power-delivery related calls from TCPM.
                   This hardware binding can be extended to facilitate
                   similar hardware in different PMICs.

qcom_pmic_typec.c: Responsible for notifying and processing Type-C
                   related calls from TCPM.
                   This hardware binding can be extended to facilitate
                   similar hardware in different PMICs.

This code provides all of the same functionality as the existing
qcom typec driver plus power-delivery as well.

As a result commit 6c8cf3695176 ("usb: typec: Add QCOM PMIC typec detection
driver") can be deleted entirely.

References code from Jonathan Marek, Jack Pham, Wesley Cheng, Hemant Kumar,
Guru Das Srinagesh and Ashay Jaiswal.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 MAINTAINERS                                   |  10 +
 drivers/usb/typec/Kconfig                     |  13 -
 drivers/usb/typec/Makefile                    |   1 -
 drivers/usb/typec/qcom-pmic-typec.c           | 261 -------
 drivers/usb/typec/tcpm/Kconfig                |  11 +
 drivers/usb/typec/tcpm/Makefile               |   1 +
 drivers/usb/typec/tcpm/qcom/Makefile          |   6 +
 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c | 605 +++++++++++++++++
 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h |  85 +++
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 637 ++++++++++++++++++
 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h | 163 +++++
 .../usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c | 326 +++++++++
 12 files changed, 1844 insertions(+), 275 deletions(-)
 delete mode 100644 drivers/usb/typec/qcom-pmic-typec.c
 create mode 100644 drivers/usb/typec/tcpm/qcom/Makefile
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
 create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9b218dc388323..59f8a3c0b6364 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17435,6 +17435,16 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
 F:	drivers/thermal/qcom/
 
+QUALCOMM TYPEC PORT MANAGER DRIVER
+M:	Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+L:	linux-arm-msm@vger.kernel.org
+L:	linux-usb@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/usb/qcom,pmic-*.yaml
+F:	drivers/usb/typec/tcpm/qcom/
+F:	include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
+F:	include/dt-bindings/usb/typec/qcom,pmic-typec.h
+
 QUALCOMM VENUS VIDEO ACCELERATOR DRIVER
 M:	Stanimir Varbanov <stanimir.k.varbanov@gmail.com>
 M:	Vikash Garodia <quic_vgarodia@quicinc.com>
diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
index 831e7049977df..2f80c2792dbda 100644
--- a/drivers/usb/typec/Kconfig
+++ b/drivers/usb/typec/Kconfig
@@ -100,19 +100,6 @@ 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_PMIC
-	tristate "Qualcomm PMIC USB Type-C driver"
-	depends on ARCH_QCOM || COMPILE_TEST
-	depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH
-	help
-	  Driver for supporting role switch over the Qualcomm PMIC.  This will
-	  handle the USB Type-C role and orientation detection reported by the
-	  QCOM PMIC if the PMIC has the capability to handle USB Type-C
-	  detection.
-
-	  It will also enable the VBUS output to connected devices when a
-	  DFP connection is made.
-
 config TYPEC_WUSB3801
 	tristate "Willsemi WUSB3801 Type-C port controller driver"
 	depends on I2C
diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index 4a83dad51a6cf..7a368fea61bc9 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_TYPEC_UCSI)	+= ucsi/
 obj-$(CONFIG_TYPEC_TPS6598X)	+= tipd/
 obj-$(CONFIG_TYPEC_ANX7411)	+= anx7411.o
 obj-$(CONFIG_TYPEC_HD3SS3220)	+= hd3ss3220.o
-obj-$(CONFIG_TYPEC_QCOM_PMIC)	+= qcom-pmic-typec.o
 obj-$(CONFIG_TYPEC_STUSB160X) 	+= stusb160x.o
 obj-$(CONFIG_TYPEC_RT1719)	+= rt1719.o
 obj-$(CONFIG_TYPEC_WUSB3801)	+= wusb3801.o
diff --git a/drivers/usb/typec/qcom-pmic-typec.c b/drivers/usb/typec/qcom-pmic-typec.c
deleted file mode 100644
index 432ea62f1bab6..0000000000000
--- a/drivers/usb/typec/qcom-pmic-typec.c
+++ /dev/null
@@ -1,261 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2020, The Linux Foundation. All rights reserved.
- */
-
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/mod_devicetable.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
-#include <linux/usb/role.h>
-#include <linux/usb/typec_mux.h>
-
-#define TYPEC_MISC_STATUS		0xb
-#define CC_ATTACHED			BIT(0)
-#define CC_ORIENTATION			BIT(1)
-#define SNK_SRC_MODE			BIT(6)
-#define TYPEC_MODE_CFG			0x44
-#define TYPEC_DISABLE_CMD		BIT(0)
-#define EN_SNK_ONLY			BIT(1)
-#define EN_SRC_ONLY			BIT(2)
-#define TYPEC_VCONN_CONTROL		0x46
-#define VCONN_EN_SRC			BIT(0)
-#define VCONN_EN_VAL			BIT(1)
-#define TYPEC_EXIT_STATE_CFG		0x50
-#define SEL_SRC_UPPER_REF		BIT(2)
-#define TYPEC_INTR_EN_CFG_1		0x5e
-#define TYPEC_INTR_EN_CFG_1_MASK	GENMASK(7, 0)
-
-struct qcom_pmic_typec {
-	struct device		*dev;
-	struct regmap		*regmap;
-	u32			base;
-
-	struct typec_port	*port;
-	struct usb_role_switch *role_sw;
-
-	struct regulator	*vbus_reg;
-	bool			vbus_enabled;
-};
-
-static void qcom_pmic_typec_enable_vbus_regulator(struct qcom_pmic_typec
-							*qcom_usb, bool enable)
-{
-	int ret;
-
-	if (enable == qcom_usb->vbus_enabled)
-		return;
-
-	if (enable) {
-		ret = regulator_enable(qcom_usb->vbus_reg);
-		if (ret)
-			return;
-	} else {
-		ret = regulator_disable(qcom_usb->vbus_reg);
-		if (ret)
-			return;
-	}
-	qcom_usb->vbus_enabled = enable;
-}
-
-static void qcom_pmic_typec_check_connection(struct qcom_pmic_typec *qcom_usb)
-{
-	enum typec_orientation orientation;
-	enum usb_role role;
-	unsigned int stat;
-	bool enable_vbus;
-
-	regmap_read(qcom_usb->regmap, qcom_usb->base + TYPEC_MISC_STATUS,
-		    &stat);
-
-	if (stat & CC_ATTACHED) {
-		orientation = (stat & CC_ORIENTATION) ?
-				TYPEC_ORIENTATION_REVERSE :
-				TYPEC_ORIENTATION_NORMAL;
-		typec_set_orientation(qcom_usb->port, orientation);
-
-		role = (stat & SNK_SRC_MODE) ? USB_ROLE_HOST : USB_ROLE_DEVICE;
-		if (role == USB_ROLE_HOST)
-			enable_vbus = true;
-		else
-			enable_vbus = false;
-	} else {
-		role = USB_ROLE_NONE;
-		enable_vbus = false;
-	}
-
-	qcom_pmic_typec_enable_vbus_regulator(qcom_usb, enable_vbus);
-	usb_role_switch_set_role(qcom_usb->role_sw, role);
-}
-
-static irqreturn_t qcom_pmic_typec_interrupt(int irq, void *_qcom_usb)
-{
-	struct qcom_pmic_typec *qcom_usb = _qcom_usb;
-
-	qcom_pmic_typec_check_connection(qcom_usb);
-	return IRQ_HANDLED;
-}
-
-static void qcom_pmic_typec_typec_hw_init(struct qcom_pmic_typec *qcom_usb,
-					  enum typec_port_type type)
-{
-	u8 mode = 0;
-
-	regmap_update_bits(qcom_usb->regmap,
-			   qcom_usb->base + TYPEC_INTR_EN_CFG_1,
-			   TYPEC_INTR_EN_CFG_1_MASK, 0);
-
-	if (type == TYPEC_PORT_SRC)
-		mode = EN_SRC_ONLY;
-	else if (type == TYPEC_PORT_SNK)
-		mode = EN_SNK_ONLY;
-
-	regmap_update_bits(qcom_usb->regmap, qcom_usb->base + TYPEC_MODE_CFG,
-			   EN_SNK_ONLY | EN_SRC_ONLY, mode);
-
-	regmap_update_bits(qcom_usb->regmap,
-			   qcom_usb->base + TYPEC_VCONN_CONTROL,
-			   VCONN_EN_SRC | VCONN_EN_VAL, VCONN_EN_SRC);
-	regmap_update_bits(qcom_usb->regmap,
-			   qcom_usb->base + TYPEC_EXIT_STATE_CFG,
-			   SEL_SRC_UPPER_REF, SEL_SRC_UPPER_REF);
-}
-
-static int qcom_pmic_typec_probe(struct platform_device *pdev)
-{
-	struct qcom_pmic_typec *qcom_usb;
-	struct device *dev = &pdev->dev;
-	struct fwnode_handle *fwnode;
-	struct typec_capability cap;
-	const char *buf;
-	int ret, irq, role;
-	u32 reg;
-
-	ret = device_property_read_u32(dev, "reg", &reg);
-	if (ret < 0) {
-		dev_err(dev, "missing base address\n");
-		return ret;
-	}
-
-	qcom_usb = devm_kzalloc(dev, sizeof(*qcom_usb), GFP_KERNEL);
-	if (!qcom_usb)
-		return -ENOMEM;
-
-	qcom_usb->dev = dev;
-	qcom_usb->base = reg;
-
-	qcom_usb->regmap = dev_get_regmap(dev->parent, NULL);
-	if (!qcom_usb->regmap) {
-		dev_err(dev, "Failed to get regmap\n");
-		return -EINVAL;
-	}
-
-	qcom_usb->vbus_reg = devm_regulator_get(qcom_usb->dev, "usb_vbus");
-	if (IS_ERR(qcom_usb->vbus_reg))
-		return PTR_ERR(qcom_usb->vbus_reg);
-
-	fwnode = device_get_named_child_node(dev, "connector");
-	if (!fwnode)
-		return -EINVAL;
-
-	ret = fwnode_property_read_string(fwnode, "power-role", &buf);
-	if (!ret) {
-		role = typec_find_port_power_role(buf);
-		if (role < 0)
-			role = TYPEC_PORT_SNK;
-	} else {
-		role = TYPEC_PORT_SNK;
-	}
-	cap.type = role;
-
-	ret = fwnode_property_read_string(fwnode, "data-role", &buf);
-	if (!ret) {
-		role = typec_find_port_data_role(buf);
-		if (role < 0)
-			role = TYPEC_PORT_UFP;
-	} else {
-		role = TYPEC_PORT_UFP;
-	}
-	cap.data = role;
-
-	cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
-	cap.fwnode = fwnode;
-	qcom_usb->port = typec_register_port(dev, &cap);
-	if (IS_ERR(qcom_usb->port)) {
-		ret = PTR_ERR(qcom_usb->port);
-		dev_err(dev, "Failed to register type c port %d\n", ret);
-		goto err_put_node;
-	}
-	fwnode_handle_put(fwnode);
-
-	qcom_usb->role_sw = fwnode_usb_role_switch_get(dev_fwnode(qcom_usb->dev));
-	if (IS_ERR(qcom_usb->role_sw)) {
-		ret = dev_err_probe(dev, PTR_ERR(qcom_usb->role_sw),
-				    "failed to get role switch\n");
-		goto err_typec_port;
-	}
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		goto err_usb_role_sw;
-
-	ret = devm_request_threaded_irq(qcom_usb->dev, irq, NULL,
-					qcom_pmic_typec_interrupt, IRQF_ONESHOT,
-					"qcom-pmic-typec", qcom_usb);
-	if (ret) {
-		dev_err(&pdev->dev, "Could not request IRQ\n");
-		goto err_usb_role_sw;
-	}
-
-	platform_set_drvdata(pdev, qcom_usb);
-	qcom_pmic_typec_typec_hw_init(qcom_usb, cap.type);
-	qcom_pmic_typec_check_connection(qcom_usb);
-
-	return 0;
-
-err_usb_role_sw:
-	usb_role_switch_put(qcom_usb->role_sw);
-err_typec_port:
-	typec_unregister_port(qcom_usb->port);
-err_put_node:
-	fwnode_handle_put(fwnode);
-
-	return ret;
-}
-
-static int qcom_pmic_typec_remove(struct platform_device *pdev)
-{
-	struct qcom_pmic_typec *qcom_usb = platform_get_drvdata(pdev);
-
-	usb_role_switch_set_role(qcom_usb->role_sw, USB_ROLE_NONE);
-	qcom_pmic_typec_enable_vbus_regulator(qcom_usb, 0);
-
-	typec_unregister_port(qcom_usb->port);
-	usb_role_switch_put(qcom_usb->role_sw);
-
-	return 0;
-}
-
-static const struct of_device_id qcom_pmic_typec_table[] = {
-	{ .compatible = "qcom,pm8150b-usb-typec" },
-	{ }
-};
-MODULE_DEVICE_TABLE(of, qcom_pmic_typec_table);
-
-static struct platform_driver qcom_pmic_typec = {
-	.driver = {
-		.name = "qcom,pmic-typec",
-		.of_match_table = qcom_pmic_typec_table,
-	},
-	.probe = qcom_pmic_typec_probe,
-	.remove = qcom_pmic_typec_remove,
-};
-module_platform_driver(qcom_pmic_typec);
-
-MODULE_DESCRIPTION("QCOM PMIC USB type C driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index e6b88ca4a4b94..5d393f520fc2f 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -76,4 +76,15 @@ config TYPEC_WCOVE
 	  To compile this driver as module, choose M here: the module will be
 	  called typec_wcove.ko
 
+config TYPEC_QCOM_PMIC
+	tristate "Qualcomm PMIC USB Type-C Port Controller Manager driver"
+	depends on ARCH_QCOM || COMPILE_TEST
+	help
+	  A Type-C port and Power Delivery driver which aggregates two
+	  discrete pieces of silicon in the PM8150b PMIC block: the
+	  Type-C port controller and the Power Delivery PHY.
+
+	  This driver enables Type-C role switching, orientation, Alternate
+	  mode and Power Delivery support both for VBUS and VCONN.
+
 endif # TYPEC_TCPM
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index 08e57bb499cbc..7a8cad0c0bdb4 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_TYPEC_MT6360)		+= tcpci_mt6360.o
 obj-$(CONFIG_TYPEC_TCPCI_MT6370)	+= tcpci_mt6370.o
 obj-$(CONFIG_TYPEC_TCPCI_MAXIM)		+= tcpci_maxim.o
 tcpci_maxim-y				+= tcpci_maxim_core.o maxim_contaminant.o
+obj-$(CONFIG_TYPEC_QCOM_PMIC)		+= qcom/
diff --git a/drivers/usb/typec/tcpm/qcom/Makefile b/drivers/usb/typec/tcpm/qcom/Makefile
new file mode 100644
index 0000000000000..e78458292e0cf
--- /dev/null
+++ b/drivers/usb/typec/tcpm/qcom/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+obj-$(CONFIG_TYPEC_QCOM_PMIC)		+= qcom_pmic_tcpm.o
+qcom_pmic_tcpm-y			+= qcom_pmic_virt_tcpm.o \
+					   qcom_pmic_typec.o \
+					   qcom_pmic_pdphy.o
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c
new file mode 100644
index 0000000000000..746f6a79fc315
--- /dev/null
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c
@@ -0,0 +1,605 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/usb/pd.h>
+#include <linux/usb/tcpm.h>
+#include <dt-bindings/usb/typec/qcom,pmic-pdphy.h>
+#include "qcom_pmic_pdphy.h"
+
+#define PMIC_PDPHY_MAX_IRQS		0x08
+
+struct pmic_pdphy_irq_params {
+	int				virq;
+	char				*irq_name;
+};
+
+struct pmic_pdphy_resources {
+	unsigned int			nr_irqs;
+	struct pmic_pdphy_irq_params	irq_params[PMIC_PDPHY_MAX_IRQS];
+};
+
+struct pmic_pdphy_irq_data {
+	int				virq;
+	int				irq;
+	struct pmic_pdphy		*pmic_pdphy;
+};
+
+struct pmic_pdphy {
+	struct device			*dev;
+	struct tcpm_port		*tcpm_port;
+	struct regmap			*regmap;
+	u32				base;
+
+	unsigned int			nr_irqs;
+	struct pmic_pdphy_irq_data	*irq_data;
+
+	struct work_struct		reset_work;
+	struct work_struct		receive_work;
+	struct regulator		*vdd_pdphy;
+	spinlock_t			lock;		/* Register atomicity */
+};
+
+static void qcom_pmic_pdphy_reset_on(struct pmic_pdphy *pmic_pdphy)
+{
+	struct device *dev = pmic_pdphy->dev;
+	int ret;
+
+	/* Terminate TX */
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, 0);
+	if (ret)
+		goto err;
+
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_FRAME_FILTER_REG, 0);
+	if (ret)
+		goto err;
+
+	return;
+err:
+	dev_err(dev, "pd_reset_on error\n");
+}
+
+static void qcom_pmic_pdphy_reset_off(struct pmic_pdphy *pmic_pdphy)
+{
+	struct device *dev = pmic_pdphy->dev;
+	int ret;
+
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_FRAME_FILTER_REG,
+			   FRAME_FILTER_EN_SOP | FRAME_FILTER_EN_HARD_RESET);
+	if (ret)
+		dev_err(dev, "pd_reset_off error\n");
+}
+
+static void qcom_pmic_pdphy_sig_reset_work(struct work_struct *work)
+{
+	struct pmic_pdphy *pmic_pdphy = container_of(work, struct pmic_pdphy,
+						     reset_work);
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmic_pdphy->lock, flags);
+
+	qcom_pmic_pdphy_reset_on(pmic_pdphy);
+	qcom_pmic_pdphy_reset_off(pmic_pdphy);
+
+	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
+
+	tcpm_pd_hard_reset(pmic_pdphy->tcpm_port);
+}
+
+static int
+qcom_pmic_pdphy_clear_tx_control_reg(struct pmic_pdphy *pmic_pdphy)
+{
+	struct device *dev = pmic_pdphy->dev;
+	unsigned int val;
+	int ret;
+
+	/* Clear TX control register */
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, 0);
+	if (ret)
+		goto done;
+
+	/* Perform readback to ensure sufficient delay for command to latch */
+	ret = regmap_read(pmic_pdphy->regmap,
+			  pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, &val);
+
+done:
+	if (ret)
+		dev_err(dev, "pd_clear_tx_control_reg: clear tx flag\n");
+
+	return ret;
+}
+
+static int
+qcom_pmic_pdphy_pd_transmit_signal(struct pmic_pdphy *pmic_pdphy,
+				   enum tcpm_transmit_type type,
+				   unsigned int negotiated_rev)
+{
+	struct device *dev = pmic_pdphy->dev;
+	unsigned int val;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pmic_pdphy->lock, flags);
+
+	/* Clear TX control register */
+	ret = qcom_pmic_pdphy_clear_tx_control_reg(pmic_pdphy);
+	if (ret)
+		goto done;
+
+	val = TX_CONTROL_SEND_SIGNAL;
+	if (negotiated_rev == PD_REV30)
+		val |= TX_CONTROL_RETRY_COUNT(2);
+	else
+		val |= TX_CONTROL_RETRY_COUNT(3);
+
+	if (type == TCPC_TX_CABLE_RESET || type == TCPC_TX_HARD_RESET)
+		val |= TX_CONTROL_FRAME_TYPE(1);
+
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, val);
+
+done:
+	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
+
+	dev_vdbg(dev, "pd_transmit_signal: type %d negotiate_rev %d send %d\n",
+		 type, negotiated_rev, ret);
+
+	return ret;
+}
+
+static int
+qcom_pmic_pdphy_pd_transmit_payload(struct pmic_pdphy *pmic_pdphy,
+				    enum tcpm_transmit_type type,
+				    const struct pd_message *msg,
+				    unsigned int negotiated_rev)
+{
+	struct device *dev = pmic_pdphy->dev;
+	unsigned int val, hdr_len, txbuf_len, txsize_len;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pmic_pdphy->lock, flags);
+
+	ret = regmap_read(pmic_pdphy->regmap,
+			  pmic_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG,
+			  &val);
+	if (ret)
+		goto done;
+
+	if (val) {
+		dev_err(dev, "pd_transmit_payload: RX message pending\n");
+		ret = -EBUSY;
+		goto done;
+	}
+
+	/* Clear TX control register */
+	ret = qcom_pmic_pdphy_clear_tx_control_reg(pmic_pdphy);
+	if (ret)
+		goto done;
+
+	hdr_len = sizeof(msg->header);
+	txbuf_len = pd_header_cnt_le(msg->header) * 4;
+	txsize_len = hdr_len + txbuf_len - 1;
+
+	/* Write message header sizeof(u16) to USB_PDPHY_TX_BUFFER_HDR_REG */
+	ret = regmap_bulk_write(pmic_pdphy->regmap,
+				pmic_pdphy->base + USB_PDPHY_TX_BUFFER_HDR_REG,
+				&msg->header, hdr_len);
+	if (ret)
+		goto done;
+
+	/* Write payload to USB_PDPHY_TX_BUFFER_DATA_REG for txbuf_len */
+	if (txbuf_len) {
+		ret = regmap_bulk_write(pmic_pdphy->regmap,
+					pmic_pdphy->base + USB_PDPHY_TX_BUFFER_DATA_REG,
+					&msg->payload, txbuf_len);
+		if (ret)
+			goto done;
+	}
+
+	/* Write total length ((header + data) - 1) to USB_PDPHY_TX_SIZE_REG */
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_TX_SIZE_REG,
+			   txsize_len);
+	if (ret)
+		goto done;
+
+	/* Clear TX control register */
+	ret = qcom_pmic_pdphy_clear_tx_control_reg(pmic_pdphy);
+	if (ret)
+		goto done;
+
+	/* Initiate transmit with retry count as indicated by PD revision */
+	val = TX_CONTROL_FRAME_TYPE(type) | TX_CONTROL_SEND_MSG;
+	if (pd_header_rev(msg->header) == PD_REV30)
+		val |= TX_CONTROL_RETRY_COUNT(2);
+	else
+		val |= TX_CONTROL_RETRY_COUNT(3);
+
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, val);
+
+done:
+	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
+
+	if (ret) {
+		dev_err(dev, "pd_transmit_payload: %d hdr %*ph data %*ph ret %d\n",
+			ret, hdr_len, &msg->header, txbuf_len, &msg->payload, ret);
+	}
+
+	return ret;
+}
+
+int qcom_pmic_pdphy_pd_transmit(struct pmic_pdphy *pmic_pdphy,
+				enum tcpm_transmit_type type,
+				const struct pd_message *msg,
+				unsigned int negotiated_rev)
+{
+	struct device *dev = pmic_pdphy->dev;
+	int ret;
+
+	if (msg) {
+		ret = qcom_pmic_pdphy_pd_transmit_payload(pmic_pdphy, type, msg,
+							  negotiated_rev);
+	} else {
+		ret = qcom_pmic_pdphy_pd_transmit_signal(pmic_pdphy, type,
+							 negotiated_rev);
+	}
+
+	if (ret)
+		dev_dbg(dev, "pd_transmit: type %x result %d\n", type, ret);
+
+	return ret;
+}
+
+static void qcom_pmic_pdphy_pd_receive(struct pmic_pdphy *pmic_pdphy)
+{
+	struct device *dev = pmic_pdphy->dev;
+	struct pd_message msg;
+	unsigned int size, rx_status;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pmic_pdphy->lock, flags);
+
+	ret = regmap_read(pmic_pdphy->regmap,
+			  pmic_pdphy->base + USB_PDPHY_RX_SIZE_REG, &size);
+	if (ret)
+		goto done;
+
+	/* If we received a subsequent RX sig this value can be zero */
+	if ((size < 1 || size > sizeof(msg.payload))) {
+		dev_dbg(dev, "pd_receive: invalid size %d\n", size);
+		goto done;
+	}
+
+	size += 1;
+	ret = regmap_read(pmic_pdphy->regmap,
+			  pmic_pdphy->base + USB_PDPHY_RX_STATUS_REG,
+			  &rx_status);
+
+	if (ret)
+		goto done;
+
+	ret = regmap_bulk_read(pmic_pdphy->regmap,
+			       pmic_pdphy->base + USB_PDPHY_RX_BUFFER_REG,
+			       (u8 *)&msg, size);
+	if (ret)
+		goto done;
+
+	/* Return ownership of RX buffer to hardware */
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG, 0);
+
+done:
+	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
+
+	if (!ret) {
+		dev_vdbg(dev, "pd_receive: handing %d bytes to tcpm\n", size);
+		tcpm_pd_receive(pmic_pdphy->tcpm_port, &msg);
+	}
+}
+
+static irqreturn_t qcom_pmic_pdphy_isr(int irq, void *dev_id)
+{
+	struct pmic_pdphy_irq_data *irq_data = dev_id;
+	struct pmic_pdphy *pmic_pdphy = irq_data->pmic_pdphy;
+	struct device *dev = pmic_pdphy->dev;
+
+	switch (irq_data->virq) {
+	case PMIC_PDPHY_SIG_TX_IRQ:
+		dev_err(dev, "isr: tx_sig\n");
+		break;
+	case PMIC_PDPHY_SIG_RX_IRQ:
+		schedule_work(&pmic_pdphy->reset_work);
+		break;
+	case PMIC_PDPHY_MSG_TX_IRQ:
+		tcpm_pd_transmit_complete(pmic_pdphy->tcpm_port,
+					  TCPC_TX_SUCCESS);
+		break;
+	case PMIC_PDPHY_MSG_RX_IRQ:
+		qcom_pmic_pdphy_pd_receive(pmic_pdphy);
+		break;
+	case PMIC_PDPHY_MSG_TX_FAIL_IRQ:
+		tcpm_pd_transmit_complete(pmic_pdphy->tcpm_port,
+					  TCPC_TX_FAILED);
+		break;
+	case PMIC_PDPHY_MSG_TX_DISCARD_IRQ:
+		tcpm_pd_transmit_complete(pmic_pdphy->tcpm_port,
+					  TCPC_TX_DISCARDED);
+		break;
+	}
+
+	return IRQ_HANDLED;
+}
+
+int qcom_pmic_pdphy_set_pd_rx(struct pmic_pdphy *pmic_pdphy, bool on)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pmic_pdphy->lock, flags);
+
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG, !on);
+
+	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
+
+	dev_dbg(pmic_pdphy->dev, "set_pd_rx: %s\n", on ? "on" : "off");
+
+	return ret;
+}
+
+int qcom_pmic_pdphy_set_roles(struct pmic_pdphy *pmic_pdphy,
+			      bool data_role_host, bool power_role_src)
+{
+	struct device *dev = pmic_pdphy->dev;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pmic_pdphy->lock, flags);
+
+	ret = regmap_update_bits(pmic_pdphy->regmap,
+				 pmic_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
+				 MSG_CONFIG_PORT_DATA_ROLE |
+				 MSG_CONFIG_PORT_POWER_ROLE,
+				 data_role_host << 3 | power_role_src << 2);
+
+	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
+
+	dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
+		data_role_host, power_role_src);
+
+	return ret;
+}
+
+static int qcom_pmic_pdphy_enable(struct pmic_pdphy *pmic_pdphy)
+{
+	struct device *dev = pmic_pdphy->dev;
+	int ret;
+
+	ret = regulator_enable(pmic_pdphy->vdd_pdphy);
+	if (ret)
+		return ret;
+
+	/* PD 2.0, DR=TYPEC_DEVICE, PR=TYPEC_SINK */
+	ret = regmap_update_bits(pmic_pdphy->regmap,
+				 pmic_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
+				 MSG_CONFIG_SPEC_REV_MASK, PD_REV20);
+	if (ret)
+		goto done;
+
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_EN_CONTROL_REG, 0);
+	if (ret)
+		goto done;
+
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_EN_CONTROL_REG,
+			   CONTROL_ENABLE);
+	if (ret)
+		goto done;
+
+	qcom_pmic_pdphy_reset_off(pmic_pdphy);
+done:
+	if (ret) {
+		regulator_disable(pmic_pdphy->vdd_pdphy);
+		dev_err(dev, "pdphy_enable fail %d\n", ret);
+	}
+
+	return ret;
+}
+
+static int qcom_pmic_pdphy_disable(struct pmic_pdphy *pmic_pdphy)
+{
+	int ret;
+
+	qcom_pmic_pdphy_reset_on(pmic_pdphy);
+
+	ret = regmap_write(pmic_pdphy->regmap,
+			   pmic_pdphy->base + USB_PDPHY_EN_CONTROL_REG, 0);
+
+	regulator_disable(pmic_pdphy->vdd_pdphy);
+
+	return ret;
+}
+
+static int pmic_pdphy_reset(struct pmic_pdphy *pmic_pdphy)
+{
+	int ret;
+
+	ret = qcom_pmic_pdphy_disable(pmic_pdphy);
+	if (ret)
+		goto done;
+
+	usleep_range(400, 500);
+	ret = qcom_pmic_pdphy_enable(pmic_pdphy);
+done:
+	return ret;
+}
+
+int qcom_pmic_pdphy_init(struct pmic_pdphy *pmic_pdphy,
+			 struct tcpm_port *tcpm_port)
+{
+	int i;
+	int ret;
+
+	pmic_pdphy->tcpm_port = tcpm_port;
+
+	ret = pmic_pdphy_reset(pmic_pdphy);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < pmic_pdphy->nr_irqs; i++)
+		enable_irq(pmic_pdphy->irq_data[i].irq);
+
+	return 0;
+}
+
+void qcom_pmic_pdphy_put(struct pmic_pdphy *pmic_pdphy)
+{
+	put_device(pmic_pdphy->dev);
+}
+
+static int qcom_pmic_pdphy_probe(struct platform_device *pdev)
+{
+	struct pmic_pdphy *pmic_pdphy;
+	struct device *dev = &pdev->dev;
+	const struct pmic_pdphy_resources *res;
+	struct pmic_pdphy_irq_data *irq_data;
+	int i, ret, irq;
+	u32 reg;
+
+	ret = device_property_read_u32(dev, "reg", &reg);
+	if (ret < 0) {
+		dev_err(dev, "missing base address\n");
+		return ret;
+	}
+
+	res = of_device_get_match_data(dev);
+	if (!res)
+		return -ENODEV;
+
+	if (!res->nr_irqs || res->nr_irqs > PMIC_PDPHY_MAX_IRQS)
+		return -EINVAL;
+
+	pmic_pdphy = devm_kzalloc(dev, sizeof(*pmic_pdphy), GFP_KERNEL);
+	if (!pmic_pdphy)
+		return -ENOMEM;
+
+	irq_data = devm_kzalloc(dev, sizeof(*irq_data) * res->nr_irqs,
+				GFP_KERNEL);
+	if (!irq_data)
+		return -ENOMEM;
+
+	pmic_pdphy->vdd_pdphy = devm_regulator_get(dev, "vdd-pdphy");
+	if (IS_ERR(pmic_pdphy->vdd_pdphy))
+		return PTR_ERR(pmic_pdphy->vdd_pdphy);
+
+	pmic_pdphy->dev = dev;
+	pmic_pdphy->base = reg;
+	pmic_pdphy->nr_irqs = res->nr_irqs;
+	pmic_pdphy->irq_data = irq_data;
+	spin_lock_init(&pmic_pdphy->lock);
+	INIT_WORK(&pmic_pdphy->reset_work, qcom_pmic_pdphy_sig_reset_work);
+
+	pmic_pdphy->regmap = dev_get_regmap(dev->parent, NULL);
+	if (!pmic_pdphy->regmap) {
+		dev_err(dev, "Failed to get regmap\n");
+		return -ENODEV;
+	}
+
+	platform_set_drvdata(pdev, pmic_pdphy);
+	for (i = 0; i < res->nr_irqs; i++, irq_data++) {
+		irq = platform_get_irq_byname(pdev, res->irq_params[i].irq_name);
+		if (irq < 0)
+			return irq;
+
+		irq_data->pmic_pdphy = pmic_pdphy;
+		irq_data->irq = irq;
+		irq_data->virq = res->irq_params[i].virq;
+
+		ret = devm_request_threaded_irq(dev, irq, NULL,
+						qcom_pmic_pdphy_isr,
+						IRQF_ONESHOT | IRQF_NO_AUTOEN,
+						res->irq_params[i].irq_name,
+						irq_data);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static int qcom_pmic_pdphy_remove(struct platform_device *pdev)
+{
+	struct pmic_pdphy *pmic_pdphy = platform_get_drvdata(pdev);
+
+	qcom_pmic_pdphy_reset_on(pmic_pdphy);
+
+	return 0;
+}
+
+static struct pmic_pdphy_resources pm8150b_pdphy_res = {
+	.irq_params = {
+		{
+			.virq = PMIC_PDPHY_SIG_TX_IRQ,
+			.irq_name = "sig-tx",
+		},
+		{
+			.virq = PMIC_PDPHY_SIG_RX_IRQ,
+			.irq_name = "sig-rx",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_TX_IRQ,
+			.irq_name = "msg-tx",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_RX_IRQ,
+			.irq_name = "msg-rx",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
+			.irq_name = "msg-tx-failed",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
+			.irq_name = "msg-tx-discarded",
+		},
+		{
+			.virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
+			.irq_name = "msg-rx-discarded",
+		},
+	},
+	.nr_irqs = 7,
+};
+
+static const struct of_device_id qcom_pmic_pdphy_table[] = {
+	{ .compatible = "qcom,pm8150b-pdphy", .data = &pm8150b_pdphy_res },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, qcom_pmic_pdphy_table);
+
+struct platform_driver qcom_pmic_pdphy_platform_driver = {
+	.driver = {
+		.name = "qcom,pmic-usb-pdphy",
+		.of_match_table = qcom_pmic_pdphy_table,
+	},
+	.probe = qcom_pmic_pdphy_probe,
+	.remove = qcom_pmic_pdphy_remove,
+};
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h
new file mode 100644
index 0000000000000..ac64139d4fe93
--- /dev/null
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
+ */
+#ifndef __QCOM_PMIC_PDPHY_H__
+#define __QCOM_PMIC_PDPHY_H__
+
+#define USB_PDPHY_MAX_DATA_OBJ_LEN	28
+#define USB_PDPHY_MSG_HDR_LEN		2
+
+/* PD PHY register offsets and bit fields */
+#define USB_PDPHY_MSG_CONFIG_REG	0x40
+#define MSG_CONFIG_PORT_DATA_ROLE	BIT(3)
+#define MSG_CONFIG_PORT_POWER_ROLE	BIT(2)
+#define MSG_CONFIG_SPEC_REV_MASK	(BIT(1) | BIT(0))
+
+#define USB_PDPHY_EN_CONTROL_REG	0x46
+#define CONTROL_ENABLE			BIT(0)
+
+#define USB_PDPHY_RX_STATUS_REG		0x4A
+#define RX_FRAME_TYPE			(BIT(0) | BIT(1) | BIT(2))
+
+#define USB_PDPHY_FRAME_FILTER_REG	0x4C
+#define FRAME_FILTER_EN_HARD_RESET	BIT(5)
+#define FRAME_FILTER_EN_SOP		BIT(0)
+
+#define USB_PDPHY_TX_SIZE_REG		0x42
+#define TX_SIZE_MASK			0xF
+
+#define USB_PDPHY_TX_CONTROL_REG	0x44
+#define TX_CONTROL_RETRY_COUNT(n)	(((n) & 0x3) << 5)
+#define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
+#define TX_CONTROL_FRAME_TYPE_CABLE_RESET	(0x1 << 2)
+#define TX_CONTROL_SEND_SIGNAL		BIT(1)
+#define TX_CONTROL_SEND_MSG		BIT(0)
+
+#define USB_PDPHY_RX_SIZE_REG		0x48
+
+#define USB_PDPHY_RX_ACKNOWLEDGE_REG	0x4B
+#define RX_BUFFER_TOKEN			BIT(0)
+
+#define USB_PDPHY_BIST_MODE_REG		0x4E
+#define BIST_MODE_MASK			0xF
+#define BIST_ENABLE			BIT(7)
+#define PD_MSG_BIST			0x3
+#define PD_BIST_TEST_DATA_MODE		0x8
+
+#define USB_PDPHY_TX_BUFFER_HDR_REG	0x60
+#define USB_PDPHY_TX_BUFFER_DATA_REG	0x62
+
+#define USB_PDPHY_RX_BUFFER_REG		0x80
+
+/* VDD regulator */
+#define VDD_PDPHY_VOL_MIN		2800000	/* uV */
+#define VDD_PDPHY_VOL_MAX		3300000	/* uV */
+#define VDD_PDPHY_HPM_LOAD		3000	/* uA */
+
+/* Message Spec Rev field */
+#define PD_MSG_HDR_REV(hdr)		(((hdr) >> 6) & 3)
+
+/* timers */
+#define RECEIVER_RESPONSE_TIME		15	/* tReceiverResponse */
+#define HARD_RESET_COMPLETE_TIME	5	/* tHardResetComplete */
+
+struct pmic_pdphy;
+extern struct platform_driver qcom_pmic_pdphy_platform_driver;
+
+int qcom_pmic_pdphy_init(struct pmic_pdphy *pmic_pdphy,
+			 struct tcpm_port *tcpm_port);
+
+void qcom_pmic_pdphy_put(struct pmic_pdphy *pmic_pdphy);
+
+int qcom_pmic_pdphy_set_roles(struct pmic_pdphy *pmic_pdphy,
+			      bool power_role_src,
+			      bool data_role_host);
+
+int qcom_pmic_pdphy_set_pd_rx(struct pmic_pdphy *pmic_pdphy, bool on);
+
+int qcom_pmic_pdphy_pd_transmit(struct pmic_pdphy *pmic_pdphy,
+				enum tcpm_transmit_type type,
+				const struct pd_message *msg,
+				unsigned int negotiated_rev);
+
+#endif /* __QCOM_PMIC_PDPHY_H__ */
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
new file mode 100644
index 0000000000000..7b6f6100af949
--- /dev/null
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
@@ -0,0 +1,637 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/usb/tcpm.h>
+#include <linux/usb/typec_mux.h>
+#include <linux/workqueue.h>
+#include <dt-bindings/usb/typec/qcom,pmic-typec.h>
+#include "qcom_pmic_typec.h"
+
+#define PMIC_TYPEC_MAX_IRQS		0x08
+
+struct pmic_typec_irq_params {
+	int				virq;
+	char				*irq_name;
+};
+
+struct pmic_typec_resources {
+	unsigned int			nr_irqs;
+	struct pmic_typec_irq_params	irq_params[PMIC_TYPEC_MAX_IRQS];
+};
+
+struct pmic_typec_irq_data {
+	int				virq;
+	int				irq;
+	struct pmic_typec		*pmic_typec;
+};
+
+struct pmic_typec {
+	struct device			*dev;
+	struct tcpm_port		*tcpm_port;
+	struct regmap			*regmap;
+	u32				base;
+	unsigned int			nr_irqs;
+	struct pmic_typec_irq_data	*irq_data;
+
+	struct regulator		*vdd_vbus;
+
+	int				cc;
+	bool				debouncing_cc;
+	struct delayed_work		cc_debounce_dwork;
+
+	spinlock_t			lock;	/* Register atomicity */
+};
+
+static const char * const typec_cc_status_name[] = {
+	[TYPEC_CC_OPEN]		= "Open",
+	[TYPEC_CC_RA]		= "Ra",
+	[TYPEC_CC_RD]		= "Rd",
+	[TYPEC_CC_RP_DEF]	= "Rp-def",
+	[TYPEC_CC_RP_1_5]	= "Rp-1.5",
+	[TYPEC_CC_RP_3_0]	= "Rp-3.0",
+};
+
+static const char *rp_unknown = "unknown";
+
+static const char *cc_to_name(enum typec_cc_status cc)
+{
+	if (cc > TYPEC_CC_RP_3_0)
+		return rp_unknown;
+
+	return typec_cc_status_name[cc];
+}
+
+static const char * const rp_sel_name[] = {
+	[TYPEC_SRC_RP_SEL_80UA]		= "Rp-def-80uA",
+	[TYPEC_SRC_RP_SEL_180UA]	= "Rp-1.5-180uA",
+	[TYPEC_SRC_RP_SEL_330UA]	= "Rp-3.0-330uA",
+};
+
+static const char *rp_sel_to_name(int rp_sel)
+{
+	if (rp_sel > TYPEC_SRC_RP_SEL_330UA)
+		return rp_unknown;
+
+	return rp_sel_name[rp_sel];
+}
+
+#define misc_to_cc(msic) !!(misc & CC_ORIENTATION) ? "cc1" : "cc2"
+#define misc_to_vconn(msic) !!(misc & CC_ORIENTATION) ? "cc2" : "cc1"
+
+static void qcom_pmic_typec_cc_debounce(struct work_struct *work)
+{
+	struct pmic_typec *pmic_typec =
+		container_of(work, struct pmic_typec, cc_debounce_dwork.work);
+	unsigned long flags;
+
+	spin_lock_irqsave(&pmic_typec->lock, flags);
+	pmic_typec->debouncing_cc = false;
+	spin_unlock_irqrestore(&pmic_typec->lock, flags);
+
+	dev_dbg(pmic_typec->dev, "Debounce cc complete\n");
+}
+
+static irqreturn_t pmic_typec_isr(int irq, void *dev_id)
+{
+	struct pmic_typec_irq_data *irq_data = dev_id;
+	struct pmic_typec *pmic_typec = irq_data->pmic_typec;
+	u32 misc_stat;
+	bool vbus_change = false;
+	bool cc_change = false;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pmic_typec->lock, flags);
+
+	ret = regmap_read(pmic_typec->regmap,
+			  pmic_typec->base + TYPEC_MISC_STATUS_REG,
+			  &misc_stat);
+	if (ret)
+		goto done;
+
+	switch (irq_data->virq) {
+	case PMIC_TYPEC_VBUS_IRQ:
+		/* Incoming vbus assert/de-assert detect */
+		vbus_change = true;
+		break;
+	case PMIC_TYPEC_CC_STATE_IRQ:
+		if (!pmic_typec->debouncing_cc)
+			cc_change = true;
+		break;
+	case PMIC_TYPEC_ATTACH_DETACH_IRQ:
+		if (!pmic_typec->debouncing_cc)
+			cc_change = true;
+		break;
+	}
+
+done:
+	spin_unlock_irqrestore(&pmic_typec->lock, flags);
+
+	if (vbus_change)
+		tcpm_vbus_change(pmic_typec->tcpm_port);
+
+	if (cc_change)
+		tcpm_cc_change(pmic_typec->tcpm_port);
+
+	return IRQ_HANDLED;
+}
+
+int qcom_pmic_typec_get_vbus(struct pmic_typec *pmic_typec)
+{
+	struct device *dev = pmic_typec->dev;
+	unsigned int misc;
+	int ret;
+
+	ret = regmap_read(pmic_typec->regmap,
+			  pmic_typec->base + TYPEC_MISC_STATUS_REG,
+			  &misc);
+	if (ret)
+		misc = 0;
+
+	dev_dbg(dev, "get_vbus: 0x%08x detect %d\n", misc, !!(misc & TYPEC_VBUS_DETECT));
+
+	return !!(misc & TYPEC_VBUS_DETECT);
+}
+
+int qcom_pmic_typec_set_vbus(struct pmic_typec *pmic_typec, bool on)
+{
+	u32 sm_stat;
+	u32 val;
+	int ret;
+
+	if (on) {
+		ret = regulator_enable(pmic_typec->vdd_vbus);
+		if (ret)
+			return ret;
+
+		val = TYPEC_SM_VBUS_VSAFE5V;
+	} else {
+		ret = regulator_disable(pmic_typec->vdd_vbus);
+		if (ret)
+			return ret;
+
+		val = TYPEC_SM_VBUS_VSAFE0V;
+	}
+
+	/* Poll waiting for transition to required vSafe5V or vSafe0V */
+	ret = regmap_read_poll_timeout(pmic_typec->regmap,
+				       pmic_typec->base + TYPEC_SM_STATUS_REG,
+				       sm_stat, sm_stat & val,
+				       100, 250000);
+	if (ret)
+		dev_err(pmic_typec->dev, "vbus vsafe%dv fail\n", on ? 5 : 0);
+
+	return ret;
+}
+
+int qcom_pmic_typec_get_cc(struct pmic_typec *pmic_typec,
+			   enum typec_cc_status *cc1,
+			   enum typec_cc_status *cc2)
+{
+	struct device *dev = pmic_typec->dev;
+	unsigned int misc, val;
+	bool attached;
+	int ret = 0;
+
+	ret = regmap_read(pmic_typec->regmap,
+			  pmic_typec->base + TYPEC_MISC_STATUS_REG, &misc);
+	if (ret)
+		goto done;
+
+	attached = !!(misc & CC_ATTACHED);
+
+	if (pmic_typec->debouncing_cc) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	*cc1 = TYPEC_CC_OPEN;
+	*cc2 = TYPEC_CC_OPEN;
+
+	if (!(attached))
+		goto done;
+
+	if (misc & SNK_SRC_MODE) {
+		ret = regmap_read(pmic_typec->regmap,
+				  pmic_typec->base + TYPEC_SRC_STATUS_REG,
+				  &val);
+		if (ret)
+			goto done;
+		switch (val & DETECTED_SRC_TYPE_MASK) {
+		case SRC_RD_OPEN:
+			val = TYPEC_CC_RD;
+			break;
+		case SRC_RD_RA_VCONN:
+			val = TYPEC_CC_RD;
+			*cc1 = TYPEC_CC_RA;
+			*cc2 = TYPEC_CC_RA;
+			break;
+		default:
+			dev_warn(dev, "unexpected src status %.2x\n", val);
+			val = TYPEC_CC_RD;
+			break;
+		}
+	} else {
+		ret = regmap_read(pmic_typec->regmap,
+				  pmic_typec->base + TYPEC_SNK_STATUS_REG,
+				  &val);
+		if (ret)
+			goto done;
+		switch (val & DETECTED_SNK_TYPE_MASK) {
+		case SNK_RP_STD:
+			val = TYPEC_CC_RP_DEF;
+			break;
+		case SNK_RP_1P5:
+			val = TYPEC_CC_RP_1_5;
+			break;
+		case SNK_RP_3P0:
+			val = TYPEC_CC_RP_3_0;
+			break;
+		default:
+			dev_warn(dev, "unexpected snk status %.2x\n", val);
+			val = TYPEC_CC_RP_DEF;
+			break;
+		}
+		val = TYPEC_CC_RP_DEF;
+	}
+
+	if (misc & CC_ORIENTATION)
+		*cc2 = val;
+	else
+		*cc1 = val;
+
+done:
+	dev_dbg(dev, "get_cc: misc 0x%08x cc1 0x%08x %s cc2 0x%08x %s attached %d cc=%s\n",
+		misc, *cc1, cc_to_name(*cc1), *cc2, cc_to_name(*cc2), attached,
+		misc_to_cc(misc));
+
+	return ret;
+}
+
+static void qcom_pmic_set_cc_debounce(struct pmic_typec *pmic_typec)
+{
+	pmic_typec->debouncing_cc = true;
+	schedule_delayed_work(&pmic_typec->cc_debounce_dwork,
+			      msecs_to_jiffies(2));
+}
+
+int qcom_pmic_typec_set_cc(struct pmic_typec *pmic_typec,
+			   enum typec_cc_status cc)
+{
+	struct device *dev = pmic_typec->dev;
+	unsigned int mode, currsrc;
+	unsigned int misc;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pmic_typec->lock, flags);
+
+	ret = regmap_read(pmic_typec->regmap,
+			  pmic_typec->base + TYPEC_MISC_STATUS_REG,
+			  &misc);
+	if (ret)
+		goto done;
+
+	mode = EN_SRC_ONLY;
+
+	switch (cc) {
+	case TYPEC_CC_OPEN:
+		currsrc = TYPEC_SRC_RP_SEL_80UA;
+		break;
+	case TYPEC_CC_RP_DEF:
+		currsrc = TYPEC_SRC_RP_SEL_80UA;
+		break;
+	case TYPEC_CC_RP_1_5:
+		currsrc = TYPEC_SRC_RP_SEL_180UA;
+		break;
+	case TYPEC_CC_RP_3_0:
+		currsrc = TYPEC_SRC_RP_SEL_330UA;
+		break;
+	case TYPEC_CC_RD:
+		currsrc = TYPEC_SRC_RP_SEL_80UA;
+		mode = EN_SNK_ONLY;
+		break;
+	default:
+		dev_warn(dev, "unexpected set_cc %d\n", cc);
+		ret = -EINVAL;
+		goto done;
+	}
+
+	if (mode == EN_SRC_ONLY) {
+		ret = regmap_write(pmic_typec->regmap,
+				   pmic_typec->base + TYPEC_CURRSRC_CFG_REG,
+				   currsrc);
+		if (ret)
+			goto done;
+	}
+
+	pmic_typec->cc = cc;
+	qcom_pmic_set_cc_debounce(pmic_typec);
+	ret = 0;
+
+done:
+	spin_unlock_irqrestore(&pmic_typec->lock, flags);
+
+	dev_dbg(dev, "set_cc: currsrc=%x %s mode %s debounce %d attached %d cc=%s\n",
+		currsrc, rp_sel_to_name(currsrc),
+		mode == EN_SRC_ONLY ? "EN_SRC_ONLY" : "EN_SNK_ONLY",
+		pmic_typec->debouncing_cc, !!(misc & CC_ATTACHED),
+		misc_to_cc(misc));
+
+	return ret;
+}
+
+int qcom_pmic_typec_set_vconn(struct pmic_typec *pmic_typec, bool on)
+{
+	struct device *dev = pmic_typec->dev;
+	unsigned int orientation, misc, mask, value;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pmic_typec->lock, flags);
+
+	ret = regmap_read(pmic_typec->regmap,
+			  pmic_typec->base + TYPEC_MISC_STATUS_REG, &misc);
+	if (ret)
+		goto done;
+
+	/* Set VCONN on the inversion of the active CC channel */
+	orientation = (misc & CC_ORIENTATION) ? 0 : VCONN_EN_ORIENTATION;
+	if (on) {
+		mask = VCONN_EN_ORIENTATION | VCONN_EN_VALUE;
+		value = orientation | VCONN_EN_VALUE | VCONN_EN_SRC;
+	} else {
+		mask = VCONN_EN_VALUE;
+		value = 0;
+	}
+
+	ret = regmap_update_bits(pmic_typec->regmap,
+				 pmic_typec->base + TYPEC_VCONN_CONTROL_REG,
+				 mask, value);
+done:
+	spin_unlock_irqrestore(&pmic_typec->lock, flags);
+
+	dev_dbg(dev, "set_vconn: orientation %d control 0x%08x state %s cc %s vconn %s\n",
+		orientation, value, on ? "on" : "off", misc_to_vconn(misc), misc_to_cc(misc));
+
+	return ret;
+}
+
+int qcom_pmic_typec_start_toggling(struct pmic_typec *pmic_typec,
+				   enum typec_port_type port_type,
+				   enum typec_cc_status cc)
+{
+	struct device *dev = pmic_typec->dev;
+	unsigned int misc;
+	u8 mode = 0;
+	unsigned long flags;
+	int ret;
+
+	switch (port_type) {
+	case TYPEC_PORT_SRC:
+		mode = EN_SRC_ONLY;
+		break;
+	case TYPEC_PORT_SNK:
+		mode = EN_SNK_ONLY;
+		break;
+	case TYPEC_PORT_DRP:
+		mode = EN_TRY_SNK;
+		break;
+	}
+
+	spin_lock_irqsave(&pmic_typec->lock, flags);
+
+	ret = regmap_read(pmic_typec->regmap,
+			  pmic_typec->base + TYPEC_MISC_STATUS_REG, &misc);
+	if (ret)
+		goto done;
+
+	dev_dbg(dev, "start_toggling: misc 0x%08x attached %d port_type %d current cc %d new %d\n",
+		misc, !!(misc & CC_ATTACHED), port_type, pmic_typec->cc, cc);
+
+	qcom_pmic_set_cc_debounce(pmic_typec);
+
+	/* force it to toggle at least once */
+	ret = regmap_write(pmic_typec->regmap,
+			   pmic_typec->base + TYPEC_MODE_CFG_REG,
+			   TYPEC_DISABLE_CMD);
+	if (ret)
+		goto done;
+
+	ret = regmap_write(pmic_typec->regmap,
+			   pmic_typec->base + TYPEC_MODE_CFG_REG,
+			   mode);
+done:
+	spin_unlock_irqrestore(&pmic_typec->lock, flags);
+
+	return ret;
+}
+
+#define TYPEC_INTR_EN_CFG_1_MASK		  \
+	(TYPEC_LEGACY_CABLE_INT_EN		| \
+	 TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN	| \
+	 TYPEC_TRYSOURCE_DETECT_INT_EN		| \
+	 TYPEC_TRYSINK_DETECT_INT_EN		| \
+	 TYPEC_CCOUT_DETACH_INT_EN		| \
+	 TYPEC_CCOUT_ATTACH_INT_EN		| \
+	 TYPEC_VBUS_DEASSERT_INT_EN		| \
+	 TYPEC_VBUS_ASSERT_INT_EN)
+
+#define TYPEC_INTR_EN_CFG_2_MASK \
+	(TYPEC_STATE_MACHINE_CHANGE_INT_EN | TYPEC_VBUS_ERROR_INT_EN | \
+	 TYPEC_DEBOUNCE_DONE_INT_EN)
+
+int qcom_pmic_typec_init(struct pmic_typec *pmic_typec,
+			 struct tcpm_port *tcpm_port)
+{
+	int i;
+	int mask;
+	int ret;
+
+	/* Configure interrupt sources */
+	ret = regmap_write(pmic_typec->regmap,
+			   pmic_typec->base + TYPEC_INTERRUPT_EN_CFG_1_REG,
+			   TYPEC_INTR_EN_CFG_1_MASK);
+	if (ret)
+		goto done;
+
+	ret = regmap_write(pmic_typec->regmap,
+			   pmic_typec->base + TYPEC_INTERRUPT_EN_CFG_2_REG,
+			   TYPEC_INTR_EN_CFG_2_MASK);
+	if (ret)
+		goto done;
+
+	/* start in TRY_SNK mode */
+	ret = regmap_write(pmic_typec->regmap,
+			   pmic_typec->base + TYPEC_MODE_CFG_REG, EN_TRY_SNK);
+	if (ret)
+		goto done;
+
+	/* Configure VCONN for software control */
+	ret = regmap_update_bits(pmic_typec->regmap,
+				 pmic_typec->base + TYPEC_VCONN_CONTROL_REG,
+				 VCONN_EN_SRC | VCONN_EN_VALUE, VCONN_EN_SRC);
+	if (ret)
+		goto done;
+
+	/* Set CC threshold to 1.6 Volts | tPDdebounce = 10-20ms */
+	mask = SEL_SRC_UPPER_REF | USE_TPD_FOR_EXITING_ATTACHSRC;
+	ret = regmap_update_bits(pmic_typec->regmap,
+				 pmic_typec->base + TYPEC_EXIT_STATE_CFG_REG,
+				 mask, mask);
+	if (ret)
+		goto done;
+
+	pmic_typec->tcpm_port = tcpm_port;
+
+	for (i = 0; i < pmic_typec->nr_irqs; i++)
+		enable_irq(pmic_typec->irq_data[i].irq);
+
+done:
+	return ret;
+}
+
+void qcom_pmic_typec_put(struct pmic_typec *pmic_typec)
+{
+	put_device(pmic_typec->dev);
+}
+
+static int qcom_pmic_typec_probe(struct platform_device *pdev)
+{
+	struct pmic_typec *pmic_typec;
+	struct device *dev = &pdev->dev;
+	const struct pmic_typec_resources *res;
+	struct pmic_typec_irq_data *irq_data;
+	int i, ret, irq;
+	u32 reg;
+
+	ret = device_property_read_u32(dev, "reg", &reg);
+	if (ret < 0) {
+		dev_err(dev, "missing base address\n");
+		return ret;
+	}
+
+	res = of_device_get_match_data(dev);
+	if (!res)
+		return -ENODEV;
+
+	if (!res->nr_irqs || res->nr_irqs > PMIC_TYPEC_MAX_IRQS)
+		return -EINVAL;
+
+	pmic_typec = devm_kzalloc(dev, sizeof(*pmic_typec), GFP_KERNEL);
+	if (!pmic_typec)
+		return -ENOMEM;
+
+	irq_data = devm_kzalloc(dev, sizeof(*irq_data) * res->nr_irqs,
+				GFP_KERNEL);
+	if (!irq_data)
+		return -ENOMEM;
+
+	pmic_typec->vdd_vbus = devm_regulator_get(dev, "vdd-vbus");
+	if (IS_ERR(pmic_typec->vdd_vbus))
+		return PTR_ERR(pmic_typec->vdd_vbus);
+
+	pmic_typec->dev = dev;
+	pmic_typec->base = reg;
+	pmic_typec->nr_irqs = res->nr_irqs;
+	pmic_typec->irq_data = irq_data;
+	spin_lock_init(&pmic_typec->lock);
+	INIT_DELAYED_WORK(&pmic_typec->cc_debounce_dwork,
+			  qcom_pmic_typec_cc_debounce);
+
+	pmic_typec->regmap = dev_get_regmap(dev->parent, NULL);
+	if (!pmic_typec->regmap) {
+		dev_err(dev, "Failed to get regmap\n");
+		return -ENODEV;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	platform_set_drvdata(pdev, pmic_typec);
+
+	for (i = 0; i < res->nr_irqs; i++, irq_data++) {
+		irq = platform_get_irq_byname(pdev,
+					      res->irq_params[i].irq_name);
+		if (irq < 0)
+			return irq;
+
+		irq_data->pmic_typec = pmic_typec;
+		irq_data->irq = irq;
+		irq_data->virq = res->irq_params[i].virq;
+		ret = devm_request_threaded_irq(dev, irq, NULL, pmic_typec_isr,
+						IRQF_ONESHOT | IRQF_NO_AUTOEN,
+						res->irq_params[i].irq_name,
+						irq_data);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static struct pmic_typec_resources pm8150b_typec_res = {
+	.irq_params = {
+		{
+			.irq_name = "vpd-detect",
+			.virq = PMIC_TYPEC_VPD_IRQ,
+		},
+
+		{
+			.irq_name = "cc-state-change",
+			.virq = PMIC_TYPEC_CC_STATE_IRQ,
+		},
+		{
+			.irq_name = "vconn-oc",
+			.virq = PMIC_TYPEC_VCONN_OC_IRQ,
+		},
+
+		{
+			.irq_name = "vbus-change",
+			.virq = PMIC_TYPEC_VBUS_IRQ,
+		},
+
+		{
+			.irq_name = "attach-detach",
+			.virq = PMIC_TYPEC_ATTACH_DETACH_IRQ,
+		},
+		{
+			.irq_name = "legacy-cable-detect",
+			.virq = PMIC_TYPEC_LEGACY_CABLE_IRQ,
+		},
+
+		{
+			.irq_name = "try-snk-src-detect",
+			.virq = PMIC_TYPEC_TRY_SNK_SRC_IRQ,
+		},
+	},
+	.nr_irqs = 7,
+};
+
+static const struct of_device_id qcom_pmic_typec_table[] = {
+	{ .compatible = "qcom,pm8150b-typec", .data = &pm8150b_typec_res },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, qcom_pmic_typec_table);
+
+struct platform_driver qcom_pmic_typec_platform_driver = {
+	.driver = {
+		.name = "qcom,pmic-typec",
+		.of_match_table = qcom_pmic_typec_table,
+	},
+	.probe = qcom_pmic_typec_probe,
+};
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
new file mode 100644
index 0000000000000..1428325954795
--- /dev/null
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
+ */
+#ifndef __QCOM_PMIC_TYPEC_H__
+#define __QCOM_PMIC_TYPEC_H__
+
+#include <linux/usb/tcpm.h>
+
+#define TYPEC_SNK_STATUS_REG				0x06
+#define DETECTED_SNK_TYPE_MASK				GENMASK(6, 0)
+#define SNK_DAM_MASK					GENMASK(6, 4)
+#define SNK_DAM_500MA					BIT(6)
+#define SNK_DAM_1500MA					BIT(5)
+#define SNK_DAM_3000MA					BIT(4)
+#define SNK_RP_STD					BIT(3)
+#define SNK_RP_1P5					BIT(2)
+#define SNK_RP_3P0					BIT(1)
+#define SNK_RP_SHORT					BIT(0)
+
+#define TYPEC_SRC_STATUS_REG				0x08
+#define DETECTED_SRC_TYPE_MASK				GENMASK(4, 0)
+#define SRC_HIGH_BATT					BIT(5)
+#define SRC_DEBUG_ACCESS				BIT(4)
+#define SRC_RD_OPEN					BIT(3)
+#define SRC_RD_RA_VCONN					BIT(2)
+#define SRC_RA_OPEN					BIT(1)
+#define AUDIO_ACCESS_RA_RA				BIT(0)
+
+#define TYPEC_STATE_MACHINE_STATUS_REG			0x09
+#define TYPEC_ATTACH_DETACH_STATE			BIT(5)
+
+#define TYPEC_SM_STATUS_REG				0x0A
+#define TYPEC_SM_VBUS_VSAFE5V				BIT(5)
+#define TYPEC_SM_VBUS_VSAFE0V				BIT(6)
+#define TYPEC_SM_USBIN_LT_LV				BIT(7)
+
+#define TYPEC_MISC_STATUS_REG				0x0B
+#define TYPEC_WATER_DETECTION_STATUS			BIT(7)
+#define SNK_SRC_MODE					BIT(6)
+#define TYPEC_VBUS_DETECT				BIT(5)
+#define TYPEC_VBUS_ERROR_STATUS				BIT(4)
+#define TYPEC_DEBOUNCE_DONE				BIT(3)
+#define CC_ORIENTATION					BIT(1)
+#define CC_ATTACHED					BIT(0)
+
+#define LEGACY_CABLE_STATUS_REG				0x0D
+#define TYPEC_LEGACY_CABLE_STATUS			BIT(1)
+#define TYPEC_NONCOMP_LEGACY_CABLE_STATUS		BIT(0)
+
+#define TYPEC_U_USB_STATUS_REG				0x0F
+#define U_USB_GROUND_NOVBUS				BIT(6)
+#define U_USB_GROUND					BIT(4)
+#define U_USB_FMB1					BIT(3)
+#define U_USB_FLOAT1					BIT(2)
+#define U_USB_FMB2					BIT(1)
+#define U_USB_FLOAT2					BIT(0)
+
+#define TYPEC_MODE_CFG_REG				0x44
+#define TYPEC_TRY_MODE_MASK				GENMASK(4, 3)
+#define EN_TRY_SNK					BIT(4)
+#define EN_TRY_SRC					BIT(3)
+#define TYPEC_POWER_ROLE_CMD_MASK			GENMASK(2, 0)
+#define EN_SRC_ONLY					BIT(2)
+#define EN_SNK_ONLY					BIT(1)
+#define TYPEC_DISABLE_CMD				BIT(0)
+
+#define TYPEC_VCONN_CONTROL_REG				0x46
+#define VCONN_EN_ORIENTATION				BIT(2)
+#define VCONN_EN_VALUE					BIT(1)
+#define VCONN_EN_SRC					BIT(0)
+
+#define TYPEC_CCOUT_CONTROL_REG				0x48
+#define TYPEC_CCOUT_BUFFER_EN				BIT(2)
+#define TYPEC_CCOUT_VALUE				BIT(1)
+#define TYPEC_CCOUT_SRC					BIT(0)
+
+#define DEBUG_ACCESS_SRC_CFG_REG			0x4C
+#define EN_UNORIENTED_DEBUG_ACCESS_SRC			BIT(0)
+
+#define TYPE_C_CRUDE_SENSOR_CFG_REG			0x4e
+#define EN_SRC_CRUDE_SENSOR				BIT(1)
+#define EN_SNK_CRUDE_SENSOR				BIT(0)
+
+#define TYPEC_EXIT_STATE_CFG_REG			0x50
+#define BYPASS_VSAFE0V_DURING_ROLE_SWAP			BIT(3)
+#define SEL_SRC_UPPER_REF				BIT(2)
+#define USE_TPD_FOR_EXITING_ATTACHSRC			BIT(1)
+#define EXIT_SNK_BASED_ON_CC				BIT(0)
+
+#define TYPEC_CURRSRC_CFG_REG				0x52
+#define TYPEC_SRC_RP_SEL_330UA				BIT(1)
+#define TYPEC_SRC_RP_SEL_180UA				BIT(0)
+#define TYPEC_SRC_RP_SEL_80UA				0
+#define TYPEC_SRC_RP_SEL_MASK				GENMASK(1, 0)
+
+#define TYPEC_INTERRUPT_EN_CFG_1_REG			0x5E
+#define TYPEC_LEGACY_CABLE_INT_EN			BIT(7)
+#define TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN		BIT(6)
+#define TYPEC_TRYSOURCE_DETECT_INT_EN			BIT(5)
+#define TYPEC_TRYSINK_DETECT_INT_EN			BIT(4)
+#define TYPEC_CCOUT_DETACH_INT_EN			BIT(3)
+#define TYPEC_CCOUT_ATTACH_INT_EN			BIT(2)
+#define TYPEC_VBUS_DEASSERT_INT_EN			BIT(1)
+#define TYPEC_VBUS_ASSERT_INT_EN			BIT(0)
+
+#define TYPEC_INTERRUPT_EN_CFG_2_REG			0x60
+#define TYPEC_SRC_BATT_HPWR_INT_EN			BIT(6)
+#define MICRO_USB_STATE_CHANGE_INT_EN			BIT(5)
+#define TYPEC_STATE_MACHINE_CHANGE_INT_EN		BIT(4)
+#define TYPEC_DEBUG_ACCESS_DETECT_INT_EN		BIT(3)
+#define TYPEC_WATER_DETECTION_INT_EN			BIT(2)
+#define TYPEC_VBUS_ERROR_INT_EN				BIT(1)
+#define TYPEC_DEBOUNCE_DONE_INT_EN			BIT(0)
+
+#define TYPEC_DEBOUNCE_OPTION_REG			0x62
+#define REDUCE_TCCDEBOUNCE_TO_2MS			BIT(2)
+
+#define TYPE_C_SBU_CFG_REG				0x6A
+#define SEL_SBU1_ISRC_VAL				0x04
+#define SEL_SBU2_ISRC_VAL				0x01
+
+#define TYPEC_U_USB_CFG_REG				0x70
+#define EN_MICRO_USB_FACTORY_MODE			BIT(1)
+#define EN_MICRO_USB_MODE				BIT(0)
+
+#define TYPEC_PMI632_U_USB_WATER_PROTECTION_CFG_REG	0x72
+
+#define TYPEC_U_USB_WATER_PROTECTION_CFG_REG		0x73
+#define EN_MICRO_USB_WATER_PROTECTION			BIT(4)
+#define MICRO_USB_DETECTION_ON_TIME_CFG_MASK		GENMASK(3, 2)
+#define MICRO_USB_DETECTION_PERIOD_CFG_MASK		GENMASK(1, 0)
+
+#define TYPEC_PMI632_MICRO_USB_MODE_REG			0x73
+#define MICRO_USB_MODE_ONLY				BIT(0)
+
+struct pmic_typec;
+extern struct platform_driver qcom_pmic_typec_platform_driver;
+
+int qcom_pmic_typec_init(struct pmic_typec *pmic_typec,
+			 struct tcpm_port *tcpm_port);
+
+void qcom_pmic_typec_put(struct pmic_typec *pmic_typec);
+
+int qcom_pmic_typec_get_cc(struct pmic_typec *pmic_typec,
+			   enum typec_cc_status *cc1,
+			   enum typec_cc_status *cc2);
+
+int qcom_pmic_typec_set_cc(struct pmic_typec *pmic_typec,
+			   enum typec_cc_status cc);
+
+int qcom_pmic_typec_get_vbus(struct pmic_typec *pmic_typec);
+
+int qcom_pmic_typec_set_vconn(struct pmic_typec *pmic_typec, bool on);
+
+int qcom_pmic_typec_start_toggling(struct pmic_typec *pmic_typec,
+				   enum typec_port_type port_type,
+				   enum typec_cc_status cc);
+
+int qcom_pmic_typec_set_vbus(struct pmic_typec *pmic_typec, bool on);
+
+#endif /* __QCOM_PMIC_TYPE_C_H__ */
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
new file mode 100644
index 0000000000000..91544b4b59439
--- /dev/null
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Linaro Ltd. All rights reserved.
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/usb/role.h>
+#include <linux/usb/tcpm.h>
+#include <linux/usb/typec_mux.h>
+#include "qcom_pmic_pdphy.h"
+#include "qcom_pmic_typec.h"
+
+struct pmic_virt_tcpm {
+	struct device		*dev;
+	struct pmic_typec	*pmic_typec;
+	struct pmic_pdphy	*pmic_pdphy;
+	struct tcpm_port	*tcpm_port;
+	struct tcpc_dev		tcpc;
+	bool			vbus_enabled;
+	struct mutex		lock;		/* VBUS state serialization */
+};
+
+#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_virt_tcpm, tcpc)
+
+static int qcom_pmic_virt_tcpm_get_vbus(struct tcpc_dev *tcpc)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+	int ret;
+
+	mutex_lock(&tcpm->lock);
+	ret = tcpm->vbus_enabled || qcom_pmic_typec_get_vbus(tcpm->pmic_typec);
+	mutex_unlock(&tcpm->lock);
+
+	return ret;
+}
+
+static int qcom_pmic_virt_tcpm_set_vbus(struct tcpc_dev *tcpc, bool on,
+					bool sink)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+	int ret = 0;
+
+	mutex_lock(&tcpm->lock);
+	if (tcpm->vbus_enabled == on)
+		goto done;
+
+	ret = qcom_pmic_typec_set_vbus(tcpm->pmic_typec, on);
+	if (ret)
+		goto done;
+
+	tcpm->vbus_enabled = on;
+	tcpm_vbus_change(tcpm->tcpm_port);
+
+done:
+	dev_dbg(tcpm->dev, "set_vbus set: %d result %d\n", on, ret);
+	mutex_unlock(&tcpm->lock);
+
+	return ret;
+}
+
+static int qcom_pmic_virt_tcpm_set_vconn(struct tcpc_dev *tcpc, bool on)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+
+	return qcom_pmic_typec_set_vconn(tcpm->pmic_typec, on);
+}
+
+static int qcom_pmic_virt_tcpm_get_cc(struct tcpc_dev *tcpc,
+				      enum typec_cc_status *cc1,
+				      enum typec_cc_status *cc2)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+
+	return qcom_pmic_typec_get_cc(tcpm->pmic_typec, cc1, cc2);
+}
+
+static int qcom_pmic_virt_tcpm_set_cc(struct tcpc_dev *tcpc,
+				      enum typec_cc_status cc)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+
+	return qcom_pmic_typec_set_cc(tcpm->pmic_typec, cc);
+}
+
+static int qcom_pmic_virt_tcpm_set_polarity(struct tcpc_dev *tcpc,
+					    enum typec_cc_polarity pol)
+{
+	/* Polarity is set separately by phy-qcom-qmp.c */
+	return 0;
+}
+
+static int qcom_pmic_virt_tcpm_start_toggling(struct tcpc_dev *tcpc,
+					      enum typec_port_type port_type,
+					      enum typec_cc_status cc)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+
+	return qcom_pmic_typec_start_toggling(tcpm->pmic_typec, port_type, cc);
+}
+
+static int qcom_pmic_virt_tcpm_set_roles(struct tcpc_dev *tcpc, bool attached,
+					 enum typec_role power_role,
+					 enum typec_data_role data_role)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+
+	return qcom_pmic_pdphy_set_roles(tcpm->pmic_pdphy, data_role,
+					 power_role);
+}
+
+static int qcom_pmic_virt_tcpm_set_pd_rx(struct tcpc_dev *tcpc, bool on)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+
+	return qcom_pmic_pdphy_set_pd_rx(tcpm->pmic_pdphy, on);
+}
+
+static int qcom_pmic_virt_tcpm_pd_transmit(struct tcpc_dev *tcpc,
+					   enum tcpm_transmit_type type,
+					   const struct pd_message *msg,
+					   unsigned int negotiated_rev)
+{
+	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
+
+	return qcom_pmic_pdphy_pd_transmit(tcpm->pmic_pdphy, type, msg,
+					   negotiated_rev);
+}
+
+static struct platform_device
+*qcom_pmic_virt_tcpm_get_pdev(struct device *dev, const char *property_name)
+{
+	struct device_node *np;
+	struct platform_device *pdev;
+	const __be32 *prop;
+
+	prop = of_get_property(dev->of_node, property_name, NULL);
+	if (!prop) {
+		dev_err(dev, "required '%s' property missing\n", property_name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	np = of_find_node_by_phandle(be32_to_cpup(prop));
+	if (!np) {
+		dev_err(dev, "could not find '%s' node\n", property_name);
+		return ERR_PTR(-ENODEV);
+	}
+
+	pdev = of_find_device_by_node(np);
+	of_node_put(np);
+
+	if (pdev)
+		return pdev;
+
+	return ERR_PTR(-ENODEV);
+}
+
+static int qcom_pmic_virt_tcpm_init(struct tcpc_dev *tcpc)
+{
+	return 0;
+}
+
+static int qcom_pmic_virt_tcpm_probe(struct platform_device *pdev)
+{
+	struct pmic_virt_tcpm *tcpm;
+	struct device *dev = &pdev->dev;
+	struct platform_device *typec_pdev;
+	struct platform_device *pdphy_pdev;
+	int ret;
+
+	tcpm = devm_kzalloc(dev, sizeof(*tcpm), GFP_KERNEL);
+	if (!tcpm)
+		return -ENOMEM;
+
+	tcpm->dev = dev;
+	tcpm->tcpc.init = qcom_pmic_virt_tcpm_init;
+	tcpm->tcpc.get_vbus = qcom_pmic_virt_tcpm_get_vbus;
+	tcpm->tcpc.set_vbus = qcom_pmic_virt_tcpm_set_vbus;
+	tcpm->tcpc.set_cc = qcom_pmic_virt_tcpm_set_cc;
+	tcpm->tcpc.get_cc = qcom_pmic_virt_tcpm_get_cc;
+	tcpm->tcpc.set_polarity = qcom_pmic_virt_tcpm_set_polarity;
+	tcpm->tcpc.set_vconn = qcom_pmic_virt_tcpm_set_vconn;
+	tcpm->tcpc.start_toggling = qcom_pmic_virt_tcpm_start_toggling;
+	tcpm->tcpc.set_pd_rx = qcom_pmic_virt_tcpm_set_pd_rx;
+	tcpm->tcpc.set_roles = qcom_pmic_virt_tcpm_set_roles;
+	tcpm->tcpc.pd_transmit = qcom_pmic_virt_tcpm_pd_transmit;
+
+	mutex_init(&tcpm->lock);
+	platform_set_drvdata(pdev, tcpm);
+
+	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+	if (ret) {
+		dev_err(dev, "Populating child devices fail\n");
+		return ret;
+	};
+
+	typec_pdev = qcom_pmic_virt_tcpm_get_pdev(dev, "qcom,pmic-typec");
+	if (IS_ERR(typec_pdev)) {
+		dev_err(dev, "Error linking typec endpoint\n");
+		return PTR_ERR(typec_pdev);
+	}
+
+	tcpm->pmic_typec = platform_get_drvdata(typec_pdev);
+	if (!tcpm->pmic_typec) {
+		ret = -EPROBE_DEFER;
+		goto put_typec_pdev;
+	}
+
+	pdphy_pdev = qcom_pmic_virt_tcpm_get_pdev(dev, "qcom,pmic-pdphy");
+	if (IS_ERR(pdphy_pdev)) {
+		dev_err(dev, "Error linking pdphy endpoint\n");
+		ret = PTR_ERR(pdphy_pdev);
+		goto put_typec_pdev;
+	}
+
+	tcpm->pmic_pdphy = platform_get_drvdata(pdphy_pdev);
+	if (!tcpm->pmic_pdphy) {
+		ret = -EPROBE_DEFER;
+		goto put_pdphy_dev;
+	}
+
+	tcpm->tcpc.fwnode = device_get_named_child_node(tcpm->dev, "connector");
+	if (IS_ERR(tcpm->tcpc.fwnode))
+		return PTR_ERR(tcpm->tcpc.fwnode);
+
+	tcpm->tcpm_port = tcpm_register_port(tcpm->dev, &tcpm->tcpc);
+	if (IS_ERR(tcpm->tcpm_port)) {
+		ret = PTR_ERR(tcpm->tcpm_port);
+		goto fwnode_remove;
+	}
+
+	ret = qcom_pmic_pdphy_init(tcpm->pmic_pdphy, tcpm->tcpm_port);
+	if (ret)
+		goto fwnode_remove;
+
+	ret = qcom_pmic_typec_init(tcpm->pmic_typec, tcpm->tcpm_port);
+	if (ret)
+		goto fwnode_remove;
+
+	return 0;
+
+fwnode_remove:
+	fwnode_remove_software_node(tcpm->tcpc.fwnode);
+
+put_pdphy_dev:
+	put_device(&pdphy_pdev->dev);
+
+put_typec_pdev:
+	put_device(&typec_pdev->dev);
+
+	return ret;
+}
+
+static int qcom_pmic_virt_tcpm_remove(struct platform_device *pdev)
+{
+	struct pmic_virt_tcpm *tcpm = platform_get_drvdata(pdev);
+
+	tcpm_unregister_port(tcpm->tcpm_port);
+	fwnode_remove_software_node(tcpm->tcpc.fwnode);
+	qcom_pmic_pdphy_put(tcpm->pmic_pdphy);
+	qcom_pmic_typec_put(tcpm->pmic_typec);
+
+	return 0;
+}
+
+static const struct of_device_id qcom_pmic_virt_tcpm_table[] = {
+	{ .compatible = "qcom,pmic-virt-tcpm" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_pmic_virt_tcpm_table);
+
+static struct platform_driver qcom_pmic_virt_tcpm_platform_driver = {
+	.driver = {
+		.name = "qcom,pmic-tcpm",
+		.of_match_table = qcom_pmic_virt_tcpm_table,
+	},
+	.probe = qcom_pmic_virt_tcpm_probe,
+	.remove = qcom_pmic_virt_tcpm_remove,
+};
+
+static int __init qcom_pmic_virt_tcpm_module_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&qcom_pmic_typec_platform_driver);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&qcom_pmic_pdphy_platform_driver);
+	if (ret)
+		goto unregister_typec;
+
+	ret = platform_driver_register(&qcom_pmic_virt_tcpm_platform_driver);
+	if (ret)
+		goto unregister_pdphy;
+
+	return 0;
+
+unregister_pdphy:
+	platform_driver_unregister(&qcom_pmic_pdphy_platform_driver);
+
+unregister_typec:
+	platform_driver_unregister(&qcom_pmic_typec_platform_driver);
+
+	return ret;
+}
+module_init(qcom_pmic_virt_tcpm_module_init);
+
+static void __exit qcom_pmic_virt_tcpm_module_exit(void)
+{
+	platform_driver_unregister(&qcom_pmic_virt_tcpm_platform_driver);
+	platform_driver_unregister(&qcom_pmic_pdphy_platform_driver);
+	platform_driver_unregister(&qcom_pmic_typec_platform_driver);
+}
+module_exit(qcom_pmic_virt_tcpm_module_exit);
+
+MODULE_DESCRIPTION("QCOM PMIC USB Type-C Port Manager Driver");
+MODULE_LICENSE("GPL");
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (11 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-18 16:42   ` kernel test robot
  2023-03-20 11:15   ` Neil Armstrong
  2023-03-18 12:18 ` [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description Bryan O'Donoghue
                   ` (5 subsequent siblings)
  18 siblings, 2 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom, Dmitry Baryshkov

From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

The lane select switch for USB typec orientation is within the USB QMP PHY.
the current device.  It could be connected through an endpoint, to an
independent device handling the typec detection, ie the QCOM SPMI typec
driver.

bod: Fixed the logic qcom_qmp_phy_typec_switch_set() to disable phy
 on disconnect if and only if we have initialized the PHY.
 Retained CC orientation logic in qcom_qmp_phy_com_init() to simplify
 patch.

bod: Ported from earlier version of driver to phy-qcom-qmp-combo.c

Co-developed-by: Wesley Cheng <wcheng@codeaurora.org>
Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
Co-developed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/phy/qualcomm/Kconfig              |  8 +++
 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 80 +++++++++++++++++++++--
 2 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
index 4850d48f31fa1..8240fffdbed4e 100644
--- a/drivers/phy/qualcomm/Kconfig
+++ b/drivers/phy/qualcomm/Kconfig
@@ -101,6 +101,14 @@ config PHY_QCOM_QMP_USB
 
 endif # PHY_QCOM_QMP
 
+config PHY_QCOM_QMP_TYPEC
+	def_bool PHY_QCOM_QMP=y && TYPEC=y || PHY_QCOM_QMP=m && TYPEC
+	help
+	  Register a type C switch from the QMP PHY driver for type C
+	  orientation support.  This has dependencies with if the type C kernel
+	  configuration is enabled or not.  This support will not be present if
+	  USB type C is disabled.
+
 config PHY_QCOM_QUSB2
 	tristate "Qualcomm QUSB2 PHY Driver"
 	depends on OF && (ARCH_QCOM || COMPILE_TEST)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index c1483e157af4a..afe708c63557d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -19,6 +19,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/slab.h>
+#include <linux/usb/typec_mux.h>
 
 #include <dt-bindings/phy/phy-qcom-qmp.h>
 
@@ -63,6 +64,10 @@
 /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
 #define CLAMP_EN				BIT(0) /* enables i/o clamp_n */
 
+/* QPHY_V3_DP_COM_TYPEC_CTRL register bits */
+#define SW_PORTSELECT_VAL			BIT(0)
+#define SW_PORTSELECT_MUX			BIT(1)
+
 #define PHY_INIT_COMPLETE_TIMEOUT		10000
 
 struct qmp_phy_init_tbl {
@@ -1323,6 +1328,9 @@ struct qmp_combo {
 	struct clk_fixed_rate pipe_clk_fixed;
 	struct clk_hw dp_link_hw;
 	struct clk_hw dp_pixel_hw;
+
+	struct typec_switch_dev *sw;
+	enum typec_orientation orientation;
 };
 
 static void qmp_v3_dp_aux_init(struct qmp_combo *qmp);
@@ -1970,7 +1978,8 @@ static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp)
 static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp)
 {
 	u32 val;
-	bool reverse = false;
+	bool reverse = qmp->orientation == TYPEC_ORIENTATION_REVERSE;
+	const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
 
 	val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
 	      DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
@@ -1989,10 +1998,18 @@ static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp)
 	 * if (orientation == ORIENTATION_CC2)
 	 *	writel(0x4c, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_MODE);
 	 */
+	if (dp_opts->lanes == 4 || reverse)
+		val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
+	if (dp_opts->lanes == 4 || !reverse)
+		val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
+
 	val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
 	writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
 
-	writel(0x5c, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE);
+	if (reverse)
+		writel(0x4c, qmp->pcs + QSERDES_DP_PHY_MODE);
+	else
+		writel(0x5c, qmp->pcs + QSERDES_DP_PHY_MODE);
 
 	return reverse;
 }
@@ -2476,6 +2493,7 @@ static int qmp_combo_com_init(struct qmp_combo *qmp)
 {
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
 	void __iomem *com = qmp->com;
+	u32 val;
 	int ret;
 
 	mutex_lock(&qmp->phy_mutex);
@@ -2513,8 +2531,11 @@ static int qmp_combo_com_init(struct qmp_combo *qmp)
 			SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
 			SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
 
-	/* Default type-c orientation, i.e CC1 */
-	qphy_setbits(com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
+	/* Latch CC orientation based on reported state by TCPM */
+	val = SW_PORTSELECT_MUX;
+	if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
+		val |= SW_PORTSELECT_VAL;
+	qphy_setbits(com, QPHY_V3_DP_COM_TYPEC_CTRL, val);
 
 	qphy_setbits(com, QPHY_V3_DP_COM_PHY_MODE_CTRL, USB3_MODE | DP_MODE);
 
@@ -3353,6 +3374,53 @@ static struct phy *qmp_combo_phy_xlate(struct device *dev, struct of_phandle_arg
 	return ERR_PTR(-EINVAL);
 }
 
+#if IS_ENABLED(CONFIG_PHY_QCOM_QMP_TYPEC)
+static int qmp_combo_typec_switch_set(struct typec_switch_dev *sw,
+				      enum typec_orientation orientation)
+{
+	struct qmp_combo *qmp = typec_switch_get_drvdata(sw);
+	struct phy *dp_phy = qmp->dp_phy;
+	int ret = 0;
+
+	dev_dbg(qmp->dev, "Toggling orientation current %d requested %d\n",
+		qmp->orientation, orientation);
+
+	qmp->orientation = orientation;
+
+	if (orientation == TYPEC_ORIENTATION_NONE) {
+		if (qmp->init_count)
+			ret = qmp_combo_dp_power_off(dp_phy);
+	} else {
+		if (!qmp->init_count)
+			ret = qmp_combo_dp_power_on(dp_phy);
+	}
+
+	return 0;
+}
+
+static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
+{
+	struct typec_switch_desc sw_desc;
+	struct device *dev = qmp->dev;
+
+	sw_desc.drvdata = qmp;
+	sw_desc.fwnode = dev->fwnode;
+	sw_desc.set = qmp_combo_typec_switch_set;
+	qmp->sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(qmp->sw)) {
+		dev_err(dev, "Error registering typec switch: %ld\n",
+			PTR_ERR(qmp->sw));
+	}
+
+	return 0;
+}
+#else
+static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
+{
+	return 0;
+}
+#endif
+
 static int qmp_combo_probe(struct platform_device *pdev)
 {
 	struct qmp_combo *qmp;
@@ -3443,6 +3511,10 @@ static int qmp_combo_probe(struct platform_device *pdev)
 	else
 		phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 
+	ret = qmp_combo_typec_switch_register(qmp);
+	if (ret)
+		goto err_node_put;
+
 	of_node_put(usb_np);
 	of_node_put(dp_np);
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (12 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-18 13:13   ` Konrad Dybcio
  2023-03-18 21:09   ` kernel test robot
  2023-03-18 12:18 ` [PATCH v4 15/18] arm64: dts: qcom: qrb5165-rb5: Switch on Type-C VBUS boost Bryan O'Donoghue
                   ` (4 subsequent siblings)
  18 siblings, 2 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Type-C port management functionality lives inside of the PMIC block on
pm8150b.

The Type-C port management logic controls orientation detection, vbus/vconn
sense and to send/receive Type-C Power Domain messages.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 arch/arm64/boot/dts/qcom/pm8150b.dtsi | 70 +++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm8150b.dtsi b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
index 66752cc063d60..6db32bdbf5747 100644
--- a/arch/arm64/boot/dts/qcom/pm8150b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
@@ -7,6 +7,8 @@
 #include <dt-bindings/iio/qcom,spmi-vadc.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/usb/typec/qcom,pmic-typec.h>
+#include <dt-bindings/usb/typec/qcom,pmic-pdphy.h>
 
 / {
 	thermal-zones {
@@ -37,6 +39,14 @@ trip2 {
 			};
 		};
 	};
+
+	tcpm: pm8150b-tcpm {
+		compatible = "qcom,pmic-virt-tcpm";
+		qcom,pmic-typec = <&pm8150b_typec>;
+		qcom,pmic-pdphy = <&pm8150b_pdphy>;
+
+		status = "disabled";
+	};
 };
 
 &spmi_bus {
@@ -59,6 +69,66 @@ pm8150b_vbus: usb-vbus-regulator@1100 {
 			reg = <0x1100>;
 		};
 
+		pm8150b_typec: typec@1500 {
+			compatible = "qcom,pm8150b-typec";
+			reg = <0x1500>;
+			interrupts = <0x2 0x15 PMIC_TYPEC_OR_RID_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x15 PMIC_TYPEC_VPD_IRQ
+				      IRQ_TYPE_EDGE_BOTH>,
+				     <0x2 0x15 PMIC_TYPEC_CC_STATE_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x15 PMIC_TYPEC_VCONN_OC_IRQ
+				      IRQ_TYPE_EDGE_BOTH>,
+				     <0x2 0x15 PMIC_TYPEC_VBUS_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x15 PMIC_TYPEC_ATTACH_DETACH_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x15 PMIC_TYPEC_LEGACY_CABLE_IRQ
+				      IRQ_TYPE_EDGE_BOTH>,
+				     <0x2 0x15 PMIC_TYPEC_TRY_SNK_SRC_IRQ
+				      IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "or-rid-detect-change",
+					  "vpd-detect",
+					  "cc-state-change",
+					  "vconn-oc",
+					  "vbus-change",
+					  "attach-detach",
+					  "legacy-cable-detect",
+					  "try-snk-src-detect";
+			vdd-vbus-supply = <&pm8150b_vbus>;
+		};
+
+		pm8150b_pdphy: pdphy@1700 {
+			compatible = "qcom,pm8150b-pdphy";
+			reg = <0x1700>;
+			interrupts = <0x2 0x17 PMIC_PDPHY_SIG_TX_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x17 PMIC_PDPHY_SIG_RX_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x17 PMIC_PDPHY_MSG_TX_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x17 PMIC_PDPHY_MSG_RX_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x17 PMIC_PDPHY_MSG_TX_FAIL_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x17 PMIC_PDPHY_MSG_TX_DISCARD_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x17 PMIC_PDPHY_MSG_RX_DISCARD_IRQ
+				      IRQ_TYPE_EDGE_RISING>,
+				     <0x2 0x17 PMIC_PDPHY_FR_SWAP_IRQ
+				      IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "sig-tx",
+					  "sig-rx",
+					  "msg-tx",
+					  "msg-rx",
+					  "msg-tx-failed",
+					  "msg-tx-discarded",
+					  "msg-rx-discarded",
+					  "fr-swap";
+			vdd-phy-supply = <&vreg_l2a_3p1>;
+		};
+
 		pm8150b_temp: temp-alarm@2400 {
 			compatible = "qcom,spmi-temp-alarm";
 			reg = <0x2400>;
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 15/18] arm64: dts: qcom: qrb5165-rb5: Switch on Type-C VBUS boost
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (13 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-18 12:18 ` [PATCH v4 16/18] arm64: dts: qcom: qrb5165-rb5: Switch on basic TCPM Bryan O'Donoghue
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Switch on VBUS for the Type-C port. We need to support a higher amperage
than the bootloader set 2 Amps.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index aa0a7bd7307ce..1ce88f0c31db2 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -1338,3 +1338,9 @@ &qup_spi0_data_clk {
 	drive-strength = <6>;
 	bias-disable;
 };
+
+&pm8150b_vbus {
+	regulator-min-microamp = <500000>;
+	regulator-max-microamp = <3000000>;
+	status = "okay";
+};
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 16/18] arm64: dts: qcom: qrb5165-rb5: Switch on basic TCPM
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (14 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 15/18] arm64: dts: qcom: qrb5165-rb5: Switch on Type-C VBUS boost Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-18 13:09   ` Konrad Dybcio
  2023-03-18 12:18 ` [PATCH v4 17/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for usb_1 Bryan O'Donoghue
                   ` (2 subsequent siblings)
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Switch on TCPM for the RB5. Here we declare as a source only not a sink
since qrb5165 doesn't support powering exclusively from the type-c port.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 25 ++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index 1ce88f0c31db2..965742a5be7ae 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -9,6 +9,7 @@
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include <dt-bindings/sound/qcom,q6afe.h>
 #include <dt-bindings/sound/qcom,q6asm.h>
+#include <dt-bindings/usb/pd.h>
 #include "sm8250.dtsi"
 #include "pm8150.dtsi"
 #include "pm8150b.dtsi"
@@ -1339,8 +1340,32 @@ &qup_spi0_data_clk {
 	bias-disable;
 };
 
+&pm8150b_typec {
+	status = "okay";
+};
+
+&pm8150b_pdphy {
+	status = "okay";
+};
+
 &pm8150b_vbus {
 	regulator-min-microamp = <500000>;
 	regulator-max-microamp = <3000000>;
 	status = "okay";
 };
+
+&tcpm {
+	status = "okay";
+	connector {
+		compatible = "usb-c-connector";
+
+		power-role = "source";
+		data-role = "dual";
+		self-powered;
+
+		source-pdos = <PDO_FIXED(5000, 3000,
+					 PDO_FIXED_DUAL_ROLE |
+					 PDO_FIXED_USB_COMM |
+					 PDO_FIXED_DATA_SWAP)>;
+	};
+};
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 17/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for usb_1
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (15 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 16/18] arm64: dts: qcom: qrb5165-rb5: Switch on basic TCPM Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-18 13:10   ` Konrad Dybcio
  2023-03-18 12:18 ` [PATCH v4 18/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for usb_1_qmpphy Bryan O'Donoghue
  2023-03-24 15:10 ` [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Luca Weiss
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Switch on usb-role-switching for usb_1 via TCPM. We need to declare
usb-role-switch in &usb_1 and associate with the remote-endpoint in TCPM
which provides the necessary signal.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index 965742a5be7ae..43d549d6672e9 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -1273,7 +1273,13 @@ &usb_1 {
 };
 
 &usb_1_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
+	usb-role-switch;
+	port {
+		dwc3_drd_switch: endpoint {
+			remote-endpoint = <&usb3_role>;
+		};
+	};
 };
 
 &usb_1_hsphy {
@@ -1356,6 +1362,12 @@ &pm8150b_vbus {
 
 &tcpm {
 	status = "okay";
+	port {
+		usb3_role: endpoint {
+			remote-endpoint = <&dwc3_drd_switch>;
+		};
+	};
+
 	connector {
 		compatible = "usb-c-connector";
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v4 18/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for usb_1_qmpphy
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (16 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 17/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for usb_1 Bryan O'Donoghue
@ 2023-03-18 12:18 ` Bryan O'Donoghue
  2023-03-18 13:11   ` Konrad Dybcio
  2023-03-24 15:10 ` [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Luca Weiss
  18 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 12:18 UTC (permalink / raw)
  To: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, bryan.odonoghue, konrad.dybcio, subbaram,
	jackp, robertom

Switch on USB orientation-switching for usb_1_qmp via TCPM. Detecting the
orientation switch is required to get the PHY to reset and bring-up the PHY
with the CC lines set to the appropriate lane.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index 43d549d6672e9..e5eecf02653ff 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -1295,6 +1295,12 @@ &usb_1_qmpphy {
 
 	vdda-phy-supply = <&vreg_l9a_1p2>;
 	vdda-pll-supply = <&vreg_l18a_0p92>;
+	orientation-switch;
+	port {
+		qmp_ss_mux: endpoint {
+			remote-endpoint = <&pmic_tcpm_ss_mux>;
+		};
+	};
 };
 
 &usb_2 {
@@ -1379,5 +1385,17 @@ connector {
 					 PDO_FIXED_DUAL_ROLE |
 					 PDO_FIXED_USB_COMM |
 					 PDO_FIXED_DATA_SWAP)>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				pmic_tcpm_ss_mux: endpoint {
+					remote-endpoint = <&qmp_ss_mux>;
+				};
+			};
+		};
 	};
 };
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 16/18] arm64: dts: qcom: qrb5165-rb5: Switch on basic TCPM
  2023-03-18 12:18 ` [PATCH v4 16/18] arm64: dts: qcom: qrb5165-rb5: Switch on basic TCPM Bryan O'Donoghue
@ 2023-03-18 13:09   ` Konrad Dybcio
  0 siblings, 0 replies; 72+ messages in thread
From: Konrad Dybcio @ 2023-03-18 13:09 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, subbaram, jackp, robertom



On 18.03.2023 13:18, Bryan O'Donoghue wrote:
> Switch on TCPM for the RB5. Here we declare as a source only not a sink
> since qrb5165 doesn't support powering exclusively from the type-c port.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 25 ++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> index 1ce88f0c31db2..965742a5be7ae 100644
> --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> @@ -9,6 +9,7 @@
>  #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
>  #include <dt-bindings/sound/qcom,q6afe.h>
>  #include <dt-bindings/sound/qcom,q6asm.h>
> +#include <dt-bindings/usb/pd.h>
>  #include "sm8250.dtsi"
>  #include "pm8150.dtsi"
>  #include "pm8150b.dtsi"
> @@ -1339,8 +1340,32 @@ &qup_spi0_data_clk {
>  	bias-disable;
>  };
>  
> +&pm8150b_typec {
> +	status = "okay";
> +};
> +
> +&pm8150b_pdphy {
> +	status = "okay";
> +};
Swap these two ('p' < 't')


> +
>  &pm8150b_vbus {
>  	regulator-min-microamp = <500000>;
>  	regulator-max-microamp = <3000000>;
>  	status = "okay";
>  };
> +
> +&tcpm {
> +	status = "okay";
Add a newline before the child node, please

With that:

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad
> +	connector {
> +		compatible = "usb-c-connector";
> +
> +		power-role = "source";
> +		data-role = "dual";
> +		self-powered;
> +
> +		source-pdos = <PDO_FIXED(5000, 3000,
> +					 PDO_FIXED_DUAL_ROLE |
> +					 PDO_FIXED_USB_COMM |
> +					 PDO_FIXED_DATA_SWAP)>;
> +	};
> +};

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 17/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for usb_1
  2023-03-18 12:18 ` [PATCH v4 17/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for usb_1 Bryan O'Donoghue
@ 2023-03-18 13:10   ` Konrad Dybcio
  2023-03-18 17:46     ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Konrad Dybcio @ 2023-03-18 13:10 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, subbaram, jackp, robertom



On 18.03.2023 13:18, Bryan O'Donoghue wrote:
> Switch on usb-role-switching for usb_1 via TCPM. We need to declare
> usb-role-switch in &usb_1 and associate with the remote-endpoint in TCPM
> which provides the necessary signal.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> index 965742a5be7ae..43d549d6672e9 100644
> --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> @@ -1273,7 +1273,13 @@ &usb_1 {
>  };
>  
>  &usb_1_dwc3 {
> -	dr_mode = "peripheral";
> +	dr_mode = "otg";
> +	usb-role-switch;
This could maybe go to the SoC DTSI.. Bjorn, Krzysztof, WDYT?

Also, please add a newline before the subnode.

> +	port {
> +		dwc3_drd_switch: endpoint {
> +			remote-endpoint = <&usb3_role>;
> +		};
> +	};
DWC3 ports (@0 for HS, @1 for SS and @2 for altmode) can definitely
go to the SoC DTSI.

>  };
>  
>  &usb_1_hsphy {
> @@ -1356,6 +1362,12 @@ &pm8150b_vbus {
>  
>  &tcpm {
>  	status = "okay";
Please add a newline before the subnode.

Konrad

> +	port {
> +		usb3_role: endpoint {
> +			remote-endpoint = <&dwc3_drd_switch>;
> +		};
> +	};
> +
>  	connector {
>  		compatible = "usb-c-connector";
>  

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 18/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for usb_1_qmpphy
  2023-03-18 12:18 ` [PATCH v4 18/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for usb_1_qmpphy Bryan O'Donoghue
@ 2023-03-18 13:11   ` Konrad Dybcio
  2023-03-18 17:47     ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Konrad Dybcio @ 2023-03-18 13:11 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, subbaram, jackp, robertom



On 18.03.2023 13:18, Bryan O'Donoghue wrote:
> Switch on USB orientation-switching for usb_1_qmp via TCPM. Detecting the
> orientation switch is required to get the PHY to reset and bring-up the PHY
> with the CC lines set to the appropriate lane.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> index 43d549d6672e9..e5eecf02653ff 100644
> --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
> @@ -1295,6 +1295,12 @@ &usb_1_qmpphy {
>  
>  	vdda-phy-supply = <&vreg_l9a_1p2>;
>  	vdda-pll-supply = <&vreg_l18a_0p92>;
> +	orientation-switch;
I think this property could be put in the SoC DTSI, the hardware
does support roleswitching

Add a newline before the subnode, please.

Konrad
> +	port {
> +		qmp_ss_mux: endpoint {
> +			remote-endpoint = <&pmic_tcpm_ss_mux>;
> +		};
> +	};
>  };
>  
>  &usb_2 {
> @@ -1379,5 +1385,17 @@ connector {
>  					 PDO_FIXED_DUAL_ROLE |
>  					 PDO_FIXED_USB_COMM |
>  					 PDO_FIXED_DATA_SWAP)>;
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				pmic_tcpm_ss_mux: endpoint {
> +					remote-endpoint = <&qmp_ss_mux>;
> +				};
> +			};
> +		};
>  	};
>  };

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description
  2023-03-18 12:18 ` [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description Bryan O'Donoghue
@ 2023-03-18 13:13   ` Konrad Dybcio
  2023-03-18 21:09   ` kernel test robot
  1 sibling, 0 replies; 72+ messages in thread
From: Konrad Dybcio @ 2023-03-18 13:13 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, subbaram, jackp, robertom



On 18.03.2023 13:18, Bryan O'Donoghue wrote:
> Type-C port management functionality lives inside of the PMIC block on
> pm8150b.
> 
> The Type-C port management logic controls orientation detection, vbus/vconn
> sense and to send/receive Type-C Power Domain messages.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/pm8150b.dtsi | 70 +++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/pm8150b.dtsi b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
> index 66752cc063d60..6db32bdbf5747 100644
> --- a/arch/arm64/boot/dts/qcom/pm8150b.dtsi
> +++ b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
> @@ -7,6 +7,8 @@
>  #include <dt-bindings/iio/qcom,spmi-vadc.h>
>  #include <dt-bindings/interrupt-controller/irq.h>
>  #include <dt-bindings/spmi/spmi.h>
> +#include <dt-bindings/usb/typec/qcom,pmic-typec.h>
> +#include <dt-bindings/usb/typec/qcom,pmic-pdphy.h>
>  
>  / {
>  	thermal-zones {
> @@ -37,6 +39,14 @@ trip2 {
>  			};
>  		};
>  	};
> +
> +	tcpm: pm8150b-tcpm {
> +		compatible = "qcom,pmic-virt-tcpm";
> +		qcom,pmic-typec = <&pm8150b_typec>;
> +		qcom,pmic-pdphy = <&pm8150b_pdphy>;
> +
> +		status = "disabled";
> +	};
>  };
>  
>  &spmi_bus {
> @@ -59,6 +69,66 @@ pm8150b_vbus: usb-vbus-regulator@1100 {
>  			reg = <0x1100>;
>  		};
>  
> +		pm8150b_typec: typec@1500 {
> +			compatible = "qcom,pm8150b-typec";
> +			reg = <0x1500>;
> +			interrupts = <0x2 0x15 PMIC_TYPEC_OR_RID_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 PMIC_TYPEC_VPD_IRQ
> +				      IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 PMIC_TYPEC_CC_STATE_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 PMIC_TYPEC_VCONN_OC_IRQ
> +				      IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 PMIC_TYPEC_VBUS_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 PMIC_TYPEC_ATTACH_DETACH_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x15 PMIC_TYPEC_LEGACY_CABLE_IRQ
> +				      IRQ_TYPE_EDGE_BOTH>,
> +				     <0x2 0x15 PMIC_TYPEC_TRY_SNK_SRC_IRQ
> +				      IRQ_TYPE_EDGE_RISING>;
> +			interrupt-names = "or-rid-detect-change",
> +					  "vpd-detect",
> +					  "cc-state-change",
> +					  "vconn-oc",
> +					  "vbus-change",
> +					  "attach-detach",
> +					  "legacy-cable-detect",
> +					  "try-snk-src-detect";
> +			vdd-vbus-supply = <&pm8150b_vbus>;
This belongs in the board dt, it references nodes defined there.
> +		};
> +
> +		pm8150b_pdphy: pdphy@1700 {
> +			compatible = "qcom,pm8150b-pdphy";
> +			reg = <0x1700>;
> +			interrupts = <0x2 0x17 PMIC_PDPHY_SIG_TX_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x17 PMIC_PDPHY_SIG_RX_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x17 PMIC_PDPHY_MSG_TX_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x17 PMIC_PDPHY_MSG_RX_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x17 PMIC_PDPHY_MSG_TX_FAIL_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x17 PMIC_PDPHY_MSG_TX_DISCARD_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x17 PMIC_PDPHY_MSG_RX_DISCARD_IRQ
> +				      IRQ_TYPE_EDGE_RISING>,
> +				     <0x2 0x17 PMIC_PDPHY_FR_SWAP_IRQ
> +				      IRQ_TYPE_EDGE_RISING>;
> +			interrupt-names = "sig-tx",
> +					  "sig-rx",
> +					  "msg-tx",
> +					  "msg-rx",
> +					  "msg-tx-failed",
> +					  "msg-tx-discarded",
> +					  "msg-rx-discarded",
> +					  "fr-swap";
> +			vdd-phy-supply = <&vreg_l2a_3p1>;
This belongs in the board dt, it references nodes defined there.

The rest lgtm, I think!

Konrad
> +		};
> +
>  		pm8150b_temp: temp-alarm@2400 {
>  			compatible = "qcom,spmi-temp-alarm";
>  			reg = <0x2400>;

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection
  2023-03-18 12:18 ` [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection Bryan O'Donoghue
@ 2023-03-18 16:42   ` kernel test robot
  2023-03-20 11:15   ` Neil Armstrong
  1 sibling, 0 replies; 72+ messages in thread
From: kernel test robot @ 2023-03-18 16:42 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: oe-kbuild-all, wcheng, caleb.connolly, bryan.odonoghue,
	konrad.dybcio, subbaram, jackp, robertom, Dmitry Baryshkov

Hi Bryan,

I love your patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on usb/usb-next usb/usb-linus robh/for-next broonie-regulator/for-next lee-mfd/for-mfd-next linus/master v6.3-rc2 next-20230317]
[cannot apply to lee-mfd/for-mfd-fixes]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Bryan-O-Donoghue/dt-bindings-regulator-qcom-usb-vbus-regulator-Mark-reg-as-required/20230318-202034
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link:    https://lore.kernel.org/r/20230318121828.739424-14-bryan.odonoghue%40linaro.org
patch subject: [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230319/202303190010.w3QR1CU6-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/76d1e355779b094d3ddb20776b0835215dc3646c
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Bryan-O-Donoghue/dt-bindings-regulator-qcom-usb-vbus-regulator-Mark-reg-as-required/20230318-202034
        git checkout 76d1e355779b094d3ddb20776b0835215dc3646c
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/phy/qualcomm/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303190010.w3QR1CU6-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/phy/qualcomm/phy-qcom-qmp-combo.c: In function 'qmp_combo_typec_switch_set':
>> drivers/phy/qualcomm/phy-qcom-qmp-combo.c:3383:13: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
    3383 |         int ret = 0;
         |             ^~~


vim +/ret +3383 drivers/phy/qualcomm/phy-qcom-qmp-combo.c

  3376	
  3377	#if IS_ENABLED(CONFIG_PHY_QCOM_QMP_TYPEC)
  3378	static int qmp_combo_typec_switch_set(struct typec_switch_dev *sw,
  3379					      enum typec_orientation orientation)
  3380	{
  3381		struct qmp_combo *qmp = typec_switch_get_drvdata(sw);
  3382		struct phy *dp_phy = qmp->dp_phy;
> 3383		int ret = 0;
  3384	
  3385		dev_dbg(qmp->dev, "Toggling orientation current %d requested %d\n",
  3386			qmp->orientation, orientation);
  3387	
  3388		qmp->orientation = orientation;
  3389	
  3390		if (orientation == TYPEC_ORIENTATION_NONE) {
  3391			if (qmp->init_count)
  3392				ret = qmp_combo_dp_power_off(dp_phy);
  3393		} else {
  3394			if (!qmp->init_count)
  3395				ret = qmp_combo_dp_power_on(dp_phy);
  3396		}
  3397	
  3398		return 0;
  3399	}
  3400	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 17/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for usb_1
  2023-03-18 13:10   ` Konrad Dybcio
@ 2023-03-18 17:46     ` Bryan O'Donoghue
  0 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 17:46 UTC (permalink / raw)
  To: Konrad Dybcio, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, subbaram, jackp, robertom

On 18/03/2023 13:10, Konrad Dybcio wrote:
>> +	usb-role-switch;
> This could maybe go to the SoC DTSI.. Bjorn, Krzysztof, WDYT?

Eh well I think this is a correct comment.

There's no good reason to have this as board-specific since it is a 
controller property. Moreover it only does something when there is a an 
agent to feed data into it.

arch/arm64/boot/dts/qcom/sc7280.dtsi:				usb-role-switch;

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 18/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for usb_1_qmpphy
  2023-03-18 13:11   ` Konrad Dybcio
@ 2023-03-18 17:47     ` Bryan O'Donoghue
  0 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-18 17:47 UTC (permalink / raw)
  To: Konrad Dybcio, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, subbaram, jackp, robertom

On 18/03/2023 13:11, Konrad Dybcio wrote:
>> +	orientation-switch;
> I think this property could be put in the SoC DTSI, the hardware
> does support roleswitching

Orientation switching, yes.

It is a PHY not a board property.

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description
  2023-03-18 12:18 ` [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description Bryan O'Donoghue
  2023-03-18 13:13   ` Konrad Dybcio
@ 2023-03-18 21:09   ` kernel test robot
  1 sibling, 0 replies; 72+ messages in thread
From: kernel test robot @ 2023-03-18 21:09 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: oe-kbuild-all, wcheng, caleb.connolly, bryan.odonoghue,
	konrad.dybcio, subbaram, jackp, robertom

Hi Bryan,

I love your patch! Yet something to improve:

[auto build test ERROR on usb/usb-testing]
[also build test ERROR on usb/usb-next usb/usb-linus robh/for-next broonie-regulator/for-next lee-mfd/for-mfd-next linus/master v6.3-rc2 next-20230317]
[cannot apply to lee-mfd/for-mfd-fixes]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Bryan-O-Donoghue/dt-bindings-regulator-qcom-usb-vbus-regulator-Mark-reg-as-required/20230318-202034
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link:    https://lore.kernel.org/r/20230318121828.739424-15-bryan.odonoghue%40linaro.org
patch subject: [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description
config: arm-randconfig-r046-20230319 (https://download.01.org/0day-ci/archive/20230319/202303190420.SG155iKR-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/f22a2d4f99f0527b2429c054e4c918c2dee8ec89
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Bryan-O-Donoghue/dt-bindings-regulator-qcom-usb-vbus-regulator-Mark-reg-as-required/20230318-202034
        git checkout f22a2d4f99f0527b2429c054e4c918c2dee8ec89
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303190420.SG155iKR-lkp@intel.com/

All errors (new ones prefixed by >>):

>> ERROR: Input tree has errors, aborting (use -f to force output)

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 01/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required
  2023-03-18 12:18 ` [PATCH v4 01/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required Bryan O'Donoghue
@ 2023-03-19 11:41   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:41 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> Mark reg as a required property.

Please say why. What you did is easily visible from the diff.

> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 02/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark regulator-*-microamp required
  2023-03-18 12:18 ` [PATCH v4 02/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark regulator-*-microamp required Bryan O'Donoghue
@ 2023-03-19 11:42   ` Krzysztof Kozlowski
  2023-03-19 11:53   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:42 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> The VBUS driver needs to know the regulator-min-microamp and
> regulator-max-microamp so they should both be marked as required.
> 
> regulator.yaml defines those two dependencies so include regulator.yaml.
> 
> We need to change from additionalProperties: false to
> unevaluatedProperties: false.
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 03/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add orientation-switch as optional
  2023-03-18 12:18 ` [PATCH v4 03/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add orientation-switch as optional Bryan O'Donoghue
@ 2023-03-19 11:42   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:42 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> orientation-switch it the standard declaration to inform the Type-C mux
> layer that a remote-endpoint is capable of processing orientation change
> messages.
> 
> Add as an optional since not all versions of the dp-phy currently support
> the orientation-switch.


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional
  2023-03-18 12:18 ` [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional Bryan O'Donoghue
@ 2023-03-19 11:45   ` Krzysztof Kozlowski
  2023-03-21 20:49     ` Rob Herring
  0 siblings, 1 reply; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:45 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> port is required to instantiate a remote-endpoint which can receive
> orientation-switch messages from a Type-C mux.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  .../bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml           | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
> index 52886cdb0e506..1c887e34b1223 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
> @@ -65,6 +65,12 @@ properties:
>      description: Flag the port as possible handler of orientation switching
>      type: boolean
>  
> +  port:
> +    $ref: /schemas/graph.yaml#/properties/port
> +    description:
> +      A port node to link the PHY to a TypeC controller for the purpose of
> +      handling altmode muxing and orientation switching.

Please extend the example as well.

Don't you have there two ports? USB and DP?

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 05/18] dt-bindings: usb: Add qcom,pmic-typec dt-binding header
  2023-03-18 12:18 ` [PATCH v4 05/18] dt-bindings: usb: Add qcom,pmic-typec dt-binding header Bryan O'Donoghue
@ 2023-03-19 11:50   ` Krzysztof Kozlowski
  2023-03-19 14:50     ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:50 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> Adds a series of defines which are used in the DTS and type-c driver for
> identifying interrupts.

I see your driver uses them, but I don't understand why and what for...
Why would we define them as bindings? We do not define interrupt numbers
as bindings. Why the driver needs it?

> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  .../dt-bindings/usb/typec/qcom,pmic-typec.h    | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>  create mode 100644 include/dt-bindings/usb/typec/qcom,pmic-typec.h
> 
> diff --git a/include/dt-bindings/usb/typec/qcom,pmic-typec.h b/include/dt-bindings/usb/typec/qcom,pmic-typec.h
> new file mode 100644
> index 0000000000000..733e23b6cdbc4
> --- /dev/null
> +++ b/include/dt-bindings/usb/typec/qcom,pmic-typec.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */

If the file stays: dual license.

And squash it with next patch. Binding headers are not a separate
feature. It's the same as adding bindings.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 07/18] dt-bindings: usb: Add qcom,pmic-pdphy dt-binding header
  2023-03-18 12:18 ` [PATCH v4 07/18] dt-bindings: usb: Add qcom,pmic-pdphy dt-binding header Bryan O'Donoghue
@ 2023-03-19 11:50   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:50 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> Adds a series of defines which are used in the DTS and pdphy driver for
> identifying interrupts.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  .../dt-bindings/usb/typec/qcom,pmic-pdphy.h    | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>  create mode 100644 include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
> 
> diff --git a/include/dt-bindings/usb/typec/qcom,pmic-pdphy.h b/include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
> new file mode 100644
> index 0000000000000..7d39985bcc779
> --- /dev/null
> +++ b/include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */

Same comments, same questions.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 06/18] dt-bindings: usb: Add Qualcomm PMIC Type-C controller YAML schema
  2023-03-18 12:18 ` [PATCH v4 06/18] dt-bindings: usb: Add Qualcomm PMIC Type-C controller YAML schema Bryan O'Donoghue
@ 2023-03-19 11:53   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:53 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> Add a YAML binding for the Type-C silicon interface inside Qualcomm's
> pm8150b hardware block.
> 
> The Type-C driver operates with a pdphy driver inside of a high level
> single TCPM device.
> 
> Based on original work by Wesley.
> 
> Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  .../bindings/usb/qcom,pmic-typec.yaml         | 88 +++++++++++++++++++
>  1 file changed, 88 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
> 
> diff --git a/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml b/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
> new file mode 100644
> index 0000000000000..d87bbab88d8be
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/usb/qcom,pmic-typec.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"

Drop quotes.

> +
> +title: Qualcomm PMIC based USB type C Detection Driver

Drop "Driver"

> +
> +maintainers:
> +  - Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> +
> +description: |
> +  Qualcomm PMIC Type C Detect

Drop description - it is useless here - or make it something more, a
proper description.

> +
> +properties:
> +  compatible:
> +    enum:
> +      - qcom,pm8150b-typec
> +
> +  reg:
> +    maxItems: 1
> +    description: Type C base address

Drop description

> +
> +  interrupts:
> +    items:
> +      - description: Bitmask of CC attach, VBUS error, tCCDebounce done and more
> +      - description: VCONN Powered Detection
> +      - description: CC state change
> +      - description: VCONN over-current condition
> +      - description: VBUS state change
> +      - description: Attach Deteach notification
> +      - description: Legacy cable detect
> +      - description: Try.Src Try.Snk state change

These are the same as binding headers, thus it suggests header change is
meaningless.

> +
> +  interrupt-names:
> +    items:
> +      - const: or-rid-detect-change
> +      - const: vpd-detect
> +      - const: cc-state-change
> +      - const: vconn-oc
> +      - const: vbus-change
> +      - const: attach-detach
> +      - const: legacy-cable-detect
> +      - const: try-snk-src-detect
> +
> +  vdd-vbus-supply:
> +    description: VBUS power supply.

The name is usually vbus-supply.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - interrupt-names
> +  - vdd-vbus-supply
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/usb/typec/qcom,pmic-typec.h>
> +    pm8150b {

Node names should be generic, so pmic.
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation

> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 02/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark regulator-*-microamp required
  2023-03-18 12:18 ` [PATCH v4 02/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark regulator-*-microamp required Bryan O'Donoghue
  2023-03-19 11:42   ` Krzysztof Kozlowski
@ 2023-03-19 11:53   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:53 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> The VBUS driver needs to know the regulator-min-microamp and
> regulator-max-microamp so they should both be marked as required.
> 
> regulator.yaml defines those two dependencies so include regulator.yaml.
> 
> We need to change from additionalProperties: false to
> unevaluatedProperties: false.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  .../bindings/regulator/qcom,usb-vbus-regulator.yaml      | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
> index 7a3b59f836092..f6ecb0f72ad9a 100644
> --- a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
> +++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml
> @@ -14,6 +14,9 @@ description: |
>    regulator will be enabled in situations where the device is required to
>    provide power to the connected peripheral.
>  
> +allOf:
> +  - $ref: "regulator.yaml#"

Drop quotes.



Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 08/18] dt-bindings: usb: Add Qualcomm PMIC PDPHY controller YAML schema
  2023-03-18 12:18 ` [PATCH v4 08/18] dt-bindings: usb: Add Qualcomm PMIC PDPHY controller YAML schema Bryan O'Donoghue
@ 2023-03-19 11:55   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:55 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> Add a YAML binding for the power-delivery PHY silicon interface inside
> Qualcomm's pm8150b hardware block.

Subject: drop second/last, redundant "YAML schema". The "dt-bindings"
prefix is already stating that.

This applies to other patches as well.


> 
> The pdphy driver operates with a type-c driver inside of a high level
> single TCPM device to provide overall TCPM functionality.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  .../bindings/usb/qcom,pmic-pdphy.yaml         | 89 +++++++++++++++++++
>  1 file changed, 89 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml b/Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml
> new file mode 100644
> index 0000000000000..79318e3da41e6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml
> @@ -0,0 +1,89 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/usb/qcom,pmic-pdphy.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"

All comments from previous patch apply

> +

> +title: Qualcomm PMIC based USB PDPHY driver
> +
> +maintainers:
> +  - Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> +
> +description: |
> +  Qualcomm PMIC Power Delivery PHY driver
> +

> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/usb/typec/qcom,pmic-pdphy.h>
> +
> +    pm8150b {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        pm8150b_pdphy: pdphy@1700 {

I guess: phy@
(and drop the label)

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-18 12:18 ` [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM " Bryan O'Donoghue
@ 2023-03-19 11:58   ` Krzysztof Kozlowski
  2023-03-19 14:59     ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:58 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> Add a YAML description for the pm8150b-tcpm driver. The pm8150b-tcpm

No, do not add YAML description for driver.

Please add bindings for some hardware and describe the hardware.

> encapsulates a type-c block and a pdphy block into one block presented to
> the TCPM Linux API.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  .../bindings/usb/qcom,pmic-virt-tcpm.yaml     | 88 +++++++++++++++++++
>  1 file changed, 88 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml
> 
> diff --git a/Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml b/Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml
> new file mode 100644
> index 0000000000000..576842c8b65b4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/usb/qcom,pmic-virt-tcpm.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Qualcomm PMIC Virtual TCPM Driver

All previous comments apply.

> +
> +maintainers:
> +  - Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> +
> +description: |
> +  Qualcomm PMIC Virtual Type-C Port Manager Driver
> +  A virtual device which manages Qualcomm PMIC provided Type-C port and
> +  Power Delivery in one place.

OK, so it looks like bindings for driver, so a no-go. Unless there is
such device as "manager", this does not look like hardware description.

> +
> +properties:
> +  compatible:
> +    const: qcom,pmic-virt-tcpm
> +
> +  connector:
> +    type: object
> +    $ref: /schemas/connector/usb-connector.yaml#
> +    unevaluatedProperties: false
> +
> +  port:
> +    $ref: /schemas/graph.yaml#/properties/port
> +    description:
> +      Contains a port which consumes data-role switching messages.
> +
> +  qcom,pmic-typec:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      A phandle to the typec port hardware driver.
> +
> +  qcom,pmic-pdphy:
> +    $ref: /schemas/types.yaml#/definitions/phandle

Having typec and phy as phandles - not children - also suggests this is
some software construct, not hardware description.



Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 10/18] dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types
  2023-03-18 12:18 ` [PATCH v4 10/18] dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types Bryan O'Donoghue
@ 2023-03-19 11:58   ` Krzysztof Kozlowski
  2023-03-21 20:58     ` Rob Herring
  0 siblings, 1 reply; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:58 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> The PDPHY sits inside of the PMIC SPMI block providing register-level
> ability to read/write USB Type-C Power Delivery protocol packets over the
> SBU pins.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> index 8f076bb622b15..111aec53caeb5 100644
> --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> @@ -140,6 +140,10 @@ patternProperties:
>      type: object
>      $ref: /schemas/power/reset/qcom,pon.yaml#
>  
> +  "pdphy@[0-9a-f]+$":

phy@



Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 11/18] dt-bindings: mfd: qcom,spmi-pmic: Add typec to SPMI device types
  2023-03-18 12:18 ` [PATCH v4 11/18] dt-bindings: mfd: qcom,spmi-pmic: Add typec " Bryan O'Donoghue
@ 2023-03-19 11:59   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 11:59 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 18/03/2023 13:18, Bryan O'Donoghue wrote:> Add the PMIC Type-C port
driver to the list of devices.

Either drop driver everywhere or drop the patches. We do not add drivers
to the bindings.


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 05/18] dt-bindings: usb: Add qcom,pmic-typec dt-binding header
  2023-03-19 11:50   ` Krzysztof Kozlowski
@ 2023-03-19 14:50     ` Bryan O'Donoghue
  0 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-19 14:50 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 19/03/2023 11:50, Krzysztof Kozlowski wrote:
> And squash it with next patch. Binding headers are not a separate
> feature. It's the same as adding bindings.

Actually I can drop these headers, you're right.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-19 11:58   ` Krzysztof Kozlowski
@ 2023-03-19 14:59     ` Bryan O'Donoghue
  2023-03-19 15:10       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-19 14:59 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 19/03/2023 11:58, Krzysztof Kozlowski wrote:
>> +
>> +maintainers:
>> +  - Bryan O'Donoghue<bryan.odonoghue@linaro.org>
>> +
>> +description: |
>> +  Qualcomm PMIC Virtual Type-C Port Manager Driver
>> +  A virtual device which manages Qualcomm PMIC provided Type-C port and
>> +  Power Delivery in one place.
> OK, so it looks like bindings for driver, so a no-go. Unless there is
> such device as "manager", this does not look like hardware description.
> 
>> +
>> +properties:
>> +  compatible:
>> +    const: qcom,pmic-virt-tcpm
>> +
>> +  connector:
>> +    type: object
>> +    $ref: /schemas/connector/usb-connector.yaml#
>> +    unevaluatedProperties: false
>> +
>> +  port:
>> +    $ref: /schemas/graph.yaml#/properties/port
>> +    description:
>> +      Contains a port which consumes data-role switching messages.
>> +
>> +  qcom,pmic-typec:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description:
>> +      A phandle to the typec port hardware driver.
>> +
>> +  qcom,pmic-pdphy:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
> Having typec and phy as phandles - not children - also suggests this is
> some software construct, not hardware description.

So probably I didn't interpret Rob's comment correctly here.

For a pure software device - a virtual device - there should be no dts 
representation at all - not even at the firmware{}, chosen{}, rpm{} 
level, it wouldn't be possible/acceptable to have a tcpm {} with a 
compat pointing to the two phandles I have here ?

---
bod



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-19 14:59     ` Bryan O'Donoghue
@ 2023-03-19 15:10       ` Krzysztof Kozlowski
  2023-03-19 15:44         ` Bryan O'Donoghue
  2023-03-19 15:50         ` Bryan O'Donoghue
  0 siblings, 2 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 15:10 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 19/03/2023 15:59, Bryan O'Donoghue wrote:
> On 19/03/2023 11:58, Krzysztof Kozlowski wrote:
>>> +
>>> +maintainers:
>>> +  - Bryan O'Donoghue<bryan.odonoghue@linaro.org>
>>> +
>>> +description: |
>>> +  Qualcomm PMIC Virtual Type-C Port Manager Driver
>>> +  A virtual device which manages Qualcomm PMIC provided Type-C port and
>>> +  Power Delivery in one place.
>> OK, so it looks like bindings for driver, so a no-go. Unless there is
>> such device as "manager", this does not look like hardware description.
>>
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: qcom,pmic-virt-tcpm
>>> +
>>> +  connector:
>>> +    type: object
>>> +    $ref: /schemas/connector/usb-connector.yaml#
>>> +    unevaluatedProperties: false
>>> +
>>> +  port:
>>> +    $ref: /schemas/graph.yaml#/properties/port
>>> +    description:
>>> +      Contains a port which consumes data-role switching messages.
>>> +
>>> +  qcom,pmic-typec:
>>> +    $ref: /schemas/types.yaml#/definitions/phandle
>>> +    description:
>>> +      A phandle to the typec port hardware driver.
>>> +
>>> +  qcom,pmic-pdphy:
>>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> Having typec and phy as phandles - not children - also suggests this is
>> some software construct, not hardware description.
> 
> So probably I didn't interpret Rob's comment correctly here.

He proposed to merge it with other node:
"probably merged with
one of the nodes these phandles point to."

"Why can't most of this binding be part of"

I don't see how you implemented his comments. Actually, nothing improved
here in this regard - you still have these phandles.

> 
> For a pure software device - a virtual device - there should be no dts 
> representation at all - not even at the firmware{}, chosen{}, rpm{} 

By software we interpret here HLOS, so Linux. Firmware is FW, thus not
software in that context. rpm{} is some firmware on some processor.

You wrote here bindings/nodes for a Linux driver.

> level, it wouldn't be possible/acceptable to have a tcpm {} with a 
> compat pointing to the two phandles I have here ?

What is tcpm? Linux driver? Then not. You cannot have device nodes for a
Linux driver.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-19 15:10       ` Krzysztof Kozlowski
@ 2023-03-19 15:44         ` Bryan O'Donoghue
  2023-03-19 17:50           ` Krzysztof Kozlowski
  2023-03-19 15:50         ` Bryan O'Donoghue
  1 sibling, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-19 15:44 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 19/03/2023 15:10, Krzysztof Kozlowski wrote:
> On 19/03/2023 15:59, Bryan O'Donoghue wrote:
>> On 19/03/2023 11:58, Krzysztof Kozlowski wrote:
>>>> +
>>>> +maintainers:
>>>> +  - Bryan O'Donoghue<bryan.odonoghue@linaro.org>
>>>> +
>>>> +description: |
>>>> +  Qualcomm PMIC Virtual Type-C Port Manager Driver
>>>> +  A virtual device which manages Qualcomm PMIC provided Type-C port and
>>>> +  Power Delivery in one place.
>>> OK, so it looks like bindings for driver, so a no-go. Unless there is
>>> such device as "manager", this does not look like hardware description.
>>>
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    const: qcom,pmic-virt-tcpm
>>>> +
>>>> +  connector:
>>>> +    type: object
>>>> +    $ref: /schemas/connector/usb-connector.yaml#
>>>> +    unevaluatedProperties: false
>>>> +
>>>> +  port:
>>>> +    $ref: /schemas/graph.yaml#/properties/port
>>>> +    description:
>>>> +      Contains a port which consumes data-role switching messages.
>>>> +
>>>> +  qcom,pmic-typec:
>>>> +    $ref: /schemas/types.yaml#/definitions/phandle
>>>> +    description:
>>>> +      A phandle to the typec port hardware driver.
>>>> +
>>>> +  qcom,pmic-pdphy:
>>>> +    $ref: /schemas/types.yaml#/definitions/phandle
>>> Having typec and phy as phandles - not children - also suggests this is
>>> some software construct, not hardware description.
>>
>> So probably I didn't interpret Rob's comment correctly here.
> 
> He proposed to merge it with other node:
> "probably merged with
> one of the nodes these phandles point to."
> 
> "Why can't most of this binding be part of"
> 
> I don't see how you implemented his comments. Actually, nothing improved
> here in this regard - you still have these phandles.

So this comment from Rob is what I was aiming for

"Your other option is instantiate your own device from the virtual
driver's initcall based on presence of the 2 nodes above. "

rather than two mush the pdphy and typec into one device, which they are 
not.

I guess what I'm trying to understand is how you guys would suggest that 
is actually done.

Could I trouble you for an example ?

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-19 15:10       ` Krzysztof Kozlowski
  2023-03-19 15:44         ` Bryan O'Donoghue
@ 2023-03-19 15:50         ` Bryan O'Donoghue
  1 sibling, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-19 15:50 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 19/03/2023 15:10, Krzysztof Kozlowski wrote:
> What is tcpm? Linux driver? Then not. You cannot have device nodes for a
> Linux driver.

Hmm. Well, actually I'll just - concatonate these into one node but, it 
will have to be called something like "typec" and encompass both 
hardware blocks.

I'll try to make the name of that make sense.

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-19 15:44         ` Bryan O'Donoghue
@ 2023-03-19 17:50           ` Krzysztof Kozlowski
  2023-03-19 21:31             ` Caleb Connolly
  2023-03-19 22:32             ` Bryan O'Donoghue
  0 siblings, 2 replies; 72+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-19 17:50 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 19/03/2023 16:44, Bryan O'Donoghue wrote:
> On 19/03/2023 15:10, Krzysztof Kozlowski wrote:
>> On 19/03/2023 15:59, Bryan O'Donoghue wrote:
>>> On 19/03/2023 11:58, Krzysztof Kozlowski wrote:
>>>>> +
>>>>> +maintainers:
>>>>> +  - Bryan O'Donoghue<bryan.odonoghue@linaro.org>
>>>>> +
>>>>> +description: |
>>>>> +  Qualcomm PMIC Virtual Type-C Port Manager Driver
>>>>> +  A virtual device which manages Qualcomm PMIC provided Type-C port and
>>>>> +  Power Delivery in one place.
>>>> OK, so it looks like bindings for driver, so a no-go. Unless there is
>>>> such device as "manager", this does not look like hardware description.
>>>>
>>>>> +
>>>>> +properties:
>>>>> +  compatible:
>>>>> +    const: qcom,pmic-virt-tcpm
>>>>> +
>>>>> +  connector:
>>>>> +    type: object
>>>>> +    $ref: /schemas/connector/usb-connector.yaml#
>>>>> +    unevaluatedProperties: false
>>>>> +
>>>>> +  port:
>>>>> +    $ref: /schemas/graph.yaml#/properties/port
>>>>> +    description:
>>>>> +      Contains a port which consumes data-role switching messages.
>>>>> +
>>>>> +  qcom,pmic-typec:
>>>>> +    $ref: /schemas/types.yaml#/definitions/phandle
>>>>> +    description:
>>>>> +      A phandle to the typec port hardware driver.
>>>>> +
>>>>> +  qcom,pmic-pdphy:
>>>>> +    $ref: /schemas/types.yaml#/definitions/phandle
>>>> Having typec and phy as phandles - not children - also suggests this is
>>>> some software construct, not hardware description.
>>>
>>> So probably I didn't interpret Rob's comment correctly here.
>>
>> He proposed to merge it with other node:
>> "probably merged with
>> one of the nodes these phandles point to."
>>
>> "Why can't most of this binding be part of"
>>
>> I don't see how you implemented his comments. Actually, nothing improved
>> here in this regard - you still have these phandles.
> 
> So this comment from Rob is what I was aiming for
> 
> "Your other option is instantiate your own device from the virtual
> driver's initcall based on presence of the 2 nodes above. "
> 
> rather than two mush the pdphy and typec into one device, which they are 
> not.

Sure, but you did not instantiate anything based on these two or one
nodes. You added virtual device node.


> I guess what I'm trying to understand is how you guys would suggest that 
> is actually done.

You have there already node for the PMIC USB Type-C, so this should be
part of it. I really do not understand why this is separate device lying
around in parallel like:

pmic {
	usb {
	};
};

virtual- pmic-tcpm {
};

What hardware piece does such description represent?

> 
> Could I trouble you for an example ?
> 
> ---
> bod

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-19 17:50           ` Krzysztof Kozlowski
@ 2023-03-19 21:31             ` Caleb Connolly
  2023-03-19 22:34               ` Bryan O'Donoghue
  2023-03-19 22:32             ` Bryan O'Donoghue
  1 sibling, 1 reply; 72+ messages in thread
From: Caleb Connolly @ 2023-03-19 21:31 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Bryan O'Donoghue, linux,
	heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, konrad.dybcio, subbaram, jackp, robertom



On 19/03/2023 17:50, Krzysztof Kozlowski wrote:
> On 19/03/2023 16:44, Bryan O'Donoghue wrote:
>> On 19/03/2023 15:10, Krzysztof Kozlowski wrote:
>>> On 19/03/2023 15:59, Bryan O'Donoghue wrote:
>>>> On 19/03/2023 11:58, Krzysztof Kozlowski wrote:
>>>>>> +
>>>>>> +maintainers:
>>>>>> +  - Bryan O'Donoghue<bryan.odonoghue@linaro.org>
>>>>>> +
>>>>>> +description: |
>>>>>> +  Qualcomm PMIC Virtual Type-C Port Manager Driver
>>>>>> +  A virtual device which manages Qualcomm PMIC provided Type-C port and
>>>>>> +  Power Delivery in one place.
>>>>> OK, so it looks like bindings for driver, so a no-go. Unless there is
>>>>> such device as "manager", this does not look like hardware description.
>>>>>
>>>>>> +
>>>>>> +properties:
>>>>>> +  compatible:
>>>>>> +    const: qcom,pmic-virt-tcpm
>>>>>> +
>>>>>> +  connector:
>>>>>> +    type: object
>>>>>> +    $ref: /schemas/connector/usb-connector.yaml#
>>>>>> +    unevaluatedProperties: false
>>>>>> +
>>>>>> +  port:
>>>>>> +    $ref: /schemas/graph.yaml#/properties/port
>>>>>> +    description:
>>>>>> +      Contains a port which consumes data-role switching messages.
>>>>>> +
>>>>>> +  qcom,pmic-typec:
>>>>>> +    $ref: /schemas/types.yaml#/definitions/phandle
>>>>>> +    description:
>>>>>> +      A phandle to the typec port hardware driver.
>>>>>> +
>>>>>> +  qcom,pmic-pdphy:
>>>>>> +    $ref: /schemas/types.yaml#/definitions/phandle
>>>>> Having typec and phy as phandles - not children - also suggests this is
>>>>> some software construct, not hardware description.
>>>>
>>>> So probably I didn't interpret Rob's comment correctly here.
>>>
>>> He proposed to merge it with other node:
>>> "probably merged with
>>> one of the nodes these phandles point to."
>>>
>>> "Why can't most of this binding be part of"
>>>
>>> I don't see how you implemented his comments. Actually, nothing improved
>>> here in this regard - you still have these phandles.
>>
>> So this comment from Rob is what I was aiming for
>>
>> "Your other option is instantiate your own device from the virtual
>> driver's initcall based on presence of the 2 nodes above. "
>>
>> rather than two mush the pdphy and typec into one device, which they are 
>> not.
> 
> Sure, but you did not instantiate anything based on these two or one
> nodes. You added virtual device node.
> 
> 
>> I guess what I'm trying to understand is how you guys would suggest that 
>> is actually done.
> 
> You have there already node for the PMIC USB Type-C, so this should be
> part of it. I really do not understand why this is separate device lying
> around in parallel like:

The pdphy is fairly well encapsulated (3 tcpm callbacks go to it, that's
all?), I think the tcpm part could be merged in with the typec driver
and it could just have a phandle to the pdphy node to represent the
dependency.

Then in the typec driver you can get the device with
spmi_device_from_of() and call into it that way for the few tcpm
callbacks that it needs to handle and to pass in the tcpm_port.


> 
> pmic {
> 	usb {
> 	};
> };
> 
> virtual- pmic-tcpm {
> };
> 
> What hardware piece does such description represent?
> 
>>
>> Could I trouble you for an example ?
>>
>> ---
>> bod
> 
> Best regards,
> Krzysztof
> 

-- 
Kind Regards,
Caleb (they/them)

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-19 17:50           ` Krzysztof Kozlowski
  2023-03-19 21:31             ` Caleb Connolly
@ 2023-03-19 22:32             ` Bryan O'Donoghue
  1 sibling, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-19 22:32 UTC (permalink / raw)
  To: Krzysztof Kozlowski, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 19/03/2023 17:50, Krzysztof Kozlowski wrote:
>> So this comment from Rob is what I was aiming for
>>
>> "Your other option is instantiate your own device from the virtual
>> driver's initcall based on presence of the 2 nodes above. "
>>
>> rather than two mush the pdphy and typec into one device, which they are
>> not.
> Sure, but you did not instantiate anything based on these two or one
> nodes. You added virtual device node.

Yes true, but I see the distinction you are making.

> 
>> I guess what I'm trying to understand is how you guys would suggest that
>> is actually done.
> You have there already node for the PMIC USB Type-C, so this should be
> part of it. I really do not understand why this is separate device lying
> around in parallel like:
> 
> pmic {
> 	usb {
> 	};
> };
> 
> virtual- pmic-tcpm {
> };
> 
> What hardware piece does such description represent?
> 

None, yes its a "HLOS" convenience, I take your point.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
  2023-03-19 21:31             ` Caleb Connolly
@ 2023-03-19 22:34               ` Bryan O'Donoghue
  0 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-19 22:34 UTC (permalink / raw)
  To: Caleb Connolly, Krzysztof Kozlowski, linux, heikki.krogerus,
	gregkh, andersson, robh+dt, krzysztof.kozlowski+dt, linux-usb,
	linux-arm-msm, devicetree
  Cc: konrad.dybcio, subbaram, jackp, robertom

On 19/03/2023 21:31, Caleb Connolly wrote:
> The pdphy is fairly well encapsulated (3 tcpm callbacks go to it, that's
> all?), I think the tcpm part could be merged in with the typec driver
> and it could just have a phandle to the pdphy node to represent the
> dependency.
> 
> Then in the typec driver you can get the device with
> spmi_device_from_of() and call into it that way for the few tcpm
> callbacks that it needs to handle and to pass in the tcpm_port.

Yes or just have one "typec" device own both register banks

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection
  2023-03-18 12:18 ` [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection Bryan O'Donoghue
  2023-03-18 16:42   ` kernel test robot
@ 2023-03-20 11:15   ` Neil Armstrong
  2023-03-20 11:19     ` Bryan O'Donoghue
  1 sibling, 1 reply; 72+ messages in thread
From: Neil Armstrong @ 2023-03-20 11:15 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom,
	Dmitry Baryshkov

Hi,

On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> The lane select switch for USB typec orientation is within the USB QMP PHY.
> the current device.  It could be connected through an endpoint, to an
> independent device handling the typec detection, ie the QCOM SPMI typec
> driver.
> 
> bod: Fixed the logic qcom_qmp_phy_typec_switch_set() to disable phy
>   on disconnect if and only if we have initialized the PHY.
>   Retained CC orientation logic in qcom_qmp_phy_com_init() to simplify
>   patch.
> 
> bod: Ported from earlier version of driver to phy-qcom-qmp-combo.c
> 
> Co-developed-by: Wesley Cheng <wcheng@codeaurora.org>
> Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
> Co-developed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/phy/qualcomm/Kconfig              |  8 +++
>   drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 80 +++++++++++++++++++++--
>   2 files changed, 84 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
> index 4850d48f31fa1..8240fffdbed4e 100644
> --- a/drivers/phy/qualcomm/Kconfig
> +++ b/drivers/phy/qualcomm/Kconfig
> @@ -101,6 +101,14 @@ config PHY_QCOM_QMP_USB
>   
>   endif # PHY_QCOM_QMP
>   
> +config PHY_QCOM_QMP_TYPEC
> +	def_bool PHY_QCOM_QMP=y && TYPEC=y || PHY_QCOM_QMP=m && TYPEC
> +	help
> +	  Register a type C switch from the QMP PHY driver for type C
> +	  orientation support.  This has dependencies with if the type C kernel
> +	  configuration is enabled or not.  This support will not be present if
> +	  USB type C is disabled.

Is there a reason to only enable the TypeC logic with a config ?

If unlinked from DT it won't be used, so no need to add a new config for that.

Neil

> +
>   config PHY_QCOM_QUSB2
>   	tristate "Qualcomm QUSB2 PHY Driver"
>   	depends on OF && (ARCH_QCOM || COMPILE_TEST)
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> index c1483e157af4a..afe708c63557d 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
> @@ -19,6 +19,7 @@
>   #include <linux/regulator/consumer.h>
>   #include <linux/reset.h>
>   #include <linux/slab.h>
> +#include <linux/usb/typec_mux.h>
>   
>   #include <dt-bindings/phy/phy-qcom-qmp.h>
>   
> @@ -63,6 +64,10 @@
>   /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
>   #define CLAMP_EN				BIT(0) /* enables i/o clamp_n */
>   
> +/* QPHY_V3_DP_COM_TYPEC_CTRL register bits */
> +#define SW_PORTSELECT_VAL			BIT(0)
> +#define SW_PORTSELECT_MUX			BIT(1)
> +
>   #define PHY_INIT_COMPLETE_TIMEOUT		10000
>   
>   struct qmp_phy_init_tbl {
> @@ -1323,6 +1328,9 @@ struct qmp_combo {
>   	struct clk_fixed_rate pipe_clk_fixed;
>   	struct clk_hw dp_link_hw;
>   	struct clk_hw dp_pixel_hw;
> +
> +	struct typec_switch_dev *sw;
> +	enum typec_orientation orientation;
>   };
>   
>   static void qmp_v3_dp_aux_init(struct qmp_combo *qmp);
> @@ -1970,7 +1978,8 @@ static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp)
>   static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp)
>   {
>   	u32 val;
> -	bool reverse = false;
> +	bool reverse = qmp->orientation == TYPEC_ORIENTATION_REVERSE;
> +	const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
>   
>   	val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
>   	      DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
> @@ -1989,10 +1998,18 @@ static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp)
>   	 * if (orientation == ORIENTATION_CC2)
>   	 *	writel(0x4c, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_MODE);
>   	 */
> +	if (dp_opts->lanes == 4 || reverse)
> +		val |= DP_PHY_PD_CTL_LANE_0_1_PWRDN;
> +	if (dp_opts->lanes == 4 || !reverse)
> +		val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
> +
>   	val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
>   	writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
>   
> -	writel(0x5c, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE);
> +	if (reverse)
> +		writel(0x4c, qmp->pcs + QSERDES_DP_PHY_MODE);
> +	else
> +		writel(0x5c, qmp->pcs + QSERDES_DP_PHY_MODE);
>   
>   	return reverse;
>   }
> @@ -2476,6 +2493,7 @@ static int qmp_combo_com_init(struct qmp_combo *qmp)
>   {
>   	const struct qmp_phy_cfg *cfg = qmp->cfg;
>   	void __iomem *com = qmp->com;
> +	u32 val;
>   	int ret;
>   
>   	mutex_lock(&qmp->phy_mutex);
> @@ -2513,8 +2531,11 @@ static int qmp_combo_com_init(struct qmp_combo *qmp)
>   			SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
>   			SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
>   
> -	/* Default type-c orientation, i.e CC1 */
> -	qphy_setbits(com, QPHY_V3_DP_COM_TYPEC_CTRL, 0x02);
> +	/* Latch CC orientation based on reported state by TCPM */
> +	val = SW_PORTSELECT_MUX;
> +	if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
> +		val |= SW_PORTSELECT_VAL;
> +	qphy_setbits(com, QPHY_V3_DP_COM_TYPEC_CTRL, val);
>   
>   	qphy_setbits(com, QPHY_V3_DP_COM_PHY_MODE_CTRL, USB3_MODE | DP_MODE);
>   
> @@ -3353,6 +3374,53 @@ static struct phy *qmp_combo_phy_xlate(struct device *dev, struct of_phandle_arg
>   	return ERR_PTR(-EINVAL);
>   }
>   
> +#if IS_ENABLED(CONFIG_PHY_QCOM_QMP_TYPEC)
> +static int qmp_combo_typec_switch_set(struct typec_switch_dev *sw,
> +				      enum typec_orientation orientation)
> +{
> +	struct qmp_combo *qmp = typec_switch_get_drvdata(sw);
> +	struct phy *dp_phy = qmp->dp_phy;
> +	int ret = 0;
> +
> +	dev_dbg(qmp->dev, "Toggling orientation current %d requested %d\n",
> +		qmp->orientation, orientation);
> +
> +	qmp->orientation = orientation;
> +
> +	if (orientation == TYPEC_ORIENTATION_NONE) {
> +		if (qmp->init_count)
> +			ret = qmp_combo_dp_power_off(dp_phy);
> +	} else {
> +		if (!qmp->init_count)
> +			ret = qmp_combo_dp_power_on(dp_phy);
> +	}
> +
> +	return 0;
> +}
> +
> +static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
> +{
> +	struct typec_switch_desc sw_desc;
> +	struct device *dev = qmp->dev;
> +
> +	sw_desc.drvdata = qmp;
> +	sw_desc.fwnode = dev->fwnode;
> +	sw_desc.set = qmp_combo_typec_switch_set;
> +	qmp->sw = typec_switch_register(dev, &sw_desc);
> +	if (IS_ERR(qmp->sw)) {
> +		dev_err(dev, "Error registering typec switch: %ld\n",
> +			PTR_ERR(qmp->sw));
> +	}
> +
> +	return 0;
> +}
> +#else
> +static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
> +{
> +	return 0;
> +}
> +#endif
> +
>   static int qmp_combo_probe(struct platform_device *pdev)
>   {
>   	struct qmp_combo *qmp;
> @@ -3443,6 +3511,10 @@ static int qmp_combo_probe(struct platform_device *pdev)
>   	else
>   		phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
>   
> +	ret = qmp_combo_typec_switch_register(qmp);
> +	if (ret)
> +		goto err_node_put;
> +
>   	of_node_put(usb_np);
>   	of_node_put(dp_np);
>   


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection
  2023-03-20 11:15   ` Neil Armstrong
@ 2023-03-20 11:19     ` Bryan O'Donoghue
  0 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-20 11:19 UTC (permalink / raw)
  To: neil.armstrong, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom,
	Dmitry Baryshkov

On 20/03/2023 11:15, Neil Armstrong wrote:
>> +    def_bool PHY_QCOM_QMP=y && TYPEC=y || PHY_QCOM_QMP=m && TYPEC
>> +    help
>> +      Register a type C switch from the QMP PHY driver for type C
>> +      orientation support.  This has dependencies with if the type C 
>> kernel
>> +      configuration is enabled or not.  This support will not be 
>> present if
>> +      USB type C is disabled.
> 
> Is there a reason to only enable the TypeC logic with a config ?
> 
> If unlinked from DT it won't be used, so no need to add a new config for 
> that.
> 
> Neil

ack, np

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional
  2023-03-19 11:45   ` Krzysztof Kozlowski
@ 2023-03-21 20:49     ` Rob Herring
  2023-03-22 14:01       ` Bryan O'Donoghue
  2023-03-23 13:39       ` Bryan O'Donoghue
  0 siblings, 2 replies; 72+ messages in thread
From: Rob Herring @ 2023-03-21 20:49 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On Sun, Mar 19, 2023 at 12:45:13PM +0100, Krzysztof Kozlowski wrote:
> On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> > port is required to instantiate a remote-endpoint which can receive
> > orientation-switch messages from a Type-C mux.
> > 
> > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> > ---
> >  .../bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml           | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
> > index 52886cdb0e506..1c887e34b1223 100644
> > --- a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
> > @@ -65,6 +65,12 @@ properties:
> >      description: Flag the port as possible handler of orientation switching
> >      type: boolean
> >  
> > +  port:
> > +    $ref: /schemas/graph.yaml#/properties/port
> > +    description:
> > +      A port node to link the PHY to a TypeC controller for the purpose of
> > +      handling altmode muxing and orientation switching.
> 
> Please extend the example as well.
> 
> Don't you have there two ports? USB and DP?

Or 3: USB, DP, and connector.

Please make sure this all aligns with what Bjorn and I discussed 
recently. It was for glink specifically.

Rob

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 10/18] dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types
  2023-03-19 11:58   ` Krzysztof Kozlowski
@ 2023-03-21 20:58     ` Rob Herring
  2023-03-21 23:52       ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Rob Herring @ 2023-03-21 20:58 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On Sun, Mar 19, 2023 at 12:58:48PM +0100, Krzysztof Kozlowski wrote:
> On 18/03/2023 13:18, Bryan O'Donoghue wrote:
> > The PDPHY sits inside of the PMIC SPMI block providing register-level
> > ability to read/write USB Type-C Power Delivery protocol packets over the
> > SBU pins.
> > 
> > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> > ---
> >  Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> > index 8f076bb622b15..111aec53caeb5 100644
> > --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> > +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
> > @@ -140,6 +140,10 @@ patternProperties:
> >      type: object
> >      $ref: /schemas/power/reset/qcom,pon.yaml#
> >  
> > +  "pdphy@[0-9a-f]+$":
> 
> phy@

But it is not a phy which I would define as something doing digital to 
analog (or vice-versa) signal conversion/encoding. Sounds like an SBU 
controller or something...

Rob

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 10/18] dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types
  2023-03-21 20:58     ` Rob Herring
@ 2023-03-21 23:52       ` Bryan O'Donoghue
  0 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-21 23:52 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski
  Cc: linux, heikki.krogerus, gregkh, andersson,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 21/03/2023 20:58, Rob Herring wrote:
> On Sun, Mar 19, 2023 at 12:58:48PM +0100, Krzysztof Kozlowski wrote:
>> On 18/03/2023 13:18, Bryan O'Donoghue wrote:
>>> The PDPHY sits inside of the PMIC SPMI block providing register-level
>>> ability to read/write USB Type-C Power Delivery protocol packets over the
>>> SBU pins.
>>>
>>> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>>> ---
>>>   Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 4 ++++
>>>   1 file changed, 4 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
>>> index 8f076bb622b15..111aec53caeb5 100644
>>> --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
>>> +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
>>> @@ -140,6 +140,10 @@ patternProperties:
>>>       type: object
>>>       $ref: /schemas/power/reset/qcom,pon.yaml#
>>>   
>>> +  "pdphy@[0-9a-f]+$":
>>
>> phy@
> 
> But it is not a phy which I would define as something doing digital to
> analog (or vice-versa) signal conversion/encoding. Sounds like an SBU
> controller or something...
> 
> Rob

Its an SBU controller.

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional
  2023-03-21 20:49     ` Rob Herring
@ 2023-03-22 14:01       ` Bryan O'Donoghue
  2023-03-23 13:39       ` Bryan O'Donoghue
  1 sibling, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-22 14:01 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski
  Cc: linux, heikki.krogerus, gregkh, andersson,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 21/03/2023 20:49, Rob Herring wrote:
> On Sun, Mar 19, 2023 at 12:45:13PM +0100, Krzysztof Kozlowski wrote:
>> On 18/03/2023 13:18, Bryan O'Donoghue wrote:
>>> port is required to instantiate a remote-endpoint which can receive
>>> orientation-switch messages from a Type-C mux.
>>>
>>> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>>> ---
>>>   .../bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml           | 6 ++++++
>>>   1 file changed, 6 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
>>> index 52886cdb0e506..1c887e34b1223 100644
>>> --- a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
>>> @@ -65,6 +65,12 @@ properties:
>>>       description: Flag the port as possible handler of orientation switching
>>>       type: boolean
>>>   
>>> +  port:
>>> +    $ref: /schemas/graph.yaml#/properties/port
>>> +    description:
>>> +      A port node to link the PHY to a TypeC controller for the purpose of
>>> +      handling altmode muxing and orientation switching.
>>
>> Please extend the example as well.
>>
>> Don't you have there two ports? USB and DP?
> 
> Or 3: USB, DP, and connector.
> 
> Please make sure this all aligns with what Bjorn and I discussed
> recently. It was for glink specifically.
> 
> Rob

Hmm.

Thanks for mentioning this.

I had erroneously built the orientation endpoint into the connector 
during development and was just carrying that in my patches.

This

&pm8150b_typec {
         status = "okay";
         port {
                 usb3_role: endpoint {
                         remote-endpoint = <&dwc3_drd_switch>;
                 };
         };

         connector {
                 compatible = "usb-c-connector";

                 power-role = "source";
                 data-role = "dual";
                 self-powered;

                 source-pdos = <PDO_FIXED(5000, 3000,
                                          PDO_FIXED_DUAL_ROLE |
                                          PDO_FIXED_USB_COMM |
                                          PDO_FIXED_DATA_SWAP)>;

                 ports {
                         #address-cells = <1>;
                         #size-cells = <0>;

                         port@0 {
                                 reg = <0>;
                                 pmic_tcpm_ss_mux: endpoint {
                                         remote-endpoint = <&qmp_ss_mux>;
                                 };
                         };
                 };
         };
};


Should be this

&pm8150b_typec {
         status = "okay";
         ports {
                 #address-cells = <1>;
                 #size-cells = <0>;

                 port@0 {
                         reg = <0>;
                         pmic_tcpm_ss_mux: endpoint {
                                 remote-endpoint = <&qmp_ss_mux>;
                         };
                 };

                 port@1 {
                         usb3_role: endpoint {
                                 remote-endpoint = <&dwc3_drd_switch>;
                         };
                 };
         };

         connector {
                 compatible = "usb-c-connector";

                 power-role = "source";
                 data-role = "dual";
                 self-powered;

                 source-pdos = <PDO_FIXED(5000, 3000,
                                          PDO_FIXED_DUAL_ROLE |
                                          PDO_FIXED_USB_COMM |
                                          PDO_FIXED_DATA_SWAP)>;
         };
};

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional
  2023-03-21 20:49     ` Rob Herring
  2023-03-22 14:01       ` Bryan O'Donoghue
@ 2023-03-23 13:39       ` Bryan O'Donoghue
  1 sibling, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-23 13:39 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski
  Cc: linux, heikki.krogerus, gregkh, andersson,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 21/03/2023 20:49, Rob Herring wrote:
> On Sun, Mar 19, 2023 at 12:45:13PM +0100, Krzysztof Kozlowski wrote:
>> On 18/03/2023 13:18, Bryan O'Donoghue wrote:
>>> port is required to instantiate a remote-endpoint which can receive
>>> orientation-switch messages from a Type-C mux.
>>>
>>> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>>> ---
>>>   .../bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml           | 6 ++++++
>>>   1 file changed, 6 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
>>> index 52886cdb0e506..1c887e34b1223 100644
>>> --- a/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
>>> +++ b/Documentation/devicetree/bindings/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml
>>> @@ -65,6 +65,12 @@ properties:
>>>       description: Flag the port as possible handler of orientation switching
>>>       type: boolean
>>>   
>>> +  port:
>>> +    $ref: /schemas/graph.yaml#/properties/port
>>> +    description:
>>> +      A port node to link the PHY to a TypeC controller for the purpose of
>>> +      handling altmode muxing and orientation switching.
>>
>> Please extend the example as well.
>>
>> Don't you have there two ports? USB and DP?
> 
> Or 3: USB, DP, and connector.
> 
> Please make sure this all aligns with what Bjorn and I discussed
> recently. It was for glink specifically.
> 
> Rob

This is a PHY though, the DP, USB endpoints will go into the connector 
or into the typec node itself.

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-18 12:18 ` [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support Bryan O'Donoghue
@ 2023-03-23 14:36   ` Jianhua Lu
  2023-03-23 17:31     ` Bryan O'Donoghue
  2023-03-24 14:00   ` Heikki Krogerus
  1 sibling, 1 reply; 72+ messages in thread
From: Jianhua Lu @ 2023-03-23 14:36 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On Sat, Mar 18, 2023 at 12:18:22PM +0000, Bryan O'Donoghue wrote:
> This commit adds a QCOM PMIC TCPM driver with an initial pm8150b
> block.
> 
> qcom_pmic_virt_tcpm.c : Responsible for registering with TCPM and
>                         arbitrates access to the Type-C and PDPHY hardware
>                         blocks in one place.
>                         This driver presents a virtual device to the Linux
>                         TCPM layer.
> 
> qcom_pmic_pdphy.c: Rsponsible for interfacing with the PDPHY hardware and
>                    processing power-delivery related calls from TCPM.
>                    This hardware binding can be extended to facilitate
>                    similar hardware in different PMICs.
> 
> qcom_pmic_typec.c: Responsible for notifying and processing Type-C
>                    related calls from TCPM.
>                    This hardware binding can be extended to facilitate
>                    similar hardware in different PMICs.
> 
> This code provides all of the same functionality as the existing
> qcom typec driver plus power-delivery as well.
> 
> As a result commit 6c8cf3695176 ("usb: typec: Add QCOM PMIC typec detection
> driver") can be deleted entirely.
> 
> References code from Jonathan Marek, Jack Pham, Wesley Cheng, Hemant Kumar,
> Guru Das Srinagesh and Ashay Jaiswal.
> 
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>  MAINTAINERS                                   |  10 +
>  drivers/usb/typec/Kconfig                     |  13 -
>  drivers/usb/typec/Makefile                    |   1 -
>  drivers/usb/typec/qcom-pmic-typec.c           | 261 -------
>  drivers/usb/typec/tcpm/Kconfig                |  11 +
>  drivers/usb/typec/tcpm/Makefile               |   1 +
>  drivers/usb/typec/tcpm/qcom/Makefile          |   6 +
>  drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c | 605 +++++++++++++++++
>  drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h |  85 +++
>  drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 637 ++++++++++++++++++
>  drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h | 163 +++++
>  .../usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c | 326 +++++++++
>  12 files changed, 1844 insertions(+), 275 deletions(-)
>  delete mode 100644 drivers/usb/typec/qcom-pmic-typec.c
>  create mode 100644 drivers/usb/typec/tcpm/qcom/Makefile
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9b218dc388323..59f8a3c0b6364 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -17435,6 +17435,16 @@ S:	Maintained
>  F:	Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
>  F:	drivers/thermal/qcom/
>  
> +QUALCOMM TYPEC PORT MANAGER DRIVER
> +M:	Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> +L:	linux-arm-msm@vger.kernel.org
> +L:	linux-usb@vger.kernel.org
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/usb/qcom,pmic-*.yaml
> +F:	drivers/usb/typec/tcpm/qcom/
> +F:	include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
> +F:	include/dt-bindings/usb/typec/qcom,pmic-typec.h
> +
>  QUALCOMM VENUS VIDEO ACCELERATOR DRIVER
>  M:	Stanimir Varbanov <stanimir.k.varbanov@gmail.com>
>  M:	Vikash Garodia <quic_vgarodia@quicinc.com>
> diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
> index 831e7049977df..2f80c2792dbda 100644
> --- a/drivers/usb/typec/Kconfig
> +++ b/drivers/usb/typec/Kconfig
> @@ -100,19 +100,6 @@ 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_PMIC
> -	tristate "Qualcomm PMIC USB Type-C driver"
> -	depends on ARCH_QCOM || COMPILE_TEST
> -	depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH
> -	help
> -	  Driver for supporting role switch over the Qualcomm PMIC.  This will
> -	  handle the USB Type-C role and orientation detection reported by the
> -	  QCOM PMIC if the PMIC has the capability to handle USB Type-C
> -	  detection.
> -
> -	  It will also enable the VBUS output to connected devices when a
> -	  DFP connection is made.
> -
>  config TYPEC_WUSB3801
>  	tristate "Willsemi WUSB3801 Type-C port controller driver"
>  	depends on I2C
> diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
> index 4a83dad51a6cf..7a368fea61bc9 100644
> --- a/drivers/usb/typec/Makefile
> +++ b/drivers/usb/typec/Makefile
> @@ -8,7 +8,6 @@ obj-$(CONFIG_TYPEC_UCSI)	+= ucsi/
>  obj-$(CONFIG_TYPEC_TPS6598X)	+= tipd/
>  obj-$(CONFIG_TYPEC_ANX7411)	+= anx7411.o
>  obj-$(CONFIG_TYPEC_HD3SS3220)	+= hd3ss3220.o
> -obj-$(CONFIG_TYPEC_QCOM_PMIC)	+= qcom-pmic-typec.o
>  obj-$(CONFIG_TYPEC_STUSB160X) 	+= stusb160x.o
>  obj-$(CONFIG_TYPEC_RT1719)	+= rt1719.o
>  obj-$(CONFIG_TYPEC_WUSB3801)	+= wusb3801.o
> diff --git a/drivers/usb/typec/qcom-pmic-typec.c b/drivers/usb/typec/qcom-pmic-typec.c
> deleted file mode 100644
> index 432ea62f1bab6..0000000000000
> --- a/drivers/usb/typec/qcom-pmic-typec.c
> +++ /dev/null
> @@ -1,261 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * Copyright (c) 2020, The Linux Foundation. All rights reserved.
> - */
> -
> -#include <linux/err.h>
> -#include <linux/interrupt.h>
> -#include <linux/kernel.h>
> -#include <linux/mod_devicetable.h>
> -#include <linux/module.h>
> -#include <linux/platform_device.h>
> -#include <linux/regmap.h>
> -#include <linux/regulator/consumer.h>
> -#include <linux/slab.h>
> -#include <linux/usb/role.h>
> -#include <linux/usb/typec_mux.h>
> -
> -#define TYPEC_MISC_STATUS		0xb
> -#define CC_ATTACHED			BIT(0)
> -#define CC_ORIENTATION			BIT(1)
> -#define SNK_SRC_MODE			BIT(6)
> -#define TYPEC_MODE_CFG			0x44
> -#define TYPEC_DISABLE_CMD		BIT(0)
> -#define EN_SNK_ONLY			BIT(1)
> -#define EN_SRC_ONLY			BIT(2)
> -#define TYPEC_VCONN_CONTROL		0x46
> -#define VCONN_EN_SRC			BIT(0)
> -#define VCONN_EN_VAL			BIT(1)
> -#define TYPEC_EXIT_STATE_CFG		0x50
> -#define SEL_SRC_UPPER_REF		BIT(2)
> -#define TYPEC_INTR_EN_CFG_1		0x5e
> -#define TYPEC_INTR_EN_CFG_1_MASK	GENMASK(7, 0)
> -
> -struct qcom_pmic_typec {
> -	struct device		*dev;
> -	struct regmap		*regmap;
> -	u32			base;
> -
> -	struct typec_port	*port;
> -	struct usb_role_switch *role_sw;
> -
> -	struct regulator	*vbus_reg;
> -	bool			vbus_enabled;
> -};
> -
> -static void qcom_pmic_typec_enable_vbus_regulator(struct qcom_pmic_typec
> -							*qcom_usb, bool enable)
> -{
> -	int ret;
> -
> -	if (enable == qcom_usb->vbus_enabled)
> -		return;
> -
> -	if (enable) {
> -		ret = regulator_enable(qcom_usb->vbus_reg);
> -		if (ret)
> -			return;
> -	} else {
> -		ret = regulator_disable(qcom_usb->vbus_reg);
> -		if (ret)
> -			return;
> -	}
> -	qcom_usb->vbus_enabled = enable;
> -}
> -
> -static void qcom_pmic_typec_check_connection(struct qcom_pmic_typec *qcom_usb)
> -{
> -	enum typec_orientation orientation;
> -	enum usb_role role;
> -	unsigned int stat;
> -	bool enable_vbus;
> -
> -	regmap_read(qcom_usb->regmap, qcom_usb->base + TYPEC_MISC_STATUS,
> -		    &stat);
> -
> -	if (stat & CC_ATTACHED) {
> -		orientation = (stat & CC_ORIENTATION) ?
> -				TYPEC_ORIENTATION_REVERSE :
> -				TYPEC_ORIENTATION_NORMAL;
> -		typec_set_orientation(qcom_usb->port, orientation);
> -
> -		role = (stat & SNK_SRC_MODE) ? USB_ROLE_HOST : USB_ROLE_DEVICE;
> -		if (role == USB_ROLE_HOST)
> -			enable_vbus = true;
> -		else
> -			enable_vbus = false;
> -	} else {
> -		role = USB_ROLE_NONE;
> -		enable_vbus = false;
> -	}
> -
> -	qcom_pmic_typec_enable_vbus_regulator(qcom_usb, enable_vbus);
> -	usb_role_switch_set_role(qcom_usb->role_sw, role);
> -}
> -
> -static irqreturn_t qcom_pmic_typec_interrupt(int irq, void *_qcom_usb)
> -{
> -	struct qcom_pmic_typec *qcom_usb = _qcom_usb;
> -
> -	qcom_pmic_typec_check_connection(qcom_usb);
> -	return IRQ_HANDLED;
> -}
> -
> -static void qcom_pmic_typec_typec_hw_init(struct qcom_pmic_typec *qcom_usb,
> -					  enum typec_port_type type)
> -{
> -	u8 mode = 0;
> -
> -	regmap_update_bits(qcom_usb->regmap,
> -			   qcom_usb->base + TYPEC_INTR_EN_CFG_1,
> -			   TYPEC_INTR_EN_CFG_1_MASK, 0);
> -
> -	if (type == TYPEC_PORT_SRC)
> -		mode = EN_SRC_ONLY;
> -	else if (type == TYPEC_PORT_SNK)
> -		mode = EN_SNK_ONLY;
> -
> -	regmap_update_bits(qcom_usb->regmap, qcom_usb->base + TYPEC_MODE_CFG,
> -			   EN_SNK_ONLY | EN_SRC_ONLY, mode);
> -
> -	regmap_update_bits(qcom_usb->regmap,
> -			   qcom_usb->base + TYPEC_VCONN_CONTROL,
> -			   VCONN_EN_SRC | VCONN_EN_VAL, VCONN_EN_SRC);
> -	regmap_update_bits(qcom_usb->regmap,
> -			   qcom_usb->base + TYPEC_EXIT_STATE_CFG,
> -			   SEL_SRC_UPPER_REF, SEL_SRC_UPPER_REF);
> -}
> -
> -static int qcom_pmic_typec_probe(struct platform_device *pdev)
> -{
> -	struct qcom_pmic_typec *qcom_usb;
> -	struct device *dev = &pdev->dev;
> -	struct fwnode_handle *fwnode;
> -	struct typec_capability cap;
> -	const char *buf;
> -	int ret, irq, role;
> -	u32 reg;
> -
> -	ret = device_property_read_u32(dev, "reg", &reg);
> -	if (ret < 0) {
> -		dev_err(dev, "missing base address\n");
> -		return ret;
> -	}
> -
> -	qcom_usb = devm_kzalloc(dev, sizeof(*qcom_usb), GFP_KERNEL);
> -	if (!qcom_usb)
> -		return -ENOMEM;
> -
> -	qcom_usb->dev = dev;
> -	qcom_usb->base = reg;
> -
> -	qcom_usb->regmap = dev_get_regmap(dev->parent, NULL);
> -	if (!qcom_usb->regmap) {
> -		dev_err(dev, "Failed to get regmap\n");
> -		return -EINVAL;
> -	}
> -
> -	qcom_usb->vbus_reg = devm_regulator_get(qcom_usb->dev, "usb_vbus");
> -	if (IS_ERR(qcom_usb->vbus_reg))
> -		return PTR_ERR(qcom_usb->vbus_reg);
> -
> -	fwnode = device_get_named_child_node(dev, "connector");
> -	if (!fwnode)
> -		return -EINVAL;
> -
> -	ret = fwnode_property_read_string(fwnode, "power-role", &buf);
> -	if (!ret) {
> -		role = typec_find_port_power_role(buf);
> -		if (role < 0)
> -			role = TYPEC_PORT_SNK;
> -	} else {
> -		role = TYPEC_PORT_SNK;
> -	}
> -	cap.type = role;
> -
> -	ret = fwnode_property_read_string(fwnode, "data-role", &buf);
> -	if (!ret) {
> -		role = typec_find_port_data_role(buf);
> -		if (role < 0)
> -			role = TYPEC_PORT_UFP;
> -	} else {
> -		role = TYPEC_PORT_UFP;
> -	}
> -	cap.data = role;
> -
> -	cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
> -	cap.fwnode = fwnode;
> -	qcom_usb->port = typec_register_port(dev, &cap);
> -	if (IS_ERR(qcom_usb->port)) {
> -		ret = PTR_ERR(qcom_usb->port);
> -		dev_err(dev, "Failed to register type c port %d\n", ret);
> -		goto err_put_node;
> -	}
> -	fwnode_handle_put(fwnode);
> -
> -	qcom_usb->role_sw = fwnode_usb_role_switch_get(dev_fwnode(qcom_usb->dev));
> -	if (IS_ERR(qcom_usb->role_sw)) {
> -		ret = dev_err_probe(dev, PTR_ERR(qcom_usb->role_sw),
> -				    "failed to get role switch\n");
> -		goto err_typec_port;
> -	}
> -
> -	irq = platform_get_irq(pdev, 0);
> -	if (irq < 0)
> -		goto err_usb_role_sw;
> -
> -	ret = devm_request_threaded_irq(qcom_usb->dev, irq, NULL,
> -					qcom_pmic_typec_interrupt, IRQF_ONESHOT,
> -					"qcom-pmic-typec", qcom_usb);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Could not request IRQ\n");
> -		goto err_usb_role_sw;
> -	}
> -
> -	platform_set_drvdata(pdev, qcom_usb);
> -	qcom_pmic_typec_typec_hw_init(qcom_usb, cap.type);
> -	qcom_pmic_typec_check_connection(qcom_usb);
> -
> -	return 0;
> -
> -err_usb_role_sw:
> -	usb_role_switch_put(qcom_usb->role_sw);
> -err_typec_port:
> -	typec_unregister_port(qcom_usb->port);
> -err_put_node:
> -	fwnode_handle_put(fwnode);
> -
> -	return ret;
> -}
> -
> -static int qcom_pmic_typec_remove(struct platform_device *pdev)
> -{
> -	struct qcom_pmic_typec *qcom_usb = platform_get_drvdata(pdev);
> -
> -	usb_role_switch_set_role(qcom_usb->role_sw, USB_ROLE_NONE);
> -	qcom_pmic_typec_enable_vbus_regulator(qcom_usb, 0);
> -
> -	typec_unregister_port(qcom_usb->port);
> -	usb_role_switch_put(qcom_usb->role_sw);
> -
> -	return 0;
> -}
> -
> -static const struct of_device_id qcom_pmic_typec_table[] = {
> -	{ .compatible = "qcom,pm8150b-usb-typec" },
> -	{ }
> -};
> -MODULE_DEVICE_TABLE(of, qcom_pmic_typec_table);
> -
> -static struct platform_driver qcom_pmic_typec = {
> -	.driver = {
> -		.name = "qcom,pmic-typec",
> -		.of_match_table = qcom_pmic_typec_table,
> -	},
> -	.probe = qcom_pmic_typec_probe,
> -	.remove = qcom_pmic_typec_remove,
> -};
> -module_platform_driver(qcom_pmic_typec);
> -
> -MODULE_DESCRIPTION("QCOM PMIC USB type C driver");
> -MODULE_LICENSE("GPL v2");
> diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
> index e6b88ca4a4b94..5d393f520fc2f 100644
> --- a/drivers/usb/typec/tcpm/Kconfig
> +++ b/drivers/usb/typec/tcpm/Kconfig
> @@ -76,4 +76,15 @@ config TYPEC_WCOVE
>  	  To compile this driver as module, choose M here: the module will be
>  	  called typec_wcove.ko
>  
> +config TYPEC_QCOM_PMIC
> +	tristate "Qualcomm PMIC USB Type-C Port Controller Manager driver"
> +	depends on ARCH_QCOM || COMPILE_TEST
> +	help
> +	  A Type-C port and Power Delivery driver which aggregates two
> +	  discrete pieces of silicon in the PM8150b PMIC block: the
> +	  Type-C port controller and the Power Delivery PHY.
> +
> +	  This driver enables Type-C role switching, orientation, Alternate
> +	  mode and Power Delivery support both for VBUS and VCONN.
> +
>  endif # TYPEC_TCPM
> diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
> index 08e57bb499cbc..7a8cad0c0bdb4 100644
> --- a/drivers/usb/typec/tcpm/Makefile
> +++ b/drivers/usb/typec/tcpm/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_TYPEC_MT6360)		+= tcpci_mt6360.o
>  obj-$(CONFIG_TYPEC_TCPCI_MT6370)	+= tcpci_mt6370.o
>  obj-$(CONFIG_TYPEC_TCPCI_MAXIM)		+= tcpci_maxim.o
>  tcpci_maxim-y				+= tcpci_maxim_core.o maxim_contaminant.o
> +obj-$(CONFIG_TYPEC_QCOM_PMIC)		+= qcom/
> diff --git a/drivers/usb/typec/tcpm/qcom/Makefile b/drivers/usb/typec/tcpm/qcom/Makefile
> new file mode 100644
> index 0000000000000..e78458292e0cf
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/Makefile
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +obj-$(CONFIG_TYPEC_QCOM_PMIC)		+= qcom_pmic_tcpm.o
> +qcom_pmic_tcpm-y			+= qcom_pmic_virt_tcpm.o \
> +					   qcom_pmic_typec.o \
> +					   qcom_pmic_pdphy.o
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c
> new file mode 100644
> index 0000000000000..746f6a79fc315
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c
> @@ -0,0 +1,605 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/usb/pd.h>
> +#include <linux/usb/tcpm.h>
> +#include <dt-bindings/usb/typec/qcom,pmic-pdphy.h>
> +#include "qcom_pmic_pdphy.h"
> +
> +#define PMIC_PDPHY_MAX_IRQS		0x08
> +
> +struct pmic_pdphy_irq_params {
> +	int				virq;
> +	char				*irq_name;
> +};
> +
> +struct pmic_pdphy_resources {
> +	unsigned int			nr_irqs;
> +	struct pmic_pdphy_irq_params	irq_params[PMIC_PDPHY_MAX_IRQS];
> +};
> +
> +struct pmic_pdphy_irq_data {
> +	int				virq;
> +	int				irq;
> +	struct pmic_pdphy		*pmic_pdphy;
> +};
> +
> +struct pmic_pdphy {
> +	struct device			*dev;
> +	struct tcpm_port		*tcpm_port;
> +	struct regmap			*regmap;
> +	u32				base;
> +
> +	unsigned int			nr_irqs;
> +	struct pmic_pdphy_irq_data	*irq_data;
> +
> +	struct work_struct		reset_work;
> +	struct work_struct		receive_work;
> +	struct regulator		*vdd_pdphy;
> +	spinlock_t			lock;		/* Register atomicity */
> +};
> +
> +static void qcom_pmic_pdphy_reset_on(struct pmic_pdphy *pmic_pdphy)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	int ret;
> +
> +	/* Terminate TX */
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, 0);
> +	if (ret)
> +		goto err;
> +
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_FRAME_FILTER_REG, 0);
> +	if (ret)
> +		goto err;
> +
> +	return;
> +err:
> +	dev_err(dev, "pd_reset_on error\n");
> +}
> +
> +static void qcom_pmic_pdphy_reset_off(struct pmic_pdphy *pmic_pdphy)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	int ret;
> +
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_FRAME_FILTER_REG,
> +			   FRAME_FILTER_EN_SOP | FRAME_FILTER_EN_HARD_RESET);
> +	if (ret)
> +		dev_err(dev, "pd_reset_off error\n");
> +}
> +
> +static void qcom_pmic_pdphy_sig_reset_work(struct work_struct *work)
> +{
> +	struct pmic_pdphy *pmic_pdphy = container_of(work, struct pmic_pdphy,
> +						     reset_work);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&pmic_pdphy->lock, flags);
> +
> +	qcom_pmic_pdphy_reset_on(pmic_pdphy);
> +	qcom_pmic_pdphy_reset_off(pmic_pdphy);
> +
> +	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
> +
> +	tcpm_pd_hard_reset(pmic_pdphy->tcpm_port);
> +}
> +
> +static int
> +qcom_pmic_pdphy_clear_tx_control_reg(struct pmic_pdphy *pmic_pdphy)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	unsigned int val;
> +	int ret;
> +
> +	/* Clear TX control register */
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, 0);
> +	if (ret)
> +		goto done;
> +
> +	/* Perform readback to ensure sufficient delay for command to latch */
> +	ret = regmap_read(pmic_pdphy->regmap,
> +			  pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, &val);
> +
> +done:
> +	if (ret)
> +		dev_err(dev, "pd_clear_tx_control_reg: clear tx flag\n");
> +
> +	return ret;
> +}
> +
> +static int
> +qcom_pmic_pdphy_pd_transmit_signal(struct pmic_pdphy *pmic_pdphy,
> +				   enum tcpm_transmit_type type,
> +				   unsigned int negotiated_rev)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	unsigned int val;
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&pmic_pdphy->lock, flags);
> +
> +	/* Clear TX control register */
> +	ret = qcom_pmic_pdphy_clear_tx_control_reg(pmic_pdphy);
> +	if (ret)
> +		goto done;
> +
> +	val = TX_CONTROL_SEND_SIGNAL;
> +	if (negotiated_rev == PD_REV30)
> +		val |= TX_CONTROL_RETRY_COUNT(2);
> +	else
> +		val |= TX_CONTROL_RETRY_COUNT(3);
> +
> +	if (type == TCPC_TX_CABLE_RESET || type == TCPC_TX_HARD_RESET)
> +		val |= TX_CONTROL_FRAME_TYPE(1);
> +
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, val);
> +
> +done:
> +	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
> +
> +	dev_vdbg(dev, "pd_transmit_signal: type %d negotiate_rev %d send %d\n",
> +		 type, negotiated_rev, ret);
> +
> +	return ret;
> +}
> +
> +static int
> +qcom_pmic_pdphy_pd_transmit_payload(struct pmic_pdphy *pmic_pdphy,
> +				    enum tcpm_transmit_type type,
> +				    const struct pd_message *msg,
> +				    unsigned int negotiated_rev)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	unsigned int val, hdr_len, txbuf_len, txsize_len;
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&pmic_pdphy->lock, flags);
> +
> +	ret = regmap_read(pmic_pdphy->regmap,
> +			  pmic_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG,
> +			  &val);
> +	if (ret)
> +		goto done;
> +
> +	if (val) {
> +		dev_err(dev, "pd_transmit_payload: RX message pending\n");
> +		ret = -EBUSY;
> +		goto done;
> +	}
> +
> +	/* Clear TX control register */
> +	ret = qcom_pmic_pdphy_clear_tx_control_reg(pmic_pdphy);
> +	if (ret)
> +		goto done;
> +
> +	hdr_len = sizeof(msg->header);
> +	txbuf_len = pd_header_cnt_le(msg->header) * 4;
> +	txsize_len = hdr_len + txbuf_len - 1;
> +
> +	/* Write message header sizeof(u16) to USB_PDPHY_TX_BUFFER_HDR_REG */
> +	ret = regmap_bulk_write(pmic_pdphy->regmap,
> +				pmic_pdphy->base + USB_PDPHY_TX_BUFFER_HDR_REG,
> +				&msg->header, hdr_len);
> +	if (ret)
> +		goto done;
> +
> +	/* Write payload to USB_PDPHY_TX_BUFFER_DATA_REG for txbuf_len */
> +	if (txbuf_len) {
> +		ret = regmap_bulk_write(pmic_pdphy->regmap,
> +					pmic_pdphy->base + USB_PDPHY_TX_BUFFER_DATA_REG,
> +					&msg->payload, txbuf_len);
> +		if (ret)
> +			goto done;
> +	}
> +
> +	/* Write total length ((header + data) - 1) to USB_PDPHY_TX_SIZE_REG */
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_TX_SIZE_REG,
> +			   txsize_len);
> +	if (ret)
> +		goto done;
> +
> +	/* Clear TX control register */
> +	ret = qcom_pmic_pdphy_clear_tx_control_reg(pmic_pdphy);
> +	if (ret)
> +		goto done;
> +
> +	/* Initiate transmit with retry count as indicated by PD revision */
> +	val = TX_CONTROL_FRAME_TYPE(type) | TX_CONTROL_SEND_MSG;
> +	if (pd_header_rev(msg->header) == PD_REV30)
> +		val |= TX_CONTROL_RETRY_COUNT(2);
> +	else
> +		val |= TX_CONTROL_RETRY_COUNT(3);
> +
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_TX_CONTROL_REG, val);
> +
> +done:
> +	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
> +
> +	if (ret) {
> +		dev_err(dev, "pd_transmit_payload: %d hdr %*ph data %*ph ret %d\n",
> +			ret, hdr_len, &msg->header, txbuf_len, &msg->payload, ret);
> +	}
> +
> +	return ret;
> +}
> +
> +int qcom_pmic_pdphy_pd_transmit(struct pmic_pdphy *pmic_pdphy,
> +				enum tcpm_transmit_type type,
> +				const struct pd_message *msg,
> +				unsigned int negotiated_rev)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	int ret;
> +
> +	if (msg) {
> +		ret = qcom_pmic_pdphy_pd_transmit_payload(pmic_pdphy, type, msg,
> +							  negotiated_rev);
> +	} else {
> +		ret = qcom_pmic_pdphy_pd_transmit_signal(pmic_pdphy, type,
> +							 negotiated_rev);
> +	}
> +
> +	if (ret)
> +		dev_dbg(dev, "pd_transmit: type %x result %d\n", type, ret);
> +
> +	return ret;
> +}
> +
> +static void qcom_pmic_pdphy_pd_receive(struct pmic_pdphy *pmic_pdphy)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	struct pd_message msg;
> +	unsigned int size, rx_status;
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&pmic_pdphy->lock, flags);
> +
> +	ret = regmap_read(pmic_pdphy->regmap,
> +			  pmic_pdphy->base + USB_PDPHY_RX_SIZE_REG, &size);
> +	if (ret)
> +		goto done;
> +
> +	/* If we received a subsequent RX sig this value can be zero */
> +	if ((size < 1 || size > sizeof(msg.payload))) {
> +		dev_dbg(dev, "pd_receive: invalid size %d\n", size);
> +		goto done;
> +	}
> +
> +	size += 1;
> +	ret = regmap_read(pmic_pdphy->regmap,
> +			  pmic_pdphy->base + USB_PDPHY_RX_STATUS_REG,
> +			  &rx_status);
> +
> +	if (ret)
> +		goto done;
> +
> +	ret = regmap_bulk_read(pmic_pdphy->regmap,
> +			       pmic_pdphy->base + USB_PDPHY_RX_BUFFER_REG,
> +			       (u8 *)&msg, size);
> +	if (ret)
> +		goto done;
> +
> +	/* Return ownership of RX buffer to hardware */
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG, 0);
> +
> +done:
> +	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
> +
> +	if (!ret) {
> +		dev_vdbg(dev, "pd_receive: handing %d bytes to tcpm\n", size);
> +		tcpm_pd_receive(pmic_pdphy->tcpm_port, &msg);
> +	}
> +}
> +
> +static irqreturn_t qcom_pmic_pdphy_isr(int irq, void *dev_id)
> +{
> +	struct pmic_pdphy_irq_data *irq_data = dev_id;
> +	struct pmic_pdphy *pmic_pdphy = irq_data->pmic_pdphy;
> +	struct device *dev = pmic_pdphy->dev;
> +
> +	switch (irq_data->virq) {
> +	case PMIC_PDPHY_SIG_TX_IRQ:
> +		dev_err(dev, "isr: tx_sig\n");
> +		break;
> +	case PMIC_PDPHY_SIG_RX_IRQ:
> +		schedule_work(&pmic_pdphy->reset_work);
> +		break;
> +	case PMIC_PDPHY_MSG_TX_IRQ:
> +		tcpm_pd_transmit_complete(pmic_pdphy->tcpm_port,
> +					  TCPC_TX_SUCCESS);
> +		break;
> +	case PMIC_PDPHY_MSG_RX_IRQ:
> +		qcom_pmic_pdphy_pd_receive(pmic_pdphy);
> +		break;
> +	case PMIC_PDPHY_MSG_TX_FAIL_IRQ:
> +		tcpm_pd_transmit_complete(pmic_pdphy->tcpm_port,
> +					  TCPC_TX_FAILED);
> +		break;
> +	case PMIC_PDPHY_MSG_TX_DISCARD_IRQ:
> +		tcpm_pd_transmit_complete(pmic_pdphy->tcpm_port,
> +					  TCPC_TX_DISCARDED);
> +		break;
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +int qcom_pmic_pdphy_set_pd_rx(struct pmic_pdphy *pmic_pdphy, bool on)
> +{
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&pmic_pdphy->lock, flags);
> +
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_RX_ACKNOWLEDGE_REG, !on);
> +
> +	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
> +
> +	dev_dbg(pmic_pdphy->dev, "set_pd_rx: %s\n", on ? "on" : "off");
> +
> +	return ret;
> +}
> +
> +int qcom_pmic_pdphy_set_roles(struct pmic_pdphy *pmic_pdphy,
> +			      bool data_role_host, bool power_role_src)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&pmic_pdphy->lock, flags);
> +
> +	ret = regmap_update_bits(pmic_pdphy->regmap,
> +				 pmic_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
> +				 MSG_CONFIG_PORT_DATA_ROLE |
> +				 MSG_CONFIG_PORT_POWER_ROLE,
> +				 data_role_host << 3 | power_role_src << 2);
> +
> +	spin_unlock_irqrestore(&pmic_pdphy->lock, flags);
> +
> +	dev_dbg(dev, "pdphy_set_roles: data_role_host=%d power_role_src=%d\n",
> +		data_role_host, power_role_src);
> +
> +	return ret;
> +}
> +
> +static int qcom_pmic_pdphy_enable(struct pmic_pdphy *pmic_pdphy)
> +{
> +	struct device *dev = pmic_pdphy->dev;
> +	int ret;
> +
> +	ret = regulator_enable(pmic_pdphy->vdd_pdphy);
> +	if (ret)
> +		return ret;
> +
> +	/* PD 2.0, DR=TYPEC_DEVICE, PR=TYPEC_SINK */
> +	ret = regmap_update_bits(pmic_pdphy->regmap,
> +				 pmic_pdphy->base + USB_PDPHY_MSG_CONFIG_REG,
> +				 MSG_CONFIG_SPEC_REV_MASK, PD_REV20);
> +	if (ret)
> +		goto done;
> +
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_EN_CONTROL_REG, 0);
> +	if (ret)
> +		goto done;
> +
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_EN_CONTROL_REG,
> +			   CONTROL_ENABLE);
> +	if (ret)
> +		goto done;
> +
> +	qcom_pmic_pdphy_reset_off(pmic_pdphy);
> +done:
> +	if (ret) {
> +		regulator_disable(pmic_pdphy->vdd_pdphy);
> +		dev_err(dev, "pdphy_enable fail %d\n", ret);
> +	}
> +
> +	return ret;
> +}
> +
> +static int qcom_pmic_pdphy_disable(struct pmic_pdphy *pmic_pdphy)
> +{
> +	int ret;
> +
> +	qcom_pmic_pdphy_reset_on(pmic_pdphy);
> +
> +	ret = regmap_write(pmic_pdphy->regmap,
> +			   pmic_pdphy->base + USB_PDPHY_EN_CONTROL_REG, 0);
> +
> +	regulator_disable(pmic_pdphy->vdd_pdphy);
> +
> +	return ret;
> +}
> +
> +static int pmic_pdphy_reset(struct pmic_pdphy *pmic_pdphy)
> +{
> +	int ret;
> +
> +	ret = qcom_pmic_pdphy_disable(pmic_pdphy);
> +	if (ret)
> +		goto done;
> +
> +	usleep_range(400, 500);
> +	ret = qcom_pmic_pdphy_enable(pmic_pdphy);
> +done:
> +	return ret;
> +}
> +
> +int qcom_pmic_pdphy_init(struct pmic_pdphy *pmic_pdphy,
> +			 struct tcpm_port *tcpm_port)
> +{
> +	int i;
> +	int ret;
> +
> +	pmic_pdphy->tcpm_port = tcpm_port;
> +
> +	ret = pmic_pdphy_reset(pmic_pdphy);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i < pmic_pdphy->nr_irqs; i++)
> +		enable_irq(pmic_pdphy->irq_data[i].irq);
> +
> +	return 0;
> +}
> +
> +void qcom_pmic_pdphy_put(struct pmic_pdphy *pmic_pdphy)
> +{
> +	put_device(pmic_pdphy->dev);
> +}
> +
> +static int qcom_pmic_pdphy_probe(struct platform_device *pdev)
> +{
> +	struct pmic_pdphy *pmic_pdphy;
> +	struct device *dev = &pdev->dev;
> +	const struct pmic_pdphy_resources *res;
> +	struct pmic_pdphy_irq_data *irq_data;
> +	int i, ret, irq;
> +	u32 reg;
> +
> +	ret = device_property_read_u32(dev, "reg", &reg);
> +	if (ret < 0) {
> +		dev_err(dev, "missing base address\n");
> +		return ret;
> +	}
> +
> +	res = of_device_get_match_data(dev);
> +	if (!res)
> +		return -ENODEV;
> +
> +	if (!res->nr_irqs || res->nr_irqs > PMIC_PDPHY_MAX_IRQS)
> +		return -EINVAL;
> +
> +	pmic_pdphy = devm_kzalloc(dev, sizeof(*pmic_pdphy), GFP_KERNEL);
> +	if (!pmic_pdphy)
> +		return -ENOMEM;
> +
> +	irq_data = devm_kzalloc(dev, sizeof(*irq_data) * res->nr_irqs,
> +				GFP_KERNEL);
> +	if (!irq_data)
> +		return -ENOMEM;
> +
> +	pmic_pdphy->vdd_pdphy = devm_regulator_get(dev, "vdd-pdphy");
> +	if (IS_ERR(pmic_pdphy->vdd_pdphy))
> +		return PTR_ERR(pmic_pdphy->vdd_pdphy);
> +
> +	pmic_pdphy->dev = dev;
> +	pmic_pdphy->base = reg;
> +	pmic_pdphy->nr_irqs = res->nr_irqs;
> +	pmic_pdphy->irq_data = irq_data;
> +	spin_lock_init(&pmic_pdphy->lock);
> +	INIT_WORK(&pmic_pdphy->reset_work, qcom_pmic_pdphy_sig_reset_work);
> +
> +	pmic_pdphy->regmap = dev_get_regmap(dev->parent, NULL);
> +	if (!pmic_pdphy->regmap) {
> +		dev_err(dev, "Failed to get regmap\n");
> +		return -ENODEV;
> +	}
> +
> +	platform_set_drvdata(pdev, pmic_pdphy);
> +	for (i = 0; i < res->nr_irqs; i++, irq_data++) {
> +		irq = platform_get_irq_byname(pdev, res->irq_params[i].irq_name);
> +		if (irq < 0)
> +			return irq;
> +
> +		irq_data->pmic_pdphy = pmic_pdphy;
> +		irq_data->irq = irq;
> +		irq_data->virq = res->irq_params[i].virq;
> +
> +		ret = devm_request_threaded_irq(dev, irq, NULL,
> +						qcom_pmic_pdphy_isr,
> +						IRQF_ONESHOT | IRQF_NO_AUTOEN,
> +						res->irq_params[i].irq_name,
> +						irq_data);
> +		if (ret)
> +			return ret;
> +	}
> +	return 0;
> +}
> +
> +static int qcom_pmic_pdphy_remove(struct platform_device *pdev)
> +{
> +	struct pmic_pdphy *pmic_pdphy = platform_get_drvdata(pdev);
> +
> +	qcom_pmic_pdphy_reset_on(pmic_pdphy);
> +
> +	return 0;
> +}
> +
> +static struct pmic_pdphy_resources pm8150b_pdphy_res = {
> +	.irq_params = {
> +		{
> +			.virq = PMIC_PDPHY_SIG_TX_IRQ,
> +			.irq_name = "sig-tx",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_SIG_RX_IRQ,
> +			.irq_name = "sig-rx",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_TX_IRQ,
> +			.irq_name = "msg-tx",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_RX_IRQ,
> +			.irq_name = "msg-rx",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_TX_FAIL_IRQ,
> +			.irq_name = "msg-tx-failed",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_TX_DISCARD_IRQ,
> +			.irq_name = "msg-tx-discarded",
> +		},
> +		{
> +			.virq = PMIC_PDPHY_MSG_RX_DISCARD_IRQ,
> +			.irq_name = "msg-rx-discarded",
> +		},
> +	},
> +	.nr_irqs = 7,
> +};
> +
> +static const struct of_device_id qcom_pmic_pdphy_table[] = {
> +	{ .compatible = "qcom,pm8150b-pdphy", .data = &pm8150b_pdphy_res },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, qcom_pmic_pdphy_table);
> +
> +struct platform_driver qcom_pmic_pdphy_platform_driver = {
> +	.driver = {
> +		.name = "qcom,pmic-usb-pdphy",
> +		.of_match_table = qcom_pmic_pdphy_table,
> +	},
> +	.probe = qcom_pmic_pdphy_probe,
> +	.remove = qcom_pmic_pdphy_remove,
> +};
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h
> new file mode 100644
> index 0000000000000..ac64139d4fe93
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h
> @@ -0,0 +1,85 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
> + * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> + */
> +#ifndef __QCOM_PMIC_PDPHY_H__
> +#define __QCOM_PMIC_PDPHY_H__
> +
> +#define USB_PDPHY_MAX_DATA_OBJ_LEN	28
> +#define USB_PDPHY_MSG_HDR_LEN		2
> +
> +/* PD PHY register offsets and bit fields */
> +#define USB_PDPHY_MSG_CONFIG_REG	0x40
> +#define MSG_CONFIG_PORT_DATA_ROLE	BIT(3)
> +#define MSG_CONFIG_PORT_POWER_ROLE	BIT(2)
> +#define MSG_CONFIG_SPEC_REV_MASK	(BIT(1) | BIT(0))
> +
> +#define USB_PDPHY_EN_CONTROL_REG	0x46
> +#define CONTROL_ENABLE			BIT(0)
> +
> +#define USB_PDPHY_RX_STATUS_REG		0x4A
> +#define RX_FRAME_TYPE			(BIT(0) | BIT(1) | BIT(2))
> +
> +#define USB_PDPHY_FRAME_FILTER_REG	0x4C
> +#define FRAME_FILTER_EN_HARD_RESET	BIT(5)
> +#define FRAME_FILTER_EN_SOP		BIT(0)
> +
> +#define USB_PDPHY_TX_SIZE_REG		0x42
> +#define TX_SIZE_MASK			0xF
> +
> +#define USB_PDPHY_TX_CONTROL_REG	0x44
> +#define TX_CONTROL_RETRY_COUNT(n)	(((n) & 0x3) << 5)
> +#define TX_CONTROL_FRAME_TYPE(n)        (((n) & 0x7) << 2)
> +#define TX_CONTROL_FRAME_TYPE_CABLE_RESET	(0x1 << 2)
> +#define TX_CONTROL_SEND_SIGNAL		BIT(1)
> +#define TX_CONTROL_SEND_MSG		BIT(0)
> +
> +#define USB_PDPHY_RX_SIZE_REG		0x48
> +
> +#define USB_PDPHY_RX_ACKNOWLEDGE_REG	0x4B
> +#define RX_BUFFER_TOKEN			BIT(0)
> +
> +#define USB_PDPHY_BIST_MODE_REG		0x4E
> +#define BIST_MODE_MASK			0xF
> +#define BIST_ENABLE			BIT(7)
> +#define PD_MSG_BIST			0x3
> +#define PD_BIST_TEST_DATA_MODE		0x8
> +
> +#define USB_PDPHY_TX_BUFFER_HDR_REG	0x60
> +#define USB_PDPHY_TX_BUFFER_DATA_REG	0x62
> +
> +#define USB_PDPHY_RX_BUFFER_REG		0x80
> +
> +/* VDD regulator */
> +#define VDD_PDPHY_VOL_MIN		2800000	/* uV */
> +#define VDD_PDPHY_VOL_MAX		3300000	/* uV */
> +#define VDD_PDPHY_HPM_LOAD		3000	/* uA */
> +
> +/* Message Spec Rev field */
> +#define PD_MSG_HDR_REV(hdr)		(((hdr) >> 6) & 3)
> +
> +/* timers */
> +#define RECEIVER_RESPONSE_TIME		15	/* tReceiverResponse */
> +#define HARD_RESET_COMPLETE_TIME	5	/* tHardResetComplete */
> +
> +struct pmic_pdphy;
> +extern struct platform_driver qcom_pmic_pdphy_platform_driver;
> +
> +int qcom_pmic_pdphy_init(struct pmic_pdphy *pmic_pdphy,
> +			 struct tcpm_port *tcpm_port);
> +
> +void qcom_pmic_pdphy_put(struct pmic_pdphy *pmic_pdphy);
> +
> +int qcom_pmic_pdphy_set_roles(struct pmic_pdphy *pmic_pdphy,
> +			      bool power_role_src,
> +			      bool data_role_host);
> +
> +int qcom_pmic_pdphy_set_pd_rx(struct pmic_pdphy *pmic_pdphy, bool on);
> +
> +int qcom_pmic_pdphy_pd_transmit(struct pmic_pdphy *pmic_pdphy,
> +				enum tcpm_transmit_type type,
> +				const struct pd_message *msg,
> +				unsigned int negotiated_rev);
> +
> +#endif /* __QCOM_PMIC_PDPHY_H__ */
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> new file mode 100644
> index 0000000000000..7b6f6100af949
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
> @@ -0,0 +1,637 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/usb/tcpm.h>
> +#include <linux/usb/typec_mux.h>
> +#include <linux/workqueue.h>
> +#include <dt-bindings/usb/typec/qcom,pmic-typec.h>
> +#include "qcom_pmic_typec.h"
> +
> +#define PMIC_TYPEC_MAX_IRQS		0x08
> +
> +struct pmic_typec_irq_params {
> +	int				virq;
> +	char				*irq_name;
> +};
> +
> +struct pmic_typec_resources {
> +	unsigned int			nr_irqs;
> +	struct pmic_typec_irq_params	irq_params[PMIC_TYPEC_MAX_IRQS];
> +};
> +
> +struct pmic_typec_irq_data {
> +	int				virq;
> +	int				irq;
> +	struct pmic_typec		*pmic_typec;
> +};
> +
> +struct pmic_typec {
> +	struct device			*dev;
> +	struct tcpm_port		*tcpm_port;
> +	struct regmap			*regmap;
> +	u32				base;
> +	unsigned int			nr_irqs;
> +	struct pmic_typec_irq_data	*irq_data;
> +
> +	struct regulator		*vdd_vbus;
> +
> +	int				cc;
> +	bool				debouncing_cc;
> +	struct delayed_work		cc_debounce_dwork;
> +
> +	spinlock_t			lock;	/* Register atomicity */
> +};
> +
> +static const char * const typec_cc_status_name[] = {
> +	[TYPEC_CC_OPEN]		= "Open",
> +	[TYPEC_CC_RA]		= "Ra",
> +	[TYPEC_CC_RD]		= "Rd",
> +	[TYPEC_CC_RP_DEF]	= "Rp-def",
> +	[TYPEC_CC_RP_1_5]	= "Rp-1.5",
> +	[TYPEC_CC_RP_3_0]	= "Rp-3.0",
> +};
> +
> +static const char *rp_unknown = "unknown";
> +
> +static const char *cc_to_name(enum typec_cc_status cc)
> +{
> +	if (cc > TYPEC_CC_RP_3_0)
> +		return rp_unknown;
> +
> +	return typec_cc_status_name[cc];
> +}
> +
> +static const char * const rp_sel_name[] = {
> +	[TYPEC_SRC_RP_SEL_80UA]		= "Rp-def-80uA",
> +	[TYPEC_SRC_RP_SEL_180UA]	= "Rp-1.5-180uA",
> +	[TYPEC_SRC_RP_SEL_330UA]	= "Rp-3.0-330uA",
> +};
> +
> +static const char *rp_sel_to_name(int rp_sel)
> +{
> +	if (rp_sel > TYPEC_SRC_RP_SEL_330UA)
> +		return rp_unknown;
> +
> +	return rp_sel_name[rp_sel];
> +}
> +
> +#define misc_to_cc(msic) !!(misc & CC_ORIENTATION) ? "cc1" : "cc2"
> +#define misc_to_vconn(msic) !!(misc & CC_ORIENTATION) ? "cc2" : "cc1"
> +
> +static void qcom_pmic_typec_cc_debounce(struct work_struct *work)
> +{
> +	struct pmic_typec *pmic_typec =
> +		container_of(work, struct pmic_typec, cc_debounce_dwork.work);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&pmic_typec->lock, flags);
> +	pmic_typec->debouncing_cc = false;
> +	spin_unlock_irqrestore(&pmic_typec->lock, flags);
> +
> +	dev_dbg(pmic_typec->dev, "Debounce cc complete\n");
> +}
> +
> +static irqreturn_t pmic_typec_isr(int irq, void *dev_id)
> +{
> +	struct pmic_typec_irq_data *irq_data = dev_id;
> +	struct pmic_typec *pmic_typec = irq_data->pmic_typec;
> +	u32 misc_stat;
> +	bool vbus_change = false;
> +	bool cc_change = false;
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&pmic_typec->lock, flags);
> +
> +	ret = regmap_read(pmic_typec->regmap,
> +			  pmic_typec->base + TYPEC_MISC_STATUS_REG,
> +			  &misc_stat);
> +	if (ret)
> +		goto done;
> +
> +	switch (irq_data->virq) {
> +	case PMIC_TYPEC_VBUS_IRQ:
> +		/* Incoming vbus assert/de-assert detect */
> +		vbus_change = true;
> +		break;
> +	case PMIC_TYPEC_CC_STATE_IRQ:
> +		if (!pmic_typec->debouncing_cc)
> +			cc_change = true;
> +		break;
> +	case PMIC_TYPEC_ATTACH_DETACH_IRQ:
> +		if (!pmic_typec->debouncing_cc)
> +			cc_change = true;
> +		break;
> +	}
> +
> +done:
> +	spin_unlock_irqrestore(&pmic_typec->lock, flags);
> +
> +	if (vbus_change)
> +		tcpm_vbus_change(pmic_typec->tcpm_port);
> +
> +	if (cc_change)
> +		tcpm_cc_change(pmic_typec->tcpm_port);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +int qcom_pmic_typec_get_vbus(struct pmic_typec *pmic_typec)
> +{
> +	struct device *dev = pmic_typec->dev;
> +	unsigned int misc;
> +	int ret;
> +
> +	ret = regmap_read(pmic_typec->regmap,
> +			  pmic_typec->base + TYPEC_MISC_STATUS_REG,
> +			  &misc);
> +	if (ret)
> +		misc = 0;
> +
> +	dev_dbg(dev, "get_vbus: 0x%08x detect %d\n", misc, !!(misc & TYPEC_VBUS_DETECT));
> +
> +	return !!(misc & TYPEC_VBUS_DETECT);
> +}
> +
> +int qcom_pmic_typec_set_vbus(struct pmic_typec *pmic_typec, bool on)
> +{
> +	u32 sm_stat;
> +	u32 val;
> +	int ret;
> +
> +	if (on) {
> +		ret = regulator_enable(pmic_typec->vdd_vbus);
> +		if (ret)
> +			return ret;
> +
> +		val = TYPEC_SM_VBUS_VSAFE5V;
> +	} else {
> +		ret = regulator_disable(pmic_typec->vdd_vbus);
> +		if (ret)
> +			return ret;
> +
> +		val = TYPEC_SM_VBUS_VSAFE0V;
> +	}
> +
> +	/* Poll waiting for transition to required vSafe5V or vSafe0V */
> +	ret = regmap_read_poll_timeout(pmic_typec->regmap,
> +				       pmic_typec->base + TYPEC_SM_STATUS_REG,
> +				       sm_stat, sm_stat & val,
> +				       100, 250000);
This statement isn't very useful and will case a error, 
After I remove it, usb-c works well. What's about dropping this statement?

[   63.030672] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[   63.030702] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 1
[   63.030895] xhci-hcd xhci-hcd.1.auto: hcc params 0x0230ffe5 hci version 0x110 quirks 0x0000000000010010
[   63.030926] xhci-hcd xhci-hcd.1.auto: irq 168, io mem 0x0a600000
[   63.031043] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[   63.031054] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 2
[   63.031063] xhci-hcd xhci-hcd.1.auto: Host supports USB 3.1 Enhanced SuperSpeed
[   63.031835] hub 1-0:1.0: USB hub found
[   63.031863] hub 1-0:1.0: 1 port detected
[   63.032151] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[   63.032690] hub 2-0:1.0: USB hub found
[   63.032713] hub 2-0:1.0: 1 port detected
[   63.168912] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: vbus vsafe5v fail
[   63.169185] xhci-hcd xhci-hcd.1.auto: remove, state 1
[   63.169195] usb usb2: USB disconnect, device number 1
[   63.178808] xhci-hcd xhci-hcd.1.auto: USB bus 2 deregistered
[   63.178825] xhci-hcd xhci-hcd.1.auto: remove, state 1
[   63.178832] usb usb1: USB disconnect, device number 1
[   63.182114] hub 1-0:1.0: activate --> -19
[   63.182791] xhci-hcd xhci-hcd.1.auto: USB bus 1 deregistered
> +	if (ret)
> +		dev_err(pmic_typec->dev, "vbus vsafe%dv fail\n", on ? 5 : 0);
> +
> +	return ret;
> +}
> +
> +int qcom_pmic_typec_get_cc(struct pmic_typec *pmic_typec,
> +			   enum typec_cc_status *cc1,
> +			   enum typec_cc_status *cc2)
> +{
> +	struct device *dev = pmic_typec->dev;
> +	unsigned int misc, val;
> +	bool attached;
> +	int ret = 0;
> +
> +	ret = regmap_read(pmic_typec->regmap,
> +			  pmic_typec->base + TYPEC_MISC_STATUS_REG, &misc);
> +	if (ret)
> +		goto done;
> +
> +	attached = !!(misc & CC_ATTACHED);
> +
> +	if (pmic_typec->debouncing_cc) {
> +		ret = -EBUSY;
> +		goto done;
> +	}
> +
> +	*cc1 = TYPEC_CC_OPEN;
> +	*cc2 = TYPEC_CC_OPEN;
> +
> +	if (!(attached))
> +		goto done;
> +
> +	if (misc & SNK_SRC_MODE) {
> +		ret = regmap_read(pmic_typec->regmap,
> +				  pmic_typec->base + TYPEC_SRC_STATUS_REG,
> +				  &val);
> +		if (ret)
> +			goto done;
> +		switch (val & DETECTED_SRC_TYPE_MASK) {
> +		case SRC_RD_OPEN:
> +			val = TYPEC_CC_RD;
> +			break;
> +		case SRC_RD_RA_VCONN:
> +			val = TYPEC_CC_RD;
> +			*cc1 = TYPEC_CC_RA;
> +			*cc2 = TYPEC_CC_RA;
> +			break;
> +		default:
> +			dev_warn(dev, "unexpected src status %.2x\n", val);
> +			val = TYPEC_CC_RD;
> +			break;
> +		}
> +	} else {
> +		ret = regmap_read(pmic_typec->regmap,
> +				  pmic_typec->base + TYPEC_SNK_STATUS_REG,
> +				  &val);
> +		if (ret)
> +			goto done;
> +		switch (val & DETECTED_SNK_TYPE_MASK) {
> +		case SNK_RP_STD:
> +			val = TYPEC_CC_RP_DEF;
> +			break;
> +		case SNK_RP_1P5:
> +			val = TYPEC_CC_RP_1_5;
> +			break;
> +		case SNK_RP_3P0:
> +			val = TYPEC_CC_RP_3_0;
> +			break;
> +		default:
> +			dev_warn(dev, "unexpected snk status %.2x\n", val);
> +			val = TYPEC_CC_RP_DEF;
> +			break;
> +		}
> +		val = TYPEC_CC_RP_DEF;
> +	}
> +
> +	if (misc & CC_ORIENTATION)
> +		*cc2 = val;
> +	else
> +		*cc1 = val;
> +
> +done:
> +	dev_dbg(dev, "get_cc: misc 0x%08x cc1 0x%08x %s cc2 0x%08x %s attached %d cc=%s\n",
> +		misc, *cc1, cc_to_name(*cc1), *cc2, cc_to_name(*cc2), attached,
> +		misc_to_cc(misc));
> +
> +	return ret;
> +}
> +
> +static void qcom_pmic_set_cc_debounce(struct pmic_typec *pmic_typec)
> +{
> +	pmic_typec->debouncing_cc = true;
> +	schedule_delayed_work(&pmic_typec->cc_debounce_dwork,
> +			      msecs_to_jiffies(2));
> +}
> +
> +int qcom_pmic_typec_set_cc(struct pmic_typec *pmic_typec,
> +			   enum typec_cc_status cc)
> +{
> +	struct device *dev = pmic_typec->dev;
> +	unsigned int mode, currsrc;
> +	unsigned int misc;
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&pmic_typec->lock, flags);
> +
> +	ret = regmap_read(pmic_typec->regmap,
> +			  pmic_typec->base + TYPEC_MISC_STATUS_REG,
> +			  &misc);
> +	if (ret)
> +		goto done;
> +
> +	mode = EN_SRC_ONLY;
> +
> +	switch (cc) {
> +	case TYPEC_CC_OPEN:
> +		currsrc = TYPEC_SRC_RP_SEL_80UA;
> +		break;
> +	case TYPEC_CC_RP_DEF:
> +		currsrc = TYPEC_SRC_RP_SEL_80UA;
> +		break;
> +	case TYPEC_CC_RP_1_5:
> +		currsrc = TYPEC_SRC_RP_SEL_180UA;
> +		break;
> +	case TYPEC_CC_RP_3_0:
> +		currsrc = TYPEC_SRC_RP_SEL_330UA;
> +		break;
> +	case TYPEC_CC_RD:
> +		currsrc = TYPEC_SRC_RP_SEL_80UA;
> +		mode = EN_SNK_ONLY;
> +		break;
> +	default:
> +		dev_warn(dev, "unexpected set_cc %d\n", cc);
> +		ret = -EINVAL;
> +		goto done;
> +	}
> +
> +	if (mode == EN_SRC_ONLY) {
> +		ret = regmap_write(pmic_typec->regmap,
> +				   pmic_typec->base + TYPEC_CURRSRC_CFG_REG,
> +				   currsrc);
> +		if (ret)
> +			goto done;
> +	}
> +
> +	pmic_typec->cc = cc;
> +	qcom_pmic_set_cc_debounce(pmic_typec);
> +	ret = 0;
> +
> +done:
> +	spin_unlock_irqrestore(&pmic_typec->lock, flags);
> +
> +	dev_dbg(dev, "set_cc: currsrc=%x %s mode %s debounce %d attached %d cc=%s\n",
> +		currsrc, rp_sel_to_name(currsrc),
> +		mode == EN_SRC_ONLY ? "EN_SRC_ONLY" : "EN_SNK_ONLY",
> +		pmic_typec->debouncing_cc, !!(misc & CC_ATTACHED),
> +		misc_to_cc(misc));
> +
> +	return ret;
> +}
> +
> +int qcom_pmic_typec_set_vconn(struct pmic_typec *pmic_typec, bool on)
> +{
> +	struct device *dev = pmic_typec->dev;
> +	unsigned int orientation, misc, mask, value;
> +	unsigned long flags;
> +	int ret;
> +
> +	spin_lock_irqsave(&pmic_typec->lock, flags);
> +
> +	ret = regmap_read(pmic_typec->regmap,
> +			  pmic_typec->base + TYPEC_MISC_STATUS_REG, &misc);
> +	if (ret)
> +		goto done;
> +
> +	/* Set VCONN on the inversion of the active CC channel */
> +	orientation = (misc & CC_ORIENTATION) ? 0 : VCONN_EN_ORIENTATION;
> +	if (on) {
> +		mask = VCONN_EN_ORIENTATION | VCONN_EN_VALUE;
> +		value = orientation | VCONN_EN_VALUE | VCONN_EN_SRC;
> +	} else {
> +		mask = VCONN_EN_VALUE;
> +		value = 0;
> +	}
> +
> +	ret = regmap_update_bits(pmic_typec->regmap,
> +				 pmic_typec->base + TYPEC_VCONN_CONTROL_REG,
> +				 mask, value);
> +done:
> +	spin_unlock_irqrestore(&pmic_typec->lock, flags);
> +
> +	dev_dbg(dev, "set_vconn: orientation %d control 0x%08x state %s cc %s vconn %s\n",
> +		orientation, value, on ? "on" : "off", misc_to_vconn(misc), misc_to_cc(misc));
> +
> +	return ret;
> +}
> +
> +int qcom_pmic_typec_start_toggling(struct pmic_typec *pmic_typec,
> +				   enum typec_port_type port_type,
> +				   enum typec_cc_status cc)
> +{
> +	struct device *dev = pmic_typec->dev;
> +	unsigned int misc;
> +	u8 mode = 0;
> +	unsigned long flags;
> +	int ret;
> +
> +	switch (port_type) {
> +	case TYPEC_PORT_SRC:
> +		mode = EN_SRC_ONLY;
> +		break;
> +	case TYPEC_PORT_SNK:
> +		mode = EN_SNK_ONLY;
> +		break;
> +	case TYPEC_PORT_DRP:
> +		mode = EN_TRY_SNK;
> +		break;
> +	}
> +
> +	spin_lock_irqsave(&pmic_typec->lock, flags);
> +
> +	ret = regmap_read(pmic_typec->regmap,
> +			  pmic_typec->base + TYPEC_MISC_STATUS_REG, &misc);
> +	if (ret)
> +		goto done;
> +
> +	dev_dbg(dev, "start_toggling: misc 0x%08x attached %d port_type %d current cc %d new %d\n",
> +		misc, !!(misc & CC_ATTACHED), port_type, pmic_typec->cc, cc);
> +
> +	qcom_pmic_set_cc_debounce(pmic_typec);
> +
> +	/* force it to toggle at least once */
> +	ret = regmap_write(pmic_typec->regmap,
> +			   pmic_typec->base + TYPEC_MODE_CFG_REG,
> +			   TYPEC_DISABLE_CMD);
> +	if (ret)
> +		goto done;
> +
> +	ret = regmap_write(pmic_typec->regmap,
> +			   pmic_typec->base + TYPEC_MODE_CFG_REG,
> +			   mode);
> +done:
> +	spin_unlock_irqrestore(&pmic_typec->lock, flags);
> +
> +	return ret;
> +}
> +
> +#define TYPEC_INTR_EN_CFG_1_MASK		  \
> +	(TYPEC_LEGACY_CABLE_INT_EN		| \
> +	 TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN	| \
> +	 TYPEC_TRYSOURCE_DETECT_INT_EN		| \
> +	 TYPEC_TRYSINK_DETECT_INT_EN		| \
> +	 TYPEC_CCOUT_DETACH_INT_EN		| \
> +	 TYPEC_CCOUT_ATTACH_INT_EN		| \
> +	 TYPEC_VBUS_DEASSERT_INT_EN		| \
> +	 TYPEC_VBUS_ASSERT_INT_EN)
> +
> +#define TYPEC_INTR_EN_CFG_2_MASK \
> +	(TYPEC_STATE_MACHINE_CHANGE_INT_EN | TYPEC_VBUS_ERROR_INT_EN | \
> +	 TYPEC_DEBOUNCE_DONE_INT_EN)
> +
> +int qcom_pmic_typec_init(struct pmic_typec *pmic_typec,
> +			 struct tcpm_port *tcpm_port)
> +{
> +	int i;
> +	int mask;
> +	int ret;
> +
> +	/* Configure interrupt sources */
> +	ret = regmap_write(pmic_typec->regmap,
> +			   pmic_typec->base + TYPEC_INTERRUPT_EN_CFG_1_REG,
> +			   TYPEC_INTR_EN_CFG_1_MASK);
> +	if (ret)
> +		goto done;
> +
> +	ret = regmap_write(pmic_typec->regmap,
> +			   pmic_typec->base + TYPEC_INTERRUPT_EN_CFG_2_REG,
> +			   TYPEC_INTR_EN_CFG_2_MASK);
> +	if (ret)
> +		goto done;
> +
> +	/* start in TRY_SNK mode */
> +	ret = regmap_write(pmic_typec->regmap,
> +			   pmic_typec->base + TYPEC_MODE_CFG_REG, EN_TRY_SNK);
> +	if (ret)
> +		goto done;
> +
> +	/* Configure VCONN for software control */
> +	ret = regmap_update_bits(pmic_typec->regmap,
> +				 pmic_typec->base + TYPEC_VCONN_CONTROL_REG,
> +				 VCONN_EN_SRC | VCONN_EN_VALUE, VCONN_EN_SRC);
> +	if (ret)
> +		goto done;
> +
> +	/* Set CC threshold to 1.6 Volts | tPDdebounce = 10-20ms */
> +	mask = SEL_SRC_UPPER_REF | USE_TPD_FOR_EXITING_ATTACHSRC;
> +	ret = regmap_update_bits(pmic_typec->regmap,
> +				 pmic_typec->base + TYPEC_EXIT_STATE_CFG_REG,
> +				 mask, mask);
> +	if (ret)
> +		goto done;
> +
> +	pmic_typec->tcpm_port = tcpm_port;
> +
> +	for (i = 0; i < pmic_typec->nr_irqs; i++)
> +		enable_irq(pmic_typec->irq_data[i].irq);
> +
> +done:
> +	return ret;
> +}
> +
> +void qcom_pmic_typec_put(struct pmic_typec *pmic_typec)
> +{
> +	put_device(pmic_typec->dev);
> +}
> +
> +static int qcom_pmic_typec_probe(struct platform_device *pdev)
> +{
> +	struct pmic_typec *pmic_typec;
> +	struct device *dev = &pdev->dev;
> +	const struct pmic_typec_resources *res;
> +	struct pmic_typec_irq_data *irq_data;
> +	int i, ret, irq;
> +	u32 reg;
> +
> +	ret = device_property_read_u32(dev, "reg", &reg);
> +	if (ret < 0) {
> +		dev_err(dev, "missing base address\n");
> +		return ret;
> +	}
> +
> +	res = of_device_get_match_data(dev);
> +	if (!res)
> +		return -ENODEV;
> +
> +	if (!res->nr_irqs || res->nr_irqs > PMIC_TYPEC_MAX_IRQS)
> +		return -EINVAL;
> +
> +	pmic_typec = devm_kzalloc(dev, sizeof(*pmic_typec), GFP_KERNEL);
> +	if (!pmic_typec)
> +		return -ENOMEM;
> +
> +	irq_data = devm_kzalloc(dev, sizeof(*irq_data) * res->nr_irqs,
> +				GFP_KERNEL);
> +	if (!irq_data)
> +		return -ENOMEM;
> +
> +	pmic_typec->vdd_vbus = devm_regulator_get(dev, "vdd-vbus");
> +	if (IS_ERR(pmic_typec->vdd_vbus))
> +		return PTR_ERR(pmic_typec->vdd_vbus);
> +
> +	pmic_typec->dev = dev;
> +	pmic_typec->base = reg;
> +	pmic_typec->nr_irqs = res->nr_irqs;
> +	pmic_typec->irq_data = irq_data;
> +	spin_lock_init(&pmic_typec->lock);
> +	INIT_DELAYED_WORK(&pmic_typec->cc_debounce_dwork,
> +			  qcom_pmic_typec_cc_debounce);
> +
> +	pmic_typec->regmap = dev_get_regmap(dev->parent, NULL);
> +	if (!pmic_typec->regmap) {
> +		dev_err(dev, "Failed to get regmap\n");
> +		return -ENODEV;
> +	}
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0)
> +		return irq;
> +
> +	platform_set_drvdata(pdev, pmic_typec);
> +
> +	for (i = 0; i < res->nr_irqs; i++, irq_data++) {
> +		irq = platform_get_irq_byname(pdev,
> +					      res->irq_params[i].irq_name);
> +		if (irq < 0)
> +			return irq;
> +
> +		irq_data->pmic_typec = pmic_typec;
> +		irq_data->irq = irq;
> +		irq_data->virq = res->irq_params[i].virq;
> +		ret = devm_request_threaded_irq(dev, irq, NULL, pmic_typec_isr,
> +						IRQF_ONESHOT | IRQF_NO_AUTOEN,
> +						res->irq_params[i].irq_name,
> +						irq_data);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct pmic_typec_resources pm8150b_typec_res = {
> +	.irq_params = {
> +		{
> +			.irq_name = "vpd-detect",
> +			.virq = PMIC_TYPEC_VPD_IRQ,
> +		},
> +
> +		{
> +			.irq_name = "cc-state-change",
> +			.virq = PMIC_TYPEC_CC_STATE_IRQ,
> +		},
> +		{
> +			.irq_name = "vconn-oc",
> +			.virq = PMIC_TYPEC_VCONN_OC_IRQ,
> +		},
> +
> +		{
> +			.irq_name = "vbus-change",
> +			.virq = PMIC_TYPEC_VBUS_IRQ,
> +		},
> +
> +		{
> +			.irq_name = "attach-detach",
> +			.virq = PMIC_TYPEC_ATTACH_DETACH_IRQ,
> +		},
> +		{
> +			.irq_name = "legacy-cable-detect",
> +			.virq = PMIC_TYPEC_LEGACY_CABLE_IRQ,
> +		},
> +
> +		{
> +			.irq_name = "try-snk-src-detect",
> +			.virq = PMIC_TYPEC_TRY_SNK_SRC_IRQ,
> +		},
> +	},
> +	.nr_irqs = 7,
> +};
> +
> +static const struct of_device_id qcom_pmic_typec_table[] = {
> +	{ .compatible = "qcom,pm8150b-typec", .data = &pm8150b_typec_res },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, qcom_pmic_typec_table);
> +
> +struct platform_driver qcom_pmic_typec_platform_driver = {
> +	.driver = {
> +		.name = "qcom,pmic-typec",
> +		.of_match_table = qcom_pmic_typec_table,
> +	},
> +	.probe = qcom_pmic_typec_probe,
> +};
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
> new file mode 100644
> index 0000000000000..1428325954795
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
> @@ -0,0 +1,163 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
> + * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> + */
> +#ifndef __QCOM_PMIC_TYPEC_H__
> +#define __QCOM_PMIC_TYPEC_H__
> +
> +#include <linux/usb/tcpm.h>
> +
> +#define TYPEC_SNK_STATUS_REG				0x06
> +#define DETECTED_SNK_TYPE_MASK				GENMASK(6, 0)
> +#define SNK_DAM_MASK					GENMASK(6, 4)
> +#define SNK_DAM_500MA					BIT(6)
> +#define SNK_DAM_1500MA					BIT(5)
> +#define SNK_DAM_3000MA					BIT(4)
> +#define SNK_RP_STD					BIT(3)
> +#define SNK_RP_1P5					BIT(2)
> +#define SNK_RP_3P0					BIT(1)
> +#define SNK_RP_SHORT					BIT(0)
> +
> +#define TYPEC_SRC_STATUS_REG				0x08
> +#define DETECTED_SRC_TYPE_MASK				GENMASK(4, 0)
> +#define SRC_HIGH_BATT					BIT(5)
> +#define SRC_DEBUG_ACCESS				BIT(4)
> +#define SRC_RD_OPEN					BIT(3)
> +#define SRC_RD_RA_VCONN					BIT(2)
> +#define SRC_RA_OPEN					BIT(1)
> +#define AUDIO_ACCESS_RA_RA				BIT(0)
> +
> +#define TYPEC_STATE_MACHINE_STATUS_REG			0x09
> +#define TYPEC_ATTACH_DETACH_STATE			BIT(5)
> +
> +#define TYPEC_SM_STATUS_REG				0x0A
> +#define TYPEC_SM_VBUS_VSAFE5V				BIT(5)
> +#define TYPEC_SM_VBUS_VSAFE0V				BIT(6)
> +#define TYPEC_SM_USBIN_LT_LV				BIT(7)
> +
> +#define TYPEC_MISC_STATUS_REG				0x0B
> +#define TYPEC_WATER_DETECTION_STATUS			BIT(7)
> +#define SNK_SRC_MODE					BIT(6)
> +#define TYPEC_VBUS_DETECT				BIT(5)
> +#define TYPEC_VBUS_ERROR_STATUS				BIT(4)
> +#define TYPEC_DEBOUNCE_DONE				BIT(3)
> +#define CC_ORIENTATION					BIT(1)
> +#define CC_ATTACHED					BIT(0)
> +
> +#define LEGACY_CABLE_STATUS_REG				0x0D
> +#define TYPEC_LEGACY_CABLE_STATUS			BIT(1)
> +#define TYPEC_NONCOMP_LEGACY_CABLE_STATUS		BIT(0)
> +
> +#define TYPEC_U_USB_STATUS_REG				0x0F
> +#define U_USB_GROUND_NOVBUS				BIT(6)
> +#define U_USB_GROUND					BIT(4)
> +#define U_USB_FMB1					BIT(3)
> +#define U_USB_FLOAT1					BIT(2)
> +#define U_USB_FMB2					BIT(1)
> +#define U_USB_FLOAT2					BIT(0)
> +
> +#define TYPEC_MODE_CFG_REG				0x44
> +#define TYPEC_TRY_MODE_MASK				GENMASK(4, 3)
> +#define EN_TRY_SNK					BIT(4)
> +#define EN_TRY_SRC					BIT(3)
> +#define TYPEC_POWER_ROLE_CMD_MASK			GENMASK(2, 0)
> +#define EN_SRC_ONLY					BIT(2)
> +#define EN_SNK_ONLY					BIT(1)
> +#define TYPEC_DISABLE_CMD				BIT(0)
> +
> +#define TYPEC_VCONN_CONTROL_REG				0x46
> +#define VCONN_EN_ORIENTATION				BIT(2)
> +#define VCONN_EN_VALUE					BIT(1)
> +#define VCONN_EN_SRC					BIT(0)
> +
> +#define TYPEC_CCOUT_CONTROL_REG				0x48
> +#define TYPEC_CCOUT_BUFFER_EN				BIT(2)
> +#define TYPEC_CCOUT_VALUE				BIT(1)
> +#define TYPEC_CCOUT_SRC					BIT(0)
> +
> +#define DEBUG_ACCESS_SRC_CFG_REG			0x4C
> +#define EN_UNORIENTED_DEBUG_ACCESS_SRC			BIT(0)
> +
> +#define TYPE_C_CRUDE_SENSOR_CFG_REG			0x4e
> +#define EN_SRC_CRUDE_SENSOR				BIT(1)
> +#define EN_SNK_CRUDE_SENSOR				BIT(0)
> +
> +#define TYPEC_EXIT_STATE_CFG_REG			0x50
> +#define BYPASS_VSAFE0V_DURING_ROLE_SWAP			BIT(3)
> +#define SEL_SRC_UPPER_REF				BIT(2)
> +#define USE_TPD_FOR_EXITING_ATTACHSRC			BIT(1)
> +#define EXIT_SNK_BASED_ON_CC				BIT(0)
> +
> +#define TYPEC_CURRSRC_CFG_REG				0x52
> +#define TYPEC_SRC_RP_SEL_330UA				BIT(1)
> +#define TYPEC_SRC_RP_SEL_180UA				BIT(0)
> +#define TYPEC_SRC_RP_SEL_80UA				0
> +#define TYPEC_SRC_RP_SEL_MASK				GENMASK(1, 0)
> +
> +#define TYPEC_INTERRUPT_EN_CFG_1_REG			0x5E
> +#define TYPEC_LEGACY_CABLE_INT_EN			BIT(7)
> +#define TYPEC_NONCOMPLIANT_LEGACY_CABLE_INT_EN		BIT(6)
> +#define TYPEC_TRYSOURCE_DETECT_INT_EN			BIT(5)
> +#define TYPEC_TRYSINK_DETECT_INT_EN			BIT(4)
> +#define TYPEC_CCOUT_DETACH_INT_EN			BIT(3)
> +#define TYPEC_CCOUT_ATTACH_INT_EN			BIT(2)
> +#define TYPEC_VBUS_DEASSERT_INT_EN			BIT(1)
> +#define TYPEC_VBUS_ASSERT_INT_EN			BIT(0)
> +
> +#define TYPEC_INTERRUPT_EN_CFG_2_REG			0x60
> +#define TYPEC_SRC_BATT_HPWR_INT_EN			BIT(6)
> +#define MICRO_USB_STATE_CHANGE_INT_EN			BIT(5)
> +#define TYPEC_STATE_MACHINE_CHANGE_INT_EN		BIT(4)
> +#define TYPEC_DEBUG_ACCESS_DETECT_INT_EN		BIT(3)
> +#define TYPEC_WATER_DETECTION_INT_EN			BIT(2)
> +#define TYPEC_VBUS_ERROR_INT_EN				BIT(1)
> +#define TYPEC_DEBOUNCE_DONE_INT_EN			BIT(0)
> +
> +#define TYPEC_DEBOUNCE_OPTION_REG			0x62
> +#define REDUCE_TCCDEBOUNCE_TO_2MS			BIT(2)
> +
> +#define TYPE_C_SBU_CFG_REG				0x6A
> +#define SEL_SBU1_ISRC_VAL				0x04
> +#define SEL_SBU2_ISRC_VAL				0x01
> +
> +#define TYPEC_U_USB_CFG_REG				0x70
> +#define EN_MICRO_USB_FACTORY_MODE			BIT(1)
> +#define EN_MICRO_USB_MODE				BIT(0)
> +
> +#define TYPEC_PMI632_U_USB_WATER_PROTECTION_CFG_REG	0x72
> +
> +#define TYPEC_U_USB_WATER_PROTECTION_CFG_REG		0x73
> +#define EN_MICRO_USB_WATER_PROTECTION			BIT(4)
> +#define MICRO_USB_DETECTION_ON_TIME_CFG_MASK		GENMASK(3, 2)
> +#define MICRO_USB_DETECTION_PERIOD_CFG_MASK		GENMASK(1, 0)
> +
> +#define TYPEC_PMI632_MICRO_USB_MODE_REG			0x73
> +#define MICRO_USB_MODE_ONLY				BIT(0)
> +
> +struct pmic_typec;
> +extern struct platform_driver qcom_pmic_typec_platform_driver;
> +
> +int qcom_pmic_typec_init(struct pmic_typec *pmic_typec,
> +			 struct tcpm_port *tcpm_port);
> +
> +void qcom_pmic_typec_put(struct pmic_typec *pmic_typec);
> +
> +int qcom_pmic_typec_get_cc(struct pmic_typec *pmic_typec,
> +			   enum typec_cc_status *cc1,
> +			   enum typec_cc_status *cc2);
> +
> +int qcom_pmic_typec_set_cc(struct pmic_typec *pmic_typec,
> +			   enum typec_cc_status cc);
> +
> +int qcom_pmic_typec_get_vbus(struct pmic_typec *pmic_typec);
> +
> +int qcom_pmic_typec_set_vconn(struct pmic_typec *pmic_typec, bool on);
> +
> +int qcom_pmic_typec_start_toggling(struct pmic_typec *pmic_typec,
> +				   enum typec_port_type port_type,
> +				   enum typec_cc_status cc);
> +
> +int qcom_pmic_typec_set_vbus(struct pmic_typec *pmic_typec, bool on);
> +
> +#endif /* __QCOM_PMIC_TYPE_C_H__ */
> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
> new file mode 100644
> index 0000000000000..91544b4b59439
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
> @@ -0,0 +1,326 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/usb/role.h>
> +#include <linux/usb/tcpm.h>
> +#include <linux/usb/typec_mux.h>
> +#include "qcom_pmic_pdphy.h"
> +#include "qcom_pmic_typec.h"
> +
> +struct pmic_virt_tcpm {
> +	struct device		*dev;
> +	struct pmic_typec	*pmic_typec;
> +	struct pmic_pdphy	*pmic_pdphy;
> +	struct tcpm_port	*tcpm_port;
> +	struct tcpc_dev		tcpc;
> +	bool			vbus_enabled;
> +	struct mutex		lock;		/* VBUS state serialization */
> +};
> +
> +#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_virt_tcpm, tcpc)
> +
> +static int qcom_pmic_virt_tcpm_get_vbus(struct tcpc_dev *tcpc)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +	int ret;
> +
> +	mutex_lock(&tcpm->lock);
> +	ret = tcpm->vbus_enabled || qcom_pmic_typec_get_vbus(tcpm->pmic_typec);
> +	mutex_unlock(&tcpm->lock);
> +
> +	return ret;
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_vbus(struct tcpc_dev *tcpc, bool on,
> +					bool sink)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +	int ret = 0;
> +
> +	mutex_lock(&tcpm->lock);
> +	if (tcpm->vbus_enabled == on)
> +		goto done;
> +
> +	ret = qcom_pmic_typec_set_vbus(tcpm->pmic_typec, on);
> +	if (ret)
> +		goto done;
> +
> +	tcpm->vbus_enabled = on;
> +	tcpm_vbus_change(tcpm->tcpm_port);
> +
> +done:
> +	dev_dbg(tcpm->dev, "set_vbus set: %d result %d\n", on, ret);
> +	mutex_unlock(&tcpm->lock);
> +
> +	return ret;
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_vconn(struct tcpc_dev *tcpc, bool on)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_typec_set_vconn(tcpm->pmic_typec, on);
> +}
> +
> +static int qcom_pmic_virt_tcpm_get_cc(struct tcpc_dev *tcpc,
> +				      enum typec_cc_status *cc1,
> +				      enum typec_cc_status *cc2)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_typec_get_cc(tcpm->pmic_typec, cc1, cc2);
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_cc(struct tcpc_dev *tcpc,
> +				      enum typec_cc_status cc)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_typec_set_cc(tcpm->pmic_typec, cc);
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_polarity(struct tcpc_dev *tcpc,
> +					    enum typec_cc_polarity pol)
> +{
> +	/* Polarity is set separately by phy-qcom-qmp.c */
> +	return 0;
> +}
> +
> +static int qcom_pmic_virt_tcpm_start_toggling(struct tcpc_dev *tcpc,
> +					      enum typec_port_type port_type,
> +					      enum typec_cc_status cc)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_typec_start_toggling(tcpm->pmic_typec, port_type, cc);
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_roles(struct tcpc_dev *tcpc, bool attached,
> +					 enum typec_role power_role,
> +					 enum typec_data_role data_role)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_pdphy_set_roles(tcpm->pmic_pdphy, data_role,
> +					 power_role);
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_pd_rx(struct tcpc_dev *tcpc, bool on)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_pdphy_set_pd_rx(tcpm->pmic_pdphy, on);
> +}
> +
> +static int qcom_pmic_virt_tcpm_pd_transmit(struct tcpc_dev *tcpc,
> +					   enum tcpm_transmit_type type,
> +					   const struct pd_message *msg,
> +					   unsigned int negotiated_rev)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_pdphy_pd_transmit(tcpm->pmic_pdphy, type, msg,
> +					   negotiated_rev);
> +}
> +
> +static struct platform_device
> +*qcom_pmic_virt_tcpm_get_pdev(struct device *dev, const char *property_name)
> +{
> +	struct device_node *np;
> +	struct platform_device *pdev;
> +	const __be32 *prop;
> +
> +	prop = of_get_property(dev->of_node, property_name, NULL);
> +	if (!prop) {
> +		dev_err(dev, "required '%s' property missing\n", property_name);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	np = of_find_node_by_phandle(be32_to_cpup(prop));
> +	if (!np) {
> +		dev_err(dev, "could not find '%s' node\n", property_name);
> +		return ERR_PTR(-ENODEV);
> +	}
> +
> +	pdev = of_find_device_by_node(np);
> +	of_node_put(np);
> +
> +	if (pdev)
> +		return pdev;
> +
> +	return ERR_PTR(-ENODEV);
> +}
> +
> +static int qcom_pmic_virt_tcpm_init(struct tcpc_dev *tcpc)
> +{
> +	return 0;
> +}
> +
> +static int qcom_pmic_virt_tcpm_probe(struct platform_device *pdev)
> +{
> +	struct pmic_virt_tcpm *tcpm;
> +	struct device *dev = &pdev->dev;
> +	struct platform_device *typec_pdev;
> +	struct platform_device *pdphy_pdev;
> +	int ret;
> +
> +	tcpm = devm_kzalloc(dev, sizeof(*tcpm), GFP_KERNEL);
> +	if (!tcpm)
> +		return -ENOMEM;
> +
> +	tcpm->dev = dev;
> +	tcpm->tcpc.init = qcom_pmic_virt_tcpm_init;
> +	tcpm->tcpc.get_vbus = qcom_pmic_virt_tcpm_get_vbus;
> +	tcpm->tcpc.set_vbus = qcom_pmic_virt_tcpm_set_vbus;
> +	tcpm->tcpc.set_cc = qcom_pmic_virt_tcpm_set_cc;
> +	tcpm->tcpc.get_cc = qcom_pmic_virt_tcpm_get_cc;
> +	tcpm->tcpc.set_polarity = qcom_pmic_virt_tcpm_set_polarity;
> +	tcpm->tcpc.set_vconn = qcom_pmic_virt_tcpm_set_vconn;
> +	tcpm->tcpc.start_toggling = qcom_pmic_virt_tcpm_start_toggling;
> +	tcpm->tcpc.set_pd_rx = qcom_pmic_virt_tcpm_set_pd_rx;
> +	tcpm->tcpc.set_roles = qcom_pmic_virt_tcpm_set_roles;
> +	tcpm->tcpc.pd_transmit = qcom_pmic_virt_tcpm_pd_transmit;
> +
> +	mutex_init(&tcpm->lock);
> +	platform_set_drvdata(pdev, tcpm);
> +
> +	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
> +	if (ret) {
> +		dev_err(dev, "Populating child devices fail\n");
> +		return ret;
> +	};
> +
> +	typec_pdev = qcom_pmic_virt_tcpm_get_pdev(dev, "qcom,pmic-typec");
> +	if (IS_ERR(typec_pdev)) {
> +		dev_err(dev, "Error linking typec endpoint\n");
> +		return PTR_ERR(typec_pdev);
> +	}
> +
> +	tcpm->pmic_typec = platform_get_drvdata(typec_pdev);
> +	if (!tcpm->pmic_typec) {
> +		ret = -EPROBE_DEFER;
> +		goto put_typec_pdev;
> +	}
> +
> +	pdphy_pdev = qcom_pmic_virt_tcpm_get_pdev(dev, "qcom,pmic-pdphy");
> +	if (IS_ERR(pdphy_pdev)) {
> +		dev_err(dev, "Error linking pdphy endpoint\n");
> +		ret = PTR_ERR(pdphy_pdev);
> +		goto put_typec_pdev;
> +	}
> +
> +	tcpm->pmic_pdphy = platform_get_drvdata(pdphy_pdev);
> +	if (!tcpm->pmic_pdphy) {
> +		ret = -EPROBE_DEFER;
> +		goto put_pdphy_dev;
> +	}
> +
> +	tcpm->tcpc.fwnode = device_get_named_child_node(tcpm->dev, "connector");
> +	if (IS_ERR(tcpm->tcpc.fwnode))
> +		return PTR_ERR(tcpm->tcpc.fwnode);
> +
> +	tcpm->tcpm_port = tcpm_register_port(tcpm->dev, &tcpm->tcpc);
> +	if (IS_ERR(tcpm->tcpm_port)) {
> +		ret = PTR_ERR(tcpm->tcpm_port);
> +		goto fwnode_remove;
> +	}
> +
> +	ret = qcom_pmic_pdphy_init(tcpm->pmic_pdphy, tcpm->tcpm_port);
> +	if (ret)
> +		goto fwnode_remove;
> +
> +	ret = qcom_pmic_typec_init(tcpm->pmic_typec, tcpm->tcpm_port);
> +	if (ret)
> +		goto fwnode_remove;
> +
> +	return 0;
> +
> +fwnode_remove:
> +	fwnode_remove_software_node(tcpm->tcpc.fwnode);
> +
> +put_pdphy_dev:
> +	put_device(&pdphy_pdev->dev);
> +
> +put_typec_pdev:
> +	put_device(&typec_pdev->dev);
> +
> +	return ret;
> +}
> +
> +static int qcom_pmic_virt_tcpm_remove(struct platform_device *pdev)
> +{
> +	struct pmic_virt_tcpm *tcpm = platform_get_drvdata(pdev);
> +
> +	tcpm_unregister_port(tcpm->tcpm_port);
> +	fwnode_remove_software_node(tcpm->tcpc.fwnode);
> +	qcom_pmic_pdphy_put(tcpm->pmic_pdphy);
> +	qcom_pmic_typec_put(tcpm->pmic_typec);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id qcom_pmic_virt_tcpm_table[] = {
> +	{ .compatible = "qcom,pmic-virt-tcpm" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, qcom_pmic_virt_tcpm_table);
> +
> +static struct platform_driver qcom_pmic_virt_tcpm_platform_driver = {
> +	.driver = {
> +		.name = "qcom,pmic-tcpm",
> +		.of_match_table = qcom_pmic_virt_tcpm_table,
> +	},
> +	.probe = qcom_pmic_virt_tcpm_probe,
> +	.remove = qcom_pmic_virt_tcpm_remove,
> +};
> +
> +static int __init qcom_pmic_virt_tcpm_module_init(void)
> +{
> +	int ret;
> +
> +	ret = platform_driver_register(&qcom_pmic_typec_platform_driver);
> +	if (ret)
> +		return ret;
> +
> +	ret = platform_driver_register(&qcom_pmic_pdphy_platform_driver);
> +	if (ret)
> +		goto unregister_typec;
> +
> +	ret = platform_driver_register(&qcom_pmic_virt_tcpm_platform_driver);
> +	if (ret)
> +		goto unregister_pdphy;
> +
> +	return 0;
> +
> +unregister_pdphy:
> +	platform_driver_unregister(&qcom_pmic_pdphy_platform_driver);
> +
> +unregister_typec:
> +	platform_driver_unregister(&qcom_pmic_typec_platform_driver);
> +
> +	return ret;
> +}
> +module_init(qcom_pmic_virt_tcpm_module_init);
> +
> +static void __exit qcom_pmic_virt_tcpm_module_exit(void)
> +{
> +	platform_driver_unregister(&qcom_pmic_virt_tcpm_platform_driver);
> +	platform_driver_unregister(&qcom_pmic_pdphy_platform_driver);
> +	platform_driver_unregister(&qcom_pmic_typec_platform_driver);
> +}
> +module_exit(qcom_pmic_virt_tcpm_module_exit);
> +
> +MODULE_DESCRIPTION("QCOM PMIC USB Type-C Port Manager Driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.39.2
> 
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-23 14:36   ` Jianhua Lu
@ 2023-03-23 17:31     ` Bryan O'Donoghue
  2023-03-24  0:43       ` Jianhua Lu
  0 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-23 17:31 UTC (permalink / raw)
  To: Jianhua Lu
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 23/03/2023 14:36, Jianhua Lu wrote:
>> +	/* Poll waiting for transition to required vSafe5V or vSafe0V */
>> +	ret = regmap_read_poll_timeout(pmic_typec->regmap,
>> +				       pmic_typec->base + TYPEC_SM_STATUS_REG,
>> +				       sm_stat, sm_stat & val,
>> +				       100, 250000);
> This statement isn't very useful and will case a error,
> After I remove it, usb-c works well. What's about dropping this statement?
> 
> [   63.030672] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
> [   63.030702] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 1
> [   63.030895] xhci-hcd xhci-hcd.1.auto: hcc params 0x0230ffe5 hci version 0x110 quirks 0x0000000000010010
> [   63.030926] xhci-hcd xhci-hcd.1.auto: irq 168, io mem 0x0a600000
> [   63.031043] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
> [   63.031054] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 2
> [   63.031063] xhci-hcd xhci-hcd.1.auto: Host supports USB 3.1 Enhanced SuperSpeed
> [   63.031835] hub 1-0:1.0: USB hub found
> [   63.031863] hub 1-0:1.0: 1 port detected
> [   63.032151] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
> [   63.032690] hub 2-0:1.0: USB hub found
> [   63.032713] hub 2-0:1.0: 1 port detected
> [   63.168912] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: vbus vsafe5v fail
> [   63.169185] xhci-hcd xhci-hcd.1.auto: remove, state 1
> [   63.169195] usb usb2: USB disconnect, device number 1
> [   63.178808] xhci-hcd xhci-hcd.1.auto: USB bus 2 deregistered
> [   63.178825] xhci-hcd xhci-hcd.1.auto: remove, state 1
> [   63.178832] usb usb1: USB disconnect, device number 1
> [   63.182114] hub 1-0:1.0: activate --> -19
> [   63.182791] xhci-hcd xhci-hcd.1.auto: USB bus 1 deregistered

Interesting.

What's your hardware configuration ? Could it be you don't have the VBUS 
regulator pointed to the correct place ?

&pm8150b_vbus {
	regulator-min-microamp = <500000>;
	regulator-max-microamp = <3000000>;
	status = "okay";
};

&pm8150b_typec {
	vdd-vbus-supply = <&pm8150b_vbus>;
};

i.e. something else on your board supplies VBUS ?

vSafe5V should indicate to the controller that you have successfully 
switched on vBus, so what this indicates to me is that on your hardware 
VBUS either hasn't been asserted or hasn't been detected.

Can you show the printout of *(pmic_typec->base + TYPEC_SM_STATUS_REG) ? 
And can you check your schematics and verify VBUS is supplied by 
pm8150b_vbus and not say by an external IC ?

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-23 17:31     ` Bryan O'Donoghue
@ 2023-03-24  0:43       ` Jianhua Lu
  2023-03-24  0:53         ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Jianhua Lu @ 2023-03-24  0:43 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On Thu, Mar 23, 2023 at 05:31:26PM +0000, Bryan O'Donoghue wrote:
> On 23/03/2023 14:36, Jianhua Lu wrote:
> >> +	/* Poll waiting for transition to required vSafe5V or vSafe0V */
> >> +	ret = regmap_read_poll_timeout(pmic_typec->regmap,
> >> +				       pmic_typec->base + TYPEC_SM_STATUS_REG,
> >> +				       sm_stat, sm_stat & val,
> >> +				       100, 250000);
> > This statement isn't very useful and will case a error,
> > After I remove it, usb-c works well. What's about dropping this statement?
> > 
> > [   63.030672] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
> > [   63.030702] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 1
> > [   63.030895] xhci-hcd xhci-hcd.1.auto: hcc params 0x0230ffe5 hci version 0x110 quirks 0x0000000000010010
> > [   63.030926] xhci-hcd xhci-hcd.1.auto: irq 168, io mem 0x0a600000
> > [   63.031043] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
> > [   63.031054] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 2
> > [   63.031063] xhci-hcd xhci-hcd.1.auto: Host supports USB 3.1 Enhanced SuperSpeed
> > [   63.031835] hub 1-0:1.0: USB hub found
> > [   63.031863] hub 1-0:1.0: 1 port detected
> > [   63.032151] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
> > [   63.032690] hub 2-0:1.0: USB hub found
> > [   63.032713] hub 2-0:1.0: 1 port detected
> > [   63.168912] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: vbus vsafe5v fail
> > [   63.169185] xhci-hcd xhci-hcd.1.auto: remove, state 1
> > [   63.169195] usb usb2: USB disconnect, device number 1
> > [   63.178808] xhci-hcd xhci-hcd.1.auto: USB bus 2 deregistered
> > [   63.178825] xhci-hcd xhci-hcd.1.auto: remove, state 1
> > [   63.178832] usb usb1: USB disconnect, device number 1
> > [   63.182114] hub 1-0:1.0: activate --> -19
> > [   63.182791] xhci-hcd xhci-hcd.1.auto: USB bus 1 deregistered
> 
> Interesting.
> 
> What's your hardware configuration ? Could it be you don't have the VBUS 
> regulator pointed to the correct place ?
> 
> &pm8150b_vbus {
> 	regulator-min-microamp = <500000>;
> 	regulator-max-microamp = <3000000>;
> 	status = "okay";
> };
> 
> &pm8150b_typec {
> 	vdd-vbus-supply = <&pm8150b_vbus>;
> };
I think I configure it correctly, I have disassemble the compiled dtb,
don't find anything wrong.

usb-vbus-regulator@1100 {
	compatible = "qcom,pm8150b-vbus-reg";
	status = "okay";
	reg = <0x1100>;
	regulator-min-microamp = <0x7a120>;
	regulator-max-microamp = <0x2dc6c0>;
	phandle = <0xc9>;
};

typec@1500 {
	compatible = "qcom,pm8150b-typec";
	reg = <0x1500>;
	interrupts = <0x02 0x15 0x00 0x01 0x02 0x15 0x01 0x03 0x02 0x15 0x02 0x01 0x02 0x15 0x03 0x03 0x02 0x15 0x04 0x01 0x02 0x15 0x05 0x01 0x02 0x15 0x06 0x03 0x02 0x15 0x07 0x01>;
	interrupt-names = "or-rid-detect-change\0vpd-detect\0cc-state-change\0vconn-oc\0vbus-change\0attach-detach\0legacy-cable-detect\0try-snk-src-detect";
	vdd-vbus-supply = <0xc9>;
	status = "okay";
	phandle = <0x103>;
};
> 
> i.e. something else on your board supplies VBUS ?
pm8150b_vbus only. I try to disable regulator permanently in code and
usb-c doesn't work.
---
static int qcom_pmic_virt_tcpm_set_vbus(struct tcpc_dev *tcpc, bool on,
					bool sink)
{
	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
	int ret = 0;

	mutex_lock(&tcpm->lock);
	if (tcpm->vbus_enabled == on)
		goto done;

	ret = qcom_pmic_typec_set_vbus(tcpm->pmic_typec, 0);
---
I hack it here.
> 
> vSafe5V should indicate to the controller that you have successfully 
> switched on vBus, so what this indicates to me is that on your hardware 
> VBUS either hasn't been asserted or hasn't been detected.
> 
> Can you show the printout of *(pmic_typec->base + TYPEC_SM_STATUS_REG) ? 
[   53.120005] hub 1-1:1.0: 4 ports detected
[   58.675134] typec base is 0x1500
[   58.675148] TYPEC_SM_STATUS_REG is 0xa
[   58.675153] typec status reg is 0x150a
It should be correct.
> And can you check your schematics and verify VBUS is supplied by 
> pm8150b_vbus and not say by an external IC ?
I haven't schematics, so I can only use hacking code to test it.
> 
> ---
> bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-24  0:43       ` Jianhua Lu
@ 2023-03-24  0:53         ` Bryan O'Donoghue
  2023-03-24  1:13           ` Jianhua Lu
  0 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-24  0:53 UTC (permalink / raw)
  To: Jianhua Lu
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 24/03/2023 00:43, Jianhua Lu wrote:
>> Can you show the printout of *(pmic_typec->base + TYPEC_SM_STATUS_REG) ?
> [   53.120005] hub 1-1:1.0: 4 ports detected
> [   58.675134] typec base is 0x1500
> [   58.675148] TYPEC_SM_STATUS_REG is 0xa
> [   58.675153] typec status reg is 0x150a
> It should be correct.
>> And can you check your schematics and verify VBUS is supplied by
>> pm8150b_vbus and not say by an external IC ?
> I haven't schematics, so I can only use hacking code to test it.

Could you show the state of TYPEC_MISC_STATUS_REG @ 0x0b ?

I wonder if BIT(5) TYPEC_VBUS_DETECT is set ?

BTW what sort of device have you connected here and is it self-powered ?

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-24  0:53         ` Bryan O'Donoghue
@ 2023-03-24  1:13           ` Jianhua Lu
  2023-03-24  2:37             ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Jianhua Lu @ 2023-03-24  1:13 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On Fri, Mar 24, 2023 at 12:53:09AM +0000, Bryan O'Donoghue wrote:
> On 24/03/2023 00:43, Jianhua Lu wrote:
> >> Can you show the printout of *(pmic_typec->base + TYPEC_SM_STATUS_REG) ?
> > [   53.120005] hub 1-1:1.0: 4 ports detected
> > [   58.675134] typec base is 0x1500
> > [   58.675148] TYPEC_SM_STATUS_REG is 0xa
> > [   58.675153] typec status reg is 0x150a
> > It should be correct.
> >> And can you check your schematics and verify VBUS is supplied by
> >> pm8150b_vbus and not say by an external IC ?
> > I haven't schematics, so I can only use hacking code to test it.
> 
> Could you show the state of TYPEC_MISC_STATUS_REG @ 0x0b ?
when connected to usb-c, it outputs:
[   47.111552] debug: typec misc status is 0xc0

when disconnected to usb-c, it outputs:
[   64.061706] debug: typec misc status is 0x42
> 
> I wonder if BIT(5) TYPEC_VBUS_DETECT is set ?
> 
> BTW what sort of device have you connected here and is it self-powered ?
It is a usb-c to 4-usb host hub without external supplies.
> 
> ---
> bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-24  1:13           ` Jianhua Lu
@ 2023-03-24  2:37             ` Bryan O'Donoghue
  2023-03-24 10:16               ` Jianhua Lu
  0 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-24  2:37 UTC (permalink / raw)
  To: Jianhua Lu
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 24/03/2023 01:13, Jianhua Lu wrote:
>> Can you show the printout of *(pmic_typec->base + TYPEC_SM_STATUS_REG) ?
> [   53.120005] hub 1-1:1.0: 4 ports detected
> [   58.675134] typec base is 0x1500
> [   58.675148] TYPEC_SM_STATUS_REG is 0xa
> [   58.675153] typec status reg is 0x150a
> It should be correct.

So that is some very very strange value you have in that register.

This is from my WIP tree so the filename has changed but

+#define DEBUG 1
  #include <linux/delay.h>
  #include <linux/err.h>
  #include <linux/interrupt.h>
@@ -181,6 +181,17 @@ int qcom_pmic_typec_port_set_vbus(struct 
pmic_typec_port *pmic_typec_port, bool
         if (ret)
                 dev_err(pmic_typec_port->dev, "vbus vsafe%dv fail\n", 
on ? 5 : 0);

+       dev_info(pmic_typec_port->dev, "%s sm_stat output 0x%08x\n", 
__func__, sm_stat);
+
+       ret = regmap_read(pmic_typec_port->regmap,
+                         pmic_typec_port->base + TYPEC_MISC_STATUS_REG,
+                         &val);
+       dev_info(pmic_typec_port->dev, "%s misc 0x%08x\n", __func__, val);
+       ret = regmap_read(pmic_typec_port->regmap,
+                         pmic_typec_port->base + TYPEC_SM_STATUS_REG,
+                         &val);
+       dev_info(pmic_typec_port->dev, "%s sm_status 0x%08x\n", 
__func__, val);

[   17.098067] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
qcom_pmic_typec_port_set_vbus sm_stat output 0x000000b9

[   17.108819] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
qcom_pmic_typec_port_set_vbus misc 0x000000cb

[   17.118659] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
qcom_pmic_typec_port_set_vbus sm_status 0x000000b9

SM_STAT == 0xb9 => 10111001

1 : TYPEC_SM_USBIN_LT_LV
0 : TYPEC_SM_VBUS_VSAFE0V
1 : TYPEC_SM_VBUS_VSAFE5V
1 : not mapped
1 : not mapped
0 : not mapped
0 : not mapped
1 : not mapped

In other words, my hardware gives a clear indication of the appropriate 
transition.

Would appreciate if you could apply the above "patch"

That said I _am_ included to believe you and to do something about it, I 
will downgrade to a warning instead of returning on error in failure to 
transition to VSafeVX

Yeah though I'd appreciate seeing the output of the above patch to see 
if there's something we are missing.

Thanks for your review/time/input

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-24  2:37             ` Bryan O'Donoghue
@ 2023-03-24 10:16               ` Jianhua Lu
  2023-03-24 13:25                 ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Jianhua Lu @ 2023-03-24 10:16 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On Fri, Mar 24, 2023 at 02:37:15AM +0000, Bryan O'Donoghue wrote:
> On 24/03/2023 01:13, Jianhua Lu wrote:
> >> Can you show the printout of *(pmic_typec->base + TYPEC_SM_STATUS_REG) ?
> 
> [   17.108819] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
> qcom_pmic_typec_port_set_vbus misc 0x000000cb
> 
> [   17.118659] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
> qcom_pmic_typec_port_set_vbus sm_status 0x000000b9
> 
> SM_STAT == 0xb9 => 10111001
When I connect my device to a usb hub with external power supply, it show

[ 1495.622026] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
get_cc: misc 0x000000c9 cc1 0x00000002 Rd cc2 0x00000000 Open attached 1 cc=cc2
[ 1495.622383] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
get_cc: misc 0x000000c9 cc1 0x00000002 Rd cc2 0x00000000 Open attached 1 cc=cc2
[ 1495.824637] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
qcom_pmic_typec_set_vbus sm_stat output 0x000000b9
[ 1495.824667] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
qcom_pmic_typec_set_vbus misc 0x000000c9
[ 1495.824685] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
qcom_pmic_typec_set_vbus sm_status 0x000000b9
[ 1495.824739] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1495.829001] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete

I think my device's pm8150b is connected to charger pump but this charger
driver hasn't been implement, so can't detect pm8150b_vbus.
> 
> In other words, my hardware gives a clear indication of the appropriate 
> transition.
> 
> Would appreciate if you could apply the above "patch"
> 
> That said I _am_ included to believe you and to do something about it, I 
> will downgrade to a warning instead of returning on error in failure to 
> transition to VSafeVX
Your patch is correct. Making it warning let other devices' type-c work normally.
I agree with your idea.
> 
> Yeah though I'd appreciate seeing the output of the above patch to see 
> if there's something we are missing.
> 
> Thanks for your review/time/input
> 
> ---
> bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-24 10:16               ` Jianhua Lu
@ 2023-03-24 13:25                 ` Bryan O'Donoghue
  2023-03-24 15:09                   ` Jianhua Lu
  0 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-24 13:25 UTC (permalink / raw)
  To: Jianhua Lu
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 24/03/2023 10:16, Jianhua Lu wrote:

With charger
> [ 1495.824667] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500:
> qcom_pmic_typec_set_vbus misc 0x000000c9

0xC9 == (TYPEC_SM_USBIN_LT_LV | TYPEC_SM_VBUS_VSAFE0V)

> [ 1495.824685] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500:
> qcom_pmic_typec_set_vbus sm_status 0x000000b9

0xC9 == (TYPEC_SM_USBIN_LT_LV | TYPEC_SM_VBUS_VSAFE5V)

so that is correct and expected i.e. VSAFE5V it shouldn't matter to the 
type-c port controller *where* VBUS comes from only that it is within range.

Could you run again with an unpowered device and post the printout?

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-18 12:18 ` [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support Bryan O'Donoghue
  2023-03-23 14:36   ` Jianhua Lu
@ 2023-03-24 14:00   ` Heikki Krogerus
  2023-03-24 14:22     ` Bryan O'Donoghue
  1 sibling, 1 reply; 72+ messages in thread
From: Heikki Krogerus @ 2023-03-24 14:00 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: linux, gregkh, andersson, robh+dt, krzysztof.kozlowski+dt,
	linux-usb, linux-arm-msm, devicetree, wcheng, caleb.connolly,
	konrad.dybcio, subbaram, jackp, robertom

Hi Bryan,

On Sat, Mar 18, 2023 at 12:18:22PM +0000, Bryan O'Donoghue wrote:
> This commit adds a QCOM PMIC TCPM driver with an initial pm8150b
> block.
> 
> qcom_pmic_virt_tcpm.c : Responsible for registering with TCPM and
>                         arbitrates access to the Type-C and PDPHY hardware
>                         blocks in one place.
>                         This driver presents a virtual device to the Linux
>                         TCPM layer.
> 
> qcom_pmic_pdphy.c: Rsponsible for interfacing with the PDPHY hardware and
>                    processing power-delivery related calls from TCPM.
>                    This hardware binding can be extended to facilitate
>                    similar hardware in different PMICs.
> 
> qcom_pmic_typec.c: Responsible for notifying and processing Type-C
>                    related calls from TCPM.
>                    This hardware binding can be extended to facilitate
>                    similar hardware in different PMICs.

I'm sorry I never asked this before, but is that virtual device really
necessary? Couldn't you just merge that qcom_omic_virt_tcpm.c into
qcom_pmic_typec.c?

<snip>

> diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
> new file mode 100644
> index 0000000000000..91544b4b59439
> --- /dev/null
> +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
> @@ -0,0 +1,326 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023, Linaro Ltd. All rights reserved.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/usb/role.h>
> +#include <linux/usb/tcpm.h>
> +#include <linux/usb/typec_mux.h>
> +#include "qcom_pmic_pdphy.h"
> +#include "qcom_pmic_typec.h"
> +
> +struct pmic_virt_tcpm {
> +	struct device		*dev;
> +	struct pmic_typec	*pmic_typec;
> +	struct pmic_pdphy	*pmic_pdphy;
> +	struct tcpm_port	*tcpm_port;
> +	struct tcpc_dev		tcpc;
> +	bool			vbus_enabled;
> +	struct mutex		lock;		/* VBUS state serialization */
> +};
> +
> +#define tcpc_to_tcpm(_tcpc_) container_of(_tcpc_, struct pmic_virt_tcpm, tcpc)
> +
> +static int qcom_pmic_virt_tcpm_get_vbus(struct tcpc_dev *tcpc)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +	int ret;
> +
> +	mutex_lock(&tcpm->lock);
> +	ret = tcpm->vbus_enabled || qcom_pmic_typec_get_vbus(tcpm->pmic_typec);
> +	mutex_unlock(&tcpm->lock);
> +
> +	return ret;
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_vbus(struct tcpc_dev *tcpc, bool on,
> +					bool sink)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +	int ret = 0;
> +
> +	mutex_lock(&tcpm->lock);
> +	if (tcpm->vbus_enabled == on)
> +		goto done;
> +
> +	ret = qcom_pmic_typec_set_vbus(tcpm->pmic_typec, on);
> +	if (ret)
> +		goto done;
> +
> +	tcpm->vbus_enabled = on;
> +	tcpm_vbus_change(tcpm->tcpm_port);
> +
> +done:
> +	dev_dbg(tcpm->dev, "set_vbus set: %d result %d\n", on, ret);
> +	mutex_unlock(&tcpm->lock);
> +
> +	return ret;
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_vconn(struct tcpc_dev *tcpc, bool on)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_typec_set_vconn(tcpm->pmic_typec, on);
> +}
> +
> +static int qcom_pmic_virt_tcpm_get_cc(struct tcpc_dev *tcpc,
> +				      enum typec_cc_status *cc1,
> +				      enum typec_cc_status *cc2)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_typec_get_cc(tcpm->pmic_typec, cc1, cc2);
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_cc(struct tcpc_dev *tcpc,
> +				      enum typec_cc_status cc)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_typec_set_cc(tcpm->pmic_typec, cc);
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_polarity(struct tcpc_dev *tcpc,
> +					    enum typec_cc_polarity pol)
> +{
> +	/* Polarity is set separately by phy-qcom-qmp.c */
> +	return 0;
> +}
> +
> +static int qcom_pmic_virt_tcpm_start_toggling(struct tcpc_dev *tcpc,
> +					      enum typec_port_type port_type,
> +					      enum typec_cc_status cc)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_typec_start_toggling(tcpm->pmic_typec, port_type, cc);
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_roles(struct tcpc_dev *tcpc, bool attached,
> +					 enum typec_role power_role,
> +					 enum typec_data_role data_role)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_pdphy_set_roles(tcpm->pmic_pdphy, data_role,
> +					 power_role);
> +}
> +
> +static int qcom_pmic_virt_tcpm_set_pd_rx(struct tcpc_dev *tcpc, bool on)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_pdphy_set_pd_rx(tcpm->pmic_pdphy, on);
> +}
> +
> +static int qcom_pmic_virt_tcpm_pd_transmit(struct tcpc_dev *tcpc,
> +					   enum tcpm_transmit_type type,
> +					   const struct pd_message *msg,
> +					   unsigned int negotiated_rev)
> +{
> +	struct pmic_virt_tcpm *tcpm = tcpc_to_tcpm(tcpc);
> +
> +	return qcom_pmic_pdphy_pd_transmit(tcpm->pmic_pdphy, type, msg,
> +					   negotiated_rev);
> +}

So this driver is clearly the aggregate, and the typec device and the
pdphy device are the components. Have you considered the component
framework (drivers/base/component.c)?

I think you could use it to simplify these drivers a bit. You probable
would not need to expose all those functions in each driver separately
like you do now, and the above functions you would not need at all.
Instead you could just share (in this case) instance of your struct
pmic_virt_tcpm with the components when they are bind and just expect
them to fill the tcpm callbacks that they are responsible of.

You also would not need to rely on things like probe deferring,
because when the aggregate is bind you are guaranteed that all the
components in it are ready. There are probable some other benefits in
it as well.

This is not a must, but I think worth taking a look.

> +static struct platform_device
> +*qcom_pmic_virt_tcpm_get_pdev(struct device *dev, const char *property_name)
> +{
> +	struct device_node *np;
> +	struct platform_device *pdev;
> +	const __be32 *prop;
> +
> +	prop = of_get_property(dev->of_node, property_name, NULL);
> +	if (!prop) {
> +		dev_err(dev, "required '%s' property missing\n", property_name);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	np = of_find_node_by_phandle(be32_to_cpup(prop));
> +	if (!np) {
> +		dev_err(dev, "could not find '%s' node\n", property_name);
> +		return ERR_PTR(-ENODEV);
> +	}
> +
> +	pdev = of_find_device_by_node(np);
> +	of_node_put(np);
> +
> +	if (pdev)
> +		return pdev;
> +
> +	return ERR_PTR(-ENODEV);
> +}
> +
> +static int qcom_pmic_virt_tcpm_init(struct tcpc_dev *tcpc)
> +{
> +	return 0;
> +}
> +
> +static int qcom_pmic_virt_tcpm_probe(struct platform_device *pdev)
> +{
> +	struct pmic_virt_tcpm *tcpm;
> +	struct device *dev = &pdev->dev;
> +	struct platform_device *typec_pdev;
> +	struct platform_device *pdphy_pdev;
> +	int ret;
> +
> +	tcpm = devm_kzalloc(dev, sizeof(*tcpm), GFP_KERNEL);
> +	if (!tcpm)
> +		return -ENOMEM;
> +
> +	tcpm->dev = dev;
> +	tcpm->tcpc.init = qcom_pmic_virt_tcpm_init;
> +	tcpm->tcpc.get_vbus = qcom_pmic_virt_tcpm_get_vbus;
> +	tcpm->tcpc.set_vbus = qcom_pmic_virt_tcpm_set_vbus;
> +	tcpm->tcpc.set_cc = qcom_pmic_virt_tcpm_set_cc;
> +	tcpm->tcpc.get_cc = qcom_pmic_virt_tcpm_get_cc;
> +	tcpm->tcpc.set_polarity = qcom_pmic_virt_tcpm_set_polarity;
> +	tcpm->tcpc.set_vconn = qcom_pmic_virt_tcpm_set_vconn;
> +	tcpm->tcpc.start_toggling = qcom_pmic_virt_tcpm_start_toggling;
> +	tcpm->tcpc.set_pd_rx = qcom_pmic_virt_tcpm_set_pd_rx;
> +	tcpm->tcpc.set_roles = qcom_pmic_virt_tcpm_set_roles;
> +	tcpm->tcpc.pd_transmit = qcom_pmic_virt_tcpm_pd_transmit;
> +
> +	mutex_init(&tcpm->lock);
> +	platform_set_drvdata(pdev, tcpm);
> +
> +	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
> +	if (ret) {
> +		dev_err(dev, "Populating child devices fail\n");
> +		return ret;
> +	};
> +
> +	typec_pdev = qcom_pmic_virt_tcpm_get_pdev(dev, "qcom,pmic-typec");
> +	if (IS_ERR(typec_pdev)) {
> +		dev_err(dev, "Error linking typec endpoint\n");
> +		return PTR_ERR(typec_pdev);
> +	}
> +
> +	tcpm->pmic_typec = platform_get_drvdata(typec_pdev);
> +	if (!tcpm->pmic_typec) {
> +		ret = -EPROBE_DEFER;
> +		goto put_typec_pdev;
> +	}
> +
> +	pdphy_pdev = qcom_pmic_virt_tcpm_get_pdev(dev, "qcom,pmic-pdphy");
> +	if (IS_ERR(pdphy_pdev)) {
> +		dev_err(dev, "Error linking pdphy endpoint\n");
> +		ret = PTR_ERR(pdphy_pdev);
> +		goto put_typec_pdev;
> +	}
> +
> +	tcpm->pmic_pdphy = platform_get_drvdata(pdphy_pdev);
> +	if (!tcpm->pmic_pdphy) {
> +		ret = -EPROBE_DEFER;
> +		goto put_pdphy_dev;
> +	}
> +
> +	tcpm->tcpc.fwnode = device_get_named_child_node(tcpm->dev, "connector");
> +	if (IS_ERR(tcpm->tcpc.fwnode))
> +		return PTR_ERR(tcpm->tcpc.fwnode);
> +
> +	tcpm->tcpm_port = tcpm_register_port(tcpm->dev, &tcpm->tcpc);
> +	if (IS_ERR(tcpm->tcpm_port)) {
> +		ret = PTR_ERR(tcpm->tcpm_port);
> +		goto fwnode_remove;
> +	}
> +
> +	ret = qcom_pmic_pdphy_init(tcpm->pmic_pdphy, tcpm->tcpm_port);
> +	if (ret)
> +		goto fwnode_remove;
> +
> +	ret = qcom_pmic_typec_init(tcpm->pmic_typec, tcpm->tcpm_port);
> +	if (ret)
> +		goto fwnode_remove;
> +
> +	return 0;
> +
> +fwnode_remove:
> +	fwnode_remove_software_node(tcpm->tcpc.fwnode);
> +
> +put_pdphy_dev:
> +	put_device(&pdphy_pdev->dev);
> +
> +put_typec_pdev:
> +	put_device(&typec_pdev->dev);
> +
> +	return ret;
> +}
> +
> +static int qcom_pmic_virt_tcpm_remove(struct platform_device *pdev)
> +{
> +	struct pmic_virt_tcpm *tcpm = platform_get_drvdata(pdev);
> +
> +	tcpm_unregister_port(tcpm->tcpm_port);
> +	fwnode_remove_software_node(tcpm->tcpc.fwnode);
> +	qcom_pmic_pdphy_put(tcpm->pmic_pdphy);
> +	qcom_pmic_typec_put(tcpm->pmic_typec);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id qcom_pmic_virt_tcpm_table[] = {
> +	{ .compatible = "qcom,pmic-virt-tcpm" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, qcom_pmic_virt_tcpm_table);
> +
> +static struct platform_driver qcom_pmic_virt_tcpm_platform_driver = {
> +	.driver = {
> +		.name = "qcom,pmic-tcpm",
> +		.of_match_table = qcom_pmic_virt_tcpm_table,
> +	},
> +	.probe = qcom_pmic_virt_tcpm_probe,
> +	.remove = qcom_pmic_virt_tcpm_remove,
> +};
> +
> +static int __init qcom_pmic_virt_tcpm_module_init(void)
> +{
> +	int ret;
> +
> +	ret = platform_driver_register(&qcom_pmic_typec_platform_driver);
> +	if (ret)
> +		return ret;
> +
> +	ret = platform_driver_register(&qcom_pmic_pdphy_platform_driver);
> +	if (ret)
> +		goto unregister_typec;
> +
> +	ret = platform_driver_register(&qcom_pmic_virt_tcpm_platform_driver);
> +	if (ret)
> +		goto unregister_pdphy;
> +
> +	return 0;

Why not just register each driver in their own init function?

thanks,

-- 
heikki

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-24 14:00   ` Heikki Krogerus
@ 2023-03-24 14:22     ` Bryan O'Donoghue
  0 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-24 14:22 UTC (permalink / raw)
  To: Heikki Krogerus
  Cc: linux, gregkh, andersson, robh+dt, krzysztof.kozlowski+dt,
	linux-usb, linux-arm-msm, devicetree, wcheng, caleb.connolly,
	konrad.dybcio, subbaram, jackp, robertom

On 24/03/2023 14:00, Heikki Krogerus wrote:
> I'm sorry I never asked this before, but is that virtual device really
> necessary? Couldn't you just merge that qcom_omic_virt_tcpm.c into
> qcom_pmic_typec.c?

You did ask it I think but, yeah that's what I'm doing/have done now.

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-24 13:25                 ` Bryan O'Donoghue
@ 2023-03-24 15:09                   ` Jianhua Lu
  2023-03-24 16:03                     ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Jianhua Lu @ 2023-03-24 15:09 UTC (permalink / raw)
  To: Bryan O'Donoghue
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On Fri, Mar 24, 2023 at 01:25:14PM +0000, Bryan O'Donoghue wrote:
> On 24/03/2023 10:16, Jianhua Lu wrote:
> 
> so that is correct and expected i.e. VSAFE5V it shouldn't matter to the 
> type-c port controller *where* VBUS comes from only that it is within range.
> 
> Could you run again with an unpowered device and post the printout?
Here is output when plugin usb-c device without power supply:

[   45.714005] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: vbus vsafe5v fail
[   45.714024] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
qcom_pmic_typec_set_vbus sm_stat output 0x00000099
[   45.714043] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
qcom_pmic_typec_set_vbus misc 0x000000c9
[   45.714060] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500:
qcom_pmic_typec_set_vbus sm_status 0x00000099
[   45.714185] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500:
set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[   45.719505] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
> 
I get schematics of same vendor's similar device, it shows usb vbus is
connected to charger pump. It can be the main reason that can't detect vbus, but
I don't know why type-c can work normally.
> ---
> bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 00/18] Add Qualcomm PMIC TPCM support
  2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
                   ` (17 preceding siblings ...)
  2023-03-18 12:18 ` [PATCH v4 18/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for usb_1_qmpphy Bryan O'Donoghue
@ 2023-03-24 15:10 ` Luca Weiss
  2023-03-24 15:28   ` Bryan O'Donoghue
  18 siblings, 1 reply; 72+ messages in thread
From: Luca Weiss @ 2023-03-24 15:10 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom,
	lujianhua000

Hi Bryan,

On Sat Mar 18, 2023 at 1:18 PM CET, Bryan O'Donoghue wrote:
> Bryan O'Donoghue (17):
>   dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required
>   dt-bindings: regulator: qcom,usb-vbus-regulator: Mark
>     regulator-*-microamp required
>   dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add orientation-switch
>     as optional
>   dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional
>   dt-bindings: usb: Add qcom,pmic-typec dt-binding header
>   dt-bindings: usb: Add Qualcomm PMIC Type-C controller YAML schema
>   dt-bindings: usb: Add qcom,pmic-pdphy dt-binding header
>   dt-bindings: usb: Add Qualcomm PMIC PDPHY controller YAML schema
>   dt-bindings: usb: Add Qualcomm PMIC TCPM YAML schema
>   dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types
>   dt-bindings: mfd: qcom,spmi-pmic: Add typec to SPMI device types
>   usb: typec: qcom: Add Qualcomm PMIC TCPM support
>   arm64: dts: qcom: pm8150b: Add a TCPM description
>   arm64: dts: qcom: qrb5165-rb5: Switch on Type-C VBUS boost
>   arm64: dts: qcom: qrb5165-rb5: Switch on basic TCPM
>   arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for
>     usb_1
>   arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for
>     usb_1_qmpphy
>
> Dmitry Baryshkov (1):
>   phy: qcom-qmp: Register as a typec switch for orientation detection

I've just given this a spin on sm7225-fairphone-fp4 with pm7250b as the
PMIC (instead of pm8150b).

Overall it seems to work, which is awesome! I think I sent you emails in
the past where I had troubles getting earlier revisions to work.

Still there's some rough edges:

As Jianhua Lu has already reported, I'm also hitting the vbus vsafe5v
message quite often. Returning 0 in that function on error seems to work
around it and everything appears to be fine regardless.

  [  243.939593] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: vbus vsafe5v fail
  [  243.939600] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 1 result -110

If you want to take a peek at the schematics for this device, they're
available here:
https://www.fairphone.com/wp-content/uploads/2022/09/FP4_Information-for-repairers-and-recyclers.pdf
USB things you can find on page 57, the pm7250b is on page 49.

When plugging in the device with TCPM on into my PC (peripheral mode)
then the USB device registers and unregisters every couple of seconds,
never stays stable on. No messages in dmesg when this happens. This only
happens with the USB-C plug in one direction, in the other it
works reliable.

Also I've had it that at some point the usb connection seemed to be kind
of stuck on host mode, plugging the device into my PC didn't appear to
do anything.

For host mode I tried using both a USB stick and a USB-C to headphone
jack dongle, both work fine in both directions.

In any case, I look very much forward to this landing, it will be
awesome to have this feature working OOTB! And let me know if you need
anything tested on this hardware.

Regards
Luca

>
>  .../bindings/mfd/qcom,spmi-pmic.yaml          |   8 +
>  .../phy/qcom,sc7180-qmp-usb3-dp-phy.yaml      |  10 +
>  .../regulator/qcom,usb-vbus-regulator.yaml    |  10 +-
>  .../bindings/usb/qcom,pmic-pdphy.yaml         |  89 +++
>  .../bindings/usb/qcom,pmic-typec.yaml         |  88 +++
>  .../bindings/usb/qcom,pmic-virt-tcpm.yaml     |  88 +++
>  MAINTAINERS                                   |  10 +
>  arch/arm64/boot/dts/qcom/pm8150b.dtsi         |  70 ++
>  arch/arm64/boot/dts/qcom/qrb5165-rb5.dts      |  63 +-
>  drivers/phy/qualcomm/Kconfig                  |   8 +
>  drivers/phy/qualcomm/phy-qcom-qmp-combo.c     |  80 ++-
>  drivers/usb/typec/Kconfig                     |  13 -
>  drivers/usb/typec/Makefile                    |   1 -
>  drivers/usb/typec/qcom-pmic-typec.c           | 261 -------
>  drivers/usb/typec/tcpm/Kconfig                |  11 +
>  drivers/usb/typec/tcpm/Makefile               |   1 +
>  drivers/usb/typec/tcpm/qcom/Makefile          |   6 +
>  drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c | 605 +++++++++++++++++
>  drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h |  85 +++
>  drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 637 ++++++++++++++++++
>  drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h | 163 +++++
>  .../usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c | 326 +++++++++
>  .../dt-bindings/usb/typec/qcom,pmic-pdphy.h   |  18 +
>  .../dt-bindings/usb/typec/qcom,pmic-typec.h   |  18 +
>  24 files changed, 2388 insertions(+), 281 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-pdphy.yaml
>  create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-typec.yaml
>  create mode 100644 Documentation/devicetree/bindings/usb/qcom,pmic-virt-tcpm.yaml
>  delete mode 100644 drivers/usb/typec/qcom-pmic-typec.c
>  create mode 100644 drivers/usb/typec/tcpm/qcom/Makefile
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.c
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_pdphy.h
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.h
>  create mode 100644 drivers/usb/typec/tcpm/qcom/qcom_pmic_virt_tcpm.c
>  create mode 100644 include/dt-bindings/usb/typec/qcom,pmic-pdphy.h
>  create mode 100644 include/dt-bindings/usb/typec/qcom,pmic-typec.h
>
> -- 
> 2.39.2


^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 00/18] Add Qualcomm PMIC TPCM support
  2023-03-24 15:10 ` [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Luca Weiss
@ 2023-03-24 15:28   ` Bryan O'Donoghue
  2023-03-31  8:48     ` Luca Weiss
  0 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-24 15:28 UTC (permalink / raw)
  To: Luca Weiss, linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom,
	lujianhua000

On 24/03/2023 15:10, Luca Weiss wrote:
> When plugging in the device with TCPM on into my PC (peripheral mode)
> then the USB device registers and unregisters every couple of seconds,
> never stays stable on. No messages in dmesg when this happens. This only
> happens with the USB-C plug in one direction, in the other it
> works reliable.

Sounds like we need to do some SoC specific debug on orientation 
switching in the PHY.

I wonder how many lanes dp_opts->lanes says for your part ?

Also potentially not having "orientation-switch" in &usb_1_qmpphy{} but, 
I think we discussed that before.

So either

- PHY orientation turn-around isn't working or
- DTS orientation-switch isn't happening

for you

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support
  2023-03-24 15:09                   ` Jianhua Lu
@ 2023-03-24 16:03                     ` Bryan O'Donoghue
  0 siblings, 0 replies; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-24 16:03 UTC (permalink / raw)
  To: Jianhua Lu
  Cc: linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree,
	wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom

On 24/03/2023 15:09, Jianhua Lu wrote:
> I get schematics of same vendor's similar device, it shows usb vbus is
> connected to charger pump. It can be the main reason that can't detect vbus, but
> I don't know why type-c can work normally.

oki doki that all makes sense - the "charger pump" is supplying vbus 
most likely - you can confirm or invalidate this theory by connecting a 
1.0/2.0 device to your external hub - making sure it is unpowered.

vbus *should* flow through the Type-C port into your external hub and 
into the 1.0/2.0 device, irrespective of vcon

Either way that's a 2x input on the VSafe5 - I'll downgrade this to a 
dev_warn() or perhaps even a dev_dbg()

thx

---
bod

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 00/18] Add Qualcomm PMIC TPCM support
  2023-03-24 15:28   ` Bryan O'Donoghue
@ 2023-03-31  8:48     ` Luca Weiss
  2023-03-31 13:52       ` Bryan O'Donoghue
  0 siblings, 1 reply; 72+ messages in thread
From: Luca Weiss @ 2023-03-31  8:48 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom,
	lujianhua000

Hi Bryan,

On Fri Mar 24, 2023 at 4:28 PM CET, Bryan O'Donoghue wrote:
> On 24/03/2023 15:10, Luca Weiss wrote:
> > When plugging in the device with TCPM on into my PC (peripheral mode)
> > then the USB device registers and unregisters every couple of seconds,
> > never stays stable on. No messages in dmesg when this happens. This only
> > happens with the USB-C plug in one direction, in the other it
> > works reliable.
>
> Sounds like we need to do some SoC specific debug on orientation 
> switching in the PHY.

I also know that the phone has a AW35743 chip in the USB path,
controlled by DP_AUX_EN and DP_AUX_SEL gpios but I think this is only
for displayport, right?

>
> I wonder how many lanes dp_opts->lanes says for your part ?

Not sure.. Where is this configured?
But I also don't have DisplayPort over USB-C (video out) configured yet.
Related question: does video out work on sm8250+pm8150b for you?

>
> Also potentially not having "orientation-switch" in &usb_1_qmpphy{} but, 
> I think we discussed that before.

Definitely have that in my device dts in that node.

When unplugged from my PC (USB-C->USB-A cable) I get

  [ 1236.114620] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_vbus: 0x00000042 detect 0

When plugging in just

  [ 1261.890238] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_vbus: 0x00000062 detect 1

The same exact message also when plugging the USB-C plug the other way
on the phone.

When testing with a USB-C->USB-C cable the behavior is similar. Only one
orientation on the phone is stable, the other one has the same unstable
behavior. The direction on the laptop doesn't matter, both directions
(when not changing the phone direction) is stable. Not sure if this
indicates where something is wrong, I don't know enough USB-C for this
;) 

>
> So either
>
> - PHY orientation turn-around isn't working or

Since plugging in a USB stick works both ways, I assume at least some
part of it is working?

> - DTS orientation-switch isn't happening for you

Not sure what this means / how to check.

I'm attaching the USB-C->USB-C logs both ways, maybe they also show
something interesting?

Regards
Luca

==================================================================================
USB stable (device plug orientation 1):
==================================================================================

[ 1722.130836] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000cb cc1 0x00000001 Ra cc2 0x00000002 Rd attached 1 cc=cc1
[ 1722.331025] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 0 requested 2
[ 1722.331152] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=1 power_role_src=1
[ 1722.331182] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: set_pd_rx: on
[ 1722.331224] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 0 control 0x00000003 state on cc cc2 vconn cc1
[ 1722.333742] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 1 result 0
[ 1722.333824] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1722.340158] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1722.373839] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000042 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc1
[ 1722.373880] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000042 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc1
[ 1722.373905] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: set_pd_rx: off
[ 1722.379037] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 0 result 0
[ 1722.379080] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 0 control 0x00000000 state off cc cc2 vconn cc1
[ 1722.379098] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 2 requested 0
[ 1722.379171] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=1 power_role_src=1
[ 1722.379193] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: start_toggling: misc 0x00000042 attached 0 port_type 0 current cc 4 new 4
[ 1722.379234] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_vbus: 0x00000042 detect 0
[ 1722.383528] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1722.448649] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1722.448717] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 1
[ 1722.449835] xhci-hcd xhci-hcd.1.auto: hcc params 0x0230fe65 hci version 0x110 quirks 0x0000000000010010
[ 1722.449871] xhci-hcd xhci-hcd.1.auto: irq 188, io mem 0x0a600000
[ 1722.449972] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1722.449982] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 2
[ 1722.449992] xhci-hcd xhci-hcd.1.auto: Host supports USB 3.0 SuperSpeed
[ 1722.450112] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.02
[ 1722.450121] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1722.450127] usb usb1: Product: xHCI Host Controller
[ 1722.450132] usb usb1: Manufacturer: Linux 6.2.1-00102-gc2551b66fbe7-dirty xhci-hcd
[ 1722.450138] usb usb1: SerialNumber: xhci-hcd.1.auto
[ 1722.450468] hub 1-0:1.0: USB hub found
[ 1722.450494] hub 1-0:1.0: 1 port detected
[ 1722.451703] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[ 1722.451810] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.02
[ 1722.451822] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1722.451831] usb usb2: Product: xHCI Host Controller
[ 1722.451839] usb usb2: Manufacturer: Linux 6.2.1-00102-gc2551b66fbe7-dirty xhci-hcd
[ 1722.451846] usb usb2: SerialNumber: xhci-hcd.1.auto
[ 1722.452491] hub 2-0:1.0: USB hub found
[ 1722.452524] hub 2-0:1.0: 1 port detected
[ 1722.453143] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 1722.453153] usb usb2: USB disconnect, device number 1
[ 1722.454619] xhci-hcd xhci-hcd.1.auto: USB bus 2 deregistered
[ 1722.454640] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 1722.454653] usb usb1: USB disconnect, device number 1
[ 1722.457569] xhci-hcd xhci-hcd.1.auto: USB bus 1 deregistered
[ 1723.255900] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000cb cc1 0x00000001 Ra cc2 0x00000002 Rd attached 1 cc=cc1
[ 1723.255956] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000cb cc1 0x00000001 Ra cc2 0x00000002 Rd attached 1 cc=cc1
[ 1723.456104] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 0 requested 2
[ 1723.456214] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=1 power_role_src=1
[ 1723.456238] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: set_pd_rx: on
[ 1723.456283] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 0 control 0x00000003 state on cc cc2 vconn cc1
[ 1723.458727] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 1 result 0
[ 1723.458784] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.466539] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.503200] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.503241] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.507535] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.523733] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.523808] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.535554] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.543851] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.543892] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.551553] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.565097] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.571515] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.575554] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.576416] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1723.576482] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 1
[ 1723.577757] xhci-hcd xhci-hcd.1.auto: hcc params 0x0230fe65 hci version 0x110 quirks 0x0000000000010010
[ 1723.577850] xhci-hcd xhci-hcd.1.auto: irq 188, io mem 0x0a600000
[ 1723.578172] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1723.578216] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 2
[ 1723.578258] xhci-hcd xhci-hcd.1.auto: Host supports USB 3.0 SuperSpeed
[ 1723.578680] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.02
[ 1723.578723] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1723.578747] usb usb1: Product: xHCI Host Controller
[ 1723.578755] usb usb1: Manufacturer: Linux 6.2.1-00102-gc2551b66fbe7-dirty xhci-hcd
[ 1723.578760] usb usb1: SerialNumber: xhci-hcd.1.auto
[ 1723.579187] hub 1-0:1.0: USB hub found
[ 1723.579211] hub 1-0:1.0: 1 port detected
[ 1723.579480] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[ 1723.579548] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.02
[ 1723.579555] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1723.579560] usb usb2: Product: xHCI Host Controller
[ 1723.579564] usb usb2: Manufacturer: Linux 6.2.1-00102-gc2551b66fbe7-dirty xhci-hcd
[ 1723.579569] usb usb2: SerialNumber: xhci-hcd.1.auto
[ 1723.581083] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 2 requested 2
[ 1723.581144] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=0 power_role_src=1
[ 1723.581192] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.581234] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.581661] hub 2-0:1.0: USB hub found
[ 1723.581690] hub 2-0:1.0: 1 port detected
[ 1723.582636] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 1723.582659] usb usb2: USB disconnect, device number 1
[ 1723.586362] xhci-hcd xhci-hcd.1.auto: USB bus 2 deregistered
[ 1723.586421] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 1723.586456] usb usb1: USB disconnect, device number 1
[ 1723.591097] xhci-hcd xhci-hcd.1.auto: USB bus 1 deregistered
[ 1723.591580] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.602619] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.602793] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.611512] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.623020] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.623062] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.631625] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.644262] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.650769] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc1
[ 1723.651546] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1723.662850] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 0 control 0x00000000 state off cc cc2 vconn cc1

- unplug -

[ 1867.223052] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000042 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc1
[ 1867.223277] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: set_pd_rx: off
[ 1867.226027] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 0 result 0
[ 1867.226064] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 0 control 0x00000000 state off cc cc2 vconn cc1
[ 1867.226084] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 2 requested 0
[ 1867.226145] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=0 power_role_src=1
[ 1867.226167] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: start_toggling: misc 0x00000042 attached 0 port_type 0 current cc 5 new 4
[ 1867.226212] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_vbus: 0x00000042 detect 0
[ 1867.236933] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete

==================================================================================
USB unstable (device plug orientation 2):
==================================================================================

[ 1894.263324] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000c9 cc1 0x00000002 Rd cc2 0x00000001 Ra attached 1 cc=cc2
[ 1894.463482] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 0 requested 1
[ 1894.463616] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=1 power_role_src=1
[ 1894.463646] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: set_pd_rx: on
[ 1894.463690] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 4 control 0x00000007 state on cc cc1 vconn cc2
[ 1894.466173] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 1 result 0
[ 1894.466257] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1894.474797] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1894.505894] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000040 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc2
[ 1894.505935] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000040 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc2
[ 1894.505963] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: set_pd_rx: off
[ 1894.510880] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 0 result 0
[ 1894.510920] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 4 control 0x00000000 state off cc cc1 vconn cc2
[ 1894.510940] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 1 requested 0
[ 1894.511021] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=1 power_role_src=1
[ 1894.511043] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: start_toggling: misc 0x00000040 attached 0 port_type 0 current cc 4 new 4
[ 1894.511084] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_vbus: 0x00000000 detect 0
[ 1894.516552] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1894.581138] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1894.581171] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 1
[ 1894.582287] xhci-hcd xhci-hcd.1.auto: hcc params 0x0230fe65 hci version 0x110 quirks 0x0000000000010010
[ 1894.582330] xhci-hcd xhci-hcd.1.auto: irq 188, io mem 0x0a600000
[ 1894.582464] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1894.582479] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 2
[ 1894.582493] xhci-hcd xhci-hcd.1.auto: Host supports USB 3.0 SuperSpeed
[ 1894.582649] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.02
[ 1894.582661] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1894.582670] usb usb1: Product: xHCI Host Controller
[ 1894.582677] usb usb1: Manufacturer: Linux 6.2.1-00102-gc2551b66fbe7-dirty xhci-hcd
[ 1894.582685] usb usb1: SerialNumber: xhci-hcd.1.auto
[ 1894.583211] hub 1-0:1.0: USB hub found
[ 1894.583255] hub 1-0:1.0: 1 port detected
[ 1894.583830] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[ 1894.583960] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.02
[ 1894.583975] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1894.583987] usb usb2: Product: xHCI Host Controller
[ 1894.583996] usb usb2: Manufacturer: Linux 6.2.1-00102-gc2551b66fbe7-dirty xhci-hcd
[ 1894.584006] usb usb2: SerialNumber: xhci-hcd.1.auto
[ 1894.584742] hub 2-0:1.0: USB hub found
[ 1894.584782] hub 2-0:1.0: 1 port detected
[ 1894.585437] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 1894.585452] usb usb2: USB disconnect, device number 1
[ 1894.588024] xhci-hcd xhci-hcd.1.auto: USB bus 2 deregistered
[ 1894.588046] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 1894.588060] usb usb1: USB disconnect, device number 1
[ 1894.591836] xhci-hcd xhci-hcd.1.auto: USB bus 1 deregistered
[ 1895.388351] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000c9 cc1 0x00000002 Rd cc2 0x00000001 Ra attached 1 cc=cc2
[ 1895.388407] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000c9 cc1 0x00000002 Rd cc2 0x00000001 Ra attached 1 cc=cc2
[ 1895.588568] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 0 requested 1
[ 1895.588643] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=1 power_role_src=1
[ 1895.588664] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: set_pd_rx: on
[ 1895.588705] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 4 control 0x00000007 state on cc cc1 vconn cc2
[ 1895.591193] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 1 result 0
[ 1895.591250] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.598187] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.635829] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.635940] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.640601] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.657692] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.657766] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.664570] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.677799] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.677836] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.684618] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.698467] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.704570] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.705452] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1895.705514] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 1
[ 1895.706625] xhci-hcd xhci-hcd.1.auto: hcc params 0x0230fe65 hci version 0x110 quirks 0x0000000000010010
[ 1895.706658] xhci-hcd xhci-hcd.1.auto: irq 188, io mem 0x0a600000
[ 1895.706747] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1895.706755] xhci-hcd xhci-hcd.1.auto: new USB bus registered, assigned bus number 2
[ 1895.706764] xhci-hcd xhci-hcd.1.auto: Host supports USB 3.0 SuperSpeed
[ 1895.706824] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.707209] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.02
[ 1895.707250] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1895.707280] usb usb1: Product: xHCI Host Controller
[ 1895.707305] usb usb1: Manufacturer: Linux 6.2.1-00102-gc2551b66fbe7-dirty xhci-hcd
[ 1895.707331] usb usb1: SerialNumber: xhci-hcd.1.auto
[ 1895.708504] hub 1-0:1.0: USB hub found
[ 1895.708635] hub 1-0:1.0: 1 port detected
[ 1895.709607] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[ 1895.709928] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.02
[ 1895.709970] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1895.709999] usb usb2: Product: xHCI Host Controller
[ 1895.710023] usb usb2: Manufacturer: Linux 6.2.1-00102-gc2551b66fbe7-dirty xhci-hcd
[ 1895.710049] usb usb2: SerialNumber: xhci-hcd.1.auto
[ 1895.711360] hub 2-0:1.0: USB hub found
[ 1895.711392] hub 2-0:1.0: 1 port detected
[ 1895.712739] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.714685] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 1 requested 1
[ 1895.714749] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=0 power_role_src=1
[ 1895.714795] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.714837] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.715104] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 1895.715114] usb usb2: USB disconnect, device number 1
[ 1895.718866] xhci-hcd xhci-hcd.1.auto: USB bus 2 deregistered
[ 1895.718889] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 1895.718901] usb usb1: USB disconnect, device number 1
[ 1895.725858] xhci-hcd xhci-hcd.1.auto: USB bus 1 deregistered
[ 1895.726158] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.735069] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.735135] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.744571] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.756079] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.756119] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=1 Rp-1.5-180uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.764615] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.776343] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.782944] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
[ 1895.784556] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete
[ 1895.795184] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 4 control 0x00000000 state off cc cc1 vconn cc2

- unplug -

[ 1907.264840] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000040 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc2
[ 1907.264888] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000040 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc2
[ 1907.265075] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: set_pd_rx: off
[ 1907.267897] qcom,pmic-tcpm pm7250b-tcpm: set_vbus set: 0 result 0
[ 1907.267932] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_vconn: orientation 4 control 0x00000000 state off cc cc1 vconn cc2
[ 1907.267951] qcom-qmp-combo-phy 88e8000.phy: Toggling orientation current 1 requested 0
[ 1907.268011] qcom,pmic-usb-pdphy c440000.spmi:pmic@2:pdphy@1700: pdphy_set_roles: data_role_host=0 power_role_src=1
[ 1907.268034] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: start_toggling: misc 0x00000040 attached 0 port_type 0 current cc 5 new 4
[ 1907.268081] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_vbus: 0x00000040 detect 0
[ 1907.272422] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: Debounce cc complete

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 00/18] Add Qualcomm PMIC TPCM support
  2023-03-31  8:48     ` Luca Weiss
@ 2023-03-31 13:52       ` Bryan O'Donoghue
  2023-03-31 14:58         ` Luca Weiss
  0 siblings, 1 reply; 72+ messages in thread
From: Bryan O'Donoghue @ 2023-03-31 13:52 UTC (permalink / raw)
  To: Luca Weiss, linux, heikki.krogerus, gregkh, andersson, robh+dt,
	krzysztof.kozlowski+dt, linux-usb, linux-arm-msm, devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom,
	lujianhua000

On 31/03/2023 09:48, Luca Weiss wrote:
> Hi Bryan,
> 
> On Fri Mar 24, 2023 at 4:28 PM CET, Bryan O'Donoghue wrote:
>> On 24/03/2023 15:10, Luca Weiss wrote:
>>> When plugging in the device with TCPM on into my PC (peripheral mode)
>>> then the USB device registers and unregisters every couple of seconds,
>>> never stays stable on. No messages in dmesg when this happens. This only
>>> happens with the USB-C plug in one direction, in the other it
>>> works reliable.
>>
>> Sounds like we need to do some SoC specific debug on orientation
>> switching in the PHY.
> 
> I also know that the phone has a AW35743 chip in the USB path,
> controlled by DP_AUX_EN and DP_AUX_SEL gpios but I think this is only
> for displayport, right?
> 

https://www.awinic.com/en/productDetail/AW35743CSR#product-details D+/D- 
looks like USB 2.x ..

Your DP should go over TX1+/1 TX2+/- depending on orientation and # of 
lanes in use.

https://www.allaboutcircuits.com/uploads/articles/Fig1m11292018.png

>>
>> I wonder how many lanes dp_opts->lanes says for your part ?
> 
> Not sure.. Where is this configured?

Heh - now that I look my lane count == 0, a bug to be fixed..

Hmm, Luca can you test this change

-       if (orientation == TYPEC_ORIENTATION_NONE) {
-               if (qmp->init_count)
-                       ret = qmp_combo_dp_power_off(dp_phy);
-       } else {
-               if (!qmp->init_count)
-                       ret = qmp_combo_dp_power_on(dp_phy);
-       }
+       if (orientation == TYPEC_ORIENTATION_NONE)
+               ret = qmp_combo_dp_power_off(dp_phy);
+       else
+               ret = qmp_combo_dp_power_on(dp_phy);


> But I also don't have DisplayPort over USB-C (video out) configured yet.
> Related question: does video out work on sm8250+pm8150b for you?

Nope - WIP. I see getting TCPM upstream and working as a first step, 
then we look at introduction of the redriver, DP work, dt etc.


> [ 1722.130836] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000cb cc1 0x00000001 Ra cc2 0x00000002 Rd attached 1 cc=cc1
> 
> - unplug -
> 
> [ 1867.223052] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000042 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc1
> ==================================================================================
> USB unstable (device plug orientation 2):
> ==================================================================================
> 
> [ 1894.263324] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000c9 cc1 0x00000002 Rd cc2 0x00000001 Ra attached 1 cc=cc2
> - unplug -
> 
> [ 1907.264840] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000040 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc2

Normal, correct.

For reference on 8250

Attached orientation reverse / cc2

[   77.719278] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: 
currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2

Detached orientation (none)
[   82.475667] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: 
misc 0x000000c0 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc2

Attached orientation normal / cc1
[   82.485375] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
start_toggling: misc 0x00000040 attached 0 port_type 0 current cc 5 new 5
[   85.247368] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: 
misc 0x000000cb cc1 0x00000001 Ra cc2 0x00000002 Rd attached 1 cc=cc1

Anyway I reckon that guard I have in the PHY code is wrong, would 
appreciate a test.

---
bod



^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v4 00/18] Add Qualcomm PMIC TPCM support
  2023-03-31 13:52       ` Bryan O'Donoghue
@ 2023-03-31 14:58         ` Luca Weiss
  0 siblings, 0 replies; 72+ messages in thread
From: Luca Weiss @ 2023-03-31 14:58 UTC (permalink / raw)
  To: Bryan O'Donoghue, linux, heikki.krogerus, gregkh, andersson,
	robh+dt, krzysztof.kozlowski+dt, linux-usb, linux-arm-msm,
	devicetree
  Cc: wcheng, caleb.connolly, konrad.dybcio, subbaram, jackp, robertom,
	lujianhua000

On Fri Mar 31, 2023 at 3:52 PM CEST, Bryan O'Donoghue wrote:
> On 31/03/2023 09:48, Luca Weiss wrote:
> > Hi Bryan,
> > 
> > On Fri Mar 24, 2023 at 4:28 PM CET, Bryan O'Donoghue wrote:
> >> On 24/03/2023 15:10, Luca Weiss wrote:
> >>> When plugging in the device with TCPM on into my PC (peripheral mode)
> >>> then the USB device registers and unregisters every couple of seconds,
> >>> never stays stable on. No messages in dmesg when this happens. This only
> >>> happens with the USB-C plug in one direction, in the other it
> >>> works reliable.
> >>
> >> Sounds like we need to do some SoC specific debug on orientation
> >> switching in the PHY.
> > 
> > I also know that the phone has a AW35743 chip in the USB path,
> > controlled by DP_AUX_EN and DP_AUX_SEL gpios but I think this is only
> > for displayport, right?
> > 
>
> https://www.awinic.com/en/productDetail/AW35743CSR#product-details D+/D- 
> looks like USB 2.x ..
>
> Your DP should go over TX1+/1 TX2+/- depending on orientation and # of 
> lanes in use.

There's USB0_DP_AUX_P & USB0_DP_AUX_M from the SoC connected on the
D1+/- & D2+/- pins of this awinic chip, and out comes USB_SBU1 and
USB_SBU2 which goes to the USB connector. So just switching polarity of
those pins.
But let's say whatever it does, it's not relevant to this use case now
without DP?

>
> https://www.allaboutcircuits.com/uploads/articles/Fig1m11292018.png
>
> >>
> >> I wonder how many lanes dp_opts->lanes says for your part ?
> > 
> > Not sure.. Where is this configured?
>
> Heh - now that I look my lane count == 0, a bug to be fixed..
>
> Hmm, Luca can you test this change
>
> -       if (orientation == TYPEC_ORIENTATION_NONE) {
> -               if (qmp->init_count)
> -                       ret = qmp_combo_dp_power_off(dp_phy);
> -       } else {
> -               if (!qmp->init_count)
> -                       ret = qmp_combo_dp_power_on(dp_phy);
> -       }
> +       if (orientation == TYPEC_ORIENTATION_NONE)
> +               ret = qmp_combo_dp_power_off(dp_phy);
> +       else
> +               ret = qmp_combo_dp_power_on(dp_phy);

I unfortunately don't really see any change in behavior with this..

>
>
> > But I also don't have DisplayPort over USB-C (video out) configured yet.
> > Related question: does video out work on sm8250+pm8150b for you?
>
> Nope - WIP. I see getting TCPM upstream and working as a first step, 
> then we look at introduction of the redriver, DP work, dt etc.

Clear, I look forward to that landing ;) But also already what the
driver does now is really useful!

Regards
Luca

>
>
> > [ 1722.130836] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000cb cc1 0x00000001 Ra cc2 0x00000002 Rd attached 1 cc=cc1
> > 
> > - unplug -
> > 
> > [ 1867.223052] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000042 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc1
> > ==================================================================================
> > USB unstable (device plug orientation 2):
> > ==================================================================================
> > 
> > [ 1894.263324] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x000000c9 cc1 0x00000002 Rd cc2 0x00000001 Ra attached 1 cc=cc2
> > - unplug -
> > 
> > [ 1907.264840] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: misc 0x00000040 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc2
>
> Normal, correct.
>
> For reference on 8250
>
> Attached orientation reverse / cc2
>
> [   77.719278] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: set_cc: 
> currsrc=2 Rp-3.0-330uA mode EN_SRC_ONLY debounce 1 attached 1 cc=cc2
>
> Detached orientation (none)
> [   82.475667] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: 
> misc 0x000000c0 cc1 0x00000000 Open cc2 0x00000000 Open attached 0 cc=cc2
>
> Attached orientation normal / cc1
> [   82.485375] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: 
> start_toggling: misc 0x00000040 attached 0 port_type 0 current cc 5 new 5
> [   85.247368] qcom,pmic-typec c440000.spmi:pmic@2:typec@1500: get_cc: 
> misc 0x000000cb cc1 0x00000001 Ra cc2 0x00000002 Rd attached 1 cc=cc1
>
> Anyway I reckon that guard I have in the PHY code is wrong, would 
> appreciate a test.
>
> ---
> bod


^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2023-03-31 14:58 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-18 12:18 [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 01/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark reg as required Bryan O'Donoghue
2023-03-19 11:41   ` Krzysztof Kozlowski
2023-03-18 12:18 ` [PATCH v4 02/18] dt-bindings: regulator: qcom,usb-vbus-regulator: Mark regulator-*-microamp required Bryan O'Donoghue
2023-03-19 11:42   ` Krzysztof Kozlowski
2023-03-19 11:53   ` Krzysztof Kozlowski
2023-03-18 12:18 ` [PATCH v4 03/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add orientation-switch as optional Bryan O'Donoghue
2023-03-19 11:42   ` Krzysztof Kozlowski
2023-03-18 12:18 ` [PATCH v4 04/18] dt-bindings: phy: qcom,sc7180-qmp-usb3-dp-phy: Add port as an optional Bryan O'Donoghue
2023-03-19 11:45   ` Krzysztof Kozlowski
2023-03-21 20:49     ` Rob Herring
2023-03-22 14:01       ` Bryan O'Donoghue
2023-03-23 13:39       ` Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 05/18] dt-bindings: usb: Add qcom,pmic-typec dt-binding header Bryan O'Donoghue
2023-03-19 11:50   ` Krzysztof Kozlowski
2023-03-19 14:50     ` Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 06/18] dt-bindings: usb: Add Qualcomm PMIC Type-C controller YAML schema Bryan O'Donoghue
2023-03-19 11:53   ` Krzysztof Kozlowski
2023-03-18 12:18 ` [PATCH v4 07/18] dt-bindings: usb: Add qcom,pmic-pdphy dt-binding header Bryan O'Donoghue
2023-03-19 11:50   ` Krzysztof Kozlowski
2023-03-18 12:18 ` [PATCH v4 08/18] dt-bindings: usb: Add Qualcomm PMIC PDPHY controller YAML schema Bryan O'Donoghue
2023-03-19 11:55   ` Krzysztof Kozlowski
2023-03-18 12:18 ` [PATCH v4 09/18] dt-bindings: usb: Add Qualcomm PMIC TCPM " Bryan O'Donoghue
2023-03-19 11:58   ` Krzysztof Kozlowski
2023-03-19 14:59     ` Bryan O'Donoghue
2023-03-19 15:10       ` Krzysztof Kozlowski
2023-03-19 15:44         ` Bryan O'Donoghue
2023-03-19 17:50           ` Krzysztof Kozlowski
2023-03-19 21:31             ` Caleb Connolly
2023-03-19 22:34               ` Bryan O'Donoghue
2023-03-19 22:32             ` Bryan O'Donoghue
2023-03-19 15:50         ` Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 10/18] dt-bindings: mfd: qcom,spmi-pmic: Add pdphy to SPMI device types Bryan O'Donoghue
2023-03-19 11:58   ` Krzysztof Kozlowski
2023-03-21 20:58     ` Rob Herring
2023-03-21 23:52       ` Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 11/18] dt-bindings: mfd: qcom,spmi-pmic: Add typec " Bryan O'Donoghue
2023-03-19 11:59   ` Krzysztof Kozlowski
2023-03-18 12:18 ` [PATCH v4 12/18] usb: typec: qcom: Add Qualcomm PMIC TCPM support Bryan O'Donoghue
2023-03-23 14:36   ` Jianhua Lu
2023-03-23 17:31     ` Bryan O'Donoghue
2023-03-24  0:43       ` Jianhua Lu
2023-03-24  0:53         ` Bryan O'Donoghue
2023-03-24  1:13           ` Jianhua Lu
2023-03-24  2:37             ` Bryan O'Donoghue
2023-03-24 10:16               ` Jianhua Lu
2023-03-24 13:25                 ` Bryan O'Donoghue
2023-03-24 15:09                   ` Jianhua Lu
2023-03-24 16:03                     ` Bryan O'Donoghue
2023-03-24 14:00   ` Heikki Krogerus
2023-03-24 14:22     ` Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 13/18] phy: qcom-qmp: Register as a typec switch for orientation detection Bryan O'Donoghue
2023-03-18 16:42   ` kernel test robot
2023-03-20 11:15   ` Neil Armstrong
2023-03-20 11:19     ` Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 14/18] arm64: dts: qcom: pm8150b: Add a TCPM description Bryan O'Donoghue
2023-03-18 13:13   ` Konrad Dybcio
2023-03-18 21:09   ` kernel test robot
2023-03-18 12:18 ` [PATCH v4 15/18] arm64: dts: qcom: qrb5165-rb5: Switch on Type-C VBUS boost Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 16/18] arm64: dts: qcom: qrb5165-rb5: Switch on basic TCPM Bryan O'Donoghue
2023-03-18 13:09   ` Konrad Dybcio
2023-03-18 12:18 ` [PATCH v4 17/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM usb-role-switching for usb_1 Bryan O'Donoghue
2023-03-18 13:10   ` Konrad Dybcio
2023-03-18 17:46     ` Bryan O'Donoghue
2023-03-18 12:18 ` [PATCH v4 18/18] arm64: dts: qcom: qrb5165-rb5: Switch on TCPM orientation-switch for usb_1_qmpphy Bryan O'Donoghue
2023-03-18 13:11   ` Konrad Dybcio
2023-03-18 17:47     ` Bryan O'Donoghue
2023-03-24 15:10 ` [PATCH v4 00/18] Add Qualcomm PMIC TPCM support Luca Weiss
2023-03-24 15:28   ` Bryan O'Donoghue
2023-03-31  8:48     ` Luca Weiss
2023-03-31 13:52       ` Bryan O'Donoghue
2023-03-31 14:58         ` Luca Weiss

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).