diff options
author | Vic Yang <victoryang@chromium.org> | 2013-08-20 16:36:38 +0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2013-09-05 07:19:59 +0000 |
commit | 93cb494a7e44864912843e63c04ae72912a1a2e4 (patch) | |
tree | 97399ed492eda3d72923bc1c6ceac977a2bf4061 | |
parent | 3f2eba22c5d3e771904f6451a4b63a41cc6964cb (diff) | |
download | chrome-ec-93cb494a7e44864912843e63c04ae72912a1a2e4.tar.gz |
Add BQ27541 battery driver
BQ27541 is not a smart battery IC, and thus we cannot use existing smart
battery driver. Let's add a driver that implements a smart-battery-like
interface.
The 'battery' console command is also moved to battery.c so that it can
be reused by different battery driver.
BUG=chrome-os-partner:22048
TEST=Type 'battery' and check the reported values are sane.
TEST=Check 'battery' command works fine on Spring.
BRANCH=None
Change-Id: I5d1eaeb3f801478f3b9473fd43c1f2a2eda75859
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/66340
-rw-r--r-- | board/kirby/board.h | 1 | ||||
-rw-r--r-- | chip/host/build.mk | 2 | ||||
-rw-r--r-- | chip/host/i2c.c | 34 | ||||
-rw-r--r-- | common/battery.c | 182 | ||||
-rw-r--r-- | common/battery_bq27541.c | 201 | ||||
-rw-r--r-- | common/build.mk | 5 | ||||
-rw-r--r-- | common/mock_smart_battery.c (renamed from common/mock_smart_battery_stub.c) | 24 | ||||
-rw-r--r-- | common/smart_battery.c | 298 | ||||
-rw-r--r-- | common/smart_battery_stub.c | 21 | ||||
-rw-r--r-- | include/battery.h | 99 | ||||
-rw-r--r-- | include/config.h | 5 | ||||
-rw-r--r-- | include/smart_battery.h | 111 | ||||
-rw-r--r-- | test/test_config.h | 4 |
13 files changed, 683 insertions, 304 deletions
diff --git a/board/kirby/board.h b/board/kirby/board.h index 6215433ef9..7cd7c87218 100644 --- a/board/kirby/board.h +++ b/board/kirby/board.h @@ -9,6 +9,7 @@ #define __BOARD_H /* Optional features */ +#define CONFIG_BATTERY_BQ27541 #define CONFIG_CHARGER #define CONFIG_CHARGER_BQ24192 #define CONFIG_ADC diff --git a/chip/host/build.mk b/chip/host/build.mk index 694734cd57..177246a925 100644 --- a/chip/host/build.mk +++ b/chip/host/build.mk @@ -8,5 +8,5 @@ CORE:=host -chip-y=system.o gpio.o uart.o persistence.o flash.o lpc.o reboot.o +chip-y=system.o gpio.o uart.o persistence.o flash.o lpc.o reboot.o i2c.o chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o diff --git a/chip/host/i2c.c b/chip/host/i2c.c new file mode 100644 index 0000000000..b9d685a656 --- /dev/null +++ b/chip/host/i2c.c @@ -0,0 +1,34 @@ +/* Copyright (c) 2013 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. + * + * Dummy I2C driver for unit test. + */ + +#include "i2c.h" + +int i2c_read16(int port, int slave_addr, int offset, int *data) +{ + return EC_ERROR_UNKNOWN; +} + +int i2c_write16(int port, int slave_addr, int offset, int data) +{ + return EC_ERROR_UNKNOWN; +} + +int i2c_read8(int port, int slave_addr, int offset, int *data) +{ + return EC_ERROR_UNKNOWN; +} + +int i2c_write8(int port, int slave_addr, int offset, int data) +{ + return EC_ERROR_UNKNOWN; +} + +int i2c_read_string(int port, int slave_addr, int offset, uint8_t *data, + int len) +{ + return EC_ERROR_UNKNOWN; +} diff --git a/common/battery.c b/common/battery.c new file mode 100644 index 0000000000..f92f538727 --- /dev/null +++ b/common/battery.c @@ -0,0 +1,182 @@ +/* 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" + +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("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_battery_mode(&value))) + ccprintf("0x%04x\n", value); + + unit = battery_is_in_10mw_mode() ? "0 mW" : " mAh"; + + 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(); + + 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); diff --git a/common/battery_bq27541.c b/common/battery_bq27541.c new file mode 100644 index 0000000000..0389579002 --- /dev/null +++ b/common/battery_bq27541.c @@ -0,0 +1,201 @@ +/* Copyright (c) 2013 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. + * + * Battery driver for BQ27541. + */ + +#include "battery.h" +#include "console.h" +#include "i2c.h" +#include "util.h" + +#define BQ27541_ADDR 0xaa +#define BQ27541_TYPE_ID 0x0541 + +#define REG_CTRL 0x00 +#define REG_AT_RATE 0x02 +#define REG_AT_RATE_TIME_TO_EMPTY 0x04 +#define REG_TEMPERATURE 0x06 +#define REG_VOLTAGE 0x08 +#define REG_FLAGS 0x0a +#define REG_NOMINAL_CAPACITY 0x0c +#define REG_FULL_AVAILABLE_CAPACITY 0x0e +#define REG_REMAINING_CAPACITY 0x10 +#define REG_FULL_CHARGE_CAPACITY 0x12 +#define REG_AVERAGE_CURRENT 0x14 +#define REG_TIME_TO_EMPTY 0x16 +#define REG_TIME_TO_FULL 0x18 +#define REG_STANDBY_CURRENT 0x1a +#define REG_STANDBY_TIME_TO_EMPTY 0x1c +#define REG_MAX_LOAD_CURRENT 0x1e +#define REG_MAX_LOAD_TIME_TO_EMPTY 0x20 +#define REG_AVAILABLE_ENERGY 0x22 +#define REG_AVERAGE_POEWR 0x24 +#define REG_TT_EAT_CONSTANT_POWER 0x26 +#define REG_CYCLE_COUNT 0x2a +#define REG_STATE_OF_CHARGE 0x2c +#define REG_DESIGN_CAPACITY 0x3c +#define REG_DEVICE_NAME_LENGTH 0x62 +#define MAX_DEVICE_NAME_LENGTH 7 +#define REG_DEVICE_NAME 0x63 + +static int bq27541_read(int offset, int *data) +{ + return i2c_read16(I2C_PORT_HOST, BQ27541_ADDR, offset, data); +} + +static int bq27541_read8(int offset, int *data) +{ + return i2c_read8(I2C_PORT_HOST, BQ27541_ADDR, offset, data); +} + +static int bq27541_write(int offset, int data) +{ + return i2c_write16(I2C_PORT_HOST, BQ27541_ADDR, offset, data); +} + +int bq27541_probe(void) +{ + int rv; + int dev_type; + + rv = bq27541_write(REG_CTRL, 0x1); + rv |= bq27541_read(REG_CTRL, &dev_type); + + if (rv) + return rv; + return (dev_type == BQ27541_TYPE_ID) ? EC_SUCCESS : EC_ERROR_UNKNOWN; +} + +int battery_device_name(char *device_name, int buf_size) +{ + int rv, i, val; + int len = MIN(7, buf_size - 1); + + rv = bq27541_read8(REG_DEVICE_NAME_LENGTH, &val); + if (rv) + return rv; + len = MIN(len, val); + + for (i = 0; i < len; ++i) { + rv |= bq27541_read8(REG_DEVICE_NAME + i, &val); + device_name[i] = val; + } + device_name[i] = '\0'; + + return rv; +} + +int battery_temperature(int *deci_kelvin) +{ + return bq27541_read(REG_TEMPERATURE, deci_kelvin); +} + +int battery_voltage(int *voltage) +{ + return bq27541_read(REG_VOLTAGE, voltage); +} + +int battery_state_of_charge(int *percent) +{ + return bq27541_read(REG_STATE_OF_CHARGE, percent); +} + +int battery_state_of_charge_abs(int *percent) +{ + return battery_state_of_charge(percent); +} + +int battery_remaining_capacity(int *capacity) +{ + return bq27541_read(REG_REMAINING_CAPACITY, capacity); +} + +int battery_full_charge_capacity(int *capacity) +{ + return bq27541_read(REG_FULL_CHARGE_CAPACITY, capacity); +} + +int battery_time_to_empty(int *minutes) +{ + return bq27541_read(REG_TIME_TO_EMPTY, minutes); +} + +int battery_time_to_full(int *minutes) +{ + return bq27541_read(REG_TIME_TO_FULL, minutes); +} + +int battery_cycle_count(int *count) +{ + return bq27541_read(REG_CYCLE_COUNT, count); +} + +int battery_design_capacity(int *capacity) +{ + return bq27541_read(REG_DESIGN_CAPACITY, capacity); +} + +int battery_average_current(int *current) +{ + int rv = bq27541_read(REG_AVERAGE_CURRENT, current); + *current = (int)((int16_t)*current); + return rv; +} + +int battery_current(int *current) +{ + return battery_average_current(current); +} + +int battery_time_at_rate(int rate, int *minutes) +{ + int rv; + + rv = bq27541_write(REG_AT_RATE, rate); + if (rv) + return rv; + return bq27541_read(REG_AT_RATE_TIME_TO_EMPTY, minutes); +} + +int battery_manufacturer_name(char *name, int buf_size) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +int battery_device_chemistry(char *chemistry, int buf_size) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +int battery_serial_number(int *serial) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +int battery_desired_voltage(int *voltage) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +int battery_design_voltage(int *voltage) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +int battery_desired_current(int *current) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +int battery_get_battery_mode(int *mode) +{ + return EC_ERROR_UNIMPLEMENTED; +} + +int battery_is_in_10mw_mode(void) +{ + /* Always using mAh unit */ + return 0; +} diff --git a/common/build.mk b/common/build.mk index 143a7e0576..fbc78039b5 100644 --- a/common/build.mk +++ b/common/build.mk @@ -22,8 +22,9 @@ common-$(BOARD_spring)+=battery_spring.o common-$(CONFIG_BACKLIGHT_X86)+=backlight_x86.o common-$(CONFIG_BATTERY_BQ20Z453)+=battery_bq20z453.o -common-$(CONFIG_BATTERY_MOCK)+=mock_smart_battery_stub.o mock_charger.o -common-$(CONFIG_BATTERY_SMART)+=smart_battery.o smart_battery_stub.o +common-$(CONFIG_BATTERY_BQ27541)+=battery.o battery_bq27541.o +common-$(CONFIG_BATTERY_MOCK)+=mock_smart_battery.o mock_charger.o +common-$(CONFIG_BATTERY_SMART)+=battery.o smart_battery.o common-$(CONFIG_CHARGER)+=charge_state.o charger_common.o common-$(CONFIG_CHARGER_BQ24192)+=charger_bq24192.o common-$(CONFIG_CHARGER_BQ24715)+=charger_bq24715.o diff --git a/common/mock_smart_battery_stub.c b/common/mock_smart_battery.c index 17287cd7ad..98112c3ec0 100644 --- a/common/mock_smart_battery_stub.c +++ b/common/mock_smart_battery.c @@ -50,30 +50,6 @@ int battery_device_chemistry(char *device_chemistry, int buf_size) return EC_SUCCESS; } -int battery_current(int *current) -{ - int rv, d; - - rv = sb_read(SB_CURRENT, &d); - if (rv) - return rv; - - *current = (int16_t)d; - return EC_SUCCESS; -} - -int battery_average_current(int *current) -{ - int rv, d; - - rv = sb_read(SB_AVERAGE_CURRENT, &d); - if (rv) - return rv; - - *current = (int16_t)d; - return EC_SUCCESS; -} - int battery_time_at_rate(int rate, int *minutes) { return EC_SUCCESS; diff --git a/common/smart_battery.c b/common/smart_battery.c index 3991a2e270..04f1eafb63 100644 --- a/common/smart_battery.c +++ b/common/smart_battery.c @@ -11,6 +11,153 @@ #include "timer.h" #include "util.h" +test_mockable int sbc_read(int cmd, int *param) +{ + return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); +} + +test_mockable int sbc_write(int cmd, int param) +{ + return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); +} + +test_mockable int sb_read(int cmd, int *param) +{ + return i2c_read16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, param); +} + +test_mockable int sb_write(int cmd, int param) +{ + return i2c_write16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, param); +} + +/* Get/set battery mode */ +int battery_get_battery_mode(int *mode) +{ + return sb_read(SB_BATTERY_MODE, mode); +} + +int battery_set_battery_mode(int mode) +{ + return sb_write(SB_BATTERY_MODE, mode); +} + +int battery_is_in_10mw_mode(void) +{ + int val; + battery_get_battery_mode(&val); + return val & MODE_CAPACITY; +} + +/* Read battery temperature + * unit: 0.1 K + */ +int battery_temperature(int *deci_kelvin) +{ + return sb_read(SB_TEMPERATURE, deci_kelvin); +} + +/* Read battery voltage + * unit: mV + */ +int battery_voltage(int *voltage) +{ + return sb_read(SB_VOLTAGE, voltage); +} + +/* Relative state of charge in percent */ +int battery_state_of_charge(int *percent) +{ + return sb_read(SB_RELATIVE_STATE_OF_CHARGE, percent); +} + +/* Absolute state of charge in percent */ +int battery_state_of_charge_abs(int *percent) +{ + return sb_read(SB_ABSOLUTE_STATE_OF_CHARGE, percent); +} + +/* Battery remaining capacity + * unit: mAh or 10mW, depends on battery mode + */ +int battery_remaining_capacity(int *capacity) +{ + return sb_read(SB_REMAINING_CAPACITY, capacity); +} + +/* Battery full charge capacity */ +int battery_full_charge_capacity(int *capacity) +{ + return sb_read(SB_FULL_CHARGE_CAPACITY, capacity); +} + +/* Time in minutes left when discharging */ +int battery_time_to_empty(int *minutes) +{ + return sb_read(SB_AVERAGE_TIME_TO_EMPTY, minutes); +} + +int battery_run_time_to_empty(int *minutes) +{ + return sb_read(SB_RUN_TIME_TO_EMPTY, minutes); +} + +/* Time in minutes to full when charging */ +int battery_time_to_full(int *minutes) +{ + return sb_read(SB_AVERAGE_TIME_TO_FULL, minutes); +} + +/* The current battery desired to charge + * unit: mA + */ +int battery_desired_current(int *current) +{ + return sb_read(SB_CHARGING_CURRENT, current); +} + +/* The voltage battery desired to charge + * unit: mV + */ +int battery_desired_voltage(int *voltage) +{ + return sb_read(SB_CHARGING_VOLTAGE, voltage); +} + +/* Read battery status */ +int battery_status(int *status) +{ + return sb_read(SB_BATTERY_STATUS, status); +} + +/* Battery charge cycle count */ +int battery_cycle_count(int *count) +{ + return sb_read(SB_CYCLE_COUNT, count); +} + +/* Designed battery capacity + * unit: mAh or 10mW depends on battery mode + */ +int battery_design_capacity(int *capacity) +{ + return sb_read(SB_DESIGN_CAPACITY, capacity); +} + +/* Designed battery output voltage + * unit: mV + */ +int battery_design_voltage(int *voltage) +{ + return sb_read(SB_DESIGN_VOLTAGE, voltage); +} + +/* Read serial number */ +int battery_serial_number(int *serial) +{ + return sb_read(SB_SERIAL_NUMBER, serial); +} + /* Read battery discharging current * unit: mA * negative value: charging @@ -45,7 +192,7 @@ int battery_average_current(int *current) * rate < 0: discharging, positive time to empty * rate == 0: invalid input, time = 0 */ -int battery_time_at_rate(int rate, int *minutes) +test_mockable int battery_time_at_rate(int rate, int *minutes) { int rv; int ok, time; @@ -87,7 +234,7 @@ int battery_time_at_rate(int rate, int *minutes) } /* Read manufacturer date */ -int battery_manufacturer_date(int *year, int *month, int *day) +test_mockable int battery_manufacturer_date(int *year, int *month, int *day) { int rv; int ymd; @@ -107,21 +254,21 @@ int battery_manufacturer_date(int *year, int *month, int *day) } /* Read manufacturer name */ -int battery_manufacturer_name(char *manufacturer_name, int buf_size) +test_mockable int battery_manufacturer_name(char *name, int buf_size) { return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR, - SB_MANUFACTURER_NAME, manufacturer_name, buf_size); + SB_MANUFACTURER_NAME, name, buf_size); } /* Read device name */ -int battery_device_name(char *device_name, int buf_size) +test_mockable int battery_device_name(char *device_name, int buf_size) { return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR, SB_DEVICE_NAME, device_name, buf_size); } /* Read battery type/chemistry */ -int battery_device_chemistry(char *device_chemistry, int buf_size) +test_mockable int battery_device_chemistry(char *device_chemistry, int buf_size) { return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR, SB_DEVICE_CHEMISTRY, device_chemistry, buf_size); @@ -130,145 +277,6 @@ int battery_device_chemistry(char *device_chemistry, int buf_size) /*****************************************************************************/ /* Console commands */ -static int print_battery_info(void) -{ - int value; - int hour, minute; - char text[32]; - const char *unit; - int rv; - - rv = battery_temperature(&value); - if (rv) - return rv; - - ccprintf(" Temp: 0x%04x = %.1d K (%.1d C)\n", - value, value, value - 2731); - - ccprintf(" Manuf: %s\n", - battery_manufacturer_name(text, sizeof(text)) == EC_SUCCESS ? - text : "(error)"); - - ccprintf(" Device: %s\n", - battery_device_name(text, sizeof(text)) == EC_SUCCESS ? - text : "(error)"); - - ccprintf(" Chem: %s\n", - battery_device_chemistry(text, sizeof(text)) == EC_SUCCESS ? - text : "(error)"); - - battery_serial_number(&value); - ccprintf(" Serial: 0x%04x\n", value); - - battery_voltage(&value); - ccprintf(" V: 0x%04x = %d mV\n", value, value); - - battery_desired_voltage(&value); - ccprintf(" V-desired: 0x%04x = %d mV\n", value, value); - - battery_design_voltage(&value); - ccprintf(" V-design: 0x%04x = %d mV\n", value, value); - - battery_current(&value); - ccprintf(" I: 0x%04x = %d mA", - value & 0xffff, value); - if (value > 0) - ccputs("(CHG)"); - else if (value < 0) - ccputs("(DISCHG)"); - ccputs("\n"); - - - battery_desired_current(&value); - ccprintf(" I-desired: 0x%04x = %d mA\n", value, value); - - battery_get_battery_mode(&value); - ccprintf(" Mode: 0x%04x\n", value); - unit = (value & MODE_CAPACITY) ? "0 mW" : " mAh"; - - battery_state_of_charge(&value); - ccprintf(" Charge: %d %%\n", value); - - battery_state_of_charge_abs(&value); - ccprintf(" Abs: %d %%\n", value); - - battery_remaining_capacity(&value); - ccprintf(" Remaining: %d%s\n", value, unit); - - battery_full_charge_capacity(&value); - ccprintf(" Cap-full: %d%s\n", value, unit); - - battery_design_capacity(&value); - ccprintf(" Design: %d%s\n", value, unit); - - battery_time_to_full(&value); - if (value == 65535) { - hour = 0; - minute = 0; - } else { - hour = value / 60; - minute = value % 60; - } - ccprintf(" Time-full: %dh:%d\n", hour, minute); - - battery_time_to_empty(&value); - if (value == 65535) { - hour = 0; - minute = 0; - } else { - hour = value / 60; - minute = value % 60; - } - ccprintf(" Empty: %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(); - - 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); - - /* Usage:sb reg [value] * sb 0x14 // read desired charging current * sb 0x15 // read desired charging voltage diff --git a/common/smart_battery_stub.c b/common/smart_battery_stub.c deleted file mode 100644 index f00cc921a7..0000000000 --- a/common/smart_battery_stub.c +++ /dev/null @@ -1,21 +0,0 @@ -/* 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. - * - * Functions needed by smart battery driver. - */ - -#include "smart_battery.h" -#include "i2c.h" - -int sbc_read(int cmd, int *param) - { return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); } - -int sbc_write(int cmd, int param) - { return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); } - -int sb_read(int cmd, int *param) - { return i2c_read16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, param); } - -int sb_write(int cmd, int param) - { return i2c_write16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, param); } diff --git a/include/battery.h b/include/battery.h index 940187fe7f..39a7aea0d1 100644 --- a/include/battery.h +++ b/include/battery.h @@ -31,5 +31,104 @@ */ #define BATTERY_LEVEL_SHUTDOWN 3 + +/* Get/set battery mode */ +int battery_get_battery_mode(int *mode); + +int battery_set_battery_mode(int mode); + +/* Read battery temperature + * unit: 0.1 K + */ +int battery_temperature(int *deci_kelvin); + +/* Read battery voltage + * unit: mV + */ +int battery_voltage(int *voltage); + +/* Relative state of charge in percent */ +int battery_state_of_charge(int *percent); + +/* Absolute state of charge in percent */ +int battery_state_of_charge_abs(int *percent); + +/* + * Return non-zero if the battery is reporting capacity in 10mW. + * Otherwise, in mAh. */ +int battery_is_in_10mw_mode(void); + +/* + * Battery remaining capacity + * unit: mAh or 10mW, depends on battery mode + */ +int battery_remaining_capacity(int *capacity); + +/* Battery full charge capacity */ +int battery_full_charge_capacity(int *capacity); + +/* Time in minutes left when discharging */ +int battery_time_to_empty(int *minutes); + +int battery_run_time_to_empty(int *minutes); + +/* Time in minutes to full when charging */ +int battery_time_to_full(int *minutes); + +/* The current battery desired to charge + * unit: mA + */ +int battery_desired_current(int *current); + +/* The voltage battery desired to charge + * unit: mV + */ +int battery_desired_voltage(int *voltage); + +/* Read battery status */ +int battery_status(int *status); + +/* Battery charge cycle count */ +int battery_cycle_count(int *count); + +/* Designed battery capacity + * unit: mAh or 10mW depends on battery mode + */ +int battery_design_capacity(int *capacity); + +/* Designed battery output voltage + * unit: mV + */ +int battery_design_voltage(int *voltage); + +/* Read serial number */ +int battery_serial_number(int *serial); + +/* Read manufacturer name */ +int battery_manufacturer_name(char *manufacturer_name, int buf_size); + +/* Read device name */ +int battery_device_name(char *device_name, int buf_size); + +/* Read battery type/chemistry */ +int battery_device_chemistry(char *device_chemistry, int buf_size); + +/* Read battery discharging current + * unit: mA + * negative value: charging + */ +int battery_current(int *current); +int battery_average_current(int *current); + +/* Calculate battery time in minutes, under a charging rate + * rate > 0: charging, negative time to full + * rate < 0: discharging, positive time to empty + * rate == 0: invalid input, time = 0 + */ +int battery_time_at_rate(int rate, int *minutes); + +/* Read manufacturer date */ +int battery_manufacturer_date(int *year, int *month, int *day); + #endif /* __CROS_EC_BATTERY_H */ diff --git a/include/config.h b/include/config.h index fd01b20398..60911d7bc2 100644 --- a/include/config.h +++ b/include/config.h @@ -55,9 +55,12 @@ /*****************************************************************************/ /* Battery config */ -/* Compile support for the BS20Z453 battery used on some of the ARM laptops */ +/* Compile support for the BQ20Z453 battery used on some of the ARM laptops */ #undef CONFIG_BATTERY_BQ20Z453 +/* Compile support for the BQ27541 battery */ +#undef CONFIG_BATTERY_BQ27541 + /* Compile mock battery support; used by tests. */ #undef CONFIG_BATTERY_MOCK diff --git a/include/smart_battery.h b/include/smart_battery.h index ef65cd9d0d..f80e63ce1b 100644 --- a/include/smart_battery.h +++ b/include/smart_battery.h @@ -8,6 +8,7 @@ #ifndef __CROS_EC_SMART_BATTERY_H #define __CROS_EC_SMART_BATTERY_H +#include "battery.h" #include "common.h" #include "i2c.h" #include "smart_battery_stub.h" @@ -128,115 +129,5 @@ #define INFO_CHARGER_SPEC(INFO) ((INFO) & 0xf) #define INFO_SELECTOR_SUPPORT(INFO) (((INFO) >> 4) & 1) -/* Get/set battery mode */ -static inline int battery_get_battery_mode(int *mode) - { return sb_read(SB_BATTERY_MODE, mode); } - -static inline int battery_set_battery_mode(int mode) - { return sb_write(SB_BATTERY_MODE, mode); } - -/* Read battery temperature - * unit: 0.1 K - */ -static inline int battery_temperature(int *deci_kelvin) - { return sb_read(SB_TEMPERATURE, deci_kelvin); } - -/* Read battery voltage - * unit: mV - */ -static inline int battery_voltage(int *voltage) - { return sb_read(SB_VOLTAGE, voltage); } - -/* Relative state of charge in percent */ -static inline int battery_state_of_charge(int *percent) - { return sb_read(SB_RELATIVE_STATE_OF_CHARGE, percent); } - -/* Absolute state of charge in percent */ -static inline int battery_state_of_charge_abs(int *percent) - { return sb_read(SB_ABSOLUTE_STATE_OF_CHARGE, percent); } - -/* Battery remaining capacity - * unit: mAh or 10mW, depends on battery mode - */ -static inline int battery_remaining_capacity(int *capacity) - { return sb_read(SB_REMAINING_CAPACITY, capacity); } - -/* Battery full charge capacity */ -static inline int battery_full_charge_capacity(int *capacity) - { return sb_read(SB_FULL_CHARGE_CAPACITY, capacity); } - -/* Time in minutes left when discharging */ -static inline int battery_time_to_empty(int *minutes) - { return sb_read(SB_AVERAGE_TIME_TO_EMPTY, minutes); } - -static inline int battery_run_time_to_empty(int *minutes) - { return sb_read(SB_RUN_TIME_TO_EMPTY, minutes); } - -/* Time in minutes to full when charging */ -static inline int battery_time_to_full(int *minutes) - { return sb_read(SB_AVERAGE_TIME_TO_FULL, minutes); } - -/* The current battery desired to charge - * unit: mA - */ -static inline int battery_desired_current(int *current) - { return sb_read(SB_CHARGING_CURRENT, current); } - -/* The voltage battery desired to charge - * unit: mV - */ -static inline int battery_desired_voltage(int *voltage) - { return sb_read(SB_CHARGING_VOLTAGE, voltage); } - -/* Read battery status */ -static inline int battery_status(int *status) - { return sb_read(SB_BATTERY_STATUS, status); } - -/* Battery charge cycle count */ -static inline int battery_cycle_count(int *count) - { return sb_read(SB_CYCLE_COUNT, count); } - -/* Designed battery capacity - * unit: mAh or 10mW depends on battery mode - */ -static inline int battery_design_capacity(int *capacity) - { return sb_read(SB_DESIGN_CAPACITY, capacity); } - -/* Designed battery output voltage - * unit: mV - */ -static inline int battery_design_voltage(int *voltage) - { return sb_read(SB_DESIGN_VOLTAGE, voltage); } - -/* Read serial number */ -static inline int battery_serial_number(int *serial) - { return sb_read(SB_SERIAL_NUMBER, serial); } - -/* Read manufacturer name */ -int battery_manufacturer_name(char *manufacturer_name, int buf_size); - -/* Read device name */ -int battery_device_name(char *device_name, int buf_size); - -/* Read battery type/chemistry */ -int battery_device_chemistry(char *device_chemistry, int buf_size); - -/* Read battery discharging current - * unit: mA - * negative value: charging - */ -int battery_current(int *current); -int battery_average_current(int *current); - -/* Calculate battery time in minutes, under a charging rate - * rate > 0: charging, negative time to full - * rate < 0: discharging, positive time to empty - * rate == 0: invalid input, time = 0 - */ -int battery_time_at_rate(int rate, int *minutes); - -/* Read manufacturer date */ -int battery_manufacturer_date(int *year, int *month, int *day); - #endif /* __CROS_EC_SMART_BATTERY_H */ diff --git a/test/test_config.h b/test/test_config.h index 21c4d64a57..0dd63b9dd8 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -15,10 +15,14 @@ #ifdef TEST_sbs_charging #define CONFIG_BATTERY_MOCK +#define CONFIG_BATTERY_SMART #define CONFIG_CHARGER #define CONFIG_CHARGER_INPUT_CURRENT 4032 #define CONFIG_CHARGER_DISCHARGE_ON_AC int board_discharge_on_ac(int enabled); +#define I2C_PORT_HOST 1 +#define I2C_PORT_BATTERY 1 +#define I2C_PORT_CHARGER 1 #endif #ifdef TEST_adapter |