aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorRamakrishna Pallala <ramakrishna.pallala@intel.com>2012-01-24 12:26:06 -0500
committerAnton Vorontsov <anton.vorontsov@linaro.org>2012-03-26 12:38:41 -0400
commite5f3872d20448706d3bb8083ee82a9226d3f8b5c (patch)
treee6631f09e2465a3770e5c6d2a9eeeb3c33b3b6f0 /drivers/power
parentf3a71a6eb13b71cc8a3dc5b6e5692e3db66b92f0 (diff)
max17042: Add support for signalling change in SOC
If platform has the alert pin attached to an interrupt source have the driver signal a change in the SOC every 1 percent. Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com> Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/max17042_battery.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
index fde7ccd62953..3a30a27b094c 100644
--- a/drivers/power/max17042_battery.c
+++ b/drivers/power/max17042_battery.c
@@ -27,6 +27,7 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/interrupt.h>
30#include <linux/mod_devicetable.h> 31#include <linux/mod_devicetable.h>
31#include <linux/power_supply.h> 32#include <linux/power_supply.h>
32#include <linux/power/max17042_battery.h> 33#include <linux/power/max17042_battery.h>
@@ -43,6 +44,11 @@
43#define STATUS_SMX_BIT (1 << 14) 44#define STATUS_SMX_BIT (1 << 14)
44#define STATUS_BR_BIT (1 << 15) 45#define STATUS_BR_BIT (1 << 15)
45 46
47/* Interrupt mask bits */
48#define CONFIG_ALRT_BIT_ENBL (1 << 2)
49#define STATUS_INTR_SOC_BIT (1 << 14)
50#define STATUS_INTR_LOW_SOC_BIT (1 << 10)
51
46#define VFSOC0_LOCK 0x0000 52#define VFSOC0_LOCK 0x0000
47#define VFSOC0_UNLOCK 0x0080 53#define VFSOC0_UNLOCK 0x0080
48#define MODEL_UNLOCK1 0X0059 54#define MODEL_UNLOCK1 0X0059
@@ -552,6 +558,39 @@ static int max17042_init_chip(struct max17042_chip *chip)
552 return 0; 558 return 0;
553} 559}
554 560
561static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off)
562{
563 u16 soc, soc_tr;
564
565 /* program interrupt thesholds such that we should
566 * get interrupt for every 'off' perc change in the soc
567 */
568 soc = max17042_read_reg(chip->client, MAX17042_RepSOC) >> 8;
569 soc_tr = (soc + off) << 8;
570 soc_tr |= (soc - off);
571 max17042_write_reg(chip->client, MAX17042_SALRT_Th, soc_tr);
572}
573
574static irqreturn_t max17042_intr_handler(int id, void *dev)
575{
576 return IRQ_WAKE_THREAD;
577}
578
579static irqreturn_t max17042_thread_handler(int id, void *dev)
580{
581 struct max17042_chip *chip = dev;
582 u16 val;
583
584 val = max17042_read_reg(chip->client, MAX17042_STATUS);
585 if ((val & STATUS_INTR_SOC_BIT) ||
586 (val & STATUS_INTR_LOW_SOC_BIT)) {
587 dev_info(&chip->client->dev, "SOC threshold INTR\n");
588 max17042_set_soc_threshold(chip, 1);
589 }
590
591 power_supply_changed(&chip->battery);
592 return IRQ_HANDLED;
593}
555 594
556static void max17042_init_worker(struct work_struct *work) 595static void max17042_init_worker(struct work_struct *work)
557{ 596{
@@ -613,6 +652,20 @@ static int __devinit max17042_probe(struct i2c_client *client,
613 max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); 652 max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
614 } 653 }
615 654
655 if (client->irq) {
656 ret = request_threaded_irq(client->irq, max17042_intr_handler,
657 max17042_thread_handler,
658 0, chip->battery.name, chip);
659 if (!ret) {
660 reg = max17042_read_reg(client, MAX17042_CONFIG);
661 reg |= CONFIG_ALRT_BIT_ENBL;
662 max17042_write_reg(client, MAX17042_CONFIG, reg);
663 max17042_set_soc_threshold(chip, 1);
664 } else
665 dev_err(&client->dev, "%s(): cannot get IRQ\n",
666 __func__);
667 }
668
616 reg = max17042_read_reg(chip->client, MAX17042_STATUS); 669 reg = max17042_read_reg(chip->client, MAX17042_STATUS);
617 670
618 if (reg & STATUS_POR_BIT) { 671 if (reg & STATUS_POR_BIT) {