summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/battery_v2.c16
-rw-r--r--include/ec_commands.h26
-rw-r--r--util/ectool.cc148
3 files changed, 158 insertions, 32 deletions
diff --git a/common/battery_v2.c b/common/battery_v2.c
index 57ae07196b..9096cbb72c 100644
--- a/common/battery_v2.c
+++ b/common/battery_v2.c
@@ -129,6 +129,20 @@ host_command_battery_get_static(struct host_cmd_handler_args *args)
r->type_ext[sizeof(r->type_ext) - 1] = 0;
args->response_size = sizeof(*r);
+ } else if (args->version == 2) {
+ struct ec_response_battery_static_info_v2 *r = args->response;
+
+ r->design_capacity = bs->design_capacity;
+ r->design_voltage = bs->design_voltage;
+ r->cycle_count = bs->cycle_count;
+
+ strzcpy(r->manufacturer, bs->manufacturer_ext,
+ sizeof(r->manufacturer));
+ strzcpy(r->device_name, bs->model_ext, sizeof(r->device_name));
+ strzcpy(r->serial, bs->serial_ext, sizeof(r->serial));
+ strzcpy(r->chemistry, bs->type_ext, sizeof(r->chemistry));
+
+ args->response_size = sizeof(*r);
} else {
return EC_RES_INVALID_VERSION;
}
@@ -136,7 +150,7 @@ host_command_battery_get_static(struct host_cmd_handler_args *args)
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));
+ EC_VER_MASK(0) | EC_VER_MASK(1) | EC_VER_MASK(2));
static enum ec_status
host_command_battery_get_dynamic(struct host_cmd_handler_args *args)
diff --git a/include/ec_commands.h b/include/ec_commands.h
index acb502ca99..5b76f369bc 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -7667,6 +7667,32 @@ struct ec_response_battery_static_info_v1 {
char type_ext[12];
} __ec_align4;
+/**
+ * struct ec_response_battery_static_info_v2 - hostcmd v2 battery static info
+ *
+ * Equivalent to struct ec_response_battery_static_info, but with strings
+ * further lengthened (relative to v1) to accommodate the maximum string length
+ * permitted by the Smart Battery Data Specification revision 1.1 and fields
+ * renamed to better match that specification.
+ *
+ * @design_capacity: battery design capacity (in mAh)
+ * @design_voltage: battery design voltage (in mV)
+ * @cycle_count: battery cycle count
+ * @manufacturer: battery manufacturer string
+ * @device_name: battery model string
+ * @serial: battery serial number string
+ * @chemistry: battery type string
+ */
+struct ec_response_battery_static_info_v2 {
+ uint16_t design_capacity;
+ uint16_t design_voltage;
+ uint32_t cycle_count;
+ char manufacturer[32];
+ char device_name[32];
+ char serial[32];
+ char chemistry[32];
+} __ec_align4;
+
/*
* Get battery dynamic information, i.e. information that is likely to change
* every time it is read.
diff --git a/util/ectool.cc b/util/ectool.cc
index c116b35fcc..213de566b8 100644
--- a/util/ectool.cc
+++ b/util/ectool.cc
@@ -8035,64 +8035,59 @@ void print_battery_flags(int flags)
printf("\n");
}
-int get_battery_command(int index)
+static int get_battery_command_print_info(
+ uint8_t index,
+ const struct ec_response_battery_static_info_v2 *const static_r)
{
- struct ec_params_battery_static_info static_p;
- struct ec_response_battery_static_info_v1 static_r;
- struct ec_params_battery_dynamic_info dynamic_p;
+ struct ec_params_battery_dynamic_info dynamic_p = {
+ .index = index,
+ };
struct ec_response_battery_dynamic_info dynamic_r;
int rv;
- printf("Battery %d info:\n", index);
-
- static_p.index = index;
- rv = ec_command(EC_CMD_BATTERY_GET_STATIC, 1, &static_p,
- sizeof(static_p), &static_r, sizeof(static_r));
- if (rv < 0)
- return -1;
-
- dynamic_p.index = index;
rv = ec_command(EC_CMD_BATTERY_GET_DYNAMIC, 0, &dynamic_p,
sizeof(dynamic_p), &dynamic_r, sizeof(dynamic_r));
if (rv < 0)
return -1;
+ printf("Battery %d info:\n", index);
+
if (dynamic_r.flags & EC_BATT_FLAG_INVALID_DATA) {
printf(" Invalid data (not present?)\n");
return -1;
}
- if (!is_string_printable(static_r.manufacturer_ext))
+ if (!is_string_printable(static_r->manufacturer))
goto cmd_error;
- printf(" OEM name: %s\n", static_r.manufacturer_ext);
+ printf(" OEM name: %s\n", static_r->manufacturer);
- if (!is_string_printable(static_r.model_ext))
+ if (!is_string_printable(static_r->device_name))
goto cmd_error;
- printf(" Model number: %s\n", static_r.model_ext);
+ printf(" Model number: %s\n", static_r->device_name);
- if (!is_string_printable(static_r.type_ext))
+ if (!is_string_printable(static_r->chemistry))
goto cmd_error;
- printf(" Chemistry : %s\n", static_r.type_ext);
+ printf(" Chemistry : %s\n", static_r->chemistry);
- if (!is_string_printable(static_r.serial_ext))
+ if (!is_string_printable(static_r->serial))
goto cmd_error;
- printf(" Serial number: %s\n", static_r.serial_ext);
+ printf(" Serial number: %s\n", static_r->serial);
- if (!is_battery_range(static_r.design_capacity))
+ if (!is_battery_range(static_r->design_capacity))
goto cmd_error;
- printf(" Design capacity: %u mAh\n", static_r.design_capacity);
+ printf(" Design capacity: %u mAh\n", static_r->design_capacity);
if (!is_battery_range(dynamic_r.full_capacity))
goto cmd_error;
printf(" Last full charge: %u mAh\n", dynamic_r.full_capacity);
- if (!is_battery_range(static_r.design_voltage))
+ if (!is_battery_range(static_r->design_voltage))
goto cmd_error;
- printf(" Design output voltage %u mV\n", static_r.design_voltage);
+ printf(" Design output voltage %u mV\n", static_r->design_voltage);
- if (!is_battery_range(static_r.cycle_count))
+ if (!is_battery_range(static_r->cycle_count))
goto cmd_error;
- printf(" Cycle count %u\n", static_r.cycle_count);
+ printf(" Cycle count %u\n", static_r->cycle_count);
if (!is_battery_range(dynamic_r.actual_voltage))
goto cmd_error;
@@ -8122,6 +8117,89 @@ cmd_error:
return -1;
}
+static int get_battery_command_v2(uint8_t index)
+{
+ struct ec_params_battery_static_info static_p = {
+ .index = index,
+ };
+ struct ec_response_battery_static_info_v2 static_r;
+ int rv;
+
+ rv = ec_command(EC_CMD_BATTERY_GET_STATIC, 2, &static_p,
+ sizeof(static_p), &static_r, sizeof(static_r));
+ if (rv < 0) {
+ fprintf(stderr, "CMD_BATTERY_GET_STATIC v2 failed: %d\n", rv);
+ return -1;
+ }
+
+ return get_battery_command_print_info(index, &static_r);
+}
+
+static int get_battery_command_v1(uint8_t index)
+{
+ struct ec_params_battery_static_info static_p {
+ .index = index,
+ };
+ struct ec_response_battery_static_info_v1 static_r;
+ int rv;
+
+ rv = ec_command(EC_CMD_BATTERY_GET_STATIC, 1, &static_p,
+ sizeof(static_p), &static_r, sizeof(static_r));
+ if (rv < 0) {
+ fprintf(stderr, "CMD_BATTERY_GET_STATIC v1 failed: %d\n", rv);
+ return -1;
+ }
+
+ /* Translate v1 response into v2 to display it */
+ struct ec_response_battery_static_info_v2 static_v2 = {
+ .design_capacity = static_r.design_capacity,
+ .design_voltage = static_r.design_voltage,
+ .cycle_count = static_r.cycle_count,
+ };
+ strncpy(static_v2.manufacturer, static_r.manufacturer_ext,
+ sizeof(static_v2.manufacturer) - 1);
+ strncpy(static_v2.device_name, static_r.model_ext,
+ sizeof(static_v2.device_name) - 1);
+ strncpy(static_v2.serial, static_r.serial_ext,
+ sizeof(static_v2.serial) - 1);
+ strncpy(static_v2.chemistry, static_r.type_ext,
+ sizeof(static_v2.chemistry) - 1);
+
+ return get_battery_command_print_info(index, &static_v2);
+}
+static int get_battery_command_v0(uint8_t index)
+{
+ struct ec_params_battery_static_info static_p = {
+ .index = index,
+ };
+ struct ec_response_battery_static_info static_r;
+ int rv;
+
+ rv = ec_command(EC_CMD_BATTERY_GET_STATIC, 0, &static_p,
+ sizeof(static_p), &static_r, sizeof(static_r));
+ if (rv < 0) {
+ fprintf(stderr, "CMD_BATTERY_GET_STATIC v0 failed: %d\n", rv);
+ return -1;
+ }
+
+ /* Translate v0 response into v2 to display it */
+ struct ec_response_battery_static_info_v2 static_v2 = {
+ .design_capacity = static_r.design_capacity,
+ .design_voltage = static_r.design_voltage,
+ .cycle_count = static_r.cycle_count,
+ };
+ strncpy(static_v2.manufacturer, static_r.manufacturer,
+ sizeof(static_v2.manufacturer) - 1);
+ strncpy(static_v2.device_name, static_r.model,
+ sizeof(static_v2.device_name) - 1);
+ strncpy(static_v2.serial, static_r.serial,
+ sizeof(static_v2.serial) - 1);
+ strncpy(static_v2.chemistry, static_r.type,
+ sizeof(static_v2.chemistry) - 1);
+
+ return get_battery_command_print_info(index, &static_v2);
+}
+
int cmd_battery(int argc, char *argv[])
{
char batt_text[EC_MEMMAP_TEXT_MAX];
@@ -8142,11 +8220,19 @@ int cmd_battery(int argc, char *argv[])
}
/*
- * Read non-primary batteries through hostcmd, and all batteries
- * if longer strings are supported for static info.
+ * Prefer to use newer hostcmd versions if supported because these allow
+ * us to read longer strings, and always use hostcmd for non-primary
+ * batteries because memmap doesn't export that data.
*/
- if (index > 0 || ec_cmd_version_supported(EC_CMD_BATTERY_GET_STATIC, 1))
- return get_battery_command(index);
+ uint32_t versions;
+ ec_get_cmd_versions(EC_CMD_BATTERY_GET_STATIC, &versions);
+
+ if (versions & EC_VER_MASK(2))
+ return get_battery_command_v2(index);
+ else if (versions & EC_VER_MASK(1))
+ return get_battery_command_v1(index);
+ else if (index > 0)
+ return get_battery_command_v0(index);
val = read_mapped_mem8(EC_MEMMAP_BATTERY_VERSION);
if (val < 1) {