summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Krummenacher <max.krummenacher@toradex.com>2018-09-12 11:28:36 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2020-02-09 22:49:20 +0100
commit60d0a3d181056f5587277458a655a47a495dae1b (patch)
treebfa862b1a88a57fe8a3a2d337270ccc5101f13a4
parent0e53439459b3ec8863b71bc58e0111b20f782835 (diff)
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 <max.krummenacher@toradex.com> (cherry picked from commit e7812f55781bd9453a231d104a2c6c520491e2e4) (cherry picked from commit 8662817b83bee3c30336f104608752fcb652f5c4)
-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 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 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;