[PATCH] usb: misc: add support for new OF onboard hub binding
Ahmad Fatoum
a.fatoum at pengutronix.de
Fri Feb 17 12:26:20 PST 2023
The new binding allows describing hubs that lacks a control bus (e.g.
I2C) in the DT and thus replaces the ugly hack of specifying USB hub
resets as gpio-hogs. It's already in use for boards we support, like the
STM32MP13/5 Discovery kits and will be useful for the i.MX8MP Debix
board, so port over the driver from Linux.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
drivers/usb/core/usb.c | 2 +
drivers/usb/misc/Kconfig | 10 ++++
drivers/usb/misc/Makefile | 1 +
drivers/usb/misc/onboard_usb_hub.c | 86 ++++++++++++++++++++++++++++++
drivers/usb/misc/onboard_usb_hub.h | 36 +++++++++++++
include/usb/usb.h | 8 +++
6 files changed, 143 insertions(+)
create mode 100644 drivers/usb/misc/onboard_usb_hub.c
create mode 100644 drivers/usb/misc/onboard_usb_hub.h
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7c589ec06f24..a974614c062e 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -576,6 +576,8 @@ int usb_host_detect(struct usb_host *host)
{
int ret;
+ of_usb_host_probe_hubs(host);
+
if (!host->root_dev) {
if (host->init) {
ret = host->init(host);
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 9799af47256e..fde57fd74309 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -14,3 +14,13 @@ config USB_HUB_USB251XB
Microchip USB251x/xBi USB 2.0 Hub Controller series. Configuration
parameters may be set in devicetree or platform data.
Say Y or M here if you need to configure such a device via SMBus.
+
+config USB_ONBOARD_HUB
+ bool "Onboard USB hub support"
+ depends on OFDEVICE || COMPILE_TEST
+ 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 Realtek
+ RTS5411.
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index be5c044f5a57..e00f66a5ed1c 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -4,3 +4,4 @@
# (the ones that don't fit into any other categories)
#
obj-$(CONFIG_USB_HUB_USB251XB) += usb251xb.o
+obj-$(CONFIG_USB_ONBOARD_HUB) += onboard_usb_hub.o
diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c
new file mode 100644
index 000000000000..0b847f06ad45
--- /dev/null
+++ b/drivers/usb/misc/onboard_usb_hub.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for onboard USB hubs
+ *
+ * Copyright (c) 2022, Google LLC
+ */
+
+#include <driver.h>
+#include <gpiod.h>
+#include <init.h>
+#include <of.h>
+#include <linux/printk.h>
+#include <of_device.h>
+#include <regulator.h>
+#include <usb/usb.h>
+
+#include "onboard_usb_hub.h"
+
+void of_usb_host_probe_hubs(struct usb_host *host)
+{
+ struct device_node *np;
+
+ np = dev_of_node(host->hw_dev);
+ if (!np)
+ return;
+
+ of_platform_populate(np, onboard_hub_match, host->hw_dev);
+}
+
+struct onboard_hub {
+ struct regulator *vdd;
+ struct device *dev;
+ const struct onboard_hub_pdata *pdata;
+ int reset_gpio;
+};
+
+static int onboard_hub_power_on(struct onboard_hub *hub)
+{
+ int err;
+
+ err = regulator_enable(hub->vdd);
+ if (err) {
+ dev_err(hub->dev, "failed to enable regulator: %pe\n",
+ ERR_PTR(err));
+ return err;
+ }
+
+ udelay(hub->pdata->reset_us);
+ gpiod_set_value(hub->reset_gpio, 0);
+
+ return 0;
+}
+
+static int onboard_hub_probe(struct device *dev)
+{
+ struct onboard_hub *hub;
+
+ hub = xzalloc(sizeof(*hub));
+
+ hub->pdata = device_get_match_data(dev);
+ if (!hub->pdata)
+ return -EINVAL;
+
+ hub->vdd = regulator_get(dev, "vdd");
+ if (IS_ERR(hub->vdd))
+ return PTR_ERR(hub->vdd);
+
+ hub->reset_gpio = gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (hub->reset_gpio < 0 && hub->reset_gpio != -ENOENT)
+ return dev_err_probe(dev, hub->reset_gpio, "failed to get reset GPIO\n");
+
+ hub->dev = dev;
+
+ return onboard_hub_power_on(hub);
+}
+
+static struct driver onboard_hub_driver = {
+ .name = "onboard-usb-hub",
+ .probe = onboard_hub_probe,
+ .of_compatible = onboard_hub_match,
+};
+device_platform_driver(onboard_hub_driver);
+
+MODULE_AUTHOR("Matthias Kaehlcke <mka at chromium.org>");
+MODULE_DESCRIPTION("Driver for discrete onboard USB hubs");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/misc/onboard_usb_hub.h b/drivers/usb/misc/onboard_usb_hub.h
new file mode 100644
index 000000000000..e90be47b6735
--- /dev/null
+++ b/drivers/usb/misc/onboard_usb_hub.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2022, Google LLC
+ */
+
+#ifndef _USB_MISC_ONBOARD_USB_HUB_H
+#define _USB_MISC_ONBOARD_USB_HUB_H
+
+struct onboard_hub_pdata {
+ unsigned long reset_us; /* reset pulse width in us */
+};
+
+static const struct onboard_hub_pdata microchip_usb424_data = {
+ .reset_us = 1,
+};
+
+static const struct onboard_hub_pdata realtek_rts5411_data = {
+ .reset_us = 0,
+};
+
+static const struct onboard_hub_pdata ti_tusb8041_data = {
+ .reset_us = 3000,
+};
+
+const struct of_device_id onboard_hub_match[] = {
+ { .compatible = "usb424,2514", .data = µchip_usb424_data, },
+ { .compatible = "usb451,8140", .data = &ti_tusb8041_data, },
+ { .compatible = "usb451,8142", .data = &ti_tusb8041_data, },
+ { .compatible = "usbbda,411", .data = &realtek_rts5411_data, },
+ { .compatible = "usbbda,5411", .data = &realtek_rts5411_data, },
+ { .compatible = "usbbda,414", .data = &realtek_rts5411_data, },
+ { .compatible = "usbbda,5414", .data = &realtek_rts5411_data, },
+ {}
+};
+
+#endif /* _USB_MISC_ONBOARD_USB_HUB_H */
diff --git a/include/usb/usb.h b/include/usb/usb.h
index 9b36122436d5..717bcf935a42 100644
--- a/include/usb/usb.h
+++ b/include/usb/usb.h
@@ -484,4 +484,12 @@ extern struct list_head usb_device_list;
bool usb_hub_is_root_hub(struct usb_device *hdev);
+#ifdef CONFIG_USB_ONBOARD_HUB
+void of_usb_host_probe_hubs(struct usb_host *host);
+#else
+static inline void of_usb_host_probe_hubs(struct usb_host *host)
+{
+}
+#endif
+
#endif /*_USB_H_ */
--
2.30.2
More information about the barebox
mailing list