mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-07 16:11:43 +00:00
The smart battery status register holds some useful info. This displays it along with all the other stuff. This decodes the alarm and status bits, but not the error code, since that field is only valid immediately after a failed i2c transaction (that's how the battery indicates error). Since we do all sorts of automatic battery probing in other threads, that value will never be reliable when we run the "battery" console command. BUG=none BRANCH=none TEST=manual Run "battery". You should see a new line amongst the output: Status: 0x00c0 DCHG INIT Change-Id: I5e684198af2cf7767f89786c91a7d946ad95d4c2 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/175659
220 lines
5.0 KiB
C
220 lines
5.0 KiB
C
/* Copyright (c) 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 "console.h"
|
|
#include "timer.h"
|
|
#include "util.h"
|
|
#include "watchdog.h"
|
|
|
|
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 int print_battery_info(void)
|
|
{
|
|
int value;
|
|
int hour, minute;
|
|
char text[32];
|
|
const char *unit;
|
|
|
|
print_item_name("Status:");
|
|
if (check_print_error(battery_status(&value))) {
|
|
const char * const st[] = {"EMPTY", "FULL", "DCHG", "INIT",};
|
|
const char * const al[] = {"RT", "RC", "--", "TD",
|
|
"OT", "--", "TC", "OC"};
|
|
int i;
|
|
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");
|
|
}
|
|
|
|
print_item_name("Temp:");
|
|
if (check_print_error(battery_temperature(&value)))
|
|
ccprintf("0x%04x = %.1d K (%.1d C)\n",
|
|
value, value, value - 2731);
|
|
|
|
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);
|
|
|
|
print_item_name("Serial:");
|
|
if (check_print_error(battery_serial_number(&value)))
|
|
ccprintf("0x%04x\n", value);
|
|
|
|
print_item_name("V:");
|
|
if (check_print_error(battery_voltage(&value)))
|
|
ccprintf("0x%04x = %d mV\n", value, value);
|
|
|
|
print_item_name("V-desired:");
|
|
if (check_print_error(battery_desired_voltage(&value)))
|
|
ccprintf("0x%04x = %d mV\n", value, value);
|
|
|
|
print_item_name("V-deisgn:");
|
|
if (check_print_error(battery_design_voltage(&value)))
|
|
ccprintf("0x%04x = %d mV\n", value, value);
|
|
|
|
print_item_name("I:");
|
|
if (check_print_error(battery_current(&value))) {
|
|
ccprintf("0x%04x = %d mA", value & 0xffff, value);
|
|
if (value > 0)
|
|
ccputs("(CHG)");
|
|
else if (value < 0)
|
|
ccputs("(DISCHG)");
|
|
ccputs("\n");
|
|
}
|
|
|
|
print_item_name("I-desired:");
|
|
if (check_print_error(battery_desired_current(&value)))
|
|
ccprintf("0x%04x = %d mA\n", value, value);
|
|
|
|
print_item_name("Mode:");
|
|
if (check_print_error(battery_get_mode(&value)))
|
|
ccprintf("0x%04x\n", value);
|
|
|
|
battery_is_in_10mw_mode(&value);
|
|
unit = value ? "0 mW" : " mAh";
|
|
|
|
print_item_name("Charging:");
|
|
if (check_print_error(battery_charging_allowed(&value)))
|
|
ccprintf("%sAllowed\n", value ? "" : "Not ");
|
|
|
|
print_item_name("Charge:");
|
|
if (check_print_error(battery_state_of_charge(&value)))
|
|
ccprintf("%d %%\n", value);
|
|
|
|
print_item_name("Abs:");
|
|
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%s\n", value, unit);
|
|
|
|
print_item_name("Cap-full:");
|
|
if (check_print_error(battery_full_charge_capacity(&value)))
|
|
ccprintf("%d%s\n", value, unit);
|
|
|
|
print_item_name(" Design:");
|
|
if (check_print_error(battery_design_capacity(&value)))
|
|
ccprintf("%d%s\n", value, unit);
|
|
|
|
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);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int command_battery(int argc, char **argv)
|
|
{
|
|
int repeat = 1;
|
|
int rv = 0;
|
|
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++) {
|
|
rv = print_battery_info();
|
|
|
|
/*
|
|
* 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);
|
|
|
|
if (rv)
|
|
break;
|
|
}
|
|
|
|
if (rv)
|
|
ccprintf("Failed - error %d\n", rv);
|
|
|
|
return rv ? EC_ERROR_UNKNOWN : EC_SUCCESS;
|
|
}
|
|
DECLARE_CONSOLE_COMMAND(battery, command_battery,
|
|
"<repeat_count> <sleep_ms>",
|
|
"Print battery info",
|
|
NULL);
|