mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 16:41:55 +00:00
Add more fields and error flags to struct batt_params
This adds two battery parameters that need to be monitored constantly: remaining_capacity and full_capacity (that one only changes occasionally, but we have to notify the AP when it does). It also adds the is_present field to indicate whether the battery is physically present or not (when we can tell), so we know whether to try to wake up a deep-discharged battery. Along with that, we clean up the error flags to provide indication of which fields were unable to be read, and replace the manual logical-or of all errors as they were set with a bitmask (BATT_FLAG_BAD_ANY). No functionality is changed, only new & better information is provided for use in the upcoming cleanup of the charge state machine. BUG=chrome-os-partner:20881 BRANCH=ToT TEST=make buildall -j All targets build; all tests pass. Change-Id: I4312c2fdd3cf2dd9570718e90571eff796b269db Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/191917 Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
@@ -294,7 +294,7 @@ static int state_common(struct charge_state_context *ctx)
|
||||
curr->error |= F_BATTERY_GET_PARAMS;
|
||||
if (batt->flags & BATT_FLAG_BAD_VOLTAGE)
|
||||
curr->error |= F_BATTERY_VOLTAGE;
|
||||
if (batt->flags & BATT_FLAG_BAD_CHARGE_PERCENT)
|
||||
if (batt->flags & BATT_FLAG_BAD_STATE_OF_CHARGE)
|
||||
curr->error |= F_BATTERY_STATE_OF_CHARGE;
|
||||
|
||||
*ctx->memmap_batt_volt = batt->voltage;
|
||||
|
||||
@@ -218,7 +218,7 @@ static int calc_next_state(int state)
|
||||
return ST_IDLE;
|
||||
|
||||
/* Start charging only when battery charge lower than 100% */
|
||||
if (!(batt.flags & BATT_FLAG_BAD_CHARGE_PERCENT)) {
|
||||
if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) {
|
||||
if (batt.state_of_charge < 100)
|
||||
return ST_CHARGING;
|
||||
}
|
||||
@@ -236,7 +236,7 @@ static int calc_next_state(int state)
|
||||
if (batt.flags & BATT_FLAG_RESPONSIVE) {
|
||||
if (!battery_start_charging_range(batt.temperature))
|
||||
return ST_IDLE0;
|
||||
if (!(batt.flags & BATT_FLAG_BAD_CHARGE_PERCENT)) {
|
||||
if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) {
|
||||
if (batt.state_of_charge >= 100)
|
||||
return ST_IDLE0;
|
||||
}
|
||||
@@ -355,7 +355,7 @@ static int calc_next_state(int state)
|
||||
return system_off();
|
||||
}
|
||||
/* Check remaining charge % */
|
||||
if (!(batt.flags & BATT_FLAG_BAD_CHARGE_PERCENT)) {
|
||||
if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) {
|
||||
/*
|
||||
* Shutdown AP when state of charge < 1.5%.
|
||||
* Moving average is rounded to integer.
|
||||
|
||||
@@ -187,19 +187,19 @@ void battery_get_params(struct batt_params *batt)
|
||||
batt->flags = 0;
|
||||
|
||||
if (bq27541_read(REG_TEMPERATURE, &batt->temperature))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY;
|
||||
batt->flags |= BATT_FLAG_BAD_TEMPERATURE;
|
||||
else
|
||||
batt->flags |= BATT_FLAG_RESPONSIVE; /* Battery is responding */
|
||||
|
||||
if (bq27541_read(REG_STATE_OF_CHARGE, &batt->state_of_charge))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY | BATT_FLAG_BAD_CHARGE_PERCENT;
|
||||
batt->flags |= BATT_FLAG_BAD_STATE_OF_CHARGE;
|
||||
|
||||
if (bq27541_read(REG_VOLTAGE, &batt->voltage))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY | BATT_FLAG_BAD_VOLTAGE;
|
||||
batt->flags |= BATT_FLAG_BAD_VOLTAGE;
|
||||
|
||||
v = 0;
|
||||
if (bq27541_read(REG_AVERAGE_CURRENT, &v))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY;
|
||||
batt->flags |= BATT_FLAG_BAD_CURRENT;
|
||||
batt->current = (int16_t)v;
|
||||
|
||||
/* Default to not desiring voltage and current */
|
||||
|
||||
@@ -218,39 +218,62 @@ void battery_get_params(struct batt_params *batt)
|
||||
memset(batt, 0, sizeof(*batt));
|
||||
|
||||
if (sb_read(SB_TEMPERATURE, &batt->temperature))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY;
|
||||
else
|
||||
batt->flags |= BATT_FLAG_RESPONSIVE; /* Battery is responding */
|
||||
batt->flags |= BATT_FLAG_BAD_TEMPERATURE;
|
||||
|
||||
if (sb_read(SB_RELATIVE_STATE_OF_CHARGE, &batt->state_of_charge))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY | BATT_FLAG_BAD_CHARGE_PERCENT;
|
||||
batt->flags |= BATT_FLAG_BAD_STATE_OF_CHARGE;
|
||||
|
||||
if (sb_read(SB_VOLTAGE, &batt->voltage))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY | BATT_FLAG_BAD_VOLTAGE;
|
||||
|
||||
/* Ensure battery current is set to 0 if unable to read it */
|
||||
v = 0;
|
||||
batt->flags |= BATT_FLAG_BAD_VOLTAGE;
|
||||
|
||||
/* This is a signed 16-bit value. */
|
||||
if (sb_read(SB_CURRENT, &v))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY;
|
||||
batt->flags |= BATT_FLAG_BAD_CURRENT;
|
||||
else
|
||||
batt->current = (int16_t)v;
|
||||
|
||||
batt->current = (int16_t)v;
|
||||
if (sb_read(SB_CHARGING_VOLTAGE, &batt->desired_voltage))
|
||||
batt->flags |= BATT_FLAG_BAD_DESIRED_VOLTAGE;
|
||||
|
||||
if (sb_read(SB_CHARGING_VOLTAGE, &batt->desired_voltage) ||
|
||||
sb_read(SB_CHARGING_CURRENT, &batt->desired_current))
|
||||
batt->flags |= BATT_FLAG_BAD_ANY;
|
||||
if (sb_read(SB_CHARGING_CURRENT, &batt->desired_current))
|
||||
batt->flags |= BATT_FLAG_BAD_DESIRED_CURRENT;
|
||||
|
||||
if (battery_remaining_capacity(&batt->remaining_capacity))
|
||||
batt->flags |= BATT_FLAG_BAD_REMAINING_CAPACITY;
|
||||
|
||||
if (battery_full_charge_capacity(&batt->full_capacity))
|
||||
batt->flags |= BATT_FLAG_BAD_FULL_CAPACITY;
|
||||
|
||||
/* If any of those reads worked, the battery is responsive */
|
||||
if ((batt->flags & BATT_FLAG_BAD_ANY) != BATT_FLAG_BAD_ANY)
|
||||
batt->flags |= BATT_FLAG_RESPONSIVE;
|
||||
|
||||
#if defined(CONFIG_BATTERY_PRESENT_CUSTOM) || \
|
||||
defined(CONFIG_BATTERY_PRESENT_GPIO)
|
||||
/* Hardware can tell us for certain */
|
||||
batt->is_present = battery_is_present();
|
||||
#else
|
||||
/* No hardware test, so we only know it's there if it responds */
|
||||
if (batt->flags & BATT_FLAG_RESPONSIVE)
|
||||
batt->is_present = BP_YES;
|
||||
else
|
||||
batt->is_present = BP_NOT_SURE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Charging allowed if both desired voltage and current are nonzero
|
||||
* and battery isn't full.
|
||||
* and battery isn't full (and we read them all correctly).
|
||||
*/
|
||||
if (batt->desired_voltage && batt->desired_current &&
|
||||
batt->state_of_charge < BATTERY_LEVEL_FULL) {
|
||||
if (!(batt->flags & (BATT_FLAG_BAD_DESIRED_VOLTAGE |
|
||||
BATT_FLAG_BAD_DESIRED_CURRENT |
|
||||
BATT_FLAG_BAD_STATE_OF_CHARGE)) &&
|
||||
batt->desired_voltage &&
|
||||
batt->desired_current &&
|
||||
batt->state_of_charge < BATTERY_LEVEL_FULL)
|
||||
batt->flags |= BATT_FLAG_WANT_CHARGE;
|
||||
} else {
|
||||
else
|
||||
/* Force both to zero */
|
||||
batt->desired_voltage = batt->desired_current = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -33,6 +33,16 @@
|
||||
*/
|
||||
#define BATTERY_LEVEL_SHUTDOWN 3
|
||||
|
||||
/*
|
||||
* Sometimes we have hardware to detect battery present, sometimes we have to
|
||||
* wait until we've been able to talk to the battery.
|
||||
*/
|
||||
enum battery_present {
|
||||
BP_NO = 0,
|
||||
BP_YES = 1,
|
||||
BP_NOT_SURE,
|
||||
};
|
||||
|
||||
/* Battery parameters */
|
||||
struct batt_params {
|
||||
int temperature; /* Temperature in 0.1 K */
|
||||
@@ -41,23 +51,31 @@ struct batt_params {
|
||||
int current; /* Battery current (mA); negative=discharging */
|
||||
int desired_voltage; /* Charging voltage desired by battery (mV) */
|
||||
int desired_current; /* Charging current desired by battery (mA) */
|
||||
int remaining_capacity; /* Remaining capacity in mAh */
|
||||
int full_capacity; /* Capacity in mAh (might change occasionally) */
|
||||
enum battery_present is_present; /* Is the battery physically present */
|
||||
int flags; /* Flags */
|
||||
};
|
||||
|
||||
/* Flags for batt_params */
|
||||
|
||||
/* Battery wants to be charged */
|
||||
#define BATT_FLAG_WANT_CHARGE (1 << 0)
|
||||
#define BATT_FLAG_WANT_CHARGE 0x00000001
|
||||
|
||||
/* Battery is responsive (talking to us via I2C) */
|
||||
#define BATT_FLAG_RESPONSIVE (1 << 1)
|
||||
#define BATT_FLAG_RESPONSIVE 0x00000002
|
||||
|
||||
/* Able to talk to battery, but it won't tell us voltage or charge percent */
|
||||
#define BATT_FLAG_BAD_VOLTAGE (1 << 2)
|
||||
#define BATT_FLAG_BAD_CHARGE_PERCENT (1 << 3)
|
||||
|
||||
/* Battery couldn't tell us every params we want */
|
||||
#define BATT_FLAG_BAD_ANY (1 << 4)
|
||||
/* Bits to indicate which parameter(s) could not be read */
|
||||
#define BATT_FLAG_BAD_TEMPERATURE 0x00000004
|
||||
#define BATT_FLAG_BAD_STATE_OF_CHARGE 0x00000008
|
||||
#define BATT_FLAG_BAD_VOLTAGE 0x00000010
|
||||
#define BATT_FLAG_BAD_CURRENT 0x00000020
|
||||
#define BATT_FLAG_BAD_DESIRED_VOLTAGE 0x00000040
|
||||
#define BATT_FLAG_BAD_DESIRED_CURRENT 0x00000080
|
||||
#define BATT_FLAG_BAD_REMAINING_CAPACITY 0x00000100
|
||||
#define BATT_FLAG_BAD_FULL_CAPACITY 0x00000200
|
||||
/* All of the above BATT_FLAG_BAD_* bits */
|
||||
#define BATT_FLAG_BAD_ANY 0x000003fc
|
||||
|
||||
/* Battery constants */
|
||||
struct battery_info {
|
||||
@@ -102,11 +120,7 @@ void battery_vendor_params(struct batt_params *batt);
|
||||
*
|
||||
* @return Whether there is a battery attached or not, or if we can't tell.
|
||||
*/
|
||||
enum battery_present {
|
||||
BP_NO = 0,
|
||||
BP_YES = 1,
|
||||
BP_NOT_SURE,
|
||||
} battery_is_present(void);
|
||||
enum battery_present battery_is_present(void);
|
||||
|
||||
/**
|
||||
* Get battery mode.
|
||||
|
||||
Reference in New Issue
Block a user