From d2ba32aa3fb8a96a6e38fff367b48ea301b1db23 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Wed, 14 Dec 2016 13:34:37 -0800 Subject: [PATCH] charge_ramp: Fix OC detection on chargers which recover quickly If VBUS is lost and then quickly recovers, we may detect the re-presence of the charger before charge_ramp has been informed about the loss. In this case, charge manager's supplier registration time will precede our ACTIVE_OC_INFO timestamp. Fix our timestamp comparison to correctly detect OC in this case. In addition, correctly mark all OC events stale once we have encountered a disconnect / reconnect that we determine not to be related to OC. BUG=chrome-os-partner:56367 TEST=Manual on reef, verify Motorola 800mA DCP charger settles at ~800mA after OC. BRANCH=reef Signed-off-by: Shawn Nematbakhsh Change-Id: I3fdfd3929d07c60b82655999dd5aa731c1c7bc9b Reviewed-on: https://chromium-review.googlesource.com/419775 Reviewed-by: Vijay P Hiremath Reviewed-by: Vincent Palatin (cherry picked from commit 19ba4a053027486ca415c4d703944b38e3c5e652) Reviewed-on: https://chromium-review.googlesource.com/421208 Commit-Ready: Vijay P Hiremath Tested-by: Vijay P Hiremath Reviewed-by: Aaron Durbin --- common/charge_ramp.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/common/charge_ramp.c b/common/charge_ramp.c index 175592e030..f6942d7516 100644 --- a/common/charge_ramp.c +++ b/common/charge_ramp.c @@ -52,7 +52,7 @@ static enum chg_ramp_state ramp_st; struct oc_info { timestamp_t ts; - uint64_t recover; + int oc_detected; int sup; int icl; }; @@ -175,15 +175,23 @@ void chg_ramp_task(void) case CHG_RAMP_CHARGE_DETECT_DELAY: /* Delay for charge_manager to determine supplier */ /* - * On entry to state, or if port changes, store the - * OC recovery time, and calculate the detect end - * time to exit this state. + * On entry to state, or if port changes, check + * timestamps to determine if this was likely an + * OC event (check if we lost VBUS and it came back + * within OC_RECOVER_MAX_TIME). */ if (ramp_st_prev != ramp_st || active_port != last_active_port) { last_active_port = active_port; - ACTIVE_OC_INFO.recover = - reg_time.val - ACTIVE_OC_INFO.ts.val; + if (reg_time.val < + ACTIVE_OC_INFO.ts.val + + OC_RECOVER_MAX_TIME) { + ACTIVE_OC_INFO.oc_detected = 1; + } else { + for (i = 0; i < RAMP_COUNT; ++i) + oc_info[active_port][i]. + oc_detected = 0; + } detect_end_time_us = get_time().val + CHARGE_DETECT_DELAY; task_wait_time = CHARGE_DETECT_DELAY; @@ -227,8 +235,7 @@ void chg_ramp_task(void) */ for (i = 0; i < RAMP_COUNT; i++) { if (oc_info[active_port][i].sup != active_sup || - oc_info[active_port][i].recover > - OC_RECOVER_MAX_TIME) + !oc_info[active_port][i].oc_detected) break; } @@ -352,9 +359,9 @@ static int command_chgramp(int argc, char **argv) ccprintf("Port %d:\n", port); ccprintf(" OC idx:%d\n", oc_info_idx[port]); for (i = 0; i < RAMP_COUNT; i++) { - ccprintf(" OC %d: s%d recover%lu icl%d\n", i, + ccprintf(" OC %d: s%d oc_det%d icl%d\n", i, oc_info[port][i].sup, - oc_info[port][i].recover, + oc_info[port][i].oc_detected, oc_info[port][i].icl); } }