/*
* Battery driver for Marvell 88PM860x PMIC
*
* Copyright (c) 2012 Marvell International Ltd.
* Author: Jett Zhou <jtzhou@marvell.com>
* Haojian Zhuang <haojian.zhuang@marvell.com>
*
* This program 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.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/power_supply.h>
#include <linux/mfd/88pm860x.h>
#include <linux/delay.h>
/* bit definitions of Status Query Interface 2 */
#define STATUS2_CHG (1 << 2)
#define STATUS2_BAT (1 << 3)
#define STATUS2_VBUS (1 << 4)
/* bit definitions of Measurement Enable 1 Register */
#define MEAS1_TINT (1 << 3)
#define MEAS1_GP1 (1 << 5)
/* bit definitions of Measurement Enable 3 Register */
#define MEAS3_IBAT (1 << 0)
#define MEAS3_BAT_DET (1 << 1)
#define MEAS3_CC (1 << 2)
/* bit definitions of Measurement Off Time Register */
#define MEAS_OFF_SLEEP_EN (1 << 1)
/* bit definitions of GPADC Bias Current 2 Register */
#define GPBIAS2_GPADC1_SET (2 << 4)
/* GPADC1 Bias Current value in uA unit */
#define GPBIAS2_GPADC1_UA ((GPBIAS2_GPADC1_SET >> 4) * 5 + 1)
/* bit definitions of GPADC Misc 1 Register */
#define GPMISC1_GPADC_EN (1 << 0)
/* bit definitions of Charger Control 6 Register */
#define CC6_BAT_DET_GPADC1 1
/* bit definitions of Coulomb Counter Reading Register */
#define CCNT_AVG_SEL (4 << 3)
/* bit definitions of RTC miscellaneous Register1 */
#define RTC_SOC_5LSB (0x1F << 3)
/* bit definitions of RTC Register1 */
#define RTC_SOC_3MSB (0x7)
/* bit definitions of Power up Log register */
#define BAT_WU_LOG (1<<6)
/* coulomb counter index */
#define CCNT_POS1 0
#define CCNT_POS2 1
#define CCNT_NEG1 2
#define CCNT_NEG2 3
#define CCNT_SPOS 4
#define CCNT_SNEG 5
/* OCV -- Open Circuit Voltage */
#define OCV_MODE_ACTIVE 0
#define OCV_MODE_SLEEP 1
/* Vbat range of CC for measuring Rbat */
#define LOW_BAT_THRESHOLD 3600
#define VBATT_RESISTOR_MIN 3800
#define VBATT_RESISTOR_MAX 4100
/* TBAT for batt, TINT for chip itself */
#define PM860X_TEMP_TINT (0)
#define PM860X_TEMP_TBAT (1)
/*
* Battery temperature based on NTC resistor, defined
* corresponding resistor value -- Ohm / C degeree.
*/
#define TBAT_NEG_25D 127773 /* -25 */
#define TBAT_NEG_10D 54564 /* -10 */
#define TBAT_0D 32330 /* 0 */
#define TBAT_10D 19785 /* 10 */
#define TBAT_20D 12468 /* 20 */
#define TBAT_30D 8072 /* 30 */
#define TBAT_40D 5356 /* 40 */
struct pm860x_battery_info {
struct pm860x_chip *chip;
struct i2c_client *i2c;
struct device *dev;
struct power_supply *battery;
struct mutex lock;
int status;
int irq_cc;
int irq_batt;
int max_capacity;
int resistor; /* Battery Internal Resistor */
int last_capacity;
int start_soc;
unsigned present:1;
unsigned temp_type:1; /* TINT or TBAT */
};
struct ccnt {
unsigned long long int pos;
unsigned long long int neg;
unsigned int spos;
unsigned int sneg;
int total_chg; /* mAh(3.6C) */
int total_dischg; /* mAh(3.6C) */
};
/*
* State of Charge.
* The first number is mAh(=3.6C), and the second number is percent point.
*/
static int array_soc[][2] = {
{4170, 100}, {4154, 99}, {4136, 98}, {4122, 97}, {4107, 96},
{4102, 95}, {4088, 94}, {4081, 93}, {4070, 92}, {4060, 91},
{4053, 90}, {4044, 89}, {4035, 88}, {4028, 87}, {4019, 86},
{4013, 85}, {4006, 84}, {3995, 83}, {3987, 82}, {3982, 81},
{3976, 80}, {3968, 79}, {3962, 78}, {3954, 77}, {3946, 76},
{3941, 75}, {3934, 74}, {3929, 73}, {3922, 72}, {3916, 71},
{3910, 70}, {3904, 69}, {3898, 68}, {3892, 67}, {3887, 66},
{3880, 65}, {3874, 64}, {3868, 63}, {3862, 62}, {3854, 61},
{3849, 60}, {3843, 59}, {3840, 58}, {3833, 57}, {3829, 56},
{3824, 55}, {3818, 54}, {3815, 53}, {3810, 52}, {3808, 51},
{3804, 50}, {3801, 49}, {3798, 48}, {3796, 47}, {3792, 46},
{3789, 45}, {3785, 44}, {3784, 43}, {3782, 42}, {3780, 41},
{3777, 40}, {3776, 39}, {3774, 38}, {3772, 37}, {3771, 36},
{3769, 35}, {3768, 34