/*
* BQ27xxx battery driver
*
* Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>
* Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
* Copyright (C) 2010-2011 Lars-Peter Clausen <lars@metafoo.de>
* Copyright (C) 2011 Pali Rohár <pali.rohar@gmail.com>
*
* Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Datasheets:
* http://www.ti.com/product/bq27000
* http://www.ti.com/product/bq27200
* http://www.ti.com/product/bq27010
* http://www.ti.com/product/bq27210
* http://www.ti.com/product/bq27500
* http://www.ti.com/product/bq27510-g3
* http://www.ti.com/product/bq27520-g4
* http://www.ti.com/product/bq27530-g1
* http://www.ti.com/product/bq27531-g1
* http://www.ti.com/product/bq27541-g1
* http://www.ti.com/product/bq27542-g1
* http://www.ti.com/product/bq27546-g1
* http://www.ti.com/product/bq27742-g1
* http://www.ti.com/product/bq27545-g1
* http://www.ti.com/product/bq27421-g1
* http://www.ti.com/product/bq27425-g1
* http://www.ti.com/product/bq27411-g1
* http://www.ti.com/product/bq27621-g1
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/param.h>
#include <linux/jiffies.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/power/bq27xxx_battery.h>
#define DRIVER_VERSION "1.2.0"
#define BQ27XXX_MANUFACTURER "Texas Instruments"
/* BQ27XXX Flags */
#define BQ27XXX_FLAG_DSC BIT(0)
#define BQ27XXX_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */
#define BQ27XXX_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */
#define BQ27XXX_FLAG_FC BIT(9)
#define BQ27XXX_FLAG_OTD BIT(14)
#define BQ27XXX_FLAG_OTC BIT(15)
#define BQ27XXX_FLAG_UT BIT(14)
#define BQ27XXX_FLAG_OT BIT(15)
/* BQ27000 has different layout for Flags register */
#define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */
#define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */
#define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */
#define BQ27000_FLAG_FC BIT(5)
#define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */
#define BQ27XXX_RS (20) /* Resistor sense mOhm */
#define BQ27XXX_POWER_CONSTANT (29200) /* 29.2 µV^2 * 1000 */
#define BQ27XXX_CURRENT_CONSTANT (3570) /* 3.57 µV * 1000 */
#define INVALID_REG_ADDR 0xff
/*
* bq27xxx_reg_index - Register names
*
* These are indexes into a device's register mapping array.
*/
enum bq27xxx_reg_index {
BQ27XXX_REG_CTRL = 0, /* Control */
BQ27XXX_REG_TEMP, /* Temperature */
BQ27XXX_REG_INT_TEMP, /* Internal Temperature */
BQ27XXX_REG_VOLT, /* Voltage */
BQ27XXX_REG_AI, /* Average Current */
BQ27XXX_REG_FLAGS, /* Flags */
BQ27XXX_REG_TTE, /* Time-to-Empty */
BQ27XXX_REG_TTF, /* Time-to-Full */
BQ27XXX_REG_TTES, /* Time-to-Empty Standby */
BQ27XXX_REG_TTECP, /* Time-to-Empty at Constant Power */
BQ27XXX_REG_NAC, /* Nominal Available Capacity */
BQ27XXX_REG_FCC, /* Full Charge Capacity */
BQ27XXX_REG_CYCT, /* Cycle Count */
BQ27XXX_REG_AE, /* Available Energy */
BQ27XXX_REG_SOC, /* State-of-Charge */
BQ27XXX_REG_DCAP, /* Design Capacity */
BQ27XXX_REG_AP, /* Average Power */
};
/* Register mappings */
static u8 bq27000_regs[] = {
0x00, /* CONTROL */
0x06, /* TEMP */
INVALID_REG_ADDR, /* INT TEMP - NA*/
0x08, /* VOLT */
0x14, /* AVG CURR */
0x0a, /* FLAGS */
0x16, /* TTE */
0x18, /* TTF */
0x1c, /* TTES */
0x26, /* TTECP */
0x0c, /* NAC */
0x12, /* LMD(FCC) */
0x2a, /* CYCT */
0x22, /* AE */
0x0b, /* SOC(RSOC) */
0x76, /* DCAP(ILMD) */
0x24, /* AP */
};
static u8 bq27010_regs[] = {
0x00, /* CONTROL */
0x06, /* TEMP */
INVALID_REG_ADDR, /* INT TEMP - NA*/
0x08, /* VOLT */
0x14, /* AVG CURR */
0x0a, /* FLAGS */
0x16, /* TTE */
0x18, /* TTF */
0x1c, /* TTES */
0x26, /* TTECP */
0x0c, /* NAC */
0x12, /* LMD(FCC) */
0x2a, /* CYCT */
INVALID_REG_ADDR, /* AE - NA */
0x0b, /* SOC(RSOC) */
0x76, /* DCAP(ILMD) */
INVALID_REG_ADDR, /* AP - NA */
};
static u8 bq27500_regs[] = {
0x00, /* CONTROL */
0x06, /* TEMP */
0x28, /* INT TEMP */
0x08, /* VOLT */
0x14, /* AVG CURR */
0x0a, /* FLAGS */
0x16, /* TTE */
INVALID_REG_ADDR, /* TTF - NA */
0x1a, /* TTES */
INVALID_REG_ADDR, /* TTECP - NA */
0x0c, /* NAC */
0x12, /* LMD(FCC) */
0x2a, /* CYCT */
INVALID_REG_ADDR, /* AE - NA */
0x2c, /* SOC(RSOC) */
0x3c, /* DCAP(ILMD) */
INVALID_REG_ADDR, /* AP - NA */
};
static u8 bq27530_regs[] = {
0x00, /* CONTROL */
0x06, /* TEMP */
0x32, /* INT TEMP */
0x08, /* VOLT */
0x14, /* AVG CURR */
0x0a, /* FLAGS */
0x16, /* TTE */
INVALID_REG_ADDR, /* TTF - NA */
INVALID_REG_ADDR, /* TTES - NA */
INVALID_REG_ADDR, /* TTECP - NA */
0x0c, /* NAC */
0x12, /* LMD(FCC) */
0x2a, /* CYCT */
INVALID_REG_ADDR, /* AE - NA */
0x2c, /* SOC(RSOC) */
INVALID_REG_ADDR,