From d96857fbff930a2b2c339ef22b0c6329609d9639 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Thu, 17 Nov 2016 13:19:49 -0800 Subject: usb: pd: Don't suspend charging unless changing voltages To optimize charging during power negotiation and the voltage is not changing, for example when transitioning from implicit contract to the default 5V PDO, there is no requirement to suspend the charging and hence setting the charger's PROP_PD_CURRENT_MAX can be avoided. It is only needed when changing voltages, in which case current limit should be calculated based on pSnkStdby (2.5W), or when staying at the same voltage and decreasing current. Also fix the incorrect setting of PROP_CURRENT_MAX to PROP_PD_CURRENT_MAX when doing a sink->source swap. Change-Id: Ib53902459646e590df4dc7fcb00f833d5e8f41ed Signed-off-by: Jack Pham --- drivers/usb/pd/policy_engine.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index b4d7c7d8bddf..27a963aac984 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -913,7 +913,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_PRS_SNK_SRC_TRANSITION_TO_OFF: val.intval = pd->requested_current = 0; /* suspend charging */ power_supply_set_property(pd->usb_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, &val); + POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val); pd->in_explicit_contract = false; @@ -1731,6 +1731,8 @@ static void usbpd_sm(struct work_struct *w) case PE_SNK_SELECT_CAPABILITY: if (IS_CTRL(rx_msg, MSG_ACCEPT)) { + usbpd_set_state(pd, PE_SNK_TRANSITION_SINK); + /* prepare for voltage increase/decrease */ val.intval = pd->requested_voltage; power_supply_set_property(pd->usb_psy, @@ -1740,16 +1742,31 @@ static void usbpd_sm(struct work_struct *w) &val); /* - * disable charging; technically we are allowed to - * charge up to pSnkStdby (2.5 W) during this - * transition, but disable it just for simplicity. + * if we are changing voltages, we must lower input + * current to pSnkStdby (2.5W). Calculate it and set + * PD_CURRENT_MAX accordingly. */ - val.intval = 0; - power_supply_set_property(pd->usb_psy, + if (pd->requested_voltage != pd->current_voltage) { + int mv = max(pd->requested_voltage, + pd->current_voltage) / 1000; + val.intval = (2500000 / mv) * 1000; + power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val); + } else { + /* decreasing current? */ + ret = power_supply_get_property(pd->usb_psy, + POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val); + if (!ret && + pd->requested_current < val.intval) { + val.intval = + pd->requested_current * 1000; + power_supply_set_property(pd->usb_psy, + POWER_SUPPLY_PROP_PD_CURRENT_MAX, + &val); + } + } pd->selected_pdo = pd->requested_pdo; - usbpd_set_state(pd, PE_SNK_TRANSITION_SINK); } else if (IS_CTRL(rx_msg, MSG_REJECT) || IS_CTRL(rx_msg, MSG_WAIT)) { if (pd->in_explicit_contract) -- cgit v1.2.3