diff options
-rw-r--r-- | common/charge_state.c | 29 | ||||
-rw-r--r-- | common/charger_bq24725.c | 25 | ||||
-rw-r--r-- | include/charger.h | 9 |
3 files changed, 51 insertions, 12 deletions
diff --git a/common/charge_state.c b/common/charge_state.c index e907d5e90a..468eb92adb 100644 --- a/common/charge_state.c +++ b/common/charge_state.c @@ -346,8 +346,14 @@ static enum power_state state_idle(struct power_state_context *ctx) ctx->trickle_charging_time = get_time(); } else { /* Normal charging */ + int want_current = + charger_closest_current(batt->desired_current); + + CPRINTF("[%T Charge start %dmV %dmA]\n", + batt->desired_voltage, want_current); + if (charger_set_voltage(batt->desired_voltage) || - charger_set_current(batt->desired_current)) + charger_set_current(want_current)) return PWR_STATE_ERROR; } update_charger_time(ctx, get_time()); @@ -367,6 +373,7 @@ static enum power_state state_charge(struct power_state_context *ctx) struct batt_params *batt = &ctx->curr.batt; const struct charger_info *c_info = ctx->charger; int debounce = 0; + int want_current; timestamp_t now; if (curr->error) @@ -394,24 +401,36 @@ static enum power_state state_charge(struct power_state_context *ctx) now = get_time(); if (batt->desired_voltage != curr->charging_voltage) { + CPRINTF("[%T Charge voltage %dmV]\n", batt->desired_voltage); if (charger_set_voltage(batt->desired_voltage)) return PWR_STATE_ERROR; update_charger_time(ctx, now); } - if (batt->desired_current == curr->charging_current) { + /* + * Adjust desired current to one the charger can actually supply before + * we do debouncing, or else we'll keep asking for a current the + * charger can't actually supply. + */ + want_current = charger_closest_current(batt->desired_current); + + if (want_current == curr->charging_current) { /* Tick charger watchdog */ if (!is_charger_expired(ctx, now)) return PWR_STATE_UNCHANGE; - } else if (batt->desired_current > curr->charging_current) { + } else if (want_current > curr->charging_current) { if (!timestamp_expired(ctx->voltage_debounce_time, &now)) return PWR_STATE_UNCHANGE; } else { - /* Debounce charging current on falling edge */ debounce = 1; } - if (charger_set_current(batt->desired_current)) + if (want_current != curr->charging_current) { + CPRINTF("[%T Charge current %dmA @ %dmV]\n", + want_current, batt->desired_voltage); + } + + if (charger_set_current(want_current)) return PWR_STATE_ERROR; /* Update charger watchdog timer and debounce timer */ diff --git a/common/charger_bq24725.c b/common/charger_bq24725.c index 84dc8897a2..11077301a7 100644 --- a/common/charger_bq24725.c +++ b/common/charger_bq24725.c @@ -134,17 +134,28 @@ int charger_get_current(int *current) return EC_SUCCESS; } -int charger_set_current(int current) +int charger_closest_current(int current) { - const struct charger_info *info = charger_get_info(); + const struct charger_info * const info = charger_get_info(); - /* Clip the charge current to the range the charger can supply. This - * is a temporary workaround for the battery requesting a very small - * current for trickle-charging. See crosbug.com/p/8662. */ + /* + * If the requested current is non-zero but below our minimum, + * return the minimum. See crosbug.com/p/8662. + */ if (current > 0 && current < info->current_min) - current = info->current_min; + return info->current_min; + + /* Clip to max */ if (current > info->current_max) - current = info->current_max; + return info->current_max; + + /* Otherwise round down to nearest current step */ + return current - (current % info->current_step); +} + +int charger_set_current(int current) +{ + current = charger_closest_current(current); return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS)); } diff --git a/include/charger.h b/include/charger.h index 899dbd4883..572ae51aea 100644 --- a/include/charger.h +++ b/include/charger.h @@ -44,6 +44,15 @@ int charger_get_status(int *status); */ int charger_set_mode(int mode); +/** + * Return the closest match the charger can supply to the requested current. + * + * @param current Requested current in mA. + * + * @return Current the charger will actually supply if <current> is requested. + */ +int charger_closest_current(int current); + /* Get/set charge current limit in mA */ int charger_get_current(int *current); int charger_set_current(int current); |