aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGraeme Gregory <gg@slimlogic.co.uk>2012-02-17 09:36:33 +0000
committerDmytro Kedrovskyi <x0169235@ti.com>2012-06-12 15:25:55 +0300
commitecedde48e8cc1cb43c4bab38bc67484146db511c (patch)
tree4f8fc0093ae2c02bf699b739a960822878df420a
parent2c606c7784d7c5caad6bfdd92ddd0883ec99360b (diff)
downloadkernel_samsung_espresso10-ecedde48e8cc1cb43c4bab38bc67484146db511c.zip
kernel_samsung_espresso10-ecedde48e8cc1cb43c4bab38bc67484146db511c.tar.gz
kernel_samsung_espresso10-ecedde48e8cc1cb43c4bab38bc67484146db511c.tar.bz2
twl6030_bci_battery correct the current readings.
Correct the current reading functions for current_now and current_avg. This was done with advice on the correct algorithm from the design team and application engineers. Also by default twl6030 and twl6032 use different sense resistors and according to design team these resistors may be tuned for certain boards. So allow the resistor value to be passed as platform data but select sensible defaults if it is not. Change-Id: Ib60742ec5779708d7156a4c6b4acd16b84cc8f0c Signed-off-by: Graeme Gregory <gg@slimlogic.co.uk>
-rw-r--r--drivers/power/twl6030_bci_battery.c38
-rw-r--r--include/linux/i2c/twl.h2
2 files changed, 35 insertions, 5 deletions
diff --git a/drivers/power/twl6030_bci_battery.c b/drivers/power/twl6030_bci_battery.c
index 9515ab5..ef94f75 100644
--- a/drivers/power/twl6030_bci_battery.c
+++ b/drivers/power/twl6030_bci_battery.c
@@ -252,7 +252,7 @@ static inline unsigned int twl6030_get_usb_max_power(struct otg_transceiver *x)
#endif
/* Ptr to thermistor table */
-static const unsigned int fuelgauge_rate[4] = {4, 16, 64, 256};
+static const unsigned int fuelgauge_rate[4] = {1, 4, 16, 64};
static struct wake_lock chrg_lock;
@@ -319,6 +319,9 @@ struct twl6030_bci_device_info {
int use_hw_charger;
int use_power_path;
+
+ /* max scale current based on sense resitor */
+ int current_max_scale;
};
static BLOCKING_NOTIFIER_HEAD(notifier_list);
@@ -1071,7 +1074,7 @@ static void twl6030battery_current(struct twl6030_bci_device_info *di)
/* current drawn per sec */
current_now = current_now * fuelgauge_rate[di->fuelgauge_mode];
/* current in mAmperes */
- current_now = (current_now * 3000) >> 14;
+ current_now = (current_now * di->current_max_scale) >> 13;
/* current in uAmperes */
current_now = current_now * 1000;
di->current_uA = current_now;
@@ -1252,12 +1255,26 @@ static void twl6030_current_avg(struct work_struct *work)
if (di->timer_n1 < di->timer_n2)
samples = samples + (1 << 24);
+ /* offset is accumulative over number of samples */
cc_offset = cc_offset * samples;
+
current_avg_uA = ((di->charge_n1 - di->charge_n2 - cc_offset)
- * 3000) >> 12;
- if (samples)
+ * di->current_max_scale) /
+ fuelgauge_rate[di->fuelgauge_mode];
+ /* clock is a fixed 32Khz */
+ current_avg_uA >>= 15;
+
+ /* Correct for the fuelguage sampling rate */
+ samples /= fuelgauge_rate[di->fuelgauge_mode] * 4;
+
+ /*
+ * Only update the current average if we have had a valid number
+ * of samples in the accumulation.
+ */
+ if (samples) {
current_avg_uA = current_avg_uA / samples;
- di->current_avg_uA = current_avg_uA * 1000;
+ di->current_avg_uA = current_avg_uA * 1000;
+ }
schedule_delayed_work(&di->twl6030_current_avg_work,
msecs_to_jiffies(1000 * di->current_avg_interval));
@@ -2344,6 +2361,17 @@ static int __devinit twl6030_bci_battery_probe(struct platform_device *pdev)
di->ac_next_refresh = jiffies - 1;
platform_set_drvdata(pdev, di);
+ /* calculate current max scale from sense */
+ if (pdata->sense_resistor_mohm) {
+ di->current_max_scale = (62000) / pdata->sense_resistor_mohm;
+ } else {
+ /* Set sensible defaults if platform data is missing */
+ if (di->features & TWL6032_SUBCLASS)
+ di->current_max_scale = 3100;
+ else
+ di->current_max_scale = 6200;
+ }
+
wake_lock_init(&chrg_lock, WAKE_LOCK_SUSPEND, "ac_chrg_wake_lock");
if (di->errata & TWL6032_ERRATA_DB00119490) {
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 5f95ecf..da327bd 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -640,6 +640,8 @@ struct twl4030_bci_platform_data {
unsigned int max_bat_voltagemV;
unsigned int low_bat_voltagemV;
+ unsigned int sense_resistor_mohm;
+
/* twl6032 */
unsigned long features;