diff --git a/src/board/system76/common/acpi.c b/src/board/system76/common/acpi.c index d9bec01ca..132dd6cdc 100644 --- a/src/board/system76/common/acpi.c +++ b/src/board/system76/common/acpi.c @@ -221,6 +221,7 @@ void acpi_write(uint8_t addr, uint8_t data) { case 0xBD: battery_set_end_threshold(data); + (void)battery_save_thresholds(); break; #if HAVE_LED_AIRPLANE_N diff --git a/src/board/system76/common/battery.c b/src/board/system76/common/battery.c index 0821560ed..f98a42a25 100644 --- a/src/board/system76/common/battery.c +++ b/src/board/system76/common/battery.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only #include +#include #include #include #include @@ -13,6 +14,18 @@ uint16_t battery_charger_input_current = CHARGER_INPUT_CURRENT; #define BATTERY_START_DEFAULT 0 #define BATTERY_END_DEFAULT 100 +// Flash address to save charging thresholds to +static const uint32_t BAT_CFG_ADDR = CONFIG_EC_FLASH_SIZE - (2 * 1024); +static const uint16_t BAT_CFG_MAGIC = 0x4254; + +struct battery_config { + uint16_t magic; + uint8_t start_threshold; + uint8_t end_threshold; +}; + +static struct battery_config __xdata bat_cfg = { { 0 } }; + // Represents a battery percentage level, below which charging will begin. // Valid values are [0, 100] // A value of 0 turns off the start threshold control. @@ -112,3 +125,38 @@ void battery_reset(void) { battery_start_threshold = BATTERY_START_THRESHOLD; battery_end_threshold = BATTERY_END_THRESHOLD; } + +// Read the charge thresholds from flash. Falls back to defaults if not found. +bool battery_load_thresholds(void) { + bool loaded = true; + + flash_read(BAT_CFG_ADDR, (uint8_t *)&bat_cfg, sizeof(bat_cfg)); + + if (bat_cfg.magic != BAT_CFG_MAGIC) { + bat_cfg.magic = BAT_CFG_MAGIC; + bat_cfg.start_threshold = BATTERY_START_THRESHOLD; + bat_cfg.end_threshold = BATTERY_END_THRESHOLD; + loaded = false; + } + + (void)battery_set_start_threshold(bat_cfg.start_threshold); + (void)battery_set_end_threshold(bat_cfg.end_threshold); + + return loaded; +} + +// Write the charge thresholds to flash. +bool battery_save_thresholds(void) { + if ((bat_cfg.start_threshold == battery_start_threshold) && + (bat_cfg.end_threshold == battery_end_threshold)) { + return true; + } + + bat_cfg.start_threshold = battery_start_threshold; + bat_cfg.end_threshold = battery_end_threshold; + + flash_erase(BAT_CFG_ADDR); + flash_write(BAT_CFG_ADDR, (uint8_t *)&bat_cfg, sizeof(bat_cfg)); + + return flash_read_u16(BAT_CFG_ADDR) == BAT_CFG_MAGIC; +} diff --git a/src/board/system76/common/include/board/battery.h b/src/board/system76/common/include/board/battery.h index b1523e762..850420910 100644 --- a/src/board/system76/common/include/board/battery.h +++ b/src/board/system76/common/include/board/battery.h @@ -43,6 +43,9 @@ bool battery_set_start_threshold(uint8_t value); uint8_t battery_get_end_threshold(void); bool battery_set_end_threshold(uint8_t value); +bool battery_load_thresholds(void); +bool battery_save_thresholds(void); + int16_t battery_charger_configure(void); void battery_event(void); void battery_reset(void); diff --git a/src/board/system76/common/main.c b/src/board/system76/common/main.c index 4d2c24b52..9f14c5f47 100644 --- a/src/board/system76/common/main.c +++ b/src/board/system76/common/main.c @@ -90,6 +90,7 @@ void init(void) { // Must happen last power_init(); board_init(); + (void)battery_load_thresholds(); } void main(void) {