mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Implement vbus support for HD3SS3220 port controller
@ 2025-10-24 18:18 Krishna Kurapati
  2025-10-24 18:18 ` [PATCH v3 1/2] dt-bindings: usb: ti,hd3ss3220: Add support for VBUS based on ID state Krishna Kurapati
  2025-10-24 18:18 ` [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state Krishna Kurapati
  0 siblings, 2 replies; 6+ messages in thread
From: Krishna Kurapati @ 2025-10-24 18:18 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Heikki Krogerus, Biju Das, Dmitry Baryshkov
  Cc: linux-usb, devicetree, linux-kernel, Krishna Kurapati

As per the data sheet of HD3SS3220:

"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"

This series implements support to read ID pin state and accordingly enable
VBUS.

Changes in v3:
Removed vbus supply from hd3ss3220 bindings.
Implemented getting vbus from connector node.

Link to v2:
https://lore.kernel.org/all/20251008175750.1770454-1-krishna.kurapati@oss.qualcomm.com/

Changes in v2:
Fixed inclusion of header files appropriately.
Modified commit text for driver patch.

Link to v1:
https://lore.kernel.org/all/20251002172539.586538-1-krishna.kurapati@oss.qualcomm.com/

Krishna Kurapati (2):
  dt-bindings: usb: ti,hd3ss3220: Add support for VBUS based on ID state
  usb: typec: hd3ss3220: Enable VBUS based on ID pin state

 .../devicetree/bindings/usb/ti,hd3ss3220.yaml |   8 ++
 drivers/usb/typec/hd3ss3220.c                 | 101 ++++++++++++++++++
 2 files changed, 109 insertions(+)

-- 
2.34.1


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

* [PATCH v3 1/2] dt-bindings: usb: ti,hd3ss3220: Add support for VBUS based on ID state
  2025-10-24 18:18 [PATCH v3 0/2] Implement vbus support for HD3SS3220 port controller Krishna Kurapati
@ 2025-10-24 18:18 ` Krishna Kurapati
  2025-10-24 18:18 ` [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state Krishna Kurapati
  1 sibling, 0 replies; 6+ messages in thread
From: Krishna Kurapati @ 2025-10-24 18:18 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Heikki Krogerus, Biju Das, Dmitry Baryshkov
  Cc: linux-usb, devicetree, linux-kernel, Krishna Kurapati

Update the bindings to support reading ID state and VBUS, as per the
HD3SS3220 data sheet. The ID pin is kept high if VBUS is not at VSafe0V and
asserted low once VBUS is at VSafe0V, enforcing the Type-C requirement that
VBUS must be at VSafe0V before re-enabling VBUS.

Add id-gpios property to describe the input gpio for USB ID pin.

Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
---
 Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml b/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml
index bec1c8047bc0..06099e93c6c3 100644
--- a/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml
+++ b/Documentation/devicetree/bindings/usb/ti,hd3ss3220.yaml
@@ -25,6 +25,14 @@ properties:
   interrupts:
     maxItems: 1
 
+  id-gpios:
+    description:
+      An input gpio for USB ID pin. 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.
+    maxItems: 1
+
   ports:
     $ref: /schemas/graph.yaml#/properties/ports
     description: OF graph bindings (specified in bindings/graph.txt) that model
-- 
2.34.1


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

* [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state
  2025-10-24 18:18 [PATCH v3 0/2] Implement vbus support for HD3SS3220 port controller Krishna Kurapati
  2025-10-24 18:18 ` [PATCH v3 1/2] dt-bindings: usb: ti,hd3ss3220: Add support for VBUS based on ID state Krishna Kurapati
@ 2025-10-24 18:18 ` Krishna Kurapati
  2025-10-24 23:37   ` Dmitry Baryshkov
  2025-10-25  7:01   ` Biju Das
  1 sibling, 2 replies; 6+ messages in thread
From: Krishna Kurapati @ 2025-10-24 18:18 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Heikki Krogerus, Biju Das, Dmitry Baryshkov
  Cc: linux-usb, devicetree, linux-kernel, Krishna Kurapati

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@oss.qualcomm.com>
---
 drivers/usb/typec/hd3ss3220.c | 101 ++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c
index 3ecc688dda82..089c4168c7b5 100644
--- a/drivers/usb/typec/hd3ss3220.c
+++ b/drivers/usb/typec/hd3ss3220.c
@@ -15,6 +15,9 @@
 #include <linux/usb/typec.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_graph.h>
 
 #define HD3SS3220_REG_CN_STAT		0x08
 #define HD3SS3220_REG_CN_STAT_CTRL	0x09
@@ -54,6 +57,11 @@ struct hd3ss3220 {
 	struct delayed_work output_poll_work;
 	enum usb_role role_state;
 	bool poll;
+
+	struct gpio_desc *id_gpiod;
+	int id_irq;
+
+	struct regulator *vbus;
 };
 
 static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220, int power_opmode)
@@ -319,6 +327,71 @@ static const struct regmap_config config = {
 	.max_register = 0x0A,
 };
 
+static irqreturn_t hd3ss3220_id_isr(int irq, void *dev_id)
+{
+	struct hd3ss3220 *hd3ss3220 = dev_id;
+	int ret;
+	int id;
+
+	if (IS_ERR_OR_NULL(hd3ss3220->vbus))
+		return IRQ_HANDLED;
+
+	id = hd3ss3220->id_gpiod ? gpiod_get_value_cansleep(hd3ss3220->id_gpiod) : 1;
+
+	if (!id) {
+		ret = regulator_enable(hd3ss3220->vbus);
+		if (ret)
+			dev_err(hd3ss3220->dev, "enable vbus regulator failed\n");
+	} else {
+		regulator_disable(hd3ss3220->vbus);
+	}
+
+	return IRQ_HANDLED;
+}
+
+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");
+
 	if (IS_ERR(hd3ss3220->role_sw)) {
 		ret = PTR_ERR(hd3ss3220->role_sw);
 		goto err_put_fwnode;
-- 
2.34.1


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

* Re: [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state
  2025-10-24 18:18 ` [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state Krishna Kurapati
@ 2025-10-24 23:37   ` Dmitry Baryshkov
  2025-10-25  7:01   ` Biju Das
  1 sibling, 0 replies; 6+ messages in thread
From: Dmitry Baryshkov @ 2025-10-24 23:37 UTC (permalink / raw)
  To: Krishna Kurapati, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heikki Krogerus, Biju Das
  Cc: linux-usb, devicetree, linux-kernel

On 24/10/2025 21:18, Krishna Kurapati wrote:
> 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@oss.qualcomm.com>
> ---
>   drivers/usb/typec/hd3ss3220.c | 101 ++++++++++++++++++++++++++++++++++
>   1 file changed, 101 insertions(+)
> 
> diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c
> index 3ecc688dda82..089c4168c7b5 100644
> --- a/drivers/usb/typec/hd3ss3220.c
> +++ b/drivers/usb/typec/hd3ss3220.c
> @@ -15,6 +15,9 @@
>   #include <linux/usb/typec.h>
>   #include <linux/delay.h>
>   #include <linux/workqueue.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/of_graph.h>
>   
>   #define HD3SS3220_REG_CN_STAT		0x08
>   #define HD3SS3220_REG_CN_STAT_CTRL	0x09
> @@ -54,6 +57,11 @@ struct hd3ss3220 {
>   	struct delayed_work output_poll_work;
>   	enum usb_role role_state;
>   	bool poll;
> +
> +	struct gpio_desc *id_gpiod;
> +	int id_irq;
> +
> +	struct regulator *vbus;
>   };
>   
>   static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220, int power_opmode)
> @@ -319,6 +327,71 @@ static const struct regmap_config config = {
>   	.max_register = 0x0A,
>   };
>   
> +static irqreturn_t hd3ss3220_id_isr(int irq, void *dev_id)
> +{
> +	struct hd3ss3220 *hd3ss3220 = dev_id;
> +	int ret;
> +	int id;
> +
> +	if (IS_ERR_OR_NULL(hd3ss3220->vbus))
> +		return IRQ_HANDLED;
> +
> +	id = hd3ss3220->id_gpiod ? gpiod_get_value_cansleep(hd3ss3220->id_gpiod) : 1;
> +
> +	if (!id) {
> +		ret = regulator_enable(hd3ss3220->vbus);
> +		if (ret)
> +			dev_err(hd3ss3220->dev, "enable vbus regulator failed\n");
> +	} else {
> +		regulator_disable(hd3ss3220->vbus);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +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;
> +		}

This whole loop is an overkill. You know that only port@0 can be 
connected to the usb-c-connector. There is no need to check other ports. 
there is no need to check for the compatible, etc.

> +
> +		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");
> +
>   	if (IS_ERR(hd3ss3220->role_sw)) {
>   		ret = PTR_ERR(hd3ss3220->role_sw);
>   		goto err_put_fwnode;


-- 
With best wishes
Dmitry

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

* RE: [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state
  2025-10-24 18:18 ` [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state Krishna Kurapati
  2025-10-24 23:37   ` Dmitry Baryshkov
@ 2025-10-25  7:01   ` Biju Das
  2025-10-25  8:16     ` Krishna Kurapati PSSNV
  1 sibling, 1 reply; 6+ messages in thread
From: Biju Das @ 2025-10-25  7:01 UTC (permalink / raw)
  To: Krishna Kurapati, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heikki Krogerus,
	Dmitry Baryshkov
  Cc: linux-usb, devicetree, linux-kernel



> -----Original Message-----
> From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
> Sent: 24 October 2025 19:19
> To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Rob Herring <robh@kernel.org>; Krzysztof
> Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Heikki Krogerus
> <heikki.krogerus@linux.intel.com>; Biju Das <biju.das.jz@bp.renesas.com>; Dmitry Baryshkov
> <dmitry.baryshkov@oss.qualcomm.com>
> Cc: linux-usb@vger.kernel.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; Krishna
> Kurapati <krishna.kurapati@oss.qualcomm.com>
> 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@oss.qualcomm.com>
> ---
>  drivers/usb/typec/hd3ss3220.c | 101 ++++++++++++++++++++++++++++++++++
>  1 file changed, 101 insertions(+)
> 
> diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c index
> 3ecc688dda82..089c4168c7b5 100644
> --- a/drivers/usb/typec/hd3ss3220.c
> +++ b/drivers/usb/typec/hd3ss3220.c
> @@ -15,6 +15,9 @@
>  #include <linux/usb/typec.h>
>  #include <linux/delay.h>
>  #include <linux/workqueue.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/of_graph.h>
> 
>  #define HD3SS3220_REG_CN_STAT		0x08
>  #define HD3SS3220_REG_CN_STAT_CTRL	0x09
> @@ -54,6 +57,11 @@ struct hd3ss3220 {
>  	struct delayed_work output_poll_work;
>  	enum usb_role role_state;
>  	bool poll;
> +
> +	struct gpio_desc *id_gpiod;
> +	int id_irq;
> +
> +	struct regulator *vbus;
>  };
> 
>  static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220, int power_opmode) @@ -319,6
> +327,71 @@ static const struct regmap_config config = {
>  	.max_register = 0x0A,
>  };
> 
> +static irqreturn_t hd3ss3220_id_isr(int irq, void *dev_id) {
> +	struct hd3ss3220 *hd3ss3220 = dev_id;
> +	int ret;
> +	int id;
> +
> +	if (IS_ERR_OR_NULL(hd3ss3220->vbus))
> +		return IRQ_HANDLED;
> +
> +	id = hd3ss3220->id_gpiod ?
> +gpiod_get_value_cansleep(hd3ss3220->id_gpiod) : 1;
> +
> +	if (!id) {
> +		ret = regulator_enable(hd3ss3220->vbus);
> +		if (ret)
> +			dev_err(hd3ss3220->dev, "enable vbus regulator failed\n");
> +	} else {
> +		regulator_disable(hd3ss3220->vbus);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +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

Cheers,
Biju

> +
>  	if (IS_ERR(hd3ss3220->role_sw)) {
>  		ret = PTR_ERR(hd3ss3220->role_sw);
>  		goto err_put_fwnode;
> --
> 2.34.1


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

* Re: [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state
  2025-10-25  7:01   ` Biju Das
@ 2025-10-25  8:16     ` Krishna Kurapati PSSNV
  0 siblings, 0 replies; 6+ messages in thread
From: Krishna Kurapati PSSNV @ 2025-10-25  8:16 UTC (permalink / raw)
  To: Biju Das
  Cc: linux-usb, devicetree, linux-kernel, Greg Kroah-Hartman,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heikki Krogerus,
	Dmitry Baryshkov



On 10/25/2025 12:31 PM, Biju Das wrote:
> 
> 
>> -----Original Message-----
>> From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
>> Sent: 24 October 2025 19:19
>> To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Rob Herring <robh@kernel.org>; Krzysztof
>> Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Heikki Krogerus
>> <heikki.krogerus@linux.intel.com>; Biju Das <biju.das.jz@bp.renesas.com>; Dmitry Baryshkov
>> <dmitry.baryshkov@oss.qualcomm.com>
>> Cc: linux-usb@vger.kernel.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; Krishna
>> Kurapati <krishna.kurapati@oss.qualcomm.com>
>> 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@oss.qualcomm.com>
>> ---
>>   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,

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

end of thread, other threads:[~2025-10-25  8:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-10-24 18:18 [PATCH v3 0/2] Implement vbus support for HD3SS3220 port controller Krishna Kurapati
2025-10-24 18:18 ` [PATCH v3 1/2] dt-bindings: usb: ti,hd3ss3220: Add support for VBUS based on ID state Krishna Kurapati
2025-10-24 18:18 ` [PATCH v3 2/2] usb: typec: hd3ss3220: Enable VBUS based on ID pin state Krishna Kurapati
2025-10-24 23:37   ` Dmitry Baryshkov
2025-10-25  7:01   ` Biju Das
2025-10-25  8:16     ` Krishna Kurapati PSSNV

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®