diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2021-10-15 14:18:28 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-10-26 22:16:37 +0000 |
commit | 8106efd33a7897e071410201ba85804bfba9dfcd (patch) | |
tree | 0a706751becdccdf06fb38211730da1c21bd8efc /common | |
parent | 1f1103b4b875a4ce12fb666fa69572747e02996c (diff) | |
download | chrome-ec-8106efd33a7897e071410201ba85804bfba9dfcd.tar.gz |
Battery: Move battery code to battery_v1.c and v2.c
BUG=b:198722643, b:203031618
BRANCH=None
TEST=buildall
Change-Id: I595da56412f4d30684b00d1138f7e2339c7f5204
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3227372
Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Reviewed-by: Keith Short <keithshort@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/battery.c | 154 | ||||
-rw-r--r-- | common/battery_v1.c | 172 | ||||
-rw-r--r-- | common/battery_v2.c | 368 | ||||
-rw-r--r-- | common/build.mk | 2 | ||||
-rw-r--r-- | common/charge_state_v2.c | 393 |
5 files changed, 558 insertions, 531 deletions
diff --git a/common/battery.c b/common/battery.c index 6791e4d3a2..6339573d2e 100644 --- a/common/battery.c +++ b/common/battery.c @@ -29,15 +29,6 @@ const static int batt_host_full_factor = CONFIG_BATT_HOST_FULL_FACTOR; const static int batt_host_shutdown_pct = CONFIG_BATT_HOST_SHUTDOWN_PERCENTAGE; -#ifdef CONFIG_BATTERY_V2 -/* - * Store battery information in these 2 structures. Main (lid) battery is always - * at index 0, and secondary (base) battery at index 1. - */ -struct ec_response_battery_static_info_v1 battery_static[CONFIG_BATTERY_COUNT]; -struct ec_response_battery_dynamic_info battery_dynamic[CONFIG_BATTERY_COUNT]; -#endif - #ifdef CONFIG_BATTERY_CUT_OFF #ifndef CONFIG_BATTERY_CUTOFF_DELAY_US @@ -469,151 +460,6 @@ DECLARE_HOST_COMMAND(EC_CMD_BATTERY_VENDOR_PARAM, EC_VER_MASK(0)); #endif /* CONFIG_BATTERY_VENDOR_PARAM */ -#ifdef CONFIG_BATTERY_V2 -#ifdef CONFIG_HOSTCMD_BATTERY_V2 -static void battery_update(enum battery_index i); -static enum ec_status -host_command_battery_get_static(struct host_cmd_handler_args *args) -{ - const struct ec_params_battery_static_info *p = args->params; - struct ec_response_battery_static_info_v1 *bat; - - if (p->index < 0 || p->index >= CONFIG_BATTERY_COUNT) - return EC_RES_INVALID_PARAM; - bat = &battery_static[p->index]; - - battery_update(p->index); - if (args->version == 0) { - struct ec_response_battery_static_info *r = args->response; - - args->response_size = sizeof(*r); - r->design_capacity = bat->design_capacity; - r->design_voltage = bat->design_voltage; - r->cycle_count = bat->cycle_count; - - /* Truncate strings to reduced v0 size */ - memcpy(&r->manufacturer, &bat->manufacturer_ext, - sizeof(r->manufacturer)); - r->manufacturer[sizeof(r->manufacturer) - 1] = 0; - memcpy(&r->model, &bat->model_ext, sizeof(r->model)); - r->model[sizeof(r->model) - 1] = 0; - memcpy(&r->serial, &bat->serial_ext, sizeof(r->serial)); - r->serial[sizeof(r->serial) - 1] = 0; - memcpy(&r->type, &bat->type_ext, sizeof(r->type)); - r->type[sizeof(r->type) - 1] = 0; - } else { - /* v1 command stores the same data internally */ - struct ec_response_battery_static_info_v1 *r = args->response; - - args->response_size = sizeof(*r); - memcpy(r, bat, sizeof(*r)); - } - - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_BATTERY_GET_STATIC, - host_command_battery_get_static, - EC_VER_MASK(0) | EC_VER_MASK(1)); - -static enum ec_status -host_command_battery_get_dynamic(struct host_cmd_handler_args *args) -{ - const struct ec_params_battery_dynamic_info *p = args->params; - struct ec_response_battery_dynamic_info *r = args->response; - - if (p->index < 0 || p->index >= CONFIG_BATTERY_COUNT) - return EC_RES_INVALID_PARAM; - - args->response_size = sizeof(*r); - memcpy(r, &battery_dynamic[p->index], sizeof(*r)); - - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_BATTERY_GET_DYNAMIC, - host_command_battery_get_dynamic, - EC_VER_MASK(0)); -#endif /* CONFIG_HOSTCMD_BATTERY_V2 */ - -#ifdef HAS_TASK_HOSTCMD -static void battery_update(enum battery_index i) -{ - char *batt_str; - int *memmap_dcap = (int *)host_get_memmap(EC_MEMMAP_BATT_DCAP); - int *memmap_dvlt = (int *)host_get_memmap(EC_MEMMAP_BATT_DVLT); - int *memmap_ccnt = (int *)host_get_memmap(EC_MEMMAP_BATT_CCNT); - int *memmap_volt = (int *)host_get_memmap(EC_MEMMAP_BATT_VOLT); - int *memmap_rate = (int *)host_get_memmap(EC_MEMMAP_BATT_RATE); - int *memmap_cap = (int *)host_get_memmap(EC_MEMMAP_BATT_CAP); - int *memmap_lfcc = (int *)host_get_memmap(EC_MEMMAP_BATT_LFCC); - uint8_t *memmap_flags = host_get_memmap(EC_MEMMAP_BATT_FLAG); - - /* Smart battery serial number is 16 bits */ - batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_SERIAL); - memcpy(batt_str, battery_static[i].serial_ext, EC_MEMMAP_TEXT_MAX); - batt_str[EC_MEMMAP_TEXT_MAX - 1] = 0; - - /* Design Capacity of Full */ - *memmap_dcap = battery_static[i].design_capacity; - - /* Design Voltage */ - *memmap_dvlt = battery_static[i].design_voltage; - - /* Cycle Count */ - *memmap_ccnt = battery_static[i].cycle_count; - - /* Battery Manufacturer string */ - batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MFGR); - memcpy(batt_str, battery_static[i].manufacturer_ext, - EC_MEMMAP_TEXT_MAX); - batt_str[EC_MEMMAP_TEXT_MAX - 1] = 0; - - /* Battery Model string */ - batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MODEL); - memcpy(batt_str, battery_static[i].model_ext, EC_MEMMAP_TEXT_MAX); - batt_str[EC_MEMMAP_TEXT_MAX - 1] = 0; - - /* Battery Type string */ - batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_TYPE); - memcpy(batt_str, battery_static[i].type_ext, EC_MEMMAP_TEXT_MAX); - batt_str[EC_MEMMAP_TEXT_MAX - 1] = 0; - - *memmap_volt = battery_dynamic[i].actual_voltage; - *memmap_rate = battery_dynamic[i].actual_current; - *memmap_cap = battery_dynamic[i].remaining_capacity; - *memmap_lfcc = battery_dynamic[i].full_capacity; - *memmap_flags = battery_dynamic[i].flags; -} - -void battery_memmap_refresh(enum battery_index index) -{ - if (*host_get_memmap(EC_MEMMAP_BATT_INDEX) == index) - battery_update(index); -} - -void battery_memmap_set_index(enum battery_index index) -{ - if (*host_get_memmap(EC_MEMMAP_BATT_INDEX) == index) - return; - - *host_get_memmap(EC_MEMMAP_BATT_INDEX) = BATT_IDX_INVALID; - if (index < 0 || index >= CONFIG_BATTERY_COUNT) - return; - - battery_update(index); - *host_get_memmap(EC_MEMMAP_BATT_INDEX) = index; -} - -static void battery_init(void) -{ - *host_get_memmap(EC_MEMMAP_BATT_INDEX) = BATT_IDX_INVALID; - *host_get_memmap(EC_MEMMAP_BATT_COUNT) = CONFIG_BATTERY_COUNT; - *host_get_memmap(EC_MEMMAP_BATTERY_VERSION) = 2; - - battery_memmap_set_index(BATT_IDX_MAIN); -} -DECLARE_HOOK(HOOK_INIT, battery_init, HOOK_PRIO_DEFAULT); -#endif /* HAS_TASK_HOSTCMD */ -#endif /* CONFIG_BATTERY_V2 */ void battery_compensate_params(struct batt_params *batt) { diff --git a/common/battery_v1.c b/common/battery_v1.c new file mode 100644 index 0000000000..3b18f43ee5 --- /dev/null +++ b/common/battery_v1.c @@ -0,0 +1,172 @@ +/* Copyright 2021 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 V1 APIs. + */ + +#include "battery.h" +#include "charge_state.h" +#include "common.h" +#include "console.h" +#include "extpower.h" +#include "host_command.h" +#include "math_util.h" +#include "printf.h" +#include "util.h" + +#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) +#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) + +/* Returns zero if every item was updated. */ +int update_static_battery_info(void) +{ + char *batt_str; + int batt_serial; + uint8_t batt_flags = 0; + /* + * The return values have type enum ec_error_list, but EC_SUCCESS is + * zero. We'll just look for any failures so we can try them all again. + */ + int rv; + + /* Smart battery serial number is 16 bits */ + batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_SERIAL); + memset(batt_str, 0, EC_MEMMAP_TEXT_MAX); + rv = battery_serial_number(&batt_serial); + if (!rv) + snprintf(batt_str, EC_MEMMAP_TEXT_MAX, "%04X", batt_serial); + + /* Design Capacity of Full */ + rv |= battery_design_capacity( + (int *)host_get_memmap(EC_MEMMAP_BATT_DCAP)); + + /* Design Voltage */ + rv |= battery_design_voltage( + (int *)host_get_memmap(EC_MEMMAP_BATT_DVLT)); + + /* Last Full Charge Capacity (this is only mostly static) */ + rv |= battery_full_charge_capacity( + (int *)host_get_memmap(EC_MEMMAP_BATT_LFCC)); + + /* Cycle Count */ + rv |= battery_cycle_count((int *)host_get_memmap(EC_MEMMAP_BATT_CCNT)); + + /* Battery Manufacturer string */ + batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MFGR); + memset(batt_str, 0, EC_MEMMAP_TEXT_MAX); + rv |= battery_manufacturer_name(batt_str, EC_MEMMAP_TEXT_MAX); + + /* Battery Model string */ + batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MODEL); + memset(batt_str, 0, EC_MEMMAP_TEXT_MAX); + rv |= battery_device_name(batt_str, EC_MEMMAP_TEXT_MAX); + + /* Battery Type string */ + batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_TYPE); + rv |= battery_device_chemistry(batt_str, EC_MEMMAP_TEXT_MAX); + + /* Zero the dynamic entries. They'll come next. */ + *(int *)host_get_memmap(EC_MEMMAP_BATT_VOLT) = 0; + *(int *)host_get_memmap(EC_MEMMAP_BATT_RATE) = 0; + *(int *)host_get_memmap(EC_MEMMAP_BATT_CAP) = 0; + *(int *)host_get_memmap(EC_MEMMAP_BATT_LFCC) = 0; + if (extpower_is_present()) + batt_flags |= EC_BATT_FLAG_AC_PRESENT; + *host_get_memmap(EC_MEMMAP_BATT_FLAG) = batt_flags; + + if (rv) + charge_problem(PR_STATIC_UPDATE, rv); + else + /* No errors seen. Battery data is now present */ + *host_get_memmap(EC_MEMMAP_BATTERY_VERSION) = 1; + + return rv; +} + +void update_dynamic_battery_info(void) +{ + /* The memmap address is constant. We should fix these calls somehow. */ + int *memmap_volt = (int *)host_get_memmap(EC_MEMMAP_BATT_VOLT); + int *memmap_rate = (int *)host_get_memmap(EC_MEMMAP_BATT_RATE); + int *memmap_cap = (int *)host_get_memmap(EC_MEMMAP_BATT_CAP); + int *memmap_lfcc = (int *)host_get_memmap(EC_MEMMAP_BATT_LFCC); + uint8_t *memmap_flags = host_get_memmap(EC_MEMMAP_BATT_FLAG); + uint8_t tmp; + int send_batt_status_event = 0; + int send_batt_info_event = 0; + static int batt_present; + struct charge_state_data *curr; + + curr = charge_get_status(); + tmp = 0; + if (curr->ac) + tmp |= EC_BATT_FLAG_AC_PRESENT; + + if (curr->batt.is_present == BP_YES) { + tmp |= EC_BATT_FLAG_BATT_PRESENT; + batt_present = 1; + /* Tell the AP to read battery info if it is newly present. */ + if (!(*memmap_flags & EC_BATT_FLAG_BATT_PRESENT)) + send_batt_info_event++; + } else { + /* + * Require two consecutive updates with BP_NOT_SURE + * before reporting it gone to the host. + */ + if (batt_present) + tmp |= EC_BATT_FLAG_BATT_PRESENT; + else if (*memmap_flags & EC_BATT_FLAG_BATT_PRESENT) + send_batt_info_event++; + batt_present = 0; + } + + if (curr->batt.flags & EC_BATT_FLAG_INVALID_DATA) + tmp |= EC_BATT_FLAG_INVALID_DATA; + + if (!(curr->batt.flags & BATT_FLAG_BAD_VOLTAGE)) + *memmap_volt = curr->batt.voltage; + + if (!(curr->batt.flags & BATT_FLAG_BAD_CURRENT)) + *memmap_rate = ABS(curr->batt.current); + + if (!(curr->batt.flags & BATT_FLAG_BAD_REMAINING_CAPACITY)) { + /* + * If we're running off the battery, it must have some charge. + * Don't report zero charge, as that has special meaning + * to Chrome OS powerd. + */ + if (curr->batt.remaining_capacity == 0 && !curr->batt_is_charging) + *memmap_cap = 1; + else + *memmap_cap = curr->batt.remaining_capacity; + } + + if (!(curr->batt.flags & BATT_FLAG_BAD_FULL_CAPACITY) && + (curr->batt.full_capacity <= (*memmap_lfcc - LFCC_EVENT_THRESH) || + curr->batt.full_capacity >= (*memmap_lfcc + LFCC_EVENT_THRESH))) { + *memmap_lfcc = curr->batt.full_capacity; + /* Poke the AP if the full_capacity changes. */ + send_batt_info_event++; + } + + if (curr->batt.is_present == BP_YES && + !(curr->batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) && + curr->batt.state_of_charge <= BATTERY_LEVEL_CRITICAL) + tmp |= EC_BATT_FLAG_LEVEL_CRITICAL; + + tmp |= curr->batt_is_charging ? EC_BATT_FLAG_CHARGING : + EC_BATT_FLAG_DISCHARGING; + + /* Tell the AP to re-read battery status if charge state changes */ + if (*memmap_flags != tmp) + send_batt_status_event++; + + /* Update flags before sending host events. */ + *memmap_flags = tmp; + + if (send_batt_info_event) + host_set_single_event(EC_HOST_EVENT_BATTERY); + if (send_batt_status_event) + host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS); +} diff --git a/common/battery_v2.c b/common/battery_v2.c new file mode 100644 index 0000000000..3fc203b9e8 --- /dev/null +++ b/common/battery_v2.c @@ -0,0 +1,368 @@ +/* Copyright 2021 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 V2 APIs. + */ + +#include "battery.h" +#include "charge_state.h" +#include "common.h" +#include "console.h" +#include "hooks.h" +#include "host_command.h" +#include "printf.h" +#include "util.h" + +#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) +#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) + +/* + * Store battery information in these 2 structures. Main (lid) battery is always + * at index 0, and secondary (base) battery at index 1. + */ +struct ec_response_battery_static_info_v1 battery_static[CONFIG_BATTERY_COUNT]; +struct ec_response_battery_dynamic_info battery_dynamic[CONFIG_BATTERY_COUNT]; + +#ifdef HAS_TASK_HOSTCMD +static void battery_update(enum battery_index i) +{ + char *batt_str; + int *memmap_dcap = (int *)host_get_memmap(EC_MEMMAP_BATT_DCAP); + int *memmap_dvlt = (int *)host_get_memmap(EC_MEMMAP_BATT_DVLT); + int *memmap_ccnt = (int *)host_get_memmap(EC_MEMMAP_BATT_CCNT); + int *memmap_volt = (int *)host_get_memmap(EC_MEMMAP_BATT_VOLT); + int *memmap_rate = (int *)host_get_memmap(EC_MEMMAP_BATT_RATE); + int *memmap_cap = (int *)host_get_memmap(EC_MEMMAP_BATT_CAP); + int *memmap_lfcc = (int *)host_get_memmap(EC_MEMMAP_BATT_LFCC); + uint8_t *memmap_flags = host_get_memmap(EC_MEMMAP_BATT_FLAG); + + /* Smart battery serial number is 16 bits */ + batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_SERIAL); + memcpy(batt_str, battery_static[i].serial_ext, EC_MEMMAP_TEXT_MAX); + batt_str[EC_MEMMAP_TEXT_MAX - 1] = 0; + + /* Design Capacity of Full */ + *memmap_dcap = battery_static[i].design_capacity; + + /* Design Voltage */ + *memmap_dvlt = battery_static[i].design_voltage; + + /* Cycle Count */ + *memmap_ccnt = battery_static[i].cycle_count; + + /* Battery Manufacturer string */ + batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MFGR); + memcpy(batt_str, battery_static[i].manufacturer_ext, + EC_MEMMAP_TEXT_MAX); + batt_str[EC_MEMMAP_TEXT_MAX - 1] = 0; + + /* Battery Model string */ + batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MODEL); + memcpy(batt_str, battery_static[i].model_ext, EC_MEMMAP_TEXT_MAX); + batt_str[EC_MEMMAP_TEXT_MAX - 1] = 0; + + /* Battery Type string */ + batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_TYPE); + memcpy(batt_str, battery_static[i].type_ext, EC_MEMMAP_TEXT_MAX); + batt_str[EC_MEMMAP_TEXT_MAX - 1] = 0; + + *memmap_volt = battery_dynamic[i].actual_voltage; + *memmap_rate = battery_dynamic[i].actual_current; + *memmap_cap = battery_dynamic[i].remaining_capacity; + *memmap_lfcc = battery_dynamic[i].full_capacity; + *memmap_flags = battery_dynamic[i].flags; +} + +#ifdef CONFIG_HOSTCMD_BATTERY_V2 +static enum ec_status +host_command_battery_get_static(struct host_cmd_handler_args *args) +{ + const struct ec_params_battery_static_info *p = args->params; + const struct ec_response_battery_static_info_v1 *bat; + + if (p->index < 0 || p->index >= CONFIG_BATTERY_COUNT) + return EC_RES_INVALID_PARAM; + bat = &battery_static[p->index]; + + battery_update(p->index); + if (args->version == 0) { + struct ec_response_battery_static_info *r = args->response; + + r->design_capacity = bat->design_capacity; + r->design_voltage = bat->design_voltage; + r->cycle_count = bat->cycle_count; + + /* Truncate strings to reduced v0 size */ + memcpy(&r->manufacturer, &bat->manufacturer_ext, + sizeof(r->manufacturer)); + r->manufacturer[sizeof(r->manufacturer) - 1] = 0; + memcpy(&r->model, &bat->model_ext, sizeof(r->model)); + r->model[sizeof(r->model) - 1] = 0; + memcpy(&r->serial, &bat->serial_ext, sizeof(r->serial)); + r->serial[sizeof(r->serial) - 1] = 0; + memcpy(&r->type, &bat->type_ext, sizeof(r->type)); + r->type[sizeof(r->type) - 1] = 0; + + args->response_size = sizeof(*r); + } else if (args->version == 1) { + /* v1 command stores the same data internally */ + struct ec_response_battery_static_info_v1 *r = args->response; + + args->response_size = sizeof(*r); + memcpy(r, bat, sizeof(*r)); + } + + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_BATTERY_GET_STATIC, + host_command_battery_get_static, + EC_VER_MASK(0) | EC_VER_MASK(1)); + +static enum ec_status +host_command_battery_get_dynamic(struct host_cmd_handler_args *args) +{ + const struct ec_params_battery_dynamic_info *p = args->params; + struct ec_response_battery_dynamic_info *r = args->response; + + if (p->index < 0 || p->index >= CONFIG_BATTERY_COUNT) + return EC_RES_INVALID_PARAM; + + args->response_size = sizeof(*r); + memcpy(r, &battery_dynamic[p->index], sizeof(*r)); + + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_BATTERY_GET_DYNAMIC, + host_command_battery_get_dynamic, + EC_VER_MASK(0)); +#endif /* CONFIG_HOSTCMD_BATTERY_V2 */ + +void battery_memmap_refresh(enum battery_index index) +{ + if (*host_get_memmap(EC_MEMMAP_BATT_INDEX) == index) + battery_update(index); +} + +void battery_memmap_set_index(enum battery_index index) +{ + if (*host_get_memmap(EC_MEMMAP_BATT_INDEX) == index) + return; + + *host_get_memmap(EC_MEMMAP_BATT_INDEX) = BATT_IDX_INVALID; + if (index < 0 || index >= CONFIG_BATTERY_COUNT) + return; + + battery_update(index); + *host_get_memmap(EC_MEMMAP_BATT_INDEX) = index; +} + +static void battery_init(void) +{ + *host_get_memmap(EC_MEMMAP_BATT_INDEX) = BATT_IDX_INVALID; + *host_get_memmap(EC_MEMMAP_BATT_COUNT) = CONFIG_BATTERY_COUNT; + *host_get_memmap(EC_MEMMAP_BATTERY_VERSION) = 2; + + battery_memmap_set_index(BATT_IDX_MAIN); +} +DECLARE_HOOK(HOOK_INIT, battery_init, HOOK_PRIO_DEFAULT); +#endif /* HAS_TASK_HOSTCMD */ + +static int is_battery_string_reliable(const char *buf) +{ + /* + * From is_string_printable rule, 0xFF is not printable. + * So, EC should think battery string is unreliable if string + * include 0xFF. + */ + while (*buf) { + if ((*buf) == 0xFF) + return 0; + buf++; + } + + return 1; +} + +int update_static_battery_info(void) +{ + int batt_serial; + int val; + /* + * The return values have type enum ec_error_list, but EC_SUCCESS is + * zero. We'll just look for any failures so we can try them all again. + */ + int rv, ret; + + struct ec_response_battery_static_info_v1 *const bs = + &battery_static[BATT_IDX_MAIN]; + + /* Clear all static information. */ + memset(bs, 0, sizeof(*bs)); + + /* Smart battery serial number is 16 bits */ + rv = battery_serial_number(&batt_serial); + if (!rv) + snprintf(bs->serial_ext, sizeof(bs->serial_ext), + "%04X", batt_serial); + + /* Design Capacity of Full */ + ret = battery_design_capacity(&val); + if (!ret) + bs->design_capacity = val; + rv |= ret; + + /* Design Voltage */ + ret = battery_design_voltage(&val); + if (!ret) + bs->design_voltage = val; + rv |= ret; + + /* Cycle Count */ + ret = battery_cycle_count(&val); + if (!ret) + bs->cycle_count = val; + rv |= ret; + + /* Battery Manufacturer string */ + rv |= battery_manufacturer_name(bs->manufacturer_ext, + sizeof(bs->manufacturer_ext)); + + /* Battery Model string */ + rv |= battery_device_name(bs->model_ext, sizeof(bs->model_ext)); + + /* Battery Type string */ + rv |= battery_device_chemistry(bs->type_ext, sizeof(bs->type_ext)); + + /* + * b/181639264: Battery gauge follow SMBus SPEC and SMBus define + * cumulative clock low extend time for both controller (master) and + * peripheral (slave). However, I2C doesn't. + * Regarding this issue, we observe EC sometimes pull I2C CLK low + * a while after EC start running. Actually, we are not sure the + * reason until now. + * If EC pull I2C CLK low too long, and it may cause battery fw timeout + * because battery count cumulative clock extend time over 25ms. + * When it happened, battery will release both its CLK and DATA and + * reset itself. So, EC may get 0xFF when EC keep reading data from + * battery. Battery static information will be unreliable and need to + * be updated. + * This change is improvement that EC should retry if battery string is + * unreliable. + */ + if (!is_battery_string_reliable(bs->serial_ext) || + !is_battery_string_reliable(bs->manufacturer_ext) || + !is_battery_string_reliable(bs->model_ext) || + !is_battery_string_reliable(bs->type_ext)) + rv |= EC_ERROR_UNKNOWN; + + /* Zero the dynamic entries. They'll come next. */ + memset(&battery_dynamic[BATT_IDX_MAIN], 0, + sizeof(battery_dynamic[BATT_IDX_MAIN])); + + if (rv) + charge_problem(PR_STATIC_UPDATE, rv); + +#ifdef HAS_TASK_HOSTCMD + battery_memmap_refresh(BATT_IDX_MAIN); +#endif + + return rv; +} + +void update_dynamic_battery_info(void) +{ + static int batt_present; + uint8_t tmp; + int send_batt_status_event = 0; + int send_batt_info_event = 0; + struct charge_state_data *curr; + struct ec_response_battery_dynamic_info *const bd = + &battery_dynamic[BATT_IDX_MAIN]; + + curr = charge_get_status(); + tmp = 0; + if (curr->ac) + tmp |= EC_BATT_FLAG_AC_PRESENT; + + if (curr->batt.is_present == BP_YES) { + tmp |= EC_BATT_FLAG_BATT_PRESENT; + batt_present = 1; + /* Tell the AP to read battery info if it is newly present. */ + if (!(bd->flags & EC_BATT_FLAG_BATT_PRESENT)) + send_batt_info_event++; + } else { + /* + * Require two consecutive updates with BP_NOT_SURE + * before reporting it gone to the host. + */ + if (batt_present) + tmp |= EC_BATT_FLAG_BATT_PRESENT; + else if (bd->flags & EC_BATT_FLAG_BATT_PRESENT) + send_batt_info_event++; + batt_present = 0; + } + + if (curr->batt.flags & EC_BATT_FLAG_INVALID_DATA) + tmp |= EC_BATT_FLAG_INVALID_DATA; + + if (!(curr->batt.flags & BATT_FLAG_BAD_VOLTAGE)) + bd->actual_voltage = curr->batt.voltage; + + if (!(curr->batt.flags & BATT_FLAG_BAD_CURRENT)) + bd->actual_current = curr->batt.current; + + if (!(curr->batt.flags & BATT_FLAG_BAD_DESIRED_VOLTAGE)) + bd->desired_voltage = curr->batt.desired_voltage; + + if (!(curr->batt.flags & BATT_FLAG_BAD_DESIRED_CURRENT)) + bd->desired_current = curr->batt.desired_current; + + if (!(curr->batt.flags & BATT_FLAG_BAD_REMAINING_CAPACITY)) { + /* + * If we're running off the battery, it must have some charge. + * Don't report zero charge, as that has special meaning + * to Chrome OS powerd. + */ + if (curr->batt.remaining_capacity == 0 && + !curr->batt_is_charging) + bd->remaining_capacity = 1; + else + bd->remaining_capacity = curr->batt.remaining_capacity; + } + + if (!(curr->batt.flags & BATT_FLAG_BAD_FULL_CAPACITY) && + (curr->batt.full_capacity <= + (bd->full_capacity - LFCC_EVENT_THRESH) || + curr->batt.full_capacity >= + (bd->full_capacity + LFCC_EVENT_THRESH))) { + bd->full_capacity = curr->batt.full_capacity; + /* Poke the AP if the full_capacity changes. */ + send_batt_info_event++; + } + + if (curr->batt.is_present == BP_YES && + !(curr->batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) && + curr->batt.state_of_charge <= BATTERY_LEVEL_CRITICAL) + tmp |= EC_BATT_FLAG_LEVEL_CRITICAL; + + tmp |= curr->batt_is_charging ? EC_BATT_FLAG_CHARGING : + EC_BATT_FLAG_DISCHARGING; + + /* Tell the AP to re-read battery status if charge state changes */ + if (bd->flags != tmp) + send_batt_status_event++; + + bd->flags = tmp; + +#ifdef HAS_TASK_HOSTCMD + battery_memmap_refresh(BATT_IDX_MAIN); +#endif + +#ifdef CONFIG_HOSTCMD_EVENTS + if (send_batt_info_event) + host_set_single_event(EC_HOST_EVENT_BATTERY); + if (send_batt_status_event) + host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS); +#endif +} diff --git a/common/build.mk b/common/build.mk index 4135b58800..67217be550 100644 --- a/common/build.mk +++ b/common/build.mk @@ -46,6 +46,8 @@ common-$(CONFIG_BASE32)+=base32.o common-$(CONFIG_BLINK)+=blink.o common-$(CONFIG_DETACHABLE_BASE)+=base_state.o common-$(CONFIG_BATTERY)+=battery.o math_util.o +common-$(CONFIG_BATTERY_V1)+=battery_v1.o +common-$(CONFIG_BATTERY_V2)+=battery_v2.o common-$(CONFIG_BATTERY_FUEL_GAUGE)+=battery_fuel_gauge.o common-$(CONFIG_BLUETOOTH_LE)+=bluetooth_le.o common-$(CONFIG_BLUETOOTH_LE_STACK)+=btle_hci_controller.o btle_ll.o diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index e767ec8d83..abb271cad4 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -44,7 +44,6 @@ #define CRITICAL_BATTERY_SHUTDOWN_TIMEOUT_US \ (CONFIG_BATTERY_CRITICAL_SHUTDOWN_TIMEOUT * SECOND) #define PRECHARGE_TIMEOUT_US (PRECHARGE_TIMEOUT * SECOND) -#define LFCC_EVENT_THRESH 5 /* Full-capacity change reqd for host event */ #ifdef CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT #ifndef CONFIG_HOSTCMD_EVENTS @@ -156,21 +155,6 @@ static int problems_exist; static int debugging; -/* Track problems in communicating with the battery or charger */ -enum problem_type { - PR_STATIC_UPDATE, - PR_SET_VOLTAGE, - PR_SET_CURRENT, - PR_SET_MODE, - PR_SET_INPUT_CURR, - PR_POST_INIT, - PR_CHG_FLAGS, - PR_BATT_FLAGS, - PR_CUSTOM, - PR_CFG_SEC_CHG, - - NUM_PROBLEM_TYPES -}; static const char * const prob_text[] = { "static update", "set voltage", @@ -189,7 +173,7 @@ BUILD_ASSERT(ARRAY_SIZE(prob_text) == NUM_PROBLEM_TYPES); * TODO(crosbug.com/p/27639): When do we decide a problem is real and not * just intermittent? And what do we do about it? */ -static void problem(enum problem_type p, int v) +void charge_problem(enum problem_type p, int v) { static int last_prob_val[NUM_PROBLEM_TYPES]; static timestamp_t last_prob_time[NUM_PROBLEM_TYPES]; @@ -770,357 +754,6 @@ static void charge_allocate_input_current_limit(void) } #endif /* CONFIG_EC_EC_COMM_BATTERY_CLIENT */ -#ifndef CONFIG_BATTERY_V2 -/* Returns zero if every item was updated. */ -static int update_static_battery_info(void) -{ - char *batt_str; - int batt_serial; - uint8_t batt_flags = 0; - /* - * The return values have type enum ec_error_list, but EC_SUCCESS is - * zero. We'll just look for any failures so we can try them all again. - */ - int rv; - - /* Smart battery serial number is 16 bits */ - batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_SERIAL); - memset(batt_str, 0, EC_MEMMAP_TEXT_MAX); - rv = battery_serial_number(&batt_serial); - if (!rv) - snprintf(batt_str, EC_MEMMAP_TEXT_MAX, "%04X", batt_serial); - - /* Design Capacity of Full */ - rv |= battery_design_capacity( - (int *)host_get_memmap(EC_MEMMAP_BATT_DCAP)); - - /* Design Voltage */ - rv |= battery_design_voltage( - (int *)host_get_memmap(EC_MEMMAP_BATT_DVLT)); - - /* Last Full Charge Capacity (this is only mostly static) */ - rv |= battery_full_charge_capacity( - (int *)host_get_memmap(EC_MEMMAP_BATT_LFCC)); - - /* Cycle Count */ - rv |= battery_cycle_count((int *)host_get_memmap(EC_MEMMAP_BATT_CCNT)); - - /* Battery Manufacturer string */ - batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MFGR); - memset(batt_str, 0, EC_MEMMAP_TEXT_MAX); - rv |= battery_manufacturer_name(batt_str, EC_MEMMAP_TEXT_MAX); - - /* Battery Model string */ - batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_MODEL); - memset(batt_str, 0, EC_MEMMAP_TEXT_MAX); - rv |= battery_device_name(batt_str, EC_MEMMAP_TEXT_MAX); - - /* Battery Type string */ - batt_str = (char *)host_get_memmap(EC_MEMMAP_BATT_TYPE); - rv |= battery_device_chemistry(batt_str, EC_MEMMAP_TEXT_MAX); - - /* Zero the dynamic entries. They'll come next. */ - *(int *)host_get_memmap(EC_MEMMAP_BATT_VOLT) = 0; - *(int *)host_get_memmap(EC_MEMMAP_BATT_RATE) = 0; - *(int *)host_get_memmap(EC_MEMMAP_BATT_CAP) = 0; - *(int *)host_get_memmap(EC_MEMMAP_BATT_LFCC) = 0; - if (extpower_is_present()) - batt_flags |= EC_BATT_FLAG_AC_PRESENT; - *host_get_memmap(EC_MEMMAP_BATT_FLAG) = batt_flags; - - if (rv) - problem(PR_STATIC_UPDATE, rv); - else - /* No errors seen. Battery data is now present */ - *host_get_memmap(EC_MEMMAP_BATTERY_VERSION) = 1; - - return rv; -} - -static void update_dynamic_battery_info(void) -{ - /* The memmap address is constant. We should fix these calls somehow. */ - int *memmap_volt = (int *)host_get_memmap(EC_MEMMAP_BATT_VOLT); - int *memmap_rate = (int *)host_get_memmap(EC_MEMMAP_BATT_RATE); - int *memmap_cap = (int *)host_get_memmap(EC_MEMMAP_BATT_CAP); - int *memmap_lfcc = (int *)host_get_memmap(EC_MEMMAP_BATT_LFCC); - uint8_t *memmap_flags = host_get_memmap(EC_MEMMAP_BATT_FLAG); - uint8_t tmp; - int send_batt_status_event = 0; - int send_batt_info_event = 0; - static int batt_present; - - tmp = 0; - if (curr.ac) - tmp |= EC_BATT_FLAG_AC_PRESENT; - - if (curr.batt.is_present == BP_YES) { - tmp |= EC_BATT_FLAG_BATT_PRESENT; - batt_present = 1; - /* Tell the AP to read battery info if it is newly present. */ - if (!(*memmap_flags & EC_BATT_FLAG_BATT_PRESENT)) - send_batt_info_event++; - } else { - /* - * Require two consecutive updates with BP_NOT_SURE - * before reporting it gone to the host. - */ - if (batt_present) - tmp |= EC_BATT_FLAG_BATT_PRESENT; - else if (*memmap_flags & EC_BATT_FLAG_BATT_PRESENT) - send_batt_info_event++; - batt_present = 0; - } - - if (curr.batt.flags & EC_BATT_FLAG_INVALID_DATA) - tmp |= EC_BATT_FLAG_INVALID_DATA; - - if (!(curr.batt.flags & BATT_FLAG_BAD_VOLTAGE)) - *memmap_volt = curr.batt.voltage; - - if (!(curr.batt.flags & BATT_FLAG_BAD_CURRENT)) - *memmap_rate = ABS(curr.batt.current); - - if (!(curr.batt.flags & BATT_FLAG_BAD_REMAINING_CAPACITY)) { - /* - * If we're running off the battery, it must have some charge. - * Don't report zero charge, as that has special meaning - * to Chrome OS powerd. - */ - if (curr.batt.remaining_capacity == 0 && !curr.batt_is_charging) - *memmap_cap = 1; - else - *memmap_cap = curr.batt.remaining_capacity; - } - - if (!(curr.batt.flags & BATT_FLAG_BAD_FULL_CAPACITY) && - (curr.batt.full_capacity <= (*memmap_lfcc - LFCC_EVENT_THRESH) || - curr.batt.full_capacity >= (*memmap_lfcc + LFCC_EVENT_THRESH))) { - *memmap_lfcc = curr.batt.full_capacity; - /* Poke the AP if the full_capacity changes. */ - send_batt_info_event++; - } - - if (curr.batt.is_present == BP_YES && - !(curr.batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) && - curr.batt.state_of_charge <= BATTERY_LEVEL_CRITICAL) - tmp |= EC_BATT_FLAG_LEVEL_CRITICAL; - - tmp |= curr.batt_is_charging ? EC_BATT_FLAG_CHARGING : - EC_BATT_FLAG_DISCHARGING; - - /* Tell the AP to re-read battery status if charge state changes */ - if (*memmap_flags != tmp) - send_batt_status_event++; - - /* Update flags before sending host events. */ - *memmap_flags = tmp; - - if (send_batt_info_event) - host_set_single_event(EC_HOST_EVENT_BATTERY); - if (send_batt_status_event) - host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS); -} -#else /* CONFIG_BATTERY_V2 */ - -static int is_battery_string_reliable(const char *buf) -{ - /* - * From is_string_printable rule, 0xFF is not printable. - * So, EC should think battery string is unreliable if string - * include 0xFF. - */ - while (*buf) { - if ((*buf) == 0xFF) - return 0; - buf++; - } - - return 1; -} - -static int update_static_battery_info(void) -{ - int batt_serial; - int val; - /* - * The return values have type enum ec_error_list, but EC_SUCCESS is - * zero. We'll just look for any failures so we can try them all again. - */ - int rv, ret; - - struct ec_response_battery_static_info_v1 *const bs = - &battery_static[BATT_IDX_MAIN]; - - /* Clear all static information. */ - memset(bs, 0, sizeof(*bs)); - - /* Smart battery serial number is 16 bits */ - rv = battery_serial_number(&batt_serial); - if (!rv) - snprintf(bs->serial_ext, sizeof(bs->serial_ext), - "%04X", batt_serial); - - /* Design Capacity of Full */ - ret = battery_design_capacity(&val); - if (!ret) - bs->design_capacity = val; - rv |= ret; - - /* Design Voltage */ - ret = battery_design_voltage(&val); - if (!ret) - bs->design_voltage = val; - rv |= ret; - - /* Cycle Count */ - ret = battery_cycle_count(&val); - if (!ret) - bs->cycle_count = val; - rv |= ret; - - /* Battery Manufacturer string */ - rv |= battery_manufacturer_name(bs->manufacturer_ext, - sizeof(bs->manufacturer_ext)); - - /* Battery Model string */ - rv |= battery_device_name(bs->model_ext, sizeof(bs->model_ext)); - - /* Battery Type string */ - rv |= battery_device_chemistry(bs->type_ext, sizeof(bs->type_ext)); - - /* - * b/181639264: Battery gauge follow SMBus SPEC and SMBus define - * cumulative clock low extend time for both controller (master) and - * peripheral (slave). However, I2C doesn't. - * Regarding this issue, we observe EC sometimes pull I2C CLK low - * a while after EC start running. Actually, we are not sure the - * reason until now. - * If EC pull I2C CLK low too long, and it may cause battery fw timeout - * because battery count cumulative clock extend time over 25ms. - * When it happened, battery will release both its CLK and DATA and - * reset itself. So, EC may get 0xFF when EC keep reading data from - * battery. Battery static information will be unreliable and need to - * be updated. - * This change is improvement that EC should retry if battery string is - * unreliable. - */ - if (!is_battery_string_reliable(bs->serial_ext) || - !is_battery_string_reliable(bs->manufacturer_ext) || - !is_battery_string_reliable(bs->model_ext) || - !is_battery_string_reliable(bs->type_ext)) - rv |= EC_ERROR_UNKNOWN; - - /* Zero the dynamic entries. They'll come next. */ - memset(&battery_dynamic[BATT_IDX_MAIN], 0, - sizeof(battery_dynamic[BATT_IDX_MAIN])); - - if (rv) - problem(PR_STATIC_UPDATE, rv); - -#ifdef HAS_TASK_HOSTCMD - battery_memmap_refresh(BATT_IDX_MAIN); -#endif - - return rv; -} - -static void update_dynamic_battery_info(void) -{ - static int batt_present; - uint8_t tmp; - int send_batt_status_event = 0; - int send_batt_info_event = 0; - - struct ec_response_battery_dynamic_info *const bd = - &battery_dynamic[BATT_IDX_MAIN]; - - tmp = 0; - if (curr.ac) - tmp |= EC_BATT_FLAG_AC_PRESENT; - - if (curr.batt.is_present == BP_YES) { - tmp |= EC_BATT_FLAG_BATT_PRESENT; - batt_present = 1; - /* Tell the AP to read battery info if it is newly present. */ - if (!(bd->flags & EC_BATT_FLAG_BATT_PRESENT)) - send_batt_info_event++; - } else { - /* - * Require two consecutive updates with BP_NOT_SURE - * before reporting it gone to the host. - */ - if (batt_present) - tmp |= EC_BATT_FLAG_BATT_PRESENT; - else if (bd->flags & EC_BATT_FLAG_BATT_PRESENT) - send_batt_info_event++; - batt_present = 0; - } - - if (curr.batt.flags & EC_BATT_FLAG_INVALID_DATA) - tmp |= EC_BATT_FLAG_INVALID_DATA; - - if (!(curr.batt.flags & BATT_FLAG_BAD_VOLTAGE)) - bd->actual_voltage = curr.batt.voltage; - - if (!(curr.batt.flags & BATT_FLAG_BAD_CURRENT)) - bd->actual_current = curr.batt.current; - - if (!(curr.batt.flags & BATT_FLAG_BAD_DESIRED_VOLTAGE)) - bd->desired_voltage = curr.batt.desired_voltage; - - if (!(curr.batt.flags & BATT_FLAG_BAD_DESIRED_CURRENT)) - bd->desired_current = curr.batt.desired_current; - - if (!(curr.batt.flags & BATT_FLAG_BAD_REMAINING_CAPACITY)) { - /* - * If we're running off the battery, it must have some charge. - * Don't report zero charge, as that has special meaning - * to Chrome OS powerd. - */ - if (curr.batt.remaining_capacity == 0 && !curr.batt_is_charging) - bd->remaining_capacity = 1; - else - bd->remaining_capacity = curr.batt.remaining_capacity; - } - - if (!(curr.batt.flags & BATT_FLAG_BAD_FULL_CAPACITY) && - (curr.batt.full_capacity <= - (bd->full_capacity - LFCC_EVENT_THRESH) || - curr.batt.full_capacity >= - (bd->full_capacity + LFCC_EVENT_THRESH))) { - bd->full_capacity = curr.batt.full_capacity; - /* Poke the AP if the full_capacity changes. */ - send_batt_info_event++; - } - - if (curr.batt.is_present == BP_YES && - !(curr.batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) && - curr.batt.state_of_charge <= BATTERY_LEVEL_CRITICAL) - tmp |= EC_BATT_FLAG_LEVEL_CRITICAL; - - tmp |= curr.batt_is_charging ? EC_BATT_FLAG_CHARGING : - EC_BATT_FLAG_DISCHARGING; - - /* Tell the AP to re-read battery status if charge state changes */ - if (bd->flags != tmp) - send_batt_status_event++; - - bd->flags = tmp; - -#ifdef HAS_TASK_HOSTCMD - battery_memmap_refresh(BATT_IDX_MAIN); -#endif - -#ifdef CONFIG_HOSTCMD_EVENTS - if (send_batt_info_event) - host_set_single_event(EC_HOST_EVENT_BATTERY); - if (send_batt_status_event) - host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS); -#endif -} -#endif /* CONFIG_BATTERY_V2 */ - static const char * const state_list[] = { "idle", "discharge", "charge", "precharge" }; @@ -1352,12 +985,12 @@ static int charge_request(int voltage, int current) r2 = charger_set_current(0, current); } if (r2 != EC_SUCCESS) - problem(PR_SET_CURRENT, r2); + charge_problem(PR_SET_CURRENT, r2); if (voltage >= 0) r1 = charger_set_voltage(0, voltage); if (r1 != EC_SUCCESS) - problem(PR_SET_VOLTAGE, r1); + charge_problem(PR_SET_VOLTAGE, r1); #ifdef CONFIG_OCPC /* @@ -1374,7 +1007,7 @@ static int charge_request(int voltage, int current) &curr.ocpc, voltage, current); if (r3 != EC_SUCCESS) - problem(PR_CFG_SEC_CHG, r3); + charge_problem(PR_CFG_SEC_CHG, r3); } #endif /* CONFIG_OCPC */ @@ -1387,7 +1020,7 @@ static int charge_request(int voltage, int current) else r4 = charger_set_mode(CHARGE_FLAG_INHIBIT_CHARGE); if (r4 != EC_SUCCESS) - problem(PR_SET_MODE, r4); + charge_problem(PR_SET_MODE, r4); /* * Only update if the request worked, so we'll keep trying on failures. @@ -1688,6 +1321,11 @@ const struct batt_params *charger_current_battery_params(void) return &curr.batt; } +struct charge_state_data *charge_get_status(void) +{ + return &curr; +} + /* Determine if the battery is outside of allowable temperature range */ static int battery_outside_charging_temperature(void) { @@ -2014,14 +1652,15 @@ void charger_task(void *u) int rv = charger_post_init(); if (rv != EC_SUCCESS) { - problem(PR_POST_INIT, rv); + charge_problem(PR_POST_INIT, rv); } else if (curr.desired_input_current != CHARGE_CURRENT_UNINITIALIZED) { rv = charger_set_input_current_limit( chgnum, curr.desired_input_current); if (rv != EC_SUCCESS) - problem(PR_SET_INPUT_CURR, rv); + charge_problem( + PR_SET_INPUT_CURR, rv); } if (rv == EC_SUCCESS) @@ -2109,9 +1748,9 @@ void charger_task(void *u) * better then flag it as an error. */ if (curr.chg.flags & CHG_FLAG_BAD_ANY) - problem(PR_CHG_FLAGS, curr.chg.flags); + charge_problem(PR_CHG_FLAGS, curr.chg.flags); if (curr.batt.flags & BATT_FLAG_BAD_ANY) - problem(PR_BATT_FLAGS, curr.batt.flags); + charge_problem(PR_BATT_FLAGS, curr.batt.flags); /* * If AC is present, check if input current is sufficient to @@ -2167,7 +1806,7 @@ wait_for_it: && get_chg_ctrl_mode() == CHARGE_CONTROL_NORMAL) { sleep_usec = charger_profile_override(&curr); if (sleep_usec < 0) - problem(PR_CUSTOM, sleep_usec); + charge_problem(PR_CUSTOM, sleep_usec); } if (IS_ENABLED(CONFIG_BATTERY_CHECK_CHARGE_TEMP_LIMITS) |