battery guage enhancements from tni.andro

Signed-off-by: flar2 <asegaert@gmail.com>
This commit is contained in:
flar2 2013-11-21 20:53:03 -05:00 committed by followmsi
parent 40861c769c
commit c7956f4a0e

View file

@ -16,6 +16,7 @@
* more details.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
@ -28,11 +29,12 @@
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <asm/unaligned.h>
#include <linux/miscdevice.h>
#include <mach/gpio.h>
#include <linux/fastchg.h>
#include <linux/fastchg.h>
#define SMBUS_RETRY (0)
#define GPIOPIN_LOW_BATTERY_DETECT 29
@ -59,7 +61,6 @@
#define THERMAL_RULE1 1
#define THERMAL_RULE2 2
/* Debug Message */
#define BAT_NOTICE(format, arg...) \
printk(KERN_NOTICE "%s " format , __FUNCTION__ , ## arg)
@ -109,7 +110,16 @@ enum {
REG_TIME_TO_FULL,
REG_STATUS,
REG_CAPACITY,
REG_SERIAL_NUMBER,
//REG_SERIAL_NUMBER,
REG_CHARGE_NOW,
REG_CHARGE_UCOMP,
REG_CHARGE_FULL,
REG_CHARGE_DESIGN,
REG_ENERGY,
REG_CHARGE_COUNTER,
REG_POWER,
REG_CYCLE,
REG_MAX
};
@ -137,6 +147,14 @@ static struct bq27541_device_data {
[REG_TIME_TO_FULL] = BQ27541_DATA(TIME_TO_FULL_AVG, 0x18, 0, 65535),
[REG_STATUS] = BQ27541_DATA(STATUS, 0x0a, 0, 65535),
[REG_CAPACITY] = BQ27541_DATA(CAPACITY, 0x2c, 0, 100),
[REG_CHARGE_NOW] = BQ27541_DATA(CHARGE_NOW, 0x10, 0, 65535),
[REG_CHARGE_UCOMP] = BQ27541_DATA(CHARGE_AVG, 0x0c, 0, 65535),
[REG_CHARGE_FULL] = BQ27541_DATA(CHARGE_FULL, 0x12, 0, 65535),
[REG_CHARGE_DESIGN] = BQ27541_DATA(CHARGE_FULL_DESIGN, 0x3c, 0, 65535),
[REG_ENERGY] = BQ27541_DATA(ENERGY_NOW, 0x22, 0, 65535),
[REG_CHARGE_COUNTER] = BQ27541_DATA(CHARGE_COUNTER, 0x34, -32768, 32767),
[REG_POWER] = BQ27541_DATA(POWER_NOW, 0x24, -32768, 32767),
[REG_CYCLE] = BQ27541_DATA(CYCLE_COUNT, 0x2a, 0, 65535),
};
static enum power_supply_property bq27541_properties[] = {
@ -148,6 +166,14 @@ static enum power_supply_property bq27541_properties[] = {
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_CHARGE_AVG,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_NOW,
POWER_SUPPLY_PROP_CHARGE_COUNTER,
POWER_SUPPLY_PROP_POWER_NOW,
POWER_SUPPLY_PROP_CYCLE_COUNT
};
unsigned get_cable_status(void)
@ -276,7 +302,7 @@ static struct bq27541_device_info {
int old_temperature;
bool temp_err;
unsigned int prj_id;
spinlock_t lock;
struct mutex lock;
} *bq27541_device;
static int bq27541_read_i2c(u8 reg, int *rt_value, int b_single)
@ -361,26 +387,6 @@ static const struct attribute_group battery_smbus_group = {
.attrs = battery_smbus_attributes,
};
static int bq27541_battery_current(void)
{
int ret;
int curr = 0;
ret = bq27541_read_i2c(bq27541_data[REG_CURRENT].addr, &curr, 0);
if (ret) {
BAT_ERR("error reading current ret = %x\n", ret);
return 0;
}
curr = (s16)curr;
if (curr >= bq27541_data[REG_CURRENT].min_value &&
curr <= bq27541_data[REG_CURRENT].max_value) {
return curr;
} else
return 0;
}
static void battery_status_poll(struct work_struct *work)
{
struct bq27541_device_info *batt_dev = container_of(work, struct bq27541_device_info, status_poll_work.work);
@ -555,6 +561,42 @@ static int bq27541_get_psp(int reg_offset, enum power_supply_property psp,
return -EINVAL;
}
if (psp == POWER_SUPPLY_PROP_CHARGE_NOW) {
val->intval = rt_value * 1000;
BAT_NOTICE("charge_now (compensated) = %u uAh\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_CHARGE_AVG) {
val->intval = rt_value * 1000;
BAT_NOTICE("charge_avg (uncompensated) = %u uAh\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_CHARGE_FULL) {
val->intval = rt_value * 1000;
BAT_NOTICE("charge_full = %u uAh\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN) {
val->intval = rt_value * 1000;
BAT_NOTICE("charge_design = %u uAh\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_ENERGY_NOW) {
val->intval = rt_value * 1000;
BAT_NOTICE("energy_now = %u uWh\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_CHARGE_COUNTER) {
val->intval = ((s16) rt_value) * 1000;
BAT_NOTICE("charge_counter = %d uWh\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_POWER_NOW) {
val->intval = ((s16) rt_value) * 1000;
BAT_NOTICE("power_now = %d uW\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_CYCLE_COUNT) {
val->intval = rt_value;
BAT_NOTICE("cycle count = %u\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_CURRENT_NOW) {
val->intval = (s16)rt_value;
BAT_NOTICE("current_now = %d mA\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_VOLTAGE_NOW) {
if (rt_value >= bq27541_data[REG_VOLTAGE].min_value &&
rt_value <= bq27541_data[REG_VOLTAGE].max_value) {
@ -613,11 +655,6 @@ static int bq27541_get_psp(int reg_offset, enum power_supply_property psp,
bq27541_device->old_temperature = val->intval = ret;
BAT_NOTICE("temperature= %d (0.1¢XC)\n", val->intval);
}
if (psp == POWER_SUPPLY_PROP_CURRENT_NOW) {
val->intval = bq27541_device->bat_current
= bq27541_battery_current();
BAT_NOTICE("current = %d mA\n", val->intval);
}
return 0;
}
@ -723,6 +760,9 @@ static int bq27541_get_property(struct power_supply *psy,
union power_supply_propval *val)
{
u8 count;
mutex_lock(&bq27541_device->lock);
switch (psp) {
case POWER_SUPPLY_PROP_PRESENT:
case POWER_SUPPLY_PROP_HEALTH:
@ -743,28 +783,36 @@ static int bq27541_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
case POWER_SUPPLY_PROP_CURRENT_NOW:
case POWER_SUPPLY_PROP_TEMP:
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
case POWER_SUPPLY_PROP_SERIAL_NUMBER:
case POWER_SUPPLY_PROP_CHARGE_NOW:
case POWER_SUPPLY_PROP_CHARGE_AVG:
case POWER_SUPPLY_PROP_CHARGE_FULL:
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
case POWER_SUPPLY_PROP_ENERGY_NOW:
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
case POWER_SUPPLY_PROP_POWER_NOW:
case POWER_SUPPLY_PROP_CYCLE_COUNT:
for (count = 0; count < REG_MAX; count++) {
if (psp == bq27541_data[count].psp)
break;
}
if (bq27541_get_psp(count, psp, val))
return -EINVAL;
goto error;
break;
default:
dev_err(&bq27541_device->client->dev,
"%s: INVALID property psp=%u\n", __func__,psp);
return -EINVAL;
goto error;
}
mutex_unlock(&bq27541_device->lock);
return 0;
error:
mutex_unlock(&bq27541_device->lock);
return -EINVAL;
}
@ -788,6 +836,7 @@ static int bq27541_probe(struct i2c_client *client,
bq27541_device->old_temperature = 0xFF;
bq27541_device->gpio_low_battery_detect = GPIOPIN_LOW_BATTERY_DETECT;
bq27541_device->bat_capacity_zero_count = 0;
mutex_init(&bq27541_device->lock);
for (i = 0; i < ARRAY_SIZE(bq27541_supply); i++) {
ret = power_supply_register(&client->dev, &bq27541_supply[i]);
@ -805,7 +854,6 @@ static int bq27541_probe(struct i2c_client *client,
INIT_DELAYED_WORK(&bq27541_device->low_low_bat_work, low_low_battery_check);
cancel_delayed_work(&bq27541_device->status_poll_work);
spin_lock_init(&bq27541_device->lock);
wake_lock_init(&bq27541_device->low_battery_wake_lock, WAKE_LOCK_SUSPEND, "low_battery_detection");
wake_lock_init(&bq27541_device->cable_wake_lock,
WAKE_LOCK_SUSPEND, "cable_state_changed");