summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/battery.c28
-rw-r--r--common/charge_state_v2.c100
-rw-r--r--common/ec_ec_comm_master.c16
-rw-r--r--common/ec_ec_comm_slave.c15
-rw-r--r--include/battery.h14
-rw-r--r--include/config.h28
-rw-r--r--include/ec_ec_comm_master.h19
-rw-r--r--include/ec_ec_comm_slave.h4
8 files changed, 126 insertions, 98 deletions
diff --git a/common/battery.c b/common/battery.c
index 65a375c02e..711d7f7913 100644
--- a/common/battery.c
+++ b/common/battery.c
@@ -21,6 +21,15 @@
#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
+#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 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
@@ -433,21 +442,20 @@ DECLARE_HOST_COMMAND(EC_CMD_BATTERY_VENDOR_PARAM,
EC_VER_MASK(0));
#endif /* CONFIG_BATTERY_VENDOR_PARAM */
-#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER
-/*
- * TODO(b:65697620): Add support for returning main battery information through
- * these commands, as well.
- */
+#ifdef CONFIG_HOSTCMD_BATTERY_V2
+#ifndef CONFIG_BATTERY_V2
+#error "CONFIG_HOSTCMD_BATTERY_V2 cannot be set without CONFIG_BATTERY_V2."
+#endif
static int 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 *r = args->response;
- if (p->index != 1)
+ if (p->index < 0 || p->index >= CONFIG_BATTERY_COUNT)
return EC_RES_INVALID_PARAM;
args->response_size = sizeof(*r);
- memcpy(r, &base_battery_static, sizeof(*r));
+ memcpy(r, &battery_static[p->index], sizeof(*r));
return EC_RES_SUCCESS;
}
@@ -460,15 +468,15 @@ static int 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 != 1)
+ if (p->index < 0 || p->index >= CONFIG_BATTERY_COUNT)
return EC_RES_INVALID_PARAM;
args->response_size = sizeof(*r);
- memcpy(r, &base_battery_dynamic, 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_EC_EC_COMM_BATTERY */
+#endif /* CONFIG_HOSTCMD_BATTERY_V2 */
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index d4ab11ca8b..608e1e92e9 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -219,13 +219,15 @@ static const struct dual_battery_policy db_policy = {
static int charge_get_base_percent(void)
{
- if (base_battery_dynamic.flags & (BATT_FLAG_BAD_FULL_CAPACITY |
- BATT_FLAG_BAD_REMAINING_CAPACITY))
+ const struct ec_response_battery_dynamic_info *const bd =
+ &battery_dynamic[BATT_IDX_BASE];
+
+ if (bd->flags & (BATT_FLAG_BAD_FULL_CAPACITY |
+ BATT_FLAG_BAD_REMAINING_CAPACITY))
return -1;
- if (base_battery_dynamic.full_capacity > 0)
- return 100 * base_battery_dynamic.remaining_capacity
- / base_battery_dynamic.full_capacity;
+ if (bd->full_capacity > 0)
+ return 100 * bd->remaining_capacity / bd->full_capacity;
return 0;
}
@@ -396,6 +398,10 @@ static void charge_allocate_input_current_limit(void)
int charge_lid = charge_get_percent();
+ const struct ec_response_battery_dynamic_info *const base_bd =
+ &battery_dynamic[BATT_IDX_BASE];
+
+
if (!base_connected) {
set_base_lid_current(0, 0, curr.desired_input_current, 1);
prev_base_battery_power = -1;
@@ -480,11 +486,11 @@ static void charge_allocate_input_current_limit(void)
lid_battery_power = MIN(lid_battery_power, lid_battery_power_max);
/* Estimate base battery power. */
- if (!(base_battery_dynamic.flags & EC_BATT_FLAG_INVALID_DATA)) {
- base_battery_power = base_battery_dynamic.actual_current *
- base_battery_dynamic.actual_voltage / 1000;
- base_battery_power_max = base_battery_dynamic.desired_current *
- base_battery_dynamic.desired_voltage / 1000;
+ if (!(base_bd->flags & EC_BATT_FLAG_INVALID_DATA)) {
+ base_battery_power = base_bd->actual_current *
+ base_bd->actual_voltage / 1000;
+ base_battery_power_max = base_bd->desired_current *
+ base_bd->desired_voltage / 1000;
}
if (base_battery_power < prev_base_battery_power)
base_battery_power = smooth_value(prev_base_battery_power,
@@ -548,7 +554,7 @@ static void charge_allocate_input_current_limit(void)
}
#endif /* CONFIG_EC_EC_COMM_BATTERY_MASTER */
-#ifdef HAS_TASK_HOSTCMD
+#ifndef CONFIG_BATTERY_V2
/* Returns zero if every item was updated. */
static int update_static_battery_info(void)
{
@@ -696,12 +702,7 @@ static void update_dynamic_battery_info(void)
if (send_batt_status_event)
host_set_single_event(EC_HOST_EVENT_BATTERY_STATUS);
}
-#elif defined(CONFIG_EC_EC_COMM_BATTERY_SLAVE)
-/*
- * TODO(b:65697620): Make this depend on a separate config option instead, so
- * that, even on systems that would typically use memmap, we can decide to use
- * these structures, and pass battery information via a host command instead.
- */
+#else /* CONFIG_BATTERY_V2 */
static int update_static_battery_info(void)
{
int batt_serial;
@@ -712,48 +713,48 @@ static int update_static_battery_info(void)
*/
int rv, ret;
+ struct ec_response_battery_static_info *const bs =
+ &battery_static[BATT_IDX_MAIN];
+
/* Clear all static information. */
- memset(&base_battery_static, 0, sizeof(base_battery_static));
+ memset(bs, 0, sizeof(*bs));
/* Smart battery serial number is 16 bits */
rv = battery_serial_number(&batt_serial);
if (!rv)
- snprintf(base_battery_static.serial,
- sizeof(base_battery_static.serial),
- "%04X", batt_serial);
+ snprintf(bs->serial, sizeof(bs->serial), "%04X", batt_serial);
/* Design Capacity of Full */
ret = battery_design_capacity(&val);
if (!ret)
- base_battery_static.design_capacity = val;
+ bs->design_capacity = val;
rv |= ret;
/* Design Voltage */
ret = battery_design_voltage(&val);
if (!ret)
- base_battery_static.design_voltage = val;
+ bs->design_voltage = val;
rv |= ret;
/* Cycle Count */
ret = battery_cycle_count(&val);
if (!ret)
- base_battery_static.cycle_count = val;
+ bs->cycle_count = val;
rv |= ret;
/* Battery Manufacturer string */
- rv |= battery_manufacturer_name(base_battery_static.manufacturer,
- sizeof(base_battery_static.manufacturer));
+ rv |= battery_manufacturer_name(bs->manufacturer,
+ sizeof(bs->manufacturer));
/* Battery Model string */
- rv |= battery_device_name(base_battery_static.model,
- sizeof(base_battery_static.model));
+ rv |= battery_device_name(bs->model, sizeof(bs->model));
/* Battery Type string */
- rv |= battery_device_chemistry(base_battery_static.type,
- sizeof(base_battery_static.type));
+ rv |= battery_device_chemistry(bs->type, sizeof(bs->type));
/* Zero the dynamic entries. They'll come next. */
- memset(&base_battery_dynamic, 0, sizeof(base_battery_dynamic));
+ memset(&battery_dynamic[BATT_IDX_MAIN], 0,
+ sizeof(battery_dynamic[BATT_IDX_MAIN]));
if (rv)
problem(PR_STATIC_UPDATE, rv);
@@ -771,6 +772,9 @@ static void update_dynamic_battery_info(void)
static int __bss_slow batt_present;
uint8_t tmp;
+ struct ec_response_battery_dynamic_info *const bd =
+ &battery_dynamic[BATT_IDX_MAIN];
+
tmp = 0;
if (curr.ac)
tmp |= EC_BATT_FLAG_AC_PRESENT;
@@ -792,18 +796,16 @@ static void update_dynamic_battery_info(void)
tmp |= EC_BATT_FLAG_INVALID_DATA;
if (!(curr.batt.flags & BATT_FLAG_BAD_VOLTAGE))
- base_battery_dynamic.actual_voltage = curr.batt.voltage;
+ bd->actual_voltage = curr.batt.voltage;
if (!(curr.batt.flags & BATT_FLAG_BAD_CURRENT))
- base_battery_dynamic.actual_current = curr.batt.current;
+ bd->actual_current = curr.batt.current;
if (!(curr.batt.flags & BATT_FLAG_BAD_DESIRED_VOLTAGE))
- base_battery_dynamic.desired_voltage =
- curr.batt.desired_voltage;
+ bd->desired_voltage = curr.batt.desired_voltage;
if (!(curr.batt.flags & BATT_FLAG_BAD_DESIRED_CURRENT))
- base_battery_dynamic.desired_current =
- curr.batt.desired_current;
+ bd->desired_current = curr.batt.desired_current;
if (!(curr.batt.flags & BATT_FLAG_BAD_REMAINING_CAPACITY)) {
/*
@@ -812,18 +814,17 @@ static void update_dynamic_battery_info(void)
* to Chrome OS powerd.
*/
if (curr.batt.remaining_capacity == 0 && !curr.batt_is_charging)
- base_battery_dynamic.remaining_capacity = 1;
+ bd->remaining_capacity = 1;
else
- base_battery_dynamic.remaining_capacity =
- curr.batt.remaining_capacity;
+ bd->remaining_capacity = curr.batt.remaining_capacity;
}
if (!(curr.batt.flags & BATT_FLAG_BAD_FULL_CAPACITY) &&
(curr.batt.full_capacity <=
- (base_battery_dynamic.full_capacity - LFCC_EVENT_THRESH) ||
+ (bd->full_capacity - LFCC_EVENT_THRESH) ||
curr.batt.full_capacity >=
- (base_battery_dynamic.full_capacity + LFCC_EVENT_THRESH))) {
- base_battery_dynamic.full_capacity = curr.batt.full_capacity;
+ (bd->full_capacity + LFCC_EVENT_THRESH))) {
+ bd->full_capacity = curr.batt.full_capacity;
}
if (curr.batt.is_present == BP_YES &&
@@ -834,9 +835,9 @@ static void update_dynamic_battery_info(void)
tmp |= curr.batt_is_charging ? EC_BATT_FLAG_CHARGING :
EC_BATT_FLAG_DISCHARGING;
- base_battery_dynamic.flags = tmp;
+ bd->flags = tmp;
}
-#endif
+#endif /* CONFIG_BATTERY_V2 */
static const char * const state_list[] = {
"idle", "discharge", "charge", "precharge"
@@ -1238,7 +1239,7 @@ void charger_task(void *u)
#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER
base_responsive = 0;
curr.input_voltage = CHARGE_VOLTAGE_UNINITIALIZED;
- base_battery_dynamic.flags = EC_BATT_FLAG_INVALID_DATA;
+ battery_dynamic[BATT_IDX_BASE].flags = EC_BATT_FLAG_INVALID_DATA;
charge_base = -1;
#endif
@@ -1302,18 +1303,19 @@ void charger_task(void *u)
if (!base_connected) {
/* Invalidate static/dynamic information */
- base_battery_dynamic.flags = EC_BATT_FLAG_INVALID_DATA;
+ battery_dynamic[BATT_IDX_BASE].flags =
+ EC_BATT_FLAG_INVALID_DATA;
charge_base = -1;
base_responsive = 0;
prev_current_base = 0;
prev_allow_charge_base = 0;
} else if (base_responsive) {
- int old_flags = base_battery_dynamic.flags;
+ int old_flags = battery_dynamic[BATT_IDX_BASE].flags;
ec_ec_master_base_get_dynamic_info();
/* Fetch static information when flags change. */
- if (old_flags != base_battery_dynamic.flags)
+ if (old_flags != battery_dynamic[BATT_IDX_BASE].flags)
ec_ec_master_base_get_static_info();
charge_base = charge_get_base_percent();
diff --git a/common/ec_ec_comm_master.c b/common/ec_ec_comm_master.c
index 9a742ea40b..a30be6d329 100644
--- a/common/ec_ec_comm_master.c
+++ b/common/ec_ec_comm_master.c
@@ -5,6 +5,7 @@
* EC-EC communication, functions and definitions for master.
*/
+#include "battery.h"
#include "common.h"
#include "console.h"
#include "crc8.h"
@@ -18,13 +19,6 @@
#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
/*
- * TODO(b:65697620): Move these to some the second position of some battery
- * array, depending on a config option.
- */
-struct ec_response_battery_static_info base_battery_static;
-struct ec_response_battery_dynamic_info base_battery_dynamic;
-
-/*
* TODO(b:65697962): The packed structures below do not play well if we force EC
* host commands structures to be aligned on 32-bit boundary. There are ways to
* fix that, possibly requiring copying data around, or modifying
@@ -281,8 +275,8 @@ int ec_ec_master_base_get_dynamic_info(void)
CPRINTF("I-desired: %d mA\n", data.resp.info.desired_current);
#endif
- memcpy(&base_battery_dynamic, &data.resp.info,
- sizeof(base_battery_dynamic));
+ memcpy(&battery_dynamic[BATT_IDX_BASE], &data.resp.info,
+ sizeof(battery_dynamic[BATT_IDX_BASE]));
return EC_RES_SUCCESS;
}
@@ -321,8 +315,8 @@ int ec_ec_master_base_get_static_info(void)
CPRINTF("C-count: %d\n", data.resp.info.cycle_count);
#endif
- memcpy(&base_battery_static, &data.resp.info,
- sizeof(base_battery_static));
+ memcpy(&battery_static[BATT_IDX_BASE], &data.resp.info,
+ sizeof(battery_static[BATT_IDX_BASE]));
return EC_RES_SUCCESS;
}
diff --git a/common/ec_ec_comm_slave.c b/common/ec_ec_comm_slave.c
index c9696a52d4..91687bb79a 100644
--- a/common/ec_ec_comm_slave.c
+++ b/common/ec_ec_comm_slave.c
@@ -26,13 +26,6 @@
/* Print extra debugging information */
#undef EXTRA_DEBUG
-/*
- * TODO(b:65697620): Move these to some other C file, depending on a config
- * option.
- */
-struct ec_response_battery_static_info base_battery_static;
-struct ec_response_battery_dynamic_info base_battery_dynamic;
-
/* Set if the master allows the slave to charge the battery. */
static int charging_allowed;
@@ -274,14 +267,14 @@ void ec_ec_comm_slave_task(void *u)
case EC_CMD_BATTERY_GET_STATIC:
/* Note that we ignore the battery index parameter. */
write_response(EC_RES_SUCCESS, seq,
- &base_battery_static,
- sizeof(base_battery_static));
+ &battery_static[BATT_IDX_MAIN],
+ sizeof(battery_static[BATT_IDX_MAIN]));
break;
case EC_CMD_BATTERY_GET_DYNAMIC:
/* Note that we ignore the battery index parameter. */
write_response(EC_RES_SUCCESS, seq,
- &base_battery_dynamic,
- sizeof(base_battery_dynamic));
+ &battery_dynamic[BATT_IDX_MAIN],
+ sizeof(battery_dynamic[BATT_IDX_MAIN]));
break;
case EC_CMD_CHARGER_CONTROL: {
handle_cmd_charger_control((void *)params,
diff --git a/include/battery.h b/include/battery.h
index 43425fcd8c..b783432ded 100644
--- a/include/battery.h
+++ b/include/battery.h
@@ -9,6 +9,20 @@
#define __CROS_EC_BATTERY_H
#include "common.h"
+#include "host_command.h"
+
+/* Battery index, only used with CONFIG_BATTERY_V2. */
+enum battery_index {
+ BATT_IDX_MAIN,
+ BATT_IDX_BASE,
+};
+
+#ifdef CONFIG_BATTERY_V2
+extern struct ec_response_battery_static_info
+ battery_static[CONFIG_BATTERY_COUNT];
+extern struct ec_response_battery_dynamic_info
+ battery_dynamic[CONFIG_BATTERY_COUNT];
+#endif
/* Stop charge when charging and battery level >= this percentage */
#define BATTERY_LEVEL_FULL 100
diff --git a/include/config.h b/include/config.h
index 243b51ca33..f091694ec1 100644
--- a/include/config.h
+++ b/include/config.h
@@ -335,6 +335,23 @@
#undef CONFIG_BATTERY_LEVEL_NEAR_FULL
/*
+ * Use an alternative method to store battery information: Instead of writing
+ * directly to host memory mapped region, this keeps the battery information in
+ * ec_response_battery_static/dynamic_info structures, that can then be fetched
+ * using host commands, or via EC_ACPI_MEM_BATTERY_INDEX command, which tells
+ * the EC to update the shared memory.
+ *
+ * This is required on dual-battery systems, and on on hostless bases with a
+ * battery.
+ */
+#undef CONFIG_BATTERY_V2
+
+/*
+ * Number of batteries, only matters when CONFIG_BATTERY_V2 is used.
+ */
+#undef CONFIG_BATTERY_COUNT
+
+/*
* Expose some data when it is needed.
* For example, battery disconnect state
*/
@@ -1546,6 +1563,13 @@
*/
#undef CONFIG_HOSTCMD_ALIGNED
+/*
+ * Include host commands to fetch battery information from
+ * ec_response_battery_static/dynamic_info structures, only makes sense when
+ * CONFIG_BATTERY_V2 is enabled.
+ */
+#undef CONFIG_HOSTCMD_BATTERY_V2
+
/* Default hcdebug mode, e.g. HCDEBUG_OFF or HCDEBUG_NORMAL */
#define CONFIG_HOSTCMD_DEBUG_MODE HCDEBUG_NORMAL
@@ -3303,10 +3327,14 @@
#ifdef CONFIG_EC_EC_COMM_BATTERY
#ifdef CONFIG_EC_EC_COMM_MASTER
#define CONFIG_EC_EC_COMM_BATTERY_MASTER
+#define CONFIG_BATTERY_V2
+#define CONFIG_BATTERY_COUNT 2
#endif
#ifdef CONFIG_EC_EC_COMM_SLAVE
#define CONFIG_EC_EC_COMM_BATTERY_SLAVE
+#define CONFIG_BATTERY_V2
+#define CONFIG_BATTERY_COUNT 1
#endif
#endif /* CONFIG_EC_EC_COMM_BATTERY */
diff --git a/include/ec_ec_comm_master.h b/include/ec_ec_comm_master.h
index 98b8011b95..adaf564c65 100644
--- a/include/ec_ec_comm_master.h
+++ b/include/ec_ec_comm_master.h
@@ -11,19 +11,12 @@
#include <stdint.h>
#include "config.h"
-/*
- * TODO(b:65697620): Move these to some other C file, depending on a config
- * option.
- */
-extern struct ec_response_battery_static_info base_battery_static;
-extern struct ec_response_battery_dynamic_info base_battery_dynamic;
-
/**
* Sends EC_CMD_BATTERY_GET_DYNAMIC command to slave, and writes the
- * battery dynamic information into base_battery_dynamic.
+ * battery dynamic information into battery_dynamic[BATT_IDX_BASE].
*
- * Leaves base_battery_dynamic intact on error: it is the callers responsability
- * to clear the data or ignore it.
+ * Leaves battery_dynamic[BATT_IDX_BASE] intact on error: it is the callers
+ * responsibility to clear the data or ignore it.
* @return EC_RES_SUCCESS on success, EC_RES_ERROR on communication error,
* else forwards the error code from the slave.
@@ -32,10 +25,10 @@ int ec_ec_master_base_get_dynamic_info(void);
/**
* Sends EC_CMD_BATTERY_GET_STATIC command to slave, and writes the
- * battery static information into base_static_dynamic.
+ * battery static information into battery_static[BATT_IDX_BASE].
*
- * Leaves base_battery_static intact on error: it is the callers responsability
- * to clear the data or ignore it.
+ * Leaves battery_static[BATT_IDX_BASE] intact on error: it is the callers
+ * responsibility to clear the data or ignore it.
*
* @return EC_RES_SUCCESS on success, EC_RES_ERROR on communication error,
* else forwards the error code from the slave.
diff --git a/include/ec_ec_comm_slave.h b/include/ec_ec_comm_slave.h
index e3501400e2..19e1912d94 100644
--- a/include/ec_ec_comm_slave.h
+++ b/include/ec_ec_comm_slave.h
@@ -12,10 +12,6 @@
#include "consumer.h"
#include "queue.h"
-/* TODO(b:65697620): Move these to battery.h, depending on a config option. */
-extern struct ec_response_battery_static_info base_battery_static;
-extern struct ec_response_battery_dynamic_info base_battery_dynamic;
-
extern struct queue const ec_ec_comm_slave_input;
extern struct queue const ec_ec_comm_slave_output;