summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorChaitanya Bandi <bandik@nvidia.com>2014-03-14 12:28:28 +0530
committerLaxman Dewangan <ldewangan@nvidia.com>2014-03-19 04:31:28 -0700
commit1bdbb13c6d5fa19d3b94c2274ade03b7deb815bb (patch)
tree6931eb588bba8e28d97b535abe4108ccf1a68c14 /drivers/power
parentecd7ce39e52296a1a9094af05311528749199c8d (diff)
power: bq2477x: Add adapter detection through GPIO
Added support for AC adapter detection through GPIO in bq2477x charger. Bug 1457299 Change-Id: I344d264312142121342403194aa5adeaec66d47d Signed-off-by: Chaitanya Bandi <bandik@nvidia.com> Reviewed-on: http://git-master/r/380285 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/bq2477x-charger.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/drivers/power/bq2477x-charger.c b/drivers/power/bq2477x-charger.c
index 14e74cef142f..04b767392753 100644
--- a/drivers/power/bq2477x-charger.c
+++ b/drivers/power/bq2477x-charger.c
@@ -40,6 +40,8 @@
#include <linux/rtc.h>
#include <linux/alarmtimer.h>
#include <linux/sched/rt.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
struct bq2477x_chip {
struct device *dev;
@@ -48,6 +50,8 @@ struct bq2477x_chip {
struct regmap *regmap_word;
struct mutex mutex;
int irq;
+ int charger_detect_gpio;
+ int charger_detect_gpio_active_low;
int ac_online;
int dac_ichg;
int dac_v;
@@ -281,6 +285,29 @@ static void of_bq2477x_parse_platform_data(struct i2c_client *client,
else
dev_warn(&client->dev, "wdt-refresh-timeout not provided\n");
+ ret = of_property_read_u32(np, "ti,charger-detect-gpio-active-low", &pval);
+ if (!ret)
+ pdata->charger_detect_gpio_active_low = pval;
+ else
+ dev_warn(&client->dev, "charger_detect_gpio_active_low not provided\n");
+
+ pdata->charger_detect_gpio = of_get_named_gpio(np, "charger-detect-gpio", 0);
+ if (pdata->charger_detect_gpio < 0)
+ dev_warn(&client->dev, "invalid pdata->charger_detect_gpio\n");
+}
+
+static irqreturn_t bq2477x_charger_detect_irq(int irq, void *data)
+{
+ struct bq2477x_chip *bq2477x = data;
+ bq2477x->ac_online =
+ gpio_get_value_cansleep(bq2477x->charger_detect_gpio);
+ bq2477x->ac_online ^= bq2477x->charger_detect_gpio_active_low;
+
+ if (bq2477x->ac_online == 1)
+ bq2477x_hw_init(bq2477x);
+
+ power_supply_changed(&bq2477x->ac);
+ return IRQ_HANDLED;
}
static int bq2477x_probe(struct i2c_client *client,
@@ -317,9 +344,11 @@ static int bq2477x_probe(struct i2c_client *client,
bq2477x->dac_minsv = pdata->dac_minsv;
bq2477x->dac_iin = pdata->dac_iin;
bq2477x->wdt_refresh_timeout = pdata->wdt_refresh_timeout;
+ bq2477x->charger_detect_gpio = pdata->charger_detect_gpio;
+ bq2477x->charger_detect_gpio_active_low =
+ pdata->charger_detect_gpio_active_low;
i2c_set_clientdata(client, bq2477x);
- bq2477x->irq = client->irq;
mutex_init(&bq2477x->mutex);
bq2477x->ac_online = 0;
@@ -359,6 +388,31 @@ static int bq2477x_probe(struct i2c_client *client,
return ret;
}
+ if (gpio_is_valid(bq2477x->charger_detect_gpio)) {
+ ret = devm_gpio_request_one(bq2477x->dev,
+ bq2477x->charger_detect_gpio, GPIOF_IN,
+ "bq2477x-charger-detect");
+ if (ret) {
+ dev_err(bq2477x->dev, "gpio request failed %d\n", ret);
+ goto psy_err;
+ }
+
+ bq2477x->irq = gpio_to_irq(bq2477x->charger_detect_gpio);
+ bq2477x->ac_online =
+ gpio_get_value_cansleep(bq2477x->charger_detect_gpio);
+ bq2477x->ac_online ^= bq2477x->charger_detect_gpio_active_low;
+
+ ret = devm_request_threaded_irq(bq2477x->dev, bq2477x->irq,
+ NULL, bq2477x_charger_detect_irq,
+ IRQF_ONESHOT | IRQF_TRIGGER_RISING
+ | IRQF_TRIGGER_FALLING, dev_name(bq2477x->dev),
+ bq2477x);
+ if (ret < 0) {
+ dev_err(bq2477x->dev, "Failed to request irq %d\n", ret);
+ goto psy_err;
+ }
+ }
+
ret = bq2477x_hw_init(bq2477x);
if (ret < 0) {
dev_err(bq2477x->dev, "Hardware init failed %d\n", ret);