From: Venkatesh Yadav Abbarapu Date: Mon, 25 Nov 2024 04:11:58 +0000 (+0530) Subject: usb: onboard-hub: Add reset-gpio support X-Git-Url: http://git.dujemihanovic.xyz/img/static/%7B%7B%20%24.Site.BaseURL%20%7D%7Dposts/%7B%7B%20%24style.RelPermalink%20%7D%7D?a=commitdiff_plain;h=0e670e2917d76005d03be7e2dc3db1b7cba2d0d8;p=u-boot.git usb: onboard-hub: Add reset-gpio support 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. Update the usb2514 hub_data with the reset delay and power on delay values. Signed-off-by: Venkatesh Yadav Abbarapu Reviewed-by: Marek Vasut --- diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c index 68a04ac041..e4d1f12cb4 100644 --- a/common/usb_onboard_hub.c +++ b/common/usb_onboard_hub.c @@ -7,14 +7,50 @@ * Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver */ +#include #include #include +#include #include struct onboard_hub { struct udevice *vdd; + struct gpio_desc *reset_gpio; }; +struct onboard_hub_data { + unsigned long reset_us; + unsigned long power_on_delay_us; +}; + +int usb_onboard_hub_reset(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; + + hub->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_IS_OUT); + + /* property is optional, don't return error! */ + if (!hub->reset_gpio) + return 0; + + 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->power_on_delay_us); + + return 0; +} + static int usb_onboard_hub_probe(struct udevice *dev) { struct onboard_hub *hub = dev_get_priv(dev); @@ -30,7 +66,7 @@ static int usb_onboard_hub_probe(struct udevice *dev) if (ret) dev_err(dev, "can't enable vdd-supply: %d\n", ret); - return ret; + return usb_onboard_hub_reset(dev); } static int usb_onboard_hub_remove(struct udevice *dev) @@ -38,6 +74,9 @@ static int usb_onboard_hub_remove(struct udevice *dev) struct onboard_hub *hub = dev_get_priv(dev); int ret; + if (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); @@ -45,10 +84,16 @@ static int usb_onboard_hub_remove(struct udevice *dev) return ret; } +static const struct onboard_hub_data usb2514_data = { + .power_on_delay_us = 500, + .reset_us = 1, +}; + 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) = {