summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRong Chang <rongchang@google.com>2012-02-08 18:40:15 -0800
committerRong Chang <rongchang@chromium.org>2012-02-10 16:12:56 -0800
commit62df62ccd4551ad2133d513be583839d229a9365 (patch)
tree836eab9eec5c5c9c7e4fabf14d6707478a749a1d
parentee7fce76b032f2a5f94f122e8214e9cfc8790f62 (diff)
downloadchrome-ec-62df62ccd4551ad2133d513be583839d229a9365.tar.gz
Add basic smart battery driver
This change adds a common part of smart battery driver. Following features are not implemented, or in chip specific driver: Battery access control, authentication, factory mode Manufacturer access/data commands Block read/write, device name, flash data Chip specific features, per cell info/temp/capacity Signed-off-by: Rong Chang <rongchang@google.com> BUG=chrome-os-partner:7856 TEST=console command check battery staus [unplug power] > battery [check voltage,current,capacity,time to empty] [plug power] > charger voltage 8400 > charger current 4250 > battery [check current,time to full] > charger input 4032 > battery [check current,time to full] [wait 130 seconds, charger watch dog timeout] > battery [check current] Change-Id: Ifac17a0892f52e8f37eebc14b00e71f18360776c Signed-off-by: Rong Chang <rongchang@chromium.org>
-rw-r--r--board/link/board.h11
-rw-r--r--common/build.mk1
-rw-r--r--common/charger_bq24725.c44
-rw-r--r--common/charger_bq24725.h3
-rw-r--r--common/smart_battery.c241
-rw-r--r--common/smart_battery.h58
-rw-r--r--include/charger.h6
-rw-r--r--include/smart_battery.h229
8 files changed, 508 insertions, 85 deletions
diff --git a/board/link/board.h b/board/link/board.h
index 9b6c40f2e1..69ea870f06 100644
--- a/board/link/board.h
+++ b/board/link/board.h
@@ -63,9 +63,20 @@ enum adc_channel
/* Charger module */
#define CONFIG_CHARGER_BQ24725
+/* Set charger input current limit
+ * Note - this value should depend on external power adapter,
+ * designed charging voltage, and the maximum power of
+ * a running system.
+ * Following value 4032 mA is the maximum input limit
+ * on Link's design.
+ */
+#define CONFIG_CHARGER_INPUT_CURRENT 4032
#define CONFIG_BQ24725_R_SNS 10 /* 10 mOhm charge sense resistor */
#define CONFIG_BQ24725_R_AC 20 /* 20 mOhm input current sense resistor */
+/* Battery module */
+#define CONFIG_SMART_BATTERY
+
/* I2C ports */
#define I2C_PORT_BATTERY 0
#define I2C_PORT_CHARGER 1
diff --git a/common/build.mk b/common/build.mk
index 564cfe80dd..afba6c9661 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -18,3 +18,4 @@ common-$(CONFIG_TEMP_SENSOR)+=temp_sensor.o temp_sensor_commands.o
# Board driver modules
common-$(CONFIG_CHARGER_BQ24725)+=charger_bq24725.o
+common-$(CONFIG_SMART_BATTERY)+=smart_battery.o
diff --git a/common/charger_bq24725.c b/common/charger_bq24725.c
index 5b70d0d0c5..e5f8b3bc74 100644
--- a/common/charger_bq24725.c
+++ b/common/charger_bq24725.c
@@ -44,8 +44,8 @@ static const struct charger_info bq24725_charger_info = {
static int charger_set_input_current(int input_current)
{
- return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR,
- BQ24725_INPUT_CURRENT, CURRENT_TO_REG(input_current, R_AC));
+ return sbc_write(BQ24725_INPUT_CURRENT,
+ CURRENT_TO_REG(input_current, R_AC));
}
static int charger_get_input_current(int *input_current)
@@ -53,8 +53,7 @@ static int charger_get_input_current(int *input_current)
int rv;
int reg;
- rv = i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR,
- BQ24725_INPUT_CURRENT, &reg);
+ rv = sbc_read(BQ24725_INPUT_CURRENT, &reg);
if (rv)
return rv;
@@ -65,26 +64,22 @@ static int charger_get_input_current(int *input_current)
static int charger_manufacturer_id(int *id)
{
- return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR,
- BQ24725_MANUFACTURE_ID, id);
+ return sbc_read(BQ24725_MANUFACTURE_ID, id);
}
static int charger_device_id(int *id)
{
- return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR,
- BQ24725_DEVICE_ID, id);
+ return sbc_read(BQ24725_DEVICE_ID, id);
}
static int charger_get_option(int *option)
{
- return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR,
- BQ24725_CHARGE_OPTION, option);
+ return sbc_read(BQ24725_CHARGE_OPTION, option);
}
static int charger_set_option(int option)
{
- return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR,
- BQ24725_CHARGE_OPTION, option);
+ return sbc_write(BQ24725_CHARGE_OPTION, option);
}
/* charger interfaces */
@@ -132,8 +127,7 @@ int charger_get_current(int *current)
int rv;
int reg;
- rv = i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR,
- SB_CHARGING_CURRENT, &reg);
+ rv = sbc_read(SB_CHARGING_CURRENT, &reg);
if (rv)
return rv;
@@ -143,32 +137,38 @@ int charger_get_current(int *current)
int charger_set_current(int current)
{
- return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR,
- SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS));
+ return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS));
}
int charger_get_voltage(int *voltage)
{
- return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR,
- SB_CHARGING_VOLTAGE, voltage);
+ return sbc_read(SB_CHARGING_VOLTAGE, voltage);
}
int charger_set_voltage(int voltage)
{
- return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR,
- SB_CHARGING_VOLTAGE, voltage);
+ return sbc_write(SB_CHARGING_VOLTAGE, voltage);
}
/* Initialization */
int charger_init(void)
{
/* bq24725 power on reset state:
- * charger watch dog timer = 175sec
- * charger input current limit = 4096 * 10 / RS_AC
+ * watch dog timer = 175 sec
+ * input current limit = ~1/2 maximum setting
+ * charging voltage = 0 mV
+ * charging current = 0 mA
*/
return EC_SUCCESS;
}
+/* Charging power state initialization */
+int charger_post_init(void)
+{
+ /* Set charger input current limit */
+ return charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT);
+}
+
/* Console commands */
diff --git a/common/charger_bq24725.h b/common/charger_bq24725.h
index ab0a4324b3..3deb41d125 100644
--- a/common/charger_bq24725.h
+++ b/common/charger_bq24725.h
@@ -8,9 +8,6 @@
#ifndef __CROS_EC_CHARGER_BQ24725_H
#define __CROS_EC_CHARGER_BQ24725_H
-/* I2C address */
-#define CHARGER_ADDR 0x12
-
/* Chip specific commands */
#define BQ24725_CHARGE_OPTION 0x12
#define BQ24725_INPUT_CURRENT 0x3f
diff --git a/common/smart_battery.c b/common/smart_battery.c
new file mode 100644
index 0000000000..12f3c84173
--- /dev/null
+++ b/common/smart_battery.c
@@ -0,0 +1,241 @@
+/* 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.
+ *
+ * Smart battery driver.
+ */
+
+#include "console.h"
+#include "smart_battery.h"
+#include "timer.h"
+#include "uart.h"
+#include "util.h"
+
+/* Read battery discharging current
+ * unit: mA
+ * negative value: charging
+ */
+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;
+}
+
+/* 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)
+{
+ int rv;
+ int ok, time;
+ int loop, cmd, output_sign;
+
+ if (rate == 0) {
+ *minutes = 0;
+ return EC_ERROR_INVAL;
+ }
+
+ rv = sb_write(SB_AT_RATE, rate);
+ if (rv)
+ return rv;
+ loop = 5;
+ while (loop--) {
+ rv = sb_read(SB_AT_RATE_OK, &ok);
+ if (rv)
+ return rv;
+ if (ok) {
+ if (rate > 0) {
+ cmd = SB_AT_RATE_TIME_TO_FULL;
+ output_sign = -1;
+ } else {
+ cmd = SB_AT_RATE_TIME_TO_EMPTY;
+ output_sign = 1;
+ }
+ rv = sb_read(cmd, &time);
+ if (rv)
+ return rv;
+
+ *minutes = (time == 0xffff) ? 0 : output_sign * time;
+ return EC_SUCCESS;
+ } else {
+ /* wait 10ms for AT_RATE_OK */
+ usleep(10000);
+ }
+ }
+ return EC_ERROR_TIMEOUT;
+}
+
+/* Read manufacturer date */
+int battery_manufacturer_date(int *year, int *month, int *day)
+{
+ int rv;
+ int ymd;
+
+ rv = sb_read(SB_SPECIFICATION_INFO, &ymd);
+ if (rv)
+ return rv;
+
+ /* battery date format:
+ * ymd = day + month * 32 + (year - 1980) * 256
+ */
+ *year = (ymd >> 8) + 1980;
+ *month = (ymd & 0xff) / 32;
+ *day = (ymd & 0xff) % 32;
+
+ return EC_SUCCESS;
+}
+
+/* Console commands */
+
+static int command_battery(int argc, char **argv)
+{
+ int rv;
+ int d;
+ int hour, minute;
+ const char *unit;
+
+ uart_puts("Reading battery...\n");
+
+ rv = battery_temperature(&d);
+ if (rv)
+ return rv;
+ uart_printf(" Temperature: 0x%04x = %d x 0.1K (%d C)\n",
+ d, d, (d-2731)/10);
+
+ battery_serial_number(&d);
+ uart_printf(" Serial number: 0x%04x\n", d);
+
+ battery_voltage(&d);
+ uart_printf(" Voltage: 0x%04x = %d mV\n", d, d);
+
+ battery_desired_voltage(&d);
+ uart_printf(" Desired voltage 0x%04x = %d mV\n", d, d);
+
+ battery_design_voltage(&d);
+ uart_printf(" Design output voltage 0x%04x = %d mV\n", d, d);
+
+ battery_current(&d);
+ uart_printf(" Current: 0x%04x = %d mA",
+ d & 0xffff, d);
+ if (d > 0)
+ uart_puts("(CHG)");
+ else if (d < 0)
+ uart_puts("(DISCHG)");
+ uart_puts("\n");
+
+
+ battery_desired_current(&d);
+ uart_printf(" Desired current 0x%04x = %d mA\n", d, d);
+
+ battery_get_battery_mode(&d);
+ uart_printf(" Battery mode: 0x%04x\n", d);
+ unit = (d & MODE_CAPACITY) ? "0 mW" : " mAh";
+
+ battery_state_of_charge(&d);
+ uart_printf(" %% of charge: %d %%\n", d);
+
+ battery_state_of_charge_abs(&d);
+ uart_printf(" Abs %% of charge: %d %%\n", d);
+
+ battery_remaining_capacity(&d);
+ uart_printf(" Remaining capacity: %d%s\n", d, unit);
+
+ battery_full_charge_capacity(&d);
+ uart_printf(" Full charge capacity: %d%s\n", d, unit);
+
+ battery_design_capacity(&d);
+ uart_printf(" Design capacity: %d%s\n", d, unit);
+
+ battery_time_to_empty(&d);
+ if (d == 65535) {
+ hour = 0;
+ minute = 0;
+ } else {
+ hour = d / 60;
+ minute = d % 60;
+ }
+ uart_printf(" Time to empty: %dh:%d\n", hour, minute);
+
+ battery_time_to_full(&d);
+ if (d == 65535) {
+ hour = 0;
+ minute = 0;
+ } else {
+ hour = d / 60;
+ minute = d % 60;
+ }
+ uart_printf(" Time to full: %dh:%d\n", hour, minute);
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(battery, command_battery);
+
+static int command_sb(int argc, char **argv)
+{
+ int rv;
+ int cmd, d;
+ char *e;
+
+ if (argc < 3)
+ goto usage;
+
+ cmd = strtoi(argv[2], &e, 0);
+ if (*e) {
+ uart_puts("Invalid cmd.\n");
+ goto usage;
+ }
+
+ if (argv[1][0] == 'r') {
+ rv = i2c_read16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, &d);
+ if (rv) {
+ uart_puts("I2C read failed.\n");
+ return rv;
+ }
+ uart_printf("R SBCMD[%04x] 0x%04x (%d)\n", cmd, d, d);
+ return EC_SUCCESS;
+ } else if (argc >= 4 && argv[1][0] == 'w') {
+ d = strtoi(argv[3], &e, 0);
+ if (*e) {
+ uart_puts("Invalid w_word.\n");
+ goto usage;
+ }
+ uart_printf("W SBCMD[%04x] 0x%04x (%d)\n", cmd, d, d);
+ rv = i2c_write16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, d);
+ if (rv) {
+ uart_puts("I2C write failed.\n");
+ return rv;
+ }
+ return EC_SUCCESS;
+ }
+
+usage:
+ uart_puts("Usage:sb <r/w> cmd [uint16_t w_word]\n");
+ uart_puts(" sb r 0x14 // desired charging current\n");
+ uart_puts(" sb r 0x15 // desired charging voltage\n");
+ uart_puts(" sb r 0x3 // battery mode\n");
+ uart_puts(" sb w 0x3 0xe001 // set battery mode\n");
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(sb, command_sb);
+
diff --git a/common/smart_battery.h b/common/smart_battery.h
deleted file mode 100644
index 0aa91f6bff..0000000000
--- a/common/smart_battery.h
+++ /dev/null
@@ -1,58 +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.
- *
- * Smart battery charger 1.1
- */
-#ifndef __CROS_EC_SMART_BATTERY_H
-#define __CROS_EC_SMART_BATTERY_H
-
-/* Smart battery charger functions */
-#define SB_CHARGER_SPEC_INFO 0x11
-#define SB_CHARGE_MODE 0x12
-#define SB_CHARGER_STATUS 0x13
-#define SB_CHARGING_CURRENT 0x14
-#define SB_CHARGING_VOLTAGE 0x15
-#define SB_ALARM_WARNING 0x16
-
-/* SB_ALARM_WARNING */
-#define ALARM_OVER_CHARGE 0x8000
-#define ALARM_TERMINATE_CHARG 0x4000
-#define ALARM_RESERVED_2000 0x2000
-#define ALARM_OVER_TEMP 0x1000
-#define ALARM_TERMINATE_DISCHARGE 0x0800
-#define ALARM_RESERVED_0400 0x0400
-#define ALARM_REMAINING_CAPACITY 0x0200
-#define ALARM_REMAINING_TIME 0x0100
-#define ALARM_STATUS_INITIALIZE 0x0080
-#define ALARM_STATUS_DISCHARGING 0x0040
-#define ALARM_STATUS_FULLY_CHARGED 0x0020
-#define ALARM_STATUS_FULLY_DISCHARG 0x0010
-/* SB_CHARGE_MODE */
-#define CHARGE_FLAG_INHIBIT_CHARGE (1 << 0)
-#define CHARGE_FLAG_ENABLE_POLLING (1 << 1)
-#define CHARGE_FLAG_POR_RESET (1 << 2)
-#define CHARGE_FLAG_RESET_TO_ZERO (1 << 3)
-/* SB_CHARGER_STATUS */
-#define CHARGER_CHARGE_INHIBITED (1 << 0)
-#define CHARGER_POLLING_ENABLED (1 << 1)
-#define CHARGER_VOLTAGE_NOTREG (1 << 2)
-#define CHARGER_CURRENT_NOTREG (1 << 3)
-#define CHARGER_LEVEL_2 (1 << 4)
-#define CHARGER_LEVEL_3 (1 << 5)
-#define CHARGER_CURRENT_OR (1 << 6)
-#define CHARGER_VOLTAGE_OR (1 << 7)
-#define CHARGER_RES_OR (1 << 8)
-#define CHARGER_RES_COLD (1 << 9)
-#define CHARGER_RES_HOT (1 << 10)
-#define CHARGER_RES_UR (1 << 11)
-#define CHARGER_ALARM_INHIBITED (1 << 12)
-#define CHARGER_POWER_FAIL (1 << 13)
-#define CHARGER_BATTERY_PRESENT (1 << 14)
-#define CHARGER_AC_PRESENT (1 << 15)
-/* SB_CHARGER_SPEC_INFO */
-#define INFO_CHARGER_SPEC(INFO) ((INFO) & 0xf)
-#define INFO_SELECTOR_SUPPORT(INFO) (((INFO) >> 4) & 1)
-
-#endif /* __CROS_EC_SMART_BATTERY_H */
-
diff --git a/include/charger.h b/include/charger.h
index 19184c5389..65ba8c1b48 100644
--- a/include/charger.h
+++ b/include/charger.h
@@ -27,10 +27,12 @@ struct charger_info {
uint16_t input_current_step;
};
-/* Initializes the charger, with AC input on and battery
- * charging off. */
+/* Initializes the charger */
int charger_init(void);
+/* Power state machine post init */
+int charger_post_init(void);
+
/* Get charger information. */
const struct charger_info *charger_get_info(void);
diff --git a/include/smart_battery.h b/include/smart_battery.h
new file mode 100644
index 0000000000..0d45fae937
--- /dev/null
+++ b/include/smart_battery.h
@@ -0,0 +1,229 @@
+/* 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.
+ *
+ * Smart battery v1.0
+ * Smart battery charger v1.1
+ */
+#ifndef __CROS_EC_SMART_BATTERY_H
+#define __CROS_EC_SMART_BATTERY_H
+
+#include "board.h"
+#include "common.h"
+#include "i2c.h"
+
+/* Smart battery and charger I2C address */
+#define BATTERY_ADDR 0x16
+#define CHARGER_ADDR 0x12
+
+/* Charger functions */
+#define SB_CHARGER_SPEC_INFO 0x11
+#define SB_CHARGE_MODE 0x12
+#define SB_CHARGER_STATUS 0x13
+#define SB_CHARGING_CURRENT 0x14
+#define SB_CHARGING_VOLTAGE 0x15
+#define SB_ALARM_WARNING 0x16
+
+/* Battery functions */
+#define SB_MANUFACTURER_ACCESS 0x00
+#define SB_REMAINING_CAPACITY_ALARM 0x01
+#define SB_REMAINING_TIME_ALARM 0x02
+#define SB_BATTERY_MODE 0x03
+#define SB_AT_RATE 0x04
+#define SB_AT_RATE_TIME_TO_FULL 0x05
+#define SB_AT_RATE_TIME_TO_EMPTY 0x06
+#define SB_AT_RATE_OK 0x07
+#define SB_TEMPERATURE 0x08
+#define SB_VOLTAGE 0x09
+#define SB_CURRENT 0x0a
+#define SB_AVERAGE_CURRENT 0x0b
+#define SB_MAX_ERROR 0x0c
+#define SB_RELATIVE_STATE_OF_CHARGE 0x0d
+#define SB_ABSOLUTE_STATE_OF_CHARGE 0x0e
+#define SB_REMAINING_CAPACITY 0x0f
+#define SB_FULL_CHARGE_CAPACITY 0x10
+#define SB_RUN_TIME_TO_EMPTY 0x11
+#define SB_AVERAGE_TIME_TO_EMPTY 0x12
+#define SB_AVERAGE_TIME_TO_FULL 0x13
+#define SB_CHARGING_CURRENT 0x14
+#define SB_CHARGING_VOLTAGE 0x15
+#define SB_BATTERY_STATUS 0x16
+#define SB_CYCLE_COUNT 0x17
+#define SB_DESIGN_CAPACITY 0x18
+#define SB_DESIGN_VOLTAGE 0x19
+#define SB_SPECIFICATION_INFO 0x1a
+#define SB_MANUFACTURER_DATE 0x1b
+#define SB_SERIAL_NUMBER 0x1c
+#define SB_MANUFACTURER_NAME 0x20
+#define SB_DEVICE_NAME 0x21
+#define SB_DEVICE_CHEMISTRY 0x22
+#define SB_MANUFACTURER_DATA 0x23
+
+/* Battery mode */
+#define MODE_CAPACITY (1 << 15)
+#define MODE_CHARGER (1 << 14)
+#define MODE_ALARM (1 << 13)
+#define MODE_PRIMARY_BATTERY (1 << 9)
+#define MODE_CHARGE_CONTROLLER_ENABLED (1 << 8)
+#define MODE_CONDITION_CYCLE (1 << 7)
+#define MODE_PRIMARY_BATTERY_SUPPORT (1 << 1)
+#define MODE_INTERNAL_CHARGE_CONTROLLER (1 << 0)
+/* Battery status */
+#define STATUS_ERR_CODE_MASK 0xf
+#define STATUS_CODE_OK 0
+#define STATUS_CODE_BUSY 1
+#define STATUS_CODE_RESERVED 2
+#define STATUS_CODE_UNSUPPORTED 3
+#define STATUS_CODE_ACCESS_DENIED 4
+#define STATUS_CODE_OVERUNDERFLOW 5
+#define STATUS_CODE_BADSIZE 6
+#define STATUS_CODE_UNKNOWN_ERROR 7
+#define STATUS_FULLY_DISCHARGED (1 << 4)
+#define STATUS_FULLY_CHARGED (1 << 5)
+#define STATUS_DISCHARGING (1 << 6)
+#define STATUS_INITIALIZING (1 << 7)
+#define STATUS_REMAINING_TIME_ALARM (1 << 8)
+#define STATUS_REMAINING_CAPACITY_ALARM (1 << 9)
+#define STATUS_TERMINATE_DISCHARGE_ALARM (1 << 11)
+#define STATUS_OVERTEMP_ALARM (1 << 12)
+#define STATUS_TERMINATE_CHARGE_ALARM (1 << 14)
+#define STATUS_OVERCHARGED_ALARM (1 << 15)
+
+/* Charger alarm warning */
+#define ALARM_OVER_CHARGE 0x8000
+#define ALARM_TERMINATE_CHARG 0x4000
+#define ALARM_RESERVED_2000 0x2000
+#define ALARM_OVER_TEMP 0x1000
+#define ALARM_TERMINATE_DISCHARGE 0x0800
+#define ALARM_RESERVED_0400 0x0400
+#define ALARM_REMAINING_CAPACITY 0x0200
+#define ALARM_REMAINING_TIME 0x0100
+#define ALARM_STATUS_INITIALIZE 0x0080
+#define ALARM_STATUS_DISCHARGING 0x0040
+#define ALARM_STATUS_FULLY_CHARGED 0x0020
+#define ALARM_STATUS_FULLY_DISCHARG 0x0010
+/* Charge mode */
+#define CHARGE_FLAG_INHIBIT_CHARGE (1 << 0)
+#define CHARGE_FLAG_ENABLE_POLLING (1 << 1)
+#define CHARGE_FLAG_POR_RESET (1 << 2)
+#define CHARGE_FLAG_RESET_TO_ZERO (1 << 3)
+/* Charger status */
+#define CHARGER_CHARGE_INHIBITED (1 << 0)
+#define CHARGER_POLLING_ENABLED (1 << 1)
+#define CHARGER_VOLTAGE_NOTREG (1 << 2)
+#define CHARGER_CURRENT_NOTREG (1 << 3)
+#define CHARGER_LEVEL_2 (1 << 4)
+#define CHARGER_LEVEL_3 (1 << 5)
+#define CHARGER_CURRENT_OR (1 << 6)
+#define CHARGER_VOLTAGE_OR (1 << 7)
+#define CHARGER_RES_OR (1 << 8)
+#define CHARGER_RES_COLD (1 << 9)
+#define CHARGER_RES_HOT (1 << 10)
+#define CHARGER_RES_UR (1 << 11)
+#define CHARGER_ALARM_INHIBITED (1 << 12)
+#define CHARGER_POWER_FAIL (1 << 13)
+#define CHARGER_BATTERY_PRESENT (1 << 14)
+#define CHARGER_AC_PRESENT (1 << 15)
+/* Charger specification info */
+#define INFO_CHARGER_SPEC(INFO) ((INFO) & 0xf)
+#define INFO_SELECTOR_SUPPORT(INFO) (((INFO) >> 4) & 1)
+
+/* Inline helper functions */
+static inline int sbc_read(int cmd, int *param)
+ { return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); }
+
+static inline int sbc_write(int cmd, int param)
+ { return i2c_write16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param); }
+
+static inline int sb_read(int cmd, int *param)
+ { return i2c_read16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, param); }
+
+static inline int sb_write(int cmd, int param)
+ { return i2c_write16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, param); }
+
+/* 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); }
+
+#endif /* __CROS_EC_SMART_BATTERY_H */
+