summaryrefslogtreecommitdiff
path: root/driver/battery/bq27541.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-10-16 13:23:10 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-10-23 20:07:25 +0000
commit8cf03ac0563294fbdeca2dc133d06f0b51c9a546 (patch)
tree6b07c493e7567a3221d8592b4337d2787d6bc531 /driver/battery/bq27541.c
parent2464d08e4d310a3f63208f22df4502c5250c4b58 (diff)
downloadchrome-ec-8cf03ac0563294fbdeca2dc133d06f0b51c9a546.tar.gz
Move source files to driver/ and power/ subdirs
The common/ subdir was getting cluttered. Move drivers for external components to a new driver/ tree, and move what used to be called chipset_*.c to a new power/ directory. This does not move/rename header files or CONFIG options. That will be done in subsequent steps, since moving and modifying .c files in the same CL is harder to review. BUG=chrome-os-partner:18343 BRANCH=none TEST=build all boards; pass unit tests Change-Id: I67a3003dc8564783a320335cf0e9620a21982d5e Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/173601 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Tested-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Vic Yang <victoryang@chromium.org>
Diffstat (limited to 'driver/battery/bq27541.c')
-rw-r--r--driver/battery/bq27541.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/driver/battery/bq27541.c b/driver/battery/bq27541.c
new file mode 100644
index 0000000000..3dce19ea54
--- /dev/null
+++ b/driver/battery/bq27541.c
@@ -0,0 +1,219 @@
+/* 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 *dest, int size)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int battery_device_chemistry(char *dest, int 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_charging_allowed(int *allowed)
+{
+ int rv, val;
+
+ rv = bq27541_read(REG_FLAGS, &val);
+ if (rv)
+ return rv;
+ *allowed = (val & 0x100);
+ return EC_SUCCESS;
+}
+
+int battery_desired_current(int *current)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int battery_get_mode(int *mode)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int battery_is_in_10mw_mode(int *val)
+{
+ /* Always using mAh unit */
+ *val = 0;
+ return EC_SUCCESS;
+}
+
+int battery_set_10mw_mode(int enabled)
+{
+ /* Not supported by this battery chip */
+ return EC_ERROR_INVAL;
+}