summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-11-18 20:32:01 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-11-18 20:32:00 -0800
commit38553d1c06c98a0754d2c3a0cf144249abc4d495 (patch)
tree416a0d99dd7fe573c5149178009e0583e5d00093 /drivers/usb
parent20038284498c5f1ab3d5eb78826d0f216ddeb27b (diff)
parentd96857fbff930a2b2c339ef22b0c6329609d9639 (diff)
Merge "usb: pd: Don't suspend charging unless changing voltages"
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/pd/policy_engine.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 517110e76157..aa2e1d9f3c70 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;
@@ -1709,6 +1709,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,
@@ -1718,16 +1720,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)