[PATCH 1/3] usb: onboard-hub: add driver to manage onboard hub supplies
Patrice CHOTARD
patrice.chotard at foss.st.com
Tue Jan 3 17:33:59 CET 2023
Hi Fabrice
On 12/12/22 11:44, Fabrice Gasnier wrote:
> The main issue the driver addresses is that a USB hub needs to be
> powered before it can be discovered. This is often solved by using
> "regulator-always-on".
>
> This driver is inspired by the Linux v6.1 driver. It only enables (or
> disables) the hub vdd (3v3) supply, so it can be enumerated.
> Scanning of the device tree is done in a similar manner to the sandbox,
> by the usb-uclass. DT part looks like:
>
> &usbh_ehci {
> ...
> #address-cells = <1>;
> #size-cells = <0>;
> hub at 1 {
> compatible = "usb424,2514";
> reg = <1>;
> vdd-supply = <&v3v3>;
> };
> };
>
> When the bus gets probed, the driver is automatically probed/removed from
> the bus tree, as an example on stm32:
> STM32MP> usb start
> starting USB...
> STM32MP> dm tree
> Class Index Probed Driver Name
> -----------------------------------------------------------
> usb 0 [ + ] ehci_generic | |-- usb at 5800d000
> usb_hub 0 [ + ] usb_onboard_hub | | `-- hub at 1
> usb_hub 1 [ + ] usb_hub | | `-- usb_hub
>
> STM32MP> usb tree
> USB device tree:
> 1 Hub (480 Mb/s, 0mA)
> | u-boot EHCI Host Controller
> |
> +-2 Hub (480 Mb/s, 2mA)
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> ---
>
> common/Makefile | 1 +
> common/usb_onboard_hub.c | 62 +++++++++++++++++++++++++++++++++++
> drivers/usb/Kconfig | 10 ++++++
> drivers/usb/host/usb-uclass.c | 16 +++++----
> 4 files changed, 83 insertions(+), 6 deletions(-)
> create mode 100644 common/usb_onboard_hub.c
>
> diff --git a/common/Makefile b/common/Makefile
> index 20addfb244c2..7789aab484fd 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_PHYLIB) += miiphyutil.o
> obj-$(CONFIG_USB_HOST) += usb.o usb_hub.o
> obj-$(CONFIG_USB_GADGET) += usb.o usb_hub.o
> obj-$(CONFIG_USB_STORAGE) += usb_storage.o
> +obj-$(CONFIG_USB_ONBOARD_HUB) += usb_onboard_hub.o
>
> # others
> obj-$(CONFIG_CONSOLE_MUX) += iomux.o
> diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
> new file mode 100644
> index 000000000000..89e18a2ddad6
> --- /dev/null
> +++ b/common/usb_onboard_hub.c
> @@ -0,0 +1,62 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Driver for onboard USB hubs
> + *
> + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
> + *
> + * Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/device_compat.h>
> +#include <power/regulator.h>
> +
> +struct onboard_hub {
> + struct udevice *vdd;
> +};
> +
> +static int usb_onboard_hub_probe(struct udevice *dev)
> +{
> + struct onboard_hub *hub = dev_get_priv(dev);
> + int ret;
> +
> + ret = device_get_supply_regulator(dev, "vdd-supply", &hub->vdd);
> + if (ret) {
> + dev_err(dev, "can't get vdd-supply: %d\n", ret);
> + return ret;
> + }
> +
> + ret = regulator_set_enable_if_allowed(hub->vdd, true);
> + if (ret)
> + dev_err(dev, "can't enable vdd-supply: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static int usb_onboard_hub_remove(struct udevice *dev)
> +{
> + struct onboard_hub *hub = dev_get_priv(dev);
> + int ret;
> +
> + ret = regulator_set_enable_if_allowed(hub->vdd, false);
> + if (ret)
> + dev_err(dev, "can't disable vdd-supply: %d\n", ret);
> +
> + return ret;
> +}
> +
> +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 */
> + { }
> +};
> +
> +U_BOOT_DRIVER(usb_onboard_hub) = {
> + .name = "usb_onboard_hub",
> + .id = UCLASS_USB_HUB,
> + .probe = usb_onboard_hub_probe,
> + .remove = usb_onboard_hub_remove,
> + .of_match = usb_onboard_hub_ids,
> + .priv_auto = sizeof(struct onboard_hub),
> +};
> diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
> index 3afb45d5ccb2..d10ee6853d40 100644
> --- a/drivers/usb/Kconfig
> +++ b/drivers/usb/Kconfig
> @@ -106,6 +106,16 @@ config USB_KEYBOARD
> Say Y here if you want to use a USB keyboard for U-Boot command line
> input.
>
> +config USB_ONBOARD_HUB
> + bool "Onboard USB hub support"
> + depends on DM_USB
> + ---help---
> + Say Y here if you want to support discrete onboard USB hubs that
> + don't require an additional control bus for initialization, but
> + need some non-trivial form of initialization, such as enabling a
> + power regulator. An example for such a hub is the Microchip
> + USB2514B.
> +
> if USB_KEYBOARD
>
> config USB_KEYBOARD_FN_KEYS
> diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
> index 060f3441df0c..f5dc93ffee39 100644
> --- a/drivers/usb/host/usb-uclass.c
> +++ b/drivers/usb/host/usb-uclass.c
> @@ -271,19 +271,23 @@ int usb_init(void)
> /* init low_level USB */
> printf("Bus %s: ", bus->name);
>
> -#ifdef CONFIG_SANDBOX
> /*
> * For Sandbox, we need scan the device tree each time when we
> * start the USB stack, in order to re-create the emulated USB
> * devices and bind drivers for them before we actually do the
> * driver probe.
> + *
> + * For USB onboard HUB, we need to do some non-trivial init
> + * like enabling a power regulator, before enumeration.
> */
> - ret = dm_scan_fdt_dev(bus);
> - if (ret) {
> - printf("Sandbox USB device scan failed (%d)\n", ret);
> - continue;
> + if (IS_ENABLED(CONFIG_SANDBOX) ||
> + IS_ENABLED(CONFIG_USB_ONBOARD_HUB)) {
> + ret = dm_scan_fdt_dev(bus);
> + if (ret) {
> + printf("USB device scan from fdt failed (%d)", ret);
> + continue;
> + }
> }
> -#endif
>
> ret = device_probe(bus);
> if (ret == -ENODEV) { /* No such device. */
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>
Thanks
Patrice
More information about the U-Boot
mailing list