From 2a783457a94943b73e4604006b2033d64de80035 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Wed, 19 Apr 2017 13:08:36 +0800 Subject: [PATCH] poppy: Enable vbus discharge using PD discharge registers poppy uses an ISL charger, which, unlike bd9995* charger based systems, cannot provide an interrupt when VBUS falls below/rises above a certain threshold. On poppy rev2 onwards, we have a precise VBUS detection pin coming from BC1.2 detection chip (PI3USB9281C), we a threshold between 3.1-3.7 V (3.5V typical) so we can use that to enable discharge, according to this logic: - When VBUS voltage falls below ~3.5V, and we're not sourcing 5V to the port, enable discharge. - When VBUS voltage rises above ~3.5V, disable discharge. - When we source 5V to the port, disable discharge. BRANCH=none BUG=b:37525769 TEST=Charge out to device (Galaxy S8), and verify that VBUS drops to 0.8V much faster than without this patch. TEST=pd 0 swap power: 28ms (vs 496ms) TEST=pd 1 swap power: 24ms to 0.875v, 202ms to 0.8v (vs 410ms) TEST=Disconnect cable (port 0): 65ms (vs 721ms) TEST=Disconnect cable (port 1): 13ms (vs 515ms) Change-Id: Ibf2dcf5de31514fa0ce0ebd0c6db53d421a586fe Reviewed-on: https://chromium-review.googlesource.com/481562 Commit-Ready: Nicolas Boichat Tested-by: Nicolas Boichat Reviewed-by: Vincent Palatin --- board/poppy/board.c | 16 ++++++++++++++++ board/poppy/usb_pd_policy.c | 11 +++++++++++ 2 files changed, 27 insertions(+) diff --git a/board/poppy/board.c b/board/poppy/board.c index 85c24610a3..6af2494333 100644 --- a/board/poppy/board.c +++ b/board/poppy/board.c @@ -70,11 +70,25 @@ static void tcpc_alert_event(enum gpio_signal signal) #endif } +/* Set PD discharge whenever VBUS detection is high (i.e. below threshold). */ +static void vbus_discharge_handler(void) +{ + if (system_get_board_version() >= 2) { + pd_set_vbus_discharge(0, + gpio_get_level(GPIO_USB_C0_VBUS_WAKE_L)); + pd_set_vbus_discharge(1, + gpio_get_level(GPIO_USB_C1_VBUS_WAKE_L)); + } +} +DECLARE_DEFERRED(vbus_discharge_handler); + void vbus0_evt(enum gpio_signal signal) { /* VBUS present GPIO is inverted */ usb_charger_vbus_change(0, !gpio_get_level(signal)); task_wake(TASK_ID_PD_C0); + + hook_call_deferred(&vbus_discharge_handler_data, 0); } void vbus1_evt(enum gpio_signal signal) @@ -82,6 +96,8 @@ void vbus1_evt(enum gpio_signal signal) /* VBUS present GPIO is inverted */ usb_charger_vbus_change(1, !gpio_get_level(signal)); task_wake(TASK_ID_PD_C1); + + hook_call_deferred(&vbus_discharge_handler_data, 0); } void usb0_evt(enum gpio_signal signal) diff --git a/board/poppy/usb_pd_policy.c b/board/poppy/usb_pd_policy.c index 085b86e738..f7d7bd874d 100644 --- a/board/poppy/usb_pd_policy.c +++ b/board/poppy/usb_pd_policy.c @@ -118,6 +118,9 @@ int pd_set_power_supply_ready(int port) vbus_en[port] = 1; board_vbus_update_source_current(port); + if (system_get_board_version() >= 2) + pd_set_vbus_discharge(port, 0); + /* notify host of power info change */ pd_send_host_event(PD_EVENT_POWER_CHANGE); @@ -126,10 +129,18 @@ int pd_set_power_supply_ready(int port) void pd_power_supply_reset(int port) { + int prev_en; + + prev_en = vbus_en[port]; + /* Disable VBUS */ vbus_en[port] = 0; board_vbus_update_source_current(port); + /* Enable discharge if we were previously sourcing 5V */ + if (system_get_board_version() >= 2 && prev_en) + pd_set_vbus_discharge(port, 1); + /* Give back the current quota we are no longer using */ charge_manager_source_port(port, 0);