diff options
-rw-r--r-- | Documentation/devicetree/bindings/usb/usb3503.txt | 5 | ||||
-rw-r--r-- | drivers/usb/misc/usb3503.c | 20 | ||||
-rw-r--r-- | include/linux/platform_data/usb3503.h | 1 |
3 files changed, 25 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt index 057dd384d473..5157c16d55d1 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 72f39a9751b5..9f655535b0c2 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -47,6 +47,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; @@ -61,6 +62,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); @@ -167,6 +171,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; @@ -236,6 +241,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; @@ -270,6 +278,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"); @@ -404,6 +423,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 e049d51c1353..df1d0f48ca75 100644 --- a/include/linux/platform_data/usb3503.h +++ b/include/linux/platform_data/usb3503.h @@ -17,6 +17,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; |