mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
battery guage enhancements from tni.andro
Signed-off-by: flar2 <asegaert@gmail.com>
This commit is contained in:
parent
40861c769c
commit
c7956f4a0e
1 changed files with 82 additions and 34 deletions
|
@ -16,6 +16,7 @@
|
|||
* more details.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
|
@ -28,6 +29,7 @@
|
|||
#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>
|
||||
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue