summaryrefslogtreecommitdiff
path: root/common/battery.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /common/battery.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14633.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'common/battery.c')
-rw-r--r--common/battery.c812
1 files changed, 0 insertions, 812 deletions
diff --git a/common/battery.c b/common/battery.c
deleted file mode 100644
index 6791e4d3a2..0000000000
--- a/common/battery.c
+++ /dev/null
@@ -1,812 +0,0 @@
-/* Copyright 2012 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.
- *
- * Common battery command.
- */
-
-#include "battery.h"
-#include "charge_manager.h"
-#include "charge_state.h"
-#include "common.h"
-#include "console.h"
-#include "ec_ec_comm_client.h"
-#include "extpower.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "math_util.h"
-#include "timer.h"
-#include "usb_pd.h"
-#include "util.h"
-#include "watchdog.h"
-
-#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
-#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
-#define CUTOFFPRINTS(info) CPRINTS("%s %s", "Battery cut off", info)
-
-/* See config.h for details */
-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
-#define CONFIG_BATTERY_CUTOFF_DELAY_US (1 * SECOND)
-#endif
-
-static enum battery_cutoff_states battery_cutoff_state =
- BATTERY_CUTOFF_STATE_NORMAL;
-
-#endif
-
-#ifdef CONFIG_BATTERY_PRESENT_GPIO
-#ifdef CONFIG_BATTERY_PRESENT_CUSTOM
-#error "Don't define both CONFIG_BATTERY_PRESENT_CUSTOM and" \
- "CONFIG_BATTERY_PRESENT_GPIO"
-#endif
-/**
- * Physical detection of battery.
- */
-enum battery_present battery_is_present(void)
-{
- /* The GPIO is low when the battery is present */
- return gpio_get_level(CONFIG_BATTERY_PRESENT_GPIO) ? BP_NO : BP_YES;
-}
-#endif
-
-static const char *get_error_text(int rv)
-{
- if (rv == EC_ERROR_UNIMPLEMENTED)
- return "(unsupported)";
- else
- return "(error)";
-}
-
-static void print_item_name(const char *name)
-{
- ccprintf(" %-11s", name);
-}
-
-static int check_print_error(int rv)
-{
- if (rv != EC_SUCCESS)
- ccprintf("%s\n", get_error_text(rv));
- return rv == EC_SUCCESS;
-}
-
-static void print_battery_status(void)
-{
- static const char * const st[] = {"EMPTY", "FULL", "DCHG", "INIT",};
- static const char * const al[] = {"RT", "RC", "--", "TD",
- "OT", "--", "TC", "OC"};
-
- int value, i;
-
- print_item_name("Status:");
- if (check_print_error(battery_status(&value))) {
- ccprintf("0x%04x", value);
-
- /* bits 0-3 are only valid when the previous transaction
- * failed, so ignore them */
-
- /* bits 4-7 are status */
- for (i = 0; i < 4; i++)
- if (value & (1 << (i+4)))
- ccprintf(" %s", st[i]);
-
- /* bits 15-8 are alarms */
- for (i = 0; i < 8; i++)
- if (value & (1 << (i+8)))
- ccprintf(" %s", al[i]);
-
- ccprintf("\n");
- }
-}
-
-static void print_battery_strings(void)
-{
- char text[32];
-
- print_item_name("Manuf:");
- if (check_print_error(battery_manufacturer_name(text, sizeof(text))))
- ccprintf("%s\n", text);
-
- print_item_name("Device:");
- if (check_print_error(battery_device_name(text, sizeof(text))))
- ccprintf("%s\n", text);
-
- print_item_name("Chem:");
- if (check_print_error(battery_device_chemistry(text, sizeof(text))))
- ccprintf("%s\n", text);
-}
-
-static void print_battery_params(void)
-{
-#if defined(HAS_TASK_CHARGER)
- /* Ask charger so that we don't need to ask battery again. */
- const struct batt_params *batt = charger_current_battery_params();
-#else
- /* This is for test code, where doesn't have charger task. */
- struct batt_params _batt;
- const struct batt_params *batt = &_batt;
-
- battery_get_params(&_batt);
-#endif
-
- print_item_name("Param flags:");
- ccprintf("%08x\n", batt->flags);
-
- print_item_name("Temp:");
- ccprintf("0x%04x = %.1d K (%.1d C)\n",
- batt->temperature,
- batt->temperature,
- batt->temperature - 2731);
-
- print_item_name("V:");
- ccprintf("0x%04x = %d mV\n", batt->voltage, batt->voltage);
-
- print_item_name("V-desired:");
- ccprintf("0x%04x = %d mV\n", batt->desired_voltage,
- batt->desired_voltage);
-
- print_item_name("I:");
- ccprintf("0x%04x = %d mA", batt->current & 0xffff, batt->current);
- if (batt->current > 0)
- ccputs("(CHG)");
- else if (batt->current < 0)
- ccputs("(DISCHG)");
- ccputs("\n");
-
- print_item_name("I-desired:");
- ccprintf("0x%04x = %d mA\n", batt->desired_current,
- batt->desired_current);
-
- print_item_name("Charging:");
- ccprintf("%sAllowed\n",
- batt->flags & BATT_FLAG_WANT_CHARGE ? "" : "Not ");
-
- print_item_name("Charge:");
- ccprintf("%d %%\n", batt->state_of_charge);
-
- if (IS_ENABLED(CONFIG_CHARGER)) {
- int value;
-
- print_item_name(" Display:");
- value = charge_get_display_charge();
- ccprintf("%d.%d %%\n", value / 10, value % 10);
- }
-}
-
-static void print_battery_info(void)
-{
- int value;
- int hour, minute;
-
- print_item_name("Serial:");
- if (check_print_error(battery_serial_number(&value)))
- ccprintf("0x%04x\n", value);
-
- print_item_name("V-design:");
- if (check_print_error(battery_design_voltage(&value)))
- ccprintf("0x%04x = %d mV\n", value, value);
-
- print_item_name("Mode:");
- if (check_print_error(battery_get_mode(&value)))
- ccprintf("0x%04x\n", value);
-
- print_item_name("Abs charge:");
- if (check_print_error(battery_state_of_charge_abs(&value)))
- ccprintf("%d %%\n", value);
-
- print_item_name("Remaining:");
- if (check_print_error(battery_remaining_capacity(&value)))
- ccprintf("%d mAh\n", value);
-
- print_item_name("Cap-full:");
- if (check_print_error(battery_full_charge_capacity(&value)))
- ccprintf("%d mAh\n", value);
-
- print_item_name(" Design:");
- if (check_print_error(battery_design_capacity(&value)))
- ccprintf("%d mAh\n", value);
-
- print_item_name("Time-full:");
- if (check_print_error(battery_time_to_full(&value))) {
- if (value == 65535) {
- hour = 0;
- minute = 0;
- } else {
- hour = value / 60;
- minute = value % 60;
- }
- ccprintf("%dh:%d\n", hour, minute);
- }
-
- print_item_name(" Empty:");
- if (check_print_error(battery_time_to_empty(&value))) {
- if (value == 65535) {
- hour = 0;
- minute = 0;
- } else {
- hour = value / 60;
- minute = value % 60;
- }
- ccprintf("%dh:%d\n", hour, minute);
- }
-
- print_item_name("full_factor:");
- ccprintf("0.%d\n", batt_host_full_factor);
-
- print_item_name("shutdown_soc:");
- ccprintf("%d %%\n", batt_host_shutdown_pct);
-}
-
-void print_battery_debug(void)
-{
- print_battery_status();
- print_battery_params();
- print_battery_strings();
- print_battery_info();
-}
-
-static int command_battery(int argc, char **argv)
-{
- int repeat = 1;
- int loop;
- int sleep_ms = 0;
- char *e;
-
- if (argc > 1) {
- repeat = strtoi(argv[1], &e, 0);
- if (*e) {
- ccputs("Invalid repeat count\n");
- return EC_ERROR_INVAL;
- }
- }
-
- if (argc > 2) {
- sleep_ms = strtoi(argv[2], &e, 0);
- if (*e) {
- ccputs("Invalid sleep ms\n");
- return EC_ERROR_INVAL;
- }
- }
-
- for (loop = 0; loop < repeat; loop++) {
- print_battery_debug();
-
- /*
- * Running with a high repeat count will take so long the
- * watchdog timer fires. So reset the watchdog timer each
- * iteration.
- */
- watchdog_reload();
-
- if (sleep_ms)
- msleep(sleep_ms);
- }
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(battery, command_battery,
- "<repeat_count> <sleep_ms>",
- "Print battery info");
-
-#ifdef CONFIG_BATTERY_CUT_OFF
-int battery_is_cut_off(void)
-{
- return (battery_cutoff_state == BATTERY_CUTOFF_STATE_CUT_OFF);
-}
-
-static void pending_cutoff_deferred(void)
-{
- int rv;
-
- rv = board_cut_off_battery();
-
- if (rv == EC_RES_SUCCESS) {
- CUTOFFPRINTS("succeeded.");
- battery_cutoff_state = BATTERY_CUTOFF_STATE_CUT_OFF;
- } else {
- CUTOFFPRINTS("failed!");
- battery_cutoff_state = BATTERY_CUTOFF_STATE_NORMAL;
- }
-}
-DECLARE_DEFERRED(pending_cutoff_deferred);
-
-static void clear_pending_cutoff(void)
-{
- if (extpower_is_present()) {
- battery_cutoff_state = BATTERY_CUTOFF_STATE_NORMAL;
- hook_call_deferred(&pending_cutoff_deferred_data, -1);
- }
-}
-DECLARE_HOOK(HOOK_AC_CHANGE, clear_pending_cutoff, HOOK_PRIO_DEFAULT);
-
-static enum ec_status battery_command_cutoff(struct host_cmd_handler_args *args)
-{
- const struct ec_params_battery_cutoff *p;
- int rv;
-
- if (args->version == 1) {
- p = args->params;
- if (p->flags & EC_BATTERY_CUTOFF_FLAG_AT_SHUTDOWN) {
- battery_cutoff_state = BATTERY_CUTOFF_STATE_PENDING;
- CUTOFFPRINTS("at-shutdown is scheduled");
- return EC_RES_SUCCESS;
- }
- }
-
- rv = board_cut_off_battery();
- if (rv == EC_RES_SUCCESS) {
- CUTOFFPRINTS("is successful.");
- battery_cutoff_state = BATTERY_CUTOFF_STATE_CUT_OFF;
- } else {
- CUTOFFPRINTS("has failed.");
- }
-
- return rv;
-}
-DECLARE_HOST_COMMAND(EC_CMD_BATTERY_CUT_OFF, battery_command_cutoff,
- EC_VER_MASK(0) | EC_VER_MASK(1));
-
-static void check_pending_cutoff(void)
-{
- if (battery_cutoff_state == BATTERY_CUTOFF_STATE_PENDING) {
- CPRINTS("Cutting off battery in %d second(s)",
- CONFIG_BATTERY_CUTOFF_DELAY_US / SECOND);
- hook_call_deferred(&pending_cutoff_deferred_data,
- CONFIG_BATTERY_CUTOFF_DELAY_US);
- }
-}
-DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, check_pending_cutoff, HOOK_PRIO_LAST);
-
-static int command_cutoff(int argc, char **argv)
-{
- int rv;
-
- if (argc > 1) {
- if (!strcasecmp(argv[1], "at-shutdown")) {
- battery_cutoff_state = BATTERY_CUTOFF_STATE_PENDING;
- return EC_SUCCESS;
- } else {
- return EC_ERROR_INVAL;
- }
- }
-
- rv = board_cut_off_battery();
- if (rv == EC_RES_SUCCESS) {
- ccprints("Battery cut off");
- battery_cutoff_state = BATTERY_CUTOFF_STATE_CUT_OFF;
- return EC_SUCCESS;
- }
-
- return EC_ERROR_UNKNOWN;
-}
-DECLARE_CONSOLE_COMMAND(cutoff, command_cutoff,
- "[at-shutdown]",
- "Cut off the battery output");
-#else
-int battery_is_cut_off(void)
-{
- return 0; /* Always return NOT cut off */
-}
-#endif /* CONFIG_BATTERY_CUT_OFF */
-
-#ifdef CONFIG_BATTERY_VENDOR_PARAM
-static int console_command_battery_vendor_param(int argc, char **argv)
-{
- uint32_t param;
- uint32_t value;
- char *e;
- int rv;
-
- if (argc < 2)
- return EC_ERROR_INVAL;
-
- param = strtoi(argv[1], &e, 0);
- if (*e) {
- ccputs("Invalid param\n");
- return EC_ERROR_INVAL;
- }
-
- if (argc > 2) {
- value = strtoi(argv[2], &e, 0);
- if (*e) {
- ccputs("Invalid value\n");
- return EC_ERROR_INVAL;
- }
- rv = battery_set_vendor_param(param, value);
- if (rv != EC_SUCCESS)
- return rv;
- }
-
- rv = battery_get_vendor_param(param, &value);
- if (rv != EC_SUCCESS)
- return rv;
-
- ccprintf("0x%08x\n", value);
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(battparam, console_command_battery_vendor_param,
- "<param> [value]",
- "Get or set battery vendor parameters");
-
-static enum ec_status
-host_command_battery_vendor_param(struct host_cmd_handler_args *args)
-{
- int rv;
- const struct ec_params_battery_vendor_param *p = args->params;
- struct ec_response_battery_vendor_param *r = args->response;
-
- args->response_size = sizeof(*r);
-
- if (p->mode != BATTERY_VENDOR_PARAM_MODE_GET &&
- p->mode != BATTERY_VENDOR_PARAM_MODE_SET)
- return EC_RES_INVALID_PARAM;
-
- if (p->mode == BATTERY_VENDOR_PARAM_MODE_SET) {
- rv = battery_set_vendor_param(p->param, p->value);
- if (rv != EC_SUCCESS)
- return rv;
- }
-
- rv = battery_get_vendor_param(p->param, &r->value);
- return rv;
-}
-DECLARE_HOST_COMMAND(EC_CMD_BATTERY_VENDOR_PARAM,
- host_command_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)
-{
- int numer, denom;
- int *remain = &(batt->remaining_capacity);
- int full = batt->full_capacity;
-
- if ((batt->flags & BATT_FLAG_BAD_FULL_CAPACITY) ||
- (batt->flags & BATT_FLAG_BAD_REMAINING_CAPACITY))
- return;
-
- if (*remain <= 0 || full <= 0)
- return;
-
- /* Some batteries don't update full capacity as often. */
- if (*remain > full)
- *remain = full;
-
- /*
- * EC calculates the display SoC like how Powerd used to do. Powerd
- * reads the display SoC from the EC. This design allows the system to
- * behave consistently on a single SoC value across all power states.
- *
- * Display SoC is computed as follows:
- *
- * actual_soc = 100 * remain / full
- *
- * actual_soc - shutdown_pct
- * display_soc = --------------------------- x 1000
- * full_factor - shutdown_pct
- *
- * (100 * remain / full) - shutdown_pct
- * = ------------------------------------ x 1000
- * full_factor - shutdown_pct
- *
- * 100 x remain - full x shutdown_pct
- * = ----------------------------------- x 1000
- * full x (full_factor - shutdown_pct)
- */
- numer = 1000 * ((100 * *remain) - (full * batt_host_shutdown_pct));
- denom = full * (batt_host_full_factor - batt_host_shutdown_pct);
- /* Rounding (instead of truncating) */
- batt->display_charge = (numer + denom / 2) / denom;
- if (batt->display_charge < 0)
- batt->display_charge = 0;
- if (batt->display_charge > 1000)
- batt->display_charge = 1000;
-}
-
-#ifdef CONFIG_CHARGER
-static enum ec_status battery_display_soc(struct host_cmd_handler_args *args)
-{
- struct ec_response_display_soc *r = args->response;
-
- r->display_soc = charge_get_display_charge();
- r->full_factor = batt_host_full_factor * 10;
- r->shutdown_soc = batt_host_shutdown_pct * 10;
- args->response_size = sizeof(*r);
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_DISPLAY_SOC, battery_display_soc, EC_VER_MASK(0));
-#endif
-
-__overridable void board_battery_compensate_params(struct batt_params *batt)
-{
-}
-
-__attribute__((weak)) int get_battery_manufacturer_name(char *dest, int size)
-{
- strzcpy(dest, "<unkn>", size);
- return EC_SUCCESS;
-}
-
-__overridable int battery_get_avg_voltage(void)
-{
- return -EC_ERROR_UNIMPLEMENTED;
-}
-
-__overridable int battery_get_avg_current(void)
-{
- return -EC_ERROR_UNIMPLEMENTED;
-}
-
-int battery_manufacturer_name(char *dest, int size)
-{
- return get_battery_manufacturer_name(dest, size);
-}
-
-__overridable enum battery_disconnect_state battery_get_disconnect_state(void)
-{
- return BATTERY_NOT_DISCONNECTED;
-}
-
-#ifdef CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV
-
-#if CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV < 5000 || \
- CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV >= PD_MAX_VOLTAGE_MV
- #error "Voltage limit must be between 5000 and PD_MAX_VOLTAGE_MV"
-#endif
-
-#if !((defined(CONFIG_USB_PD_TCPMV1) && defined(CONFIG_USB_PD_DUAL_ROLE)) || \
- (defined(CONFIG_USB_PD_TCPMV2) && defined(CONFIG_USB_PE_SM)))
- #error "Voltage reducing requires TCPM with Policy Engine"
-#endif
-
-/*
- * Returns true if input voltage should be reduced (chipset is in S5/G3) and
- * battery is full, otherwise returns false
- */
-static bool board_wants_reduced_input_voltage(void) {
- struct batt_params batt;
-
- /* Chipset not in S5/G3, so we don't want to reduce voltage */
- if (!chipset_in_or_transitioning_to_state(CHIPSET_STATE_ANY_OFF))
- return false;
-
- battery_get_params(&batt);
-
- /* Battery needs charge, so we don't want to reduce voltage */
- if (batt.flags & BATT_FLAG_WANT_CHARGE)
- return false;
-
- return true;
-}
-
-static void reduce_input_voltage_when_full(void)
-{
- static int saved_input_voltage = -1;
- int max_pd_voltage_mv = pd_get_max_voltage();
- int port;
-
- port = charge_manager_get_active_charge_port();
- if (port < 0 || port >= board_get_usb_pd_port_count())
- return;
-
- if (board_wants_reduced_input_voltage()) {
- /*
- * Board wants voltage to be reduced. Apply limit if current
- * voltage is different. Save current voltage, it will be
- * restored when board wants to stop reducing input voltage.
- */
- if (max_pd_voltage_mv !=
- CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV) {
- saved_input_voltage = max_pd_voltage_mv;
- max_pd_voltage_mv =
- CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV;
- }
- } else if (saved_input_voltage != -1) {
- /*
- * Board doesn't want to reduce input voltage. If current
- * voltage is reduced we will restore previously saved voltage.
- * If current voltage is different we will respect newer value.
- */
- if (max_pd_voltage_mv ==
- CONFIG_BATT_FULL_CHIPSET_OFF_INPUT_LIMIT_MV)
- max_pd_voltage_mv = saved_input_voltage;
-
- saved_input_voltage = -1;
- }
-
- if (pd_get_max_voltage() != max_pd_voltage_mv)
- pd_set_external_voltage_limit(port, max_pd_voltage_mv);
-}
-DECLARE_HOOK(HOOK_AC_CHANGE, reduce_input_voltage_when_full,
- HOOK_PRIO_DEFAULT);
-DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, reduce_input_voltage_when_full,
- HOOK_PRIO_DEFAULT);
-DECLARE_HOOK(HOOK_CHIPSET_STARTUP, reduce_input_voltage_when_full,
- HOOK_PRIO_DEFAULT);
-DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, reduce_input_voltage_when_full,
- HOOK_PRIO_DEFAULT);
-#endif
-
-void battery_validate_params(struct batt_params *batt)
-{
- /*
- * TODO(crosbug.com/p/27527). Sometimes the battery thinks its
- * temperature is 6280C, which seems a bit high. Let's ignore
- * anything above the boiling point of tungsten until this bug
- * is fixed. If the battery is really that warm, we probably
- * have more urgent problems.
- */
- if (batt->temperature > CELSIUS_TO_DECI_KELVIN(5660)) {
- CPRINTS("ignoring ridiculous batt.temp of %dC",
- DECI_KELVIN_TO_CELSIUS(batt->temperature));
- batt->flags |= BATT_FLAG_BAD_TEMPERATURE;
- }
-
- /* If the battery thinks it's above 100%, don't believe it */
- if (batt->state_of_charge > 100) {
- CPRINTS("ignoring ridiculous batt.soc of %d%%",
- batt->state_of_charge);
- batt->flags |= BATT_FLAG_BAD_STATE_OF_CHARGE;
- }
-}