diff options
author | Vic Yang <victoryang@chromium.org> | 2013-02-22 20:48:09 +0800 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-02-22 21:56:27 -0800 |
commit | 17e84f1589f7f4fabff1b1a10a7f1b7e4faf9754 (patch) | |
tree | 0299980a29ec8c1e8f99db007e6dbb60675c54aa | |
parent | 6492c99cca13e1a1fe00d83d0947b6fd1fcd310d (diff) | |
download | chrome-ec-17e84f1589f7f4fabff1b1a10a7f1b7e4faf9754.tar.gz |
spring: Avoid picking up USB power from AP
When powered device is removed, VBUS is still powered by the AP. We
should turn off power from AP and let it settle before we sense external
VBUS input.
BUG=chrome-os-partner:14319
TEST=Manual on Spring
BRANCH=none
Change-Id: Ie868a3df27e395c948ba8c6342e84764d182ce82
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/43779
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | board/spring/usb_charging.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/board/spring/usb_charging.c b/board/spring/usb_charging.c index 5308553160..7efc698062 100644 --- a/board/spring/usb_charging.c +++ b/board/spring/usb_charging.c @@ -229,15 +229,28 @@ void usb_charge_interrupt(enum gpio_signal signal) static void usb_device_change(int dev_type) { + int need_boost; + int retry_limit = 3; + if (current_dev_type == dev_type) return; - current_dev_type = dev_type; - /* Supply VBUS if needed */ - if (dev_type & POWERED_DEVICE_TYPE) - gpio_set_level(GPIO_BOOST_EN, 0); - else - gpio_set_level(GPIO_BOOST_EN, 1); + /* + * Supply VBUS if needed. If we toggle power output, wait for a moment, + * and then update device type. To avoid race condition, check if power + * requirement changes during this time. + */ + do { + if (retry_limit-- <= 0) + break; + + need_boost = !(dev_type & POWERED_DEVICE_TYPE); + if (need_boost != gpio_get_level(GPIO_BOOST_EN)) { + gpio_set_level(GPIO_BOOST_EN, need_boost); + msleep(20); + dev_type = tsu6721_get_device_type(); + } + } while (need_boost == !!(dev_type & POWERED_DEVICE_TYPE)); if ((dev_type & TSU6721_TYPE_VBUS_DEBOUNCED) && !(dev_type & POWERED_DEVICE_TYPE)) { @@ -286,6 +299,8 @@ static void usb_device_change(int dev_type) CPRINTF("Unknown with power]\n"); else CPRINTF("Unknown]\n"); + + current_dev_type = dev_type; } void board_usb_charge_update(int force_update) |