--- /dev/null
+// 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),
+};
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
/* 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. */