diff options
author | Jack Pham <jackp@codeaurora.org> | 2016-11-17 13:19:49 -0800 |
---|---|---|
committer | Jack Pham <jackp@codeaurora.org> | 2016-11-17 15:42:35 -0800 |
commit | d96857fbff930a2b2c339ef22b0c6329609d9639 (patch) | |
tree | 092518c9111643e79f8c56d3cd3a06ce4250d02a /drivers | |
parent | 61f26e3aa5eee4fd8947ecca1cc45b5634e146b8 (diff) |
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 <jackp@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/pd/policy_engine.c | 31 |
1 files changed, 24 insertions, 7 deletions
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) |