aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorGraeme Gregory <gg@slimlogic.co.uk>2012-02-17 09:36:33 +0000
committerZiyann <jaraidaniel@gmail.com>2014-10-01 13:00:25 +0200
commit38316fb3a30eafbfd0e9ca07ed43d7ef5da1d92c (patch)
treecc5d443bafc0cf09ba6b99b99f32c1549c3899e2 /drivers/power
parentfc1b7fb5a233ffad14a7ee33f485e08d4527ca20 (diff)
downloadkernel_samsung_tuna-38316fb3a30eafbfd0e9ca07ed43d7ef5da1d92c.zip
kernel_samsung_tuna-38316fb3a30eafbfd0e9ca07ed43d7ef5da1d92c.tar.gz
kernel_samsung_tuna-38316fb3a30eafbfd0e9ca07ed43d7ef5da1d92c.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>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/twl6030_bci_battery.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/drivers/power/twl6030_bci_battery.c b/drivers/power/twl6030_bci_battery.c
index bdf8ae2..4a3b38e 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);
@@ -1291,7 +1294,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;
@@ -1476,12 +1479,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));
@@ -2564,6 +2581,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) {