summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/charge_state.c29
-rw-r--r--common/charger_bq24725.c25
-rw-r--r--include/charger.h9
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);