From e7812f55781bd9453a231d104a2c6c520491e2e4 Mon Sep 17 00:00:00 2001 From: Max Krummenacher Date: Wed, 12 Sep 2018 11:28:36 +0200 Subject: usb: misc: usb3503: add the usb3803 variant While the usb3503 variant uses a HSIC connection to upstream, the usb3803 uses a regular USB connection and provides a bypass mode which connects the upstream port with downstream port 3. This adds an additional control gpio to the configuration which allows moving away from the bypass mode to either standby or hub mode once the driver is instantiated. Signed-off-by: Max Krummenacher --- Documentation/devicetree/bindings/usb/usb3503.txt | 5 ++++- drivers/usb/misc/usb3503.c | 20 ++++++++++++++++++++ include/linux/platform_data/usb3503.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt index c1a0a9191d26..f66f79e6fe0e 100644 --- a/Documentation/devicetree/bindings/usb/usb3503.txt +++ b/Documentation/devicetree/bindings/usb/usb3503.txt @@ -1,11 +1,14 @@ SMSC USB3503 High-Speed Hub Controller Required properties: -- compatible: Should be "smsc,usb3503" or "smsc,usb3503a". +- compatible: Should be "smsc,usb3503" or "smsc,usb3503a" or "smsc,usb3803". Optional properties: - reg: Specifies the i2c slave address, it is required and should be 0x08 if I2C is used. +- bypass-gpios: Should specify GPIO for bypass. + Follows the state of reset-gpios and is meant to be used with + usb3803's bypass pin. - connect-gpios: Should specify GPIO for connect. - disabled-ports: Should specify the ports unused. '1' or '2' or '3' are available for this property to describe the port diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index 03be5d574f23..9ca9e8e769fb 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -60,6 +60,7 @@ struct usb3503 { struct device *dev; struct clk *clk; u8 port_off_mask; + int gpio_bypass; int gpio_intn; int gpio_reset; int gpio_connect; @@ -74,6 +75,9 @@ static int usb3503_reset(struct usb3503 *hub, int state) if (gpio_is_valid(hub->gpio_reset)) gpio_set_value_cansleep(hub->gpio_reset, state); + if (gpio_is_valid(hub->gpio_bypass)) + gpio_set_value_cansleep(hub->gpio_bypass, state); + /* Wait T_HUBINIT == 4ms for hub logic to stabilize */ if (state) usleep_range(4000, 10000); @@ -180,6 +184,7 @@ static int usb3503_probe(struct usb3503 *hub) if (pdata) { hub->port_off_mask = pdata->port_off_mask; + hub->gpio_bypass = pdata->gpio_bypass; hub->gpio_intn = pdata->gpio_intn; hub->gpio_connect = pdata->gpio_connect; hub->gpio_reset = pdata->gpio_reset; @@ -255,6 +260,9 @@ static int usb3503_probe(struct usb3503 *hub) hub->gpio_connect = of_get_named_gpio(np, "connect-gpios", 0); if (hub->gpio_connect == -EPROBE_DEFER) return -EPROBE_DEFER; + hub->gpio_bypass = of_get_named_gpio(np, "bypass-gpios", 0); + if (hub->gpio_bypass == -EPROBE_DEFER) + return -EPROBE_DEFER; hub->gpio_reset = of_get_named_gpio(np, "reset-gpios", 0); if (hub->gpio_reset == -EPROBE_DEFER) return -EPROBE_DEFER; @@ -289,6 +297,17 @@ static int usb3503_probe(struct usb3503 *hub) } } + if (gpio_is_valid(hub->gpio_bypass)) { + err = devm_gpio_request_one(dev, hub->gpio_bypass, + GPIOF_OUT_INIT_LOW, "usb3503 bypass"); + if (err) { + dev_err(dev, + "unable to request GPIO %d as bypass pin (%d)\n", + hub->gpio_bypass, err); + return err; + } + } + if (gpio_is_valid(hub->gpio_reset)) { err = devm_gpio_request_one(dev, hub->gpio_reset, GPIOF_OUT_INIT_LOW, "usb3503 reset"); @@ -408,6 +427,7 @@ MODULE_DEVICE_TABLE(i2c, usb3503_id); static const struct of_device_id usb3503_of_match[] = { { .compatible = "smsc,usb3503", }, { .compatible = "smsc,usb3503a", }, + { .compatible = "smsc,usb3803", }, {}, }; MODULE_DEVICE_TABLE(of, usb3503_of_match); diff --git a/include/linux/platform_data/usb3503.h b/include/linux/platform_data/usb3503.h index 1d1b6ef871f6..043849228f69 100644 --- a/include/linux/platform_data/usb3503.h +++ b/include/linux/platform_data/usb3503.h @@ -16,6 +16,7 @@ enum usb3503_mode { struct usb3503_platform_data { enum usb3503_mode initial_mode; u8 port_off_mask; + int gpio_bypass; int gpio_intn; int gpio_connect; int gpio_reset; -- cgit v1.2.3