mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-30 18:41:11 +00:00
Since pretty much always, we've declared console commands to take a "longhelp" argument with detailed explanations of what the command does. But since almost as long, we've never actually used that argument for anything - we just silently throw it away in the macro. There's only one command (usbchargemode) that even thinks it defines that argument. We're never going to use this, let's just get rid of it. BUG=none BRANCH=none CQ-DEPEND=CL:*279060 CQ-DEPEND=CL:*279158 CQ-DEPEND=CL:*279037 TEST=make buildall; tested on Cr50 hardware Everything builds. Since we never used this arg anyway, there had better not be any difference in the result. Change-Id: Id3f71a53d02e3dc625cfcc12aa71ecb50e35eb9f Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/374163 Reviewed-by: Myles Watson <mylesgw@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
434 lines
9.9 KiB
C
434 lines
9.9 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 "charge_state.h"
|
|
#include "common.h"
|
|
#include "console.h"
|
|
#include "extpower.h"
|
|
#include "gpio.h"
|
|
#include "hooks.h"
|
|
#include "host_command.h"
|
|
#include "timer.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)
|
|
|
|
#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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
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_SUCCESS)
|
|
CPRINTF("[%T Battery cut off succeeded.]\n");
|
|
else
|
|
CPRINTF("[%T Battery cut off failed!]\n");
|
|
}
|
|
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 int 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;
|
|
CPRINTS("Battery cut off at-shutdown is scheduled");
|
|
return EC_RES_SUCCESS;
|
|
}
|
|
}
|
|
|
|
rv = board_cut_off_battery();
|
|
if (!rv) {
|
|
CPRINTS("Battery cut off is successful.");
|
|
battery_cutoff_state = BATTERY_CUTOFF_STATE_CUT_OFF;
|
|
} else {
|
|
CPRINTS("Battery cut off 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) {
|
|
CPRINTF("[%T Cutting off battery in %d second(s)]\n",
|
|
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) {
|
|
ccprintf("[%T Battery cut off]\n");
|
|
battery_cutoff_state = BATTERY_CUTOFF_STATE_CUT_OFF;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
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 int 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 */
|