summaryrefslogtreecommitdiff
path: root/driver/battery/bq27541.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/battery/bq27541.c')
-rw-r--r--driver/battery/bq27541.c432
1 files changed, 0 insertions, 432 deletions
diff --git a/driver/battery/bq27541.c b/driver/battery/bq27541.c
deleted file mode 100644
index b39147092f..0000000000
--- a/driver/battery/bq27541.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/* Copyright 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/BQ27542/BQ27741/BQ27742.
- */
-
-#include "battery.h"
-#include "battery_smart.h"
-#include "console.h"
-#include "extpower.h"
-#include "hooks.h"
-#include "i2c.h"
-#include "util.h"
-
-#define BQ27541_ADDR_FLAGS 0x55
-#define BQ27541_TYPE_ID 0x0541
-#define BQ27542_TYPE_ID 0x0542
-#define BQ27741_TYPE_ID 0x0741
-#define BQ27742_TYPE_ID 0x0742
-
-#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_DATA_FLASH_BLOCK 0x3f
-#define REG_DESIGN_CAPACITY 0x3c
-#define REG_MANUFACTURER_INFO 0x52
-#define REG_DEVICE_NAME_LENGTH 0x62
-#define MAX_DEVICE_NAME_LENGTH 7
-#define REG_DEVICE_NAME 0x63
-#define REG_PROTECTOR 0x6d
-
-/* Over-charge */
-#define BQ27542_FLAG_BATHI BIT(13)
-/* Over Temperature in discharge */
-#define BQ27542_FLAG_OTD BIT(11)
-/* Over Temperature in charge */
-#define BQ27542_FLAG_OTC BIT(7)
-/* Charge allowed */
-#define BQ27542_FLAG_CHG BIT(3)
-/* Discharge */
-#define BQ27542_FLAG_DSG BIT(0)
-
-static int battery_type_id;
-static int fake_state_of_charge = -1;
-
-static int bq27541_read(int offset, int *data)
-{
- return i2c_read16(I2C_PORT_BATTERY, BQ27541_ADDR, offset, data);
-}
-
-static int bq27541_read8(int offset, int *data)
-{
- return i2c_read8(I2C_PORT_BATTERY, BQ27541_ADDR, offset, data);
-}
-
-static int bq27541_write(int offset, int data)
-{
- return i2c_write16(I2C_PORT_BATTERY, BQ27541_ADDR, offset, data);
-}
-
-int bq27541_probe(void)
-{
- int rv;
-
- rv = bq27541_write(REG_CTRL, 0x1);
- rv |= bq27541_read(REG_CTRL, &battery_type_id);
- /* Read twice to get the right value */
- rv |= bq27541_read(REG_CTRL, &battery_type_id);
- if (rv)
- return rv;
- if (battery_type_id == BQ27541_TYPE_ID ||
- battery_type_id == BQ27542_TYPE_ID ||
- battery_type_id == BQ27741_TYPE_ID ||
- battery_type_id == BQ27742_TYPE_ID)
- return EC_SUCCESS;
- return EC_ERROR_UNKNOWN;
-}
-
-static void probe_type_id(void)
-{
- bq27541_probe();
-}
-DECLARE_HOOK(HOOK_INIT, probe_type_id, HOOK_PRIO_DEFAULT);
-
-int battery_device_name(char *device_name, int buf_size)
-{
- int rv, i, val;
- int len = MIN(7, buf_size - 1);
-
- if (battery_type_id == BQ27742_TYPE_ID) {
- /* No device name register available */
- strzcpy(device_name, "<BATT>", len);
- return 0;
- }
- /* Battery pack vendor specific */
- if (battery_type_id == BQ27542_TYPE_ID) {
- rv = bq27541_write(REG_DATA_FLASH_BLOCK, 0x1);
- for (i = 0; i < len; ++i) {
- rv |= bq27541_read8(REG_MANUFACTURER_INFO + i, &val);
- device_name[i] = val;
- }
- device_name[i] = '\0';
- return rv;
- }
-
- 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_state_of_charge_abs(int *percent)
-{
- return bq27541_read(REG_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_time_at_rate(int rate, int *minutes)
-{
- int rv;
-
- if (battery_type_id == BQ27542_TYPE_ID)
- return EC_ERROR_UNIMPLEMENTED;
-
- rv = bq27541_write(REG_AT_RATE, rate);
- if (rv)
- return rv;
- return bq27541_read(REG_AT_RATE_TIME_TO_EMPTY, minutes);
-}
-
-int battery_device_chemistry(char *dest, int size)
-{
- strzcpy(dest, "<unkn>", size);
-
- return EC_SUCCESS;
-}
-
-int battery_serial_number(int *serial)
-{
- *serial = 0x0BAD0BAD;
-
- return EC_SUCCESS;
-}
-
-int battery_manufacture_date(int *year, int *month, int *day)
-{
- return EC_ERROR_UNIMPLEMENTED;
-}
-
-int battery_design_voltage(int *voltage)
-{
- *voltage = battery_get_info()->voltage_normal;
-
- return EC_SUCCESS;
-}
-
-/**
- * Check if battery allows charging.
- *
- * @param allowed Non-zero if charging allowed; zero if not allowed.
- * @return non-zero if error.
- */
-static int battery_charging_allowed(int *allowed)
-{
- int rv, val;
-
- rv = bq27541_read(REG_FLAGS, &val);
- if (rv)
- return rv;
- if (battery_type_id == BQ27541_TYPE_ID ||
- battery_type_id == BQ27741_TYPE_ID)
- *allowed = (val & 0x100);
- else /* BQ27742_TYPE_ID, BQ27542_TYPE_ID */
- *allowed = (val & 0x8);
-
- return EC_SUCCESS;
-}
-
-int battery_get_mode(int *mode)
-{
- return EC_ERROR_UNIMPLEMENTED;
-}
-
-int battery_status(int *status)
-{
- int rv;
- int flag = 0;
-
- *status = 0;
- if (battery_type_id == BQ27542_TYPE_ID) {
- rv = bq27541_read(REG_FLAGS, &flag);
- if (rv)
- return rv;
-
- if (flag & (BQ27542_FLAG_OTC | BQ27542_FLAG_OTD))
- *status |= STATUS_OVERTEMP_ALARM;
- if (flag & BQ27542_FLAG_DSG)
- *status |= STATUS_DISCHARGING;
- if (flag & BQ27542_FLAG_BATHI)
- *status |= STATUS_OVERCHARGED_ALARM;
-
- return EC_SUCCESS;
- }
-
- return EC_ERROR_UNIMPLEMENTED;
-}
-
-enum battery_present battery_is_present(void)
-{
- int v;
- if (bq27541_read(REG_TEMPERATURE, &v))
- return BP_NO;
- return BP_YES;
-}
-
-void battery_get_params(struct batt_params *batt)
-{
- int v;
- const uint32_t flags_to_check = BATT_FLAG_BAD_TEMPERATURE |
- BATT_FLAG_BAD_STATE_OF_CHARGE |
- BATT_FLAG_BAD_VOLTAGE |
- BATT_FLAG_BAD_CURRENT;
-
- /* Reset flags */
- batt->flags = 0;
-
- if (bq27541_read(REG_TEMPERATURE, &batt->temperature))
- batt->flags |= BATT_FLAG_BAD_TEMPERATURE;
-
- if (bq27541_read8(REG_STATE_OF_CHARGE, &v) && fake_state_of_charge < 0)
- batt->flags |= BATT_FLAG_BAD_STATE_OF_CHARGE;
-
- batt->state_of_charge = fake_state_of_charge >= 0 ?
- fake_state_of_charge : v;
-
- if (bq27541_read(REG_VOLTAGE, &batt->voltage))
- batt->flags |= BATT_FLAG_BAD_VOLTAGE;
-
- v = 0;
- if (bq27541_read(REG_AVERAGE_CURRENT, &v))
- batt->flags |= BATT_FLAG_BAD_CURRENT;
- batt->current = (int16_t)v;
-
- if (battery_remaining_capacity(&batt->remaining_capacity))
- batt->flags |= BATT_FLAG_BAD_REMAINING_CAPACITY;
-
- if (battery_full_charge_capacity(&batt->full_capacity))
- batt->flags |= BATT_FLAG_BAD_FULL_CAPACITY;
-
- /* Default to not desiring voltage and current */
- batt->desired_voltage = batt->desired_current = 0;
-
- /* If any of those reads worked, the battery is responsive */
- if ((batt->flags & flags_to_check) != flags_to_check) {
- batt->flags |= BATT_FLAG_RESPONSIVE;
- batt->is_present = BP_YES;
- } else {
-
- /* If all of those reads error, the battery is not present */
- batt->is_present = BP_NO;
- }
-
- /* update the battery status */
- if (battery_status(&batt->status))
- batt->flags |= BATT_FLAG_BAD_STATUS;
-
- v = 0;
- if (battery_charging_allowed(&v)) {
- batt->flags |= BATT_FLAG_BAD_ANY;
- } else if (v) {
- batt->flags |= BATT_FLAG_WANT_CHARGE;
-
- /*
- * Desired voltage and current are not provided by the battery.
- * So ask for battery's max voltage and an arbitrarily large
- * current.
- */
- batt->desired_voltage = battery_get_info()->voltage_max;
- batt->desired_current = 4096;
- }
-}
-
-/* Wait until battery is totally stable */
-int battery_wait_for_stable(void)
-{
- /* TODO(crosbug.com/p/30426): implement me */
- return EC_SUCCESS;
-}
-
-#ifdef CONFIG_BATTERY_REVIVE_DISCONNECT
-/*
- * Check if battery is in disconnect state, a state entered by pulling
- * BATT_DISCONN_N low, and clear that state if we have external power plugged
- * and no battery faults are detected. Disconnect state resembles battery
- * shutdown mode, but extra steps must be taken to get the battery out of this
- * mode.
- */
-enum battery_disconnect_state battery_get_disconnect_state(void)
-{
- int val, rv;
- /*
- * Take note if we find that the battery isn't in disconnect state,
- * and always return NOT_DISCONNECTED without probing the battery.
- * This assumes the battery will not go to disconnect state during
- * runtime.
- */
- static int not_disconnected;
-
- if (not_disconnected)
- return BATTERY_NOT_DISCONNECTED;
-
- if (extpower_is_present()) {
- /* Check DSG_OFF bit */
- rv = bq27541_read(REG_PROTECTOR, &val);
- if (rv)
- return BATTERY_DISCONNECT_ERROR;
- if (!(val & BIT(6))) {
- not_disconnected = 1;
- return BATTERY_NOT_DISCONNECTED;
- }
-
- /* DSG_OFF is set. Verify this is not due to a safety fault */
- if (val & 0x3f)
- return BATTERY_DISCONNECT_ERROR;
- rv = bq27541_read(REG_FLAGS, &val);
- if (rv)
- return BATTERY_DISCONNECT_ERROR;
- if (val & 0xfc60)
- return BATTERY_DISCONNECT_ERROR;
- return BATTERY_DISCONNECTED;
- }
- not_disconnected = 1;
- return BATTERY_NOT_DISCONNECTED;
-}
-#endif /* CONFIG_BATTERY_REVIVE_DISCONNECT */
-
-static int command_battfake(int argc, char **argv)
-{
- char *e;
- int v;
-
- if (argc == 2) {
- v = strtoi(argv[1], &e, 0);
- if (*e || v < -1 || v > 100)
- return EC_ERROR_PARAM1;
-
- fake_state_of_charge = v;
- }
-
- if (fake_state_of_charge >= 0)
- ccprintf("Fake batt %d%%\n",
- fake_state_of_charge);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(battfake, command_battfake,
- "percent (-1 = use real level)",
- "Set fake battery level");
-
-#ifdef CONFIG_CMD_PWR_AVG
-int battery_get_avg_current(void)
-{
- int current = -EC_ERROR_UNKNOWN;
-
- bq27541_read(REG_AVERAGE_CURRENT, &current);
- return current;
-}
-
-int battery_get_avg_voltage(void)
-{
- /* BQ27541 does not have this parameter */
- return -EC_ERROR_UNIMPLEMENTED;
-}
-#endif /* CONFIG_CMD_PWR_AVG */
-