summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/battery_precharge.c248
-rw-r--r--common/build.mk2
-rw-r--r--common/charge_state.c37
-rw-r--r--include/battery.h6
4 files changed, 15 insertions, 278 deletions
diff --git a/common/battery_precharge.c b/common/battery_precharge.c
deleted file mode 100644
index 663002cfc8..0000000000
--- a/common/battery_precharge.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Battery charging task and state machine.
- */
-
-#include "battery.h"
-#include "battery_pack.h"
-#include "charge_state.h"
-#include "charger.h"
-#include "smart_battery.h"
-#include "timer.h"
-#include "uart.h"
-#include "util.h"
-
-/* Buffer size for charging resistance calculation */
-#define LOG_BUFFER_SIZE 16
-
-static int log_index;
-static short log_volt[LOG_BUFFER_SIZE];
-static short log_curr[LOG_BUFFER_SIZE];
-static int baseline_voltage;
-static int kicking_count;
-
-static inline int time_after(timestamp_t now, timestamp_t orig, uint64_t usec)
-{
- return (now.val > (orig.val + usec));
-}
-
-static inline void reset_data_log(void)
-{
- log_index = 0;
-}
-
-static inline void trickle_charging_init(void)
-{
- baseline_voltage = 0;
- kicking_count = 0;
- reset_data_log();
-}
-
-/**
- * Adjust charging voltage with voltage value range checking.
- * Reset data log and charger watchdog timer.
- */
-static int set_voltage(struct power_state_context *ctx, int voltage)
-{
- if (voltage <= ctx->curr.batt.desired_voltage && voltage > 0) {
- charger_set_voltage(voltage);
- charger_get_voltage(&ctx->curr.charging_voltage);
- ctx->charger_update_time = get_time();
- reset_data_log();
- return 0;
- }
- return -1;
-}
-
-/**
- * Increase the charging voltage one step.
- */
-static int inc_voltage(struct power_state_context *ctx)
-{
- return set_voltage(ctx, ctx->curr.charging_voltage +
- ctx->charger->voltage_step);
-}
-
-/**
- * Decrease the charging voltage one step.
- */
-static int dec_voltage(struct power_state_context *ctx)
-{
- return set_voltage(ctx, ctx->curr.charging_voltage -
- ctx->charger->voltage_step);
-}
-
-/**
- * Increase the charging voltage baseline one step.
- */
-static enum power_state go_next_level(struct power_state_context *ctx)
-{
- if (inc_voltage(ctx))
- return PWR_STATE_ERROR;
-
- /*
- * Battery chemical reaction lags behind the charging voltage
- * change. Delay the charging state machine 2 seconds.
- */
- sleep(2);
- charger_get_voltage(&baseline_voltage);
-
- return PWR_STATE_UNCHANGE;
-}
-
-/**
- * Trickle charging handler
- *
- * - check trickle charging timeout
- * - new state: INIT
- * - exit condition: when desired_current reaches current_min
- * - try to charge larger current when battery voltage reaches
- * 105% of voltage_min
- */
-enum power_state trickle_charge(struct power_state_context *ctx)
-{
- int sum_volt, sum_curr;
- int desired_volt, desired_curr;
-
- struct power_state_data *curr = &ctx->curr;
- struct batt_params *batt = &curr->batt;
- const struct charger_info *cinfo = ctx->charger;
- const struct battery_info *binfo = ctx->battery;
-
- /* Clear trickle charging duration on AC change */
- if (curr->ac != ctx->prev.ac) {
- ctx->trickle_charging_time.val = 0;
- if (!curr->ac)
- return PWR_STATE_REINIT;
- }
-
- /* Start timer */
- if (ctx->trickle_charging_time.val == 0) {
- trickle_charging_init();
- ctx->trickle_charging_time = get_time();
- }
-
- /* Check charger reset */
- if (curr->charging_voltage == 0 || curr->charging_current == 0) {
- ctx->trickle_charging_time.val = 0;
- return PWR_STATE_REINIT;
- }
-
- /*
- * 4 hours is long enough to pre-charge a large battery (8000mAh)
- * using minimal current (5mAh).
- */
- if (time_after(curr->ts, ctx->trickle_charging_time, HOUR * 4))
- return PWR_STATE_ERROR;
-
- if (curr->error & F_BATTERY_MASK)
- return PWR_STATE_UNCHANGE;
-
- /*
- * End of pre-charge condition; battery desired a current higher than
- * the minimal charging cap.
- */
- if (batt->desired_current > cinfo->current_min) {
- trickle_charging_init();
- ctx->trickle_charging_time.val = 0;
- return PWR_STATE_REINIT;
- }
-
- /*
- * If the trickle charging current drops to zero, raise charging
- * voltage baseline to next level.
- */
- if (batt->current == 0)
- return go_next_level(ctx);
-
- /*
- * When the battery voltage reaches normal charging value (105% min),
- * try kicking the current up and see if it starts normal charging.
- */
- if (kicking_count < 5 &&
- batt->voltage > (binfo->voltage_min * 105 / 100)) {
- kicking_count++;
- charger_set_voltage(batt->desired_voltage);
- sleep(5);
- desired_curr = 0;
- battery_desired_current(&desired_curr);
- if (desired_curr >= cinfo->current_min) {
- /* Exit trickle charging state */
- trickle_charging_init();
- ctx->trickle_charging_time.val = 0;
- return PWR_STATE_REINIT;
- }
- charger_set_voltage(curr->charging_voltage);
- ctx->charger_update_time = get_time();
-
- reset_data_log();
- return PWR_STATE_UNCHANGE;
- }
-
- /*
- * Over current protection. Decrease charging voltage and baseline
- * voltage.
- */
- if (batt->current > binfo->precharge_current) {
- dec_voltage(ctx);
- if (baseline_voltage > ctx->curr.charging_voltage)
- baseline_voltage = ctx->curr.charging_voltage;
- sleep(1);
- reset_data_log();
- return PWR_STATE_UNCHANGE;
- }
-
- /* Voltage and current data acquisition. */
- if (log_index < LOG_BUFFER_SIZE) {
- log_volt[log_index] = batt->voltage;
- log_curr[log_index] = batt->current;
- log_index++;
- return PWR_STATE_UNCHANGE;
- }
-
- sum_volt = 0;
- sum_curr = 0;
- for (log_index = 0; log_index < LOG_BUFFER_SIZE; log_index++) {
- sum_volt += log_volt[log_index];
- sum_curr += log_curr[log_index];
- }
-
- reset_data_log();
-
- /*
- * Estimate desired_voltage. The target current to desired voltage
- * function is a monotonic function. To simplify the calculation, use
- * linear estimation when the current delta is small.
- *
- * V_desired = I_target * ( avg(dV_batt) / avg(I_batt) ) + V_batt
- */
- desired_volt = (1 + batt->desired_current) *
- (curr->charging_voltage * LOG_BUFFER_SIZE - sum_volt) /
- sum_curr + batt->voltage;
-
- if (desired_volt > baseline_voltage) {
- if (desired_volt > curr->charging_voltage) {
- inc_voltage(ctx);
- sleep(1);
- return PWR_STATE_UNCHANGE;
- }
-
- if (desired_volt < (curr->charging_voltage -
- cinfo->voltage_step)) {
- dec_voltage(ctx);
- sleep(1);
- return PWR_STATE_UNCHANGE;
- }
- }
-
- /* Update charger watchdog periodically */
- if (time_after(curr->ts, ctx->charger_update_time,
- CHARGER_UPDATE_PERIOD)) {
- charger_set_current(curr->charging_current);
- ctx->charger_update_time = get_time();
- }
-
- return PWR_STATE_UNCHANGE;
-}
diff --git a/common/build.mk b/common/build.mk
index 858e05b7b9..0476fcb8b1 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -16,7 +16,7 @@ common-$(CONFIG_BATTERY_SLIPPY)+=battery_slippy.o
common-$(CONFIG_BATTERY_PEPPY)+=battery_peppy.o
common-$(CONFIG_BATTERY_FALCO)+=battery_falco.o
common-$(CONFIG_BATTERY_SPRING)+=battery_spring.o
-common-$(CONFIG_CHARGER)+=charge_state.o battery_precharge.o charger_common.o
+common-$(CONFIG_CHARGER)+=charge_state.o charger_common.o
common-$(CONFIG_CHARGER_BQ24715)+=charger_bq24715.o
common-$(CONFIG_CHARGER_BQ24725)+=charger_bq24725.o
common-$(CONFIG_CHARGER_BQ24707A)+=charger_bq24707a.o
diff --git a/common/charge_state.c b/common/charge_state.c
index 4810ebe8a7..83df8ad8a5 100644
--- a/common/charge_state.c
+++ b/common/charge_state.c
@@ -339,7 +339,6 @@ static enum power_state state_init(struct power_state_context *ctx)
static enum power_state state_idle(struct power_state_context *ctx)
{
struct batt_params *batt = &ctx->curr.batt;
- const struct charger_info *c_info = ctx->charger;
/* If we are forcing idle mode, then just stay in IDLE. */
if (state_machine_force_idle)
@@ -361,26 +360,16 @@ static enum power_state state_idle(struct power_state_context *ctx)
/* Configure init charger state and switch to charge state */
if (batt->desired_voltage && batt->desired_current) {
- /* Set charger output constraints */
- if (batt->desired_current < ctx->charger->current_min &&
- batt->state_of_charge < BATTERY_LEVEL_PRE_CHARGE) {
- /* Trickle charging */
- if (charger_set_current(c_info->current_min) ||
- charger_set_voltage(batt->voltage))
- return PWR_STATE_ERROR;
- 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(want_current))
- return PWR_STATE_ERROR;
- }
+ 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(want_current))
+ return PWR_STATE_ERROR;
+
update_charger_time(ctx, get_time());
if (ctx->curr.batt.state_of_charge < BATTERY_LEVEL_NEAR_FULL)
@@ -402,7 +391,6 @@ static enum power_state state_charge(struct power_state_context *ctx)
{
struct power_state_data *curr = &ctx->curr;
struct batt_params *batt = &ctx->curr.batt;
- const struct charger_info *c_info = ctx->charger;
int debounce = 0;
int want_current;
timestamp_t now;
@@ -410,11 +398,6 @@ static enum power_state state_charge(struct power_state_context *ctx)
if (curr->error)
return PWR_STATE_ERROR;
- if (batt->desired_current < c_info->current_min &&
- batt->desired_current > 0 &&
- batt->state_of_charge < BATTERY_LEVEL_PRE_CHARGE)
- return trickle_charge(ctx);
-
/* Check charger reset */
if (curr->charging_voltage == 0 ||
curr->charging_current == 0)
diff --git a/include/battery.h b/include/battery.h
index 50b4e53f7c..940187fe7f 100644
--- a/include/battery.h
+++ b/include/battery.h
@@ -10,19 +10,21 @@
/* Stop charge when charging and battery level >= this percentage */
#define BATTERY_LEVEL_FULL 100
+
/* Tell host we're charged when battery level >= this percentage */
#define BATTERY_LEVEL_NEAR_FULL 97
-/* Precharge only when charging and battery level < this level */
-#define BATTERY_LEVEL_PRE_CHARGE 25
+
/*
* Send battery-low host event when discharging and battery level <= this level
*/
#define BATTERY_LEVEL_LOW 10
+
/*
* Send battery-critical host event when discharging and battery level <= this
* level.
*/
#define BATTERY_LEVEL_CRITICAL 5
+
/*
* Shut down main processor and/or hibernate EC when discharging and battery
* level < this level.