diff mbox series

[1/7] usb: onboard-hub: Add reset-gpio support

Message ID 20240605100221.3571-2-venkatesh.abbarapu@amd.com
State Changes Requested
Delegated to: Marek Vasut
Headers show
Series Add the USB5744 hub driver as per new DT binding | expand

Commit Message

Venkatesh Yadav Abbarapu June 5, 2024, 10:02 a.m. UTC
As part of the reset, sets the direction of the pin to output before
toggling the pin. Delay of millisecond is added in between low and
high to meet the setup and hold time requirement of the reset.

Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
---
 common/usb_onboard_hub.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

Comments

Marek Vasut Sept. 2, 2024, 6:40 p.m. UTC | #1
On 6/5/24 12:02 PM, Venkatesh Yadav Abbarapu wrote:
> As part of the reset, sets the direction of the pin to output before
> toggling the pin. Delay of millisecond is added in between low and
> high to meet the setup and hold time requirement of the reset.
> 
> Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com>
> ---
>   common/usb_onboard_hub.c | 44 +++++++++++++++++++++++++++++++++++++---
>   1 file changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
> index 89e18a2ddad..2f6fb71935d 100644
> --- a/common/usb_onboard_hub.c
> +++ b/common/usb_onboard_hub.c
> @@ -7,17 +7,26 @@
>    * Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver
>    */
>   
> +#include <asm/gpio.h>
>   #include <common.h>
>   #include <dm.h>
>   #include <dm/device_compat.h>
> +#include <linux/delay.h>
>   #include <power/regulator.h>
>   
>   struct onboard_hub {
>   	struct udevice *vdd;
> +	struct gpio_desc *reset_gpio;
> +};
> +
> +struct onboard_hub_data {
> +	unsigned long reset_us;
>   };
>   
>   static int usb_onboard_hub_probe(struct udevice *dev)
>   {
> +	struct onboard_hub_data *data =
> +		(struct onboard_hub_data *)dev_get_driver_data(dev);
>   	struct onboard_hub *hub = dev_get_priv(dev);
>   	int ret;
>   
> @@ -31,7 +40,24 @@ static int usb_onboard_hub_probe(struct udevice *dev)
>   	if (ret)
>   		dev_err(dev, "can't enable vdd-supply: %d\n", ret);
>   
> -	return ret;
> +	hub->reset_gpio = devm_gpiod_get_optional(dev, "reset",
> +						  GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
> +	/* property is optional, don't return error! */
> +	if (hub->reset_gpio) {
> +		ret = dm_gpio_set_value(hub->reset_gpio, 1);
> +		if (ret)
> +			return ret;
> +
> +		udelay(data->reset_us);

Where is this assigned ?

> +		ret = dm_gpio_set_value(hub->reset_gpio, 0);
> +		if (ret)
> +			return ret;
> +
> +		udelay(data->reset_us);
> +	}

Is the reset asserted time and post-reset time identical for all USB 
HUBs ? I don't think it is.

> +	return 0;
>   }
>   
>   static int usb_onboard_hub_remove(struct udevice *dev)
> @@ -39,6 +65,12 @@ static int usb_onboard_hub_remove(struct udevice *dev)
>   	struct onboard_hub *hub = dev_get_priv(dev);
>   	int ret;
>   
> +	if (hub->reset_gpio) {
> +		struct gpio_desc *hub_reset_gpio = hub->reset_gpio;
> +
> +		dm_gpio_free(hub_reset_gpio->dev, hub_reset_gpio);
> +	}
> +
>   	ret = regulator_set_enable_if_allowed(hub->vdd, false);
>   	if (ret)
>   		dev_err(dev, "can't disable vdd-supply: %d\n", ret);
> @@ -46,10 +78,16 @@ static int usb_onboard_hub_remove(struct udevice *dev)
>   	return ret;
>   }
>   
> +static const struct onboard_hub_data usb2514_data = {
> +	/* TBD */

Do not add this if not used.
diff mbox series

Patch

diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 89e18a2ddad..2f6fb71935d 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -7,17 +7,26 @@ 
  * Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver
  */
 
+#include <asm/gpio.h>
 #include <common.h>
 #include <dm.h>
 #include <dm/device_compat.h>
+#include <linux/delay.h>
 #include <power/regulator.h>
 
 struct onboard_hub {
 	struct udevice *vdd;
+	struct gpio_desc *reset_gpio;
+};
+
+struct onboard_hub_data {
+	unsigned long reset_us;
 };
 
 static int usb_onboard_hub_probe(struct udevice *dev)
 {
+	struct onboard_hub_data *data =
+		(struct onboard_hub_data *)dev_get_driver_data(dev);
 	struct onboard_hub *hub = dev_get_priv(dev);
 	int ret;
 
@@ -31,7 +40,24 @@  static int usb_onboard_hub_probe(struct udevice *dev)
 	if (ret)
 		dev_err(dev, "can't enable vdd-supply: %d\n", ret);
 
-	return ret;
+	hub->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+						  GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
+	/* property is optional, don't return error! */
+	if (hub->reset_gpio) {
+		ret = dm_gpio_set_value(hub->reset_gpio, 1);
+		if (ret)
+			return ret;
+
+		udelay(data->reset_us);
+
+		ret = dm_gpio_set_value(hub->reset_gpio, 0);
+		if (ret)
+			return ret;
+
+		udelay(data->reset_us);
+	}
+
+	return 0;
 }
 
 static int usb_onboard_hub_remove(struct udevice *dev)
@@ -39,6 +65,12 @@  static int usb_onboard_hub_remove(struct udevice *dev)
 	struct onboard_hub *hub = dev_get_priv(dev);
 	int ret;
 
+	if (hub->reset_gpio) {
+		struct gpio_desc *hub_reset_gpio = hub->reset_gpio;
+
+		dm_gpio_free(hub_reset_gpio->dev, hub_reset_gpio);
+	}
+
 	ret = regulator_set_enable_if_allowed(hub->vdd, false);
 	if (ret)
 		dev_err(dev, "can't disable vdd-supply: %d\n", ret);
@@ -46,10 +78,16 @@  static int usb_onboard_hub_remove(struct udevice *dev)
 	return ret;
 }
 
+static const struct onboard_hub_data usb2514_data = {
+	/* TBD */
+};
+
 static const struct udevice_id usb_onboard_hub_ids[] = {
 	/* Use generic usbVID,PID dt-bindings (usb-device.yaml) */
-	{ .compatible = "usb424,2514" }, /* USB2514B USB 2.0 */
-	{ }
+	{
+		.compatible = "usb424,2514", /* USB2514B USB 2.0 */
+		.data = (ulong)&usb2514_data,
+	}
 };
 
 U_BOOT_DRIVER(usb_onboard_hub) = {