diff --git a/board/spring/board.h b/board/spring/board.h index 67f16e9b44..ea4ce7db89 100644 --- a/board/spring/board.h +++ b/board/spring/board.h @@ -59,6 +59,9 @@ /* Battery */ #define CONFIG_BATTERY_BQ20Z453 +/* Low battery threshold. In mAh. */ +#define BATTERY_AP_OFF_LEVEL 1 + /* Charger/accessories detection */ #define CONFIG_TSU6721 diff --git a/common/gaia_power.c b/common/gaia_power.c index f197890f88..7f53dd800e 100644 --- a/common/gaia_power.c +++ b/common/gaia_power.c @@ -506,6 +506,28 @@ static int next_pwr_event(void) /*****************************************************************************/ +static int wait_for_power_on(void) +{ + int value; + while (1) { + value = check_for_power_on_event(); + if (!value) { + task_wait_event(-1); + continue; + } + + if (charge_keep_power_off()) { + CPRINTF("%T battery low. ignoring power on event.\n"); + if (value == 1) /* System already on */ + power_off(); + continue; + } + + CPRINTF("%T power on %d\n", value); + return value; + } +} + void chipset_task(void) { int value; @@ -515,9 +537,7 @@ void chipset_task(void) while (1) { /* Wait until we need to power on, then power on */ - while (value = check_for_power_on_event(), !value) - task_wait_event(-1); - CPRINTF("%T power on %d\n", value); + wait_for_power_on(); if (!power_on()) { int continue_power = 0; diff --git a/common/pmu_tps65090_charger.c b/common/pmu_tps65090_charger.c index 732a5b6d98..c07d643e97 100644 --- a/common/pmu_tps65090_charger.c +++ b/common/pmu_tps65090_charger.c @@ -42,6 +42,10 @@ #define T2_USEC (10 * SECOND) #define T3_USEC (10 * SECOND) +#ifndef BATTERY_AP_OFF_LEVEL +#define BATTERY_AP_OFF_LEVEL 0 +#endif + static const char * const state_list[] = { "idle", "pre-charging", @@ -373,6 +377,19 @@ enum charging_state charge_get_state(void) return current_state; } +int charge_keep_power_off(void) +{ + int charge; + + if (BATTERY_AP_OFF_LEVEL == 0) + return 0; + + if (battery_remaining_capacity(&charge)) + return current_state != ST_CHARGING_ERROR; + + return charge <= BATTERY_AP_OFF_LEVEL; +} + void pmu_charger_task(void) { int next_state; diff --git a/include/pmu_tpschrome.h b/include/pmu_tpschrome.h index 0af241682f..57ba4c0a7e 100644 --- a/include/pmu_tpschrome.h +++ b/include/pmu_tpschrome.h @@ -269,5 +269,10 @@ void pmu_task_throttled_wake(void); */ enum charging_state charge_get_state(void); +/** + * Return non-zero if battery is so low we want to keep AP off. + */ +int charge_keep_power_off(void); + #endif /* __CROS_EC_TPSCHROME_H */