Re: [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state

From: Krishna Kurapati PSSNV
Date: Sat Oct 25 2025 - 04:16:26 EST




On 10/25/2025 12:31 PM, Biju Das wrote:


-----Original Message-----
From: Krishna Kurapati <krishna.kurapati@xxxxxxxxxxxxxxxx>
Sent: 24 October 2025 19:19
To: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>; Rob Herring <robh@xxxxxxxxxx>; Krzysztof
Kozlowski <krzk+dt@xxxxxxxxxx>; Conor Dooley <conor+dt@xxxxxxxxxx>; Heikki Krogerus
<heikki.krogerus@xxxxxxxxxxxxxxx>; Biju Das <biju.das.jz@xxxxxxxxxxxxxx>; Dmitry Baryshkov
<dmitry.baryshkov@xxxxxxxxxxxxxxxx>
Cc: linux-usb@xxxxxxxxxxxxxxx; devicetree@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Krishna
Kurapati <krishna.kurapati@xxxxxxxxxxxxxxxx>
Subject: [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state

There is a ID pin present on HD3SS3220 controller that can be routed to SoC. As per the datasheet:

"Upon detecting a UFP device, HD3SS3220 will keep ID pin high if VBUS is not at VSafe0V. Once VBUS is
at VSafe0V, the HD3SS3220 will assert ID pin low. This is done to enforce Type-C requirement that VBUS
must be at VSafe0V before re-enabling VBUS"

Add support to read the ID pin state and enable VBUS accordingly.

Signed-off-by: Krishna Kurapati <krishna.kurapati@xxxxxxxxxxxxxxxx>
---
drivers/usb/typec/hd3ss3220.c | 101 ++++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)


[...]

+static int hd3ss3220_get_vbus_supply(struct hd3ss3220 *hd3ss3220) {
+ struct device_node *hd3ss3220_node = hd3ss3220->dev->of_node;
+ const char *compat_string;
+ struct device_node *np;
+ int num_ports = 0;
+ int ret = 0;
+ int i = 0;
+
+ num_ports = of_graph_get_port_count(hd3ss3220_node);
+
+ for (i = 0; i < num_ports; i++) {
+ np = of_graph_get_remote_node(hd3ss3220_node, i, 0);
+ if (!np) {
+ dev_err(hd3ss3220->dev, "failed to get device node");
+ ret = -ENODEV;
+ goto done;
+ }
+
+ ret = of_property_read_string(np, "compatible", &compat_string);
+ if (ret) {
+ of_node_put(np);
+ dev_err(hd3ss3220->dev, "failed to get compatible string");
+ ret = -ENODEV;
+ goto done;
+ }
+
+ if (strcmp(compat_string, "usb-c-connector") == 0) {
+ hd3ss3220->vbus = of_regulator_get(hd3ss3220->dev, np, "vbus");
+ if (PTR_ERR(hd3ss3220->vbus) == -ENODEV)
+ hd3ss3220->vbus = NULL;
+
+ if (IS_ERR(hd3ss3220->vbus))
+ ret = -ENODEV;
+ }
+
+ of_node_put(np);
+ }
+
+done:
+ return ret;
+}
+
static int hd3ss3220_probe(struct i2c_client *client) {
struct typec_capability typec_cap = { }; @@ -354,6 +427,34 @@ static int hd3ss3220_probe(struct
i2c_client *client)
hd3ss3220->role_sw = usb_role_switch_get(hd3ss3220->dev);
}

+ hd3ss3220->id_gpiod = devm_gpiod_get_optional(hd3ss3220->dev, "id", GPIOD_IN);
+ if (IS_ERR(hd3ss3220->id_gpiod))
+ return PTR_ERR(hd3ss3220->id_gpiod);
+
+ if (hd3ss3220->id_gpiod) {
+ hd3ss3220->id_irq = gpiod_to_irq(hd3ss3220->id_gpiod);
+ if (hd3ss3220->id_irq < 0) {
+ dev_err(hd3ss3220->dev, "failed to get ID IRQ\n");
+ return hd3ss3220->id_irq;
+ }
+
+ ret = devm_request_threaded_irq(hd3ss3220->dev,
+ hd3ss3220->id_irq, NULL,
+ hd3ss3220_id_isr,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ dev_name(hd3ss3220->dev), hd3ss3220);
+ if (ret < 0) {
+ dev_err(hd3ss3220->dev, "failed to get id irq\n");
+ return ret;
+ }
+ }
+
+ ret = hd3ss3220_get_vbus_supply(hd3ss3220);
+ if (ret)
+ return dev_err_probe(hd3ss3220->dev,
+ PTR_ERR(hd3ss3220->vbus), "failed to get vbus\n");

Does this code backward compatible? There is no vbus definition here [1]

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts?h=next-20251024#n208


Hi Biju,

Yes. If there is no vbus supply in the usb-c-connector node, we just mark it as NULL. The ret value would be zero if there is no vbus.

Regards,
Krishna,