summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-08-09 11:41:51 +0100
committerMarek Szyprowski <m.szyprowski@samsung.com>2014-03-04 08:38:56 +0100
commit69d693b2152e83a3ef3d94e4554e2bad1203d5b0 (patch)
tree492f02e6269dfa9ae32996973993ebd72a043967
parent16231740a1003ef03fa6ec5ad7c7f9ebfbc2ecda (diff)
downloadlinux-3.10-69d693b2152e83a3ef3d94e4554e2bad1203d5b0.tar.gz
linux-3.10-69d693b2152e83a3ef3d94e4554e2bad1203d5b0.tar.bz2
linux-3.10-69d693b2152e83a3ef3d94e4554e2bad1203d5b0.zip
usb: misc: usb3503: Actively manage Hub Connect GPIO
If the connect signal is pulled high then the device will start up meaning that if we just pull it high on probe then the device will start running prior to the configuration being written out. Fix this by pulling the GPIO low when we reset and only pulling it high when configuration is finished. Signed-off-by: Mark Brown <broonie@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> [mszyprow: mainline commit 8e7245b8386cb1dc941e10a4c97307e3f48da5da] Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Change-Id: I8e7245b8386cb1dc941e10a4c97307e3f48da5da
-rw-r--r--drivers/usb/misc/usb3503.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
index 2e9e100a182..4b6572a37e8 100644
--- a/drivers/usb/misc/usb3503.c
+++ b/drivers/usb/misc/usb3503.c
@@ -100,10 +100,13 @@ static int usb3503_clear_bits(struct i2c_client *client, char reg, char req)
return 0;
}
-static int usb3503_reset(int gpio_reset, int state)
+static int usb3503_reset(struct usb3503 *hub, int state)
{
- if (gpio_is_valid(gpio_reset))
- gpio_set_value_cansleep(gpio_reset, state);
+ if (!state && gpio_is_valid(hub->gpio_connect))
+ gpio_set_value_cansleep(hub->gpio_connect, 0);
+
+ if (gpio_is_valid(hub->gpio_reset))
+ gpio_set_value_cansleep(hub->gpio_reset, state);
/* Wait T_HUBINIT == 4ms for hub logic to stabilize */
if (state)
@@ -119,7 +122,7 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
switch (mode) {
case USB3503_MODE_HUB:
- usb3503_reset(hub->gpio_reset, 1);
+ usb3503_reset(hub, 1);
/* SP_ILOCK: set connect_n, config_n for config */
err = usb3503_write_register(i2c, USB3503_SP_ILOCK,
@@ -156,12 +159,15 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
goto err_hubmode;
}
+ if (gpio_is_valid(hub->gpio_connect))
+ gpio_set_value_cansleep(hub->gpio_connect, 1);
+
hub->mode = mode;
dev_info(&i2c->dev, "switched to HUB mode\n");
break;
case USB3503_MODE_STANDBY:
- usb3503_reset(hub->gpio_reset, 0);
+ usb3503_reset(hub, 0);
hub->mode = mode;
dev_info(&i2c->dev, "switched to STANDBY mode\n");
@@ -241,7 +247,7 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
if (gpio_is_valid(hub->gpio_connect)) {
err = devm_gpio_request_one(&i2c->dev, hub->gpio_connect,
- GPIOF_OUT_INIT_HIGH, "usb3503 connect");
+ GPIOF_OUT_INIT_LOW, "usb3503 connect");
if (err) {
dev_err(&i2c->dev,
"unable to request GPIO %d as connect pin (%d)\n",