From 8cf03ac0563294fbdeca2dc133d06f0b51c9a546 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Wed, 16 Oct 2013 13:23:10 -0700 Subject: 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 Reviewed-on: https://chromium-review.googlesource.com/173601 Reviewed-by: Bill Richardson Tested-by: Bill Richardson Reviewed-by: Vic Yang --- driver/battery/bq27541.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 driver/battery/bq27541.c (limited to 'driver/battery/bq27541.c') 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; +} -- cgit v1.2.1