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@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@5800d000 > usb_hub 0 [ + ] usb_onboard_hub | | `-- hub@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.gasn...@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.chot...@foss.st.com> Thanks Patrice