aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Looijmans <mike.looijmans@topic.nl>2017-11-23 09:41:05 -0500
committerSebastian Reichel <sebastian.reichel@collabora.co.uk>2017-12-01 10:41:05 -0500
commit5f2f0d610578d380123d5c5906bbfa1ec5542b1a (patch)
tree0a0c6c1078121e333118971581ad718475093954
parent68204f2fbae26dd3ca2b4c7f52ce9d006e8dc08f (diff)
power: ltc2941-battery-gauge: Disable continuous monitoring on shutdown
The driver sets the fuel gauge to continuous monitoring on startup, for the models that support this. When the board shuts down, the chip remains in that mode, causing a few mA drain on the battery every 2 or 10 seconds. This patch registers a shutdown handler that turns off the monitoring to prevent this battery drain. Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
-rw-r--r--drivers/power/supply/ltc2941-battery-gauge.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
index 08e4fd9ee607..4cfa3f0cd689 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -60,6 +60,7 @@ enum ltc294x_id {
60#define LTC294X_REG_CONTROL_PRESCALER_SET(x) \ 60#define LTC294X_REG_CONTROL_PRESCALER_SET(x) \
61 ((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK) 61 ((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK)
62#define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED 0 62#define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED 0
63#define LTC294X_REG_CONTROL_ADC_DISABLE(x) ((x) & ~(BIT(7) | BIT(6)))
63 64
64struct ltc294x_info { 65struct ltc294x_info {
65 struct i2c_client *client; /* I2C Client pointer */ 66 struct i2c_client *client; /* I2C Client pointer */
@@ -523,6 +524,29 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
523 return 0; 524 return 0;
524} 525}
525 526
527static void ltc294x_i2c_shutdown(struct i2c_client *client)
528{
529 struct ltc294x_info *info = i2c_get_clientdata(client);
530 int ret;
531 u8 value;
532 u8 control;
533
534 /* The LTC2941 does not need any special handling */
535 if (info->id == LTC2941_ID)
536 return;
537
538 /* Read control register */
539 ret = ltc294x_read_regs(info->client, LTC294X_REG_CONTROL, &value, 1);
540 if (ret < 0)
541 return;
542
543 /* Disable continuous ADC conversion as this drains the battery */
544 control = LTC294X_REG_CONTROL_ADC_DISABLE(value);
545 if (control != value)
546 ltc294x_write_regs(info->client, LTC294X_REG_CONTROL,
547 &control, 1);
548}
549
526#ifdef CONFIG_PM_SLEEP 550#ifdef CONFIG_PM_SLEEP
527 551
528static int ltc294x_suspend(struct device *dev) 552static int ltc294x_suspend(struct device *dev)
@@ -589,6 +613,7 @@ static struct i2c_driver ltc294x_driver = {
589 }, 613 },
590 .probe = ltc294x_i2c_probe, 614 .probe = ltc294x_i2c_probe,
591 .remove = ltc294x_i2c_remove, 615 .remove = ltc294x_i2c_remove,
616 .shutdown = ltc294x_i2c_shutdown,
592 .id_table = ltc294x_i2c_id, 617 .id_table = ltc294x_i2c_id,
593}; 618};
594module_i2c_driver(ltc294x_driver); 619module_i2c_driver(ltc294x_driver);