aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorAnand Gadiyar <gadiyar@ti.com>2012-04-30 19:36:38 +0530
committerZiyann <jaraidaniel@gmail.com>2014-10-01 13:01:10 +0200
commit77bfbfa46a3fbc119f6073ca7d42f464def62fea (patch)
tree323cb0a498fa145d8af399903552a0cb9a1d9e20 /drivers/power
parent4cc9827515b9bc0d4dad7e6c9c9c1386bcaf4f8b (diff)
downloadkernel_samsung_tuna-77bfbfa46a3fbc119f6073ca7d42f464def62fea.zip
kernel_samsung_tuna-77bfbfa46a3fbc119f6073ca7d42f464def62fea.tar.gz
kernel_samsung_tuna-77bfbfa46a3fbc119f6073ca7d42f464def62fea.tar.bz2
twl6030 battery: use gas gauge for capacity estimation
Use the gas gauge in twl6030 to estimate the remaining battery capacity. At bootup, we use an estimate of initial capacity using the measured battery voltage at bootup. From that point on, all future battery capacity estimations are done by using the gas gauge to measure all addition/removal of charge from the battery. Clamp battery value to 99% if the measured value exceeds 99%. A later patch will add the code to update the initial estimate once the battery is fully charged. TODO: Minimum safe battery voltage reporting needs to be worked on Change-Id: Iab157b559f9de432a93664e8d78c003af3c75b67 Signed-off-by: Sivakumar Pothireddy <sivakumar.pothireddy@ti.com> Signed-off-by: Anand Gadiyar <gadiyar@ti.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/twl6030_bci_battery.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/power/twl6030_bci_battery.c b/drivers/power/twl6030_bci_battery.c
index 5d44d8d..a92840e 100644
--- a/drivers/power/twl6030_bci_battery.c
+++ b/drivers/power/twl6030_bci_battery.c
@@ -300,6 +300,7 @@ struct twl6030_bci_device_info {
unsigned int capacity;
unsigned int capacity_debounce_count;
+ unsigned int boot_capacity_mAh;
unsigned long ac_next_refresh;
unsigned int prev_capacity;
unsigned int wakelock_enabled;
@@ -328,6 +329,9 @@ struct twl6030_bci_device_info {
unsigned int min_vbus_val;
};
+/* FIXME: Make this a platform data passed down from the board file */
+#define BATT_CAPACITY_MAH 4000
+
/* Battery capacity estimation table */
struct batt_capacity_chart {
int volt;
@@ -1659,6 +1663,9 @@ static int capacity_changed(struct twl6030_bci_device_info *di)
int curr_capacity = di->capacity;
int charger_source = di->charger_source;
int charging_disabled = 0;
+ s32 acc_value, samples = 0;
+ int accumulated_charge;
+ int ret;
/* Because system load is always greater than
* termination current, we will never get a CHARGE DONE
@@ -1722,6 +1729,47 @@ static int capacity_changed(struct twl6030_bci_device_info *di)
twl6030_start_usb_charger(di);
}
+ /* FG_REG_01, 02, 03 is 24 bit unsigned sample counter value */
+ ret = twl_i2c_read(TWL6030_MODULE_GASGAUGE, (u8 *) &samples,
+ FG_REG_01, 3);
+ if (ret < 0)
+ dev_dbg(di->dev, "Could not read fuel gauge samples\n");
+ /*
+ * FG_REG_04, 5, 6, 7 is 32 bit signed accumulator value
+ * accumulates instantaneous current value
+ */
+ ret = twl_i2c_read(TWL6030_MODULE_GASGAUGE, (u8 *) &acc_value,
+ FG_REG_04, 4);
+ if (ret < 0)
+ dev_dbg(di->dev, "Could not read fuel gauge accumulator\n");
+
+ /*
+ * 3000 mA maps to a count of 4096 per sample
+ * We have 4 samples per second
+ * Charge added in one second == (acc_value * 3000 / (4 * 4096))
+ * mAh added == (Charge added in one second / 3600)
+ * mAh added == acc_value * (3000/3600) / (4 * 4096)
+ * mAh added == acc_value * (5/6) / (2^14)
+ * Using 5/6 instead of 3000 to avoid overflow
+ * FIXME: revisit this code for overflows
+ * FIXME: Take care of different value of samples/sec
+ */
+
+ accumulated_charge = ((acc_value - (di->cc_offset * samples))
+ * 5 / 6) >> 14;
+ curr_capacity = (di->boot_capacity_mAh + accumulated_charge)
+ / (BATT_CAPACITY_MAH / 100);
+ dev_dbg(di->dev, "voltage %d\n", di->voltage_mV);
+ dev_dbg(di->dev,
+ "initial capacity %d mAh, accumulated %d mAh, total %d mAh\n",
+ di->boot_capacity_mAh, accumulated_charge,
+ di->boot_capacity_mAh + accumulated_charge);
+ dev_dbg(di->dev, "percentage_capacity %d\n", curr_capacity);
+
+ if (curr_capacity > 99)
+ curr_capacity = 99;
+
+
/* if battery is not present we assume it is on battery simulator and
* current capacity is set to 100%
*/
@@ -2875,6 +2923,8 @@ static int __devinit twl6030_bci_battery_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Battery Voltage at Bootup is %d mV\n",
di->voltage_mV);
+ di->capacity = capacity_lookup(di->voltage_mV);
+ di->boot_capacity_mAh = di->capacity * (BATT_CAPACITY_MAH / 100);
ret = twl_i2c_read_u8(TWL6030_MODULE_ID0, &hw_state, STS_HW_CONDITIONS);
if (ret)
goto bk_batt_failed;