summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/usb/usb3503.txt5
-rw-r--r--drivers/usb/misc/usb3503.c20
-rw-r--r--include/linux/platform_data/usb3503.h1
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;