Re: [PATCH RFC 06/12] usb: typec: qcom: Add gen1 Type-C port support
From: David Heidelberg
Date: Sun Oct 18 2026 - 19:30:20 EST
On 26/09/2026 16:22, Bryan O'Donoghue wrote:
On 26/09/2026 13:40, David Heidelberg via B4 Relay wrote:
From: David Heidelberg <david@xxxxxxx>
Add a port backend for the first generation of the Qualcomm PMIC Type-C
block, found on PM660 and PMI8998.
On gen1 the Type-C CC logic is part of the charger's USBIN peripheral
(base 0x1300) instead of the standalone Type-C peripheral used by
PM8150B and later PMICs. All Type-C events (CC state change,
tCCDebounce done, VBUS change and error) are signalled through a single
aggregate "type-c-change" interrupt, the handler re-reads TYPEC_STATUS_4
to find out what changed. The PD PHY is register compatible with PM8150B
and is reused as is.
Differences to the PM8150B backend:
- get_cc() returns -EBUSY until the hardware reports tCCDebounce done,
instead of using a software debounce.
- As a source, only the default and 1.5A Rp can be advertised, 3.0A
requests are advertised as 1.5A.
- The PBS workaround of the downstream SMB2 driver (TM_IO_DTEST4_SEL)
is applied on every power role change.
VBUS sourcing is optional and only used when the connector provides
a vbus-supply, as the charger doesn't expose a VBUS regulator yet.
Assisted-by: LLM
Co-developed-by: Alexey Minnekhanov <alexeymin@xxxxxxxxxx>
Signed-off-by: Alexey Minnekhanov <alexeymin@xxxxxxxxxx>
Signed-off-by: David Heidelberg <david@xxxxxxx>
---
drivers/usb/typec/tcpm/qcom/Makefile | 1 +
drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 9 +
.../typec/tcpm/qcom/qcom_pmic_typec_port_gen1.c | 605 +++++++++++++++++++++
.../typec/tcpm/qcom/qcom_pmic_typec_port_gen1.h | 15 +
4 files changed, 630 insertions(+)
diff --git a/drivers/usb/typec/tcpm/qcom/Makefile b/drivers/usb/typec/tcpm/ qcom/Makefile
index cc23042b94878..b8b9350184c19 100644
--- a/drivers/usb/typec/tcpm/qcom/Makefile
+++ b/drivers/usb/typec/tcpm/qcom/Makefile
@@ -1,7 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
#
obj-$(CONFIG_TYPEC_QCOM_PMIC) += qcom_pmic_tcpm.o
qcom_pmic_tcpm-y += qcom_pmic_typec.o \
qcom_pmic_typec_port.o \
+ qcom_pmic_typec_port_gen1.o \
qcom_pmic_typec_pdphy.o \
qcom_pmic_typec_pdphy_stub.o \
diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/ typec/tcpm/qcom/qcom_pmic_typec.c
index 41aaae6bb3724..ea1d5b0927436 100644
--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
+++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
@@ -12,16 +12,17 @@
#include <linux/slab.h>
#include <linux/usb/tcpm.h>
#include <drm/bridge/aux-bridge.h>
#include "qcom_pmic_typec.h"
#include "qcom_pmic_typec_pdphy.h"
#include "qcom_pmic_typec_port.h"
+#include "qcom_pmic_typec_port_gen1.h"
typedef int (*pmic_typec_port_probe_fn)(struct platform_device *pdev,
struct pmic_typec *tcpm,
const struct pmic_typec_port_resources *res,
struct regmap *regmap, u32 base);
struct pmic_typec_resources {
const struct pmic_typec_pdphy_resources *pdphy_res;
@@ -134,31 +135,39 @@ static void qcom_pmic_typec_remove(struct platform_device *pdev)
struct pmic_typec *tcpm = platform_get_drvdata(pdev);
tcpm->pdphy_stop(tcpm);
tcpm->port_stop(tcpm);
tcpm_unregister_port(tcpm->tcpm_port);
fwnode_handle_put(tcpm->tcpc.fwnode);
}
+static const struct pmic_typec_resources gen1_typec_res = {
+ .pdphy_res = &pm8150b_pdphy_res,
+ .port_res = &gen1_port_res,
+ .port_probe = qcom_pmic_typec_gen1_port_probe,
+};
+
static const struct pmic_typec_resources pm8150b_typec_res = {
.pdphy_res = &pm8150b_pdphy_res,
.port_res = &pm8150b_port_res,
.port_probe = qcom_pmic_typec_port_probe,
};
static const struct pmic_typec_resources pmi632_typec_res = {
/* PD PHY not present */
.port_res = &pm8150b_port_res,
.port_probe = qcom_pmic_typec_port_probe,
};
static const struct of_device_id qcom_pmic_typec_table[] = {
+ { .compatible = "qcom,pm660-typec", .data = &gen1_typec_res },
{ .compatible = "qcom,pm8150b-typec", .data = &pm8150b_typec_res },
{ .compatible = "qcom,pmi632-typec", .data = &pmi632_typec_res },
+ { .compatible = "qcom,pmi8998-typec", .data = &gen1_typec_res },
I think this should be
> + { .compatible = "qcom,pm660-typec", .data = &pm660_typec_res },
> { .compatible = "qcom,pm8150b-typec", .data = &pm8150b_typec_res },
> { .compatible = "qcom,pmi632-typec", .data = &pmi632_typec_res },
> + { .compatible = "qcom,pmi8998-typec", .data = &pmi8998_typec_res },
Since I'm not sure "gen1" is a real thing and besides, I see this gen1/gen2/gen3 stuff in CAMSS and it means almost nothing. The silicon version is the salient thing.
Best I can do is GenZ.
But now seriously, I hoped someone from Qualcomm will chime in and tells me how is this type-c block generation properly called.
David
[...]