summaryrefslogtreecommitdiff
path: root/drivers
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 /drivers
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)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/misc/usb3503.c20
1 files changed, 20 insertions, 0 deletions
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);