summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2011-09-23 18:08:54 +0530
committerSimone Willett <swillett@nvidia.com>2011-09-26 10:47:26 -0700
commita4e9243d34f6a1a7acb2d82b725a1d3200365897 (patch)
tree37f746ea3afa34027452462e919e8a1f3cddc555
parentcf5d83a14af135bfe181294433006fd4018dcdd9 (diff)
power: tps80031-charger:Mechanism for getting charging status
Adding api which provides the mechanism to getting charging status. bug 872697 Change-Id: I2d70e33e04d6a663e55752a89e1699afb4d355b4 Reviewed-on: http://git-master/r/53785 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> Tested-by: Laxman Dewangan <ldewangan@nvidia.com>
-rw-r--r--drivers/power/tps80031-charger.c74
-rw-r--r--include/linux/tps80031-charger.h19
2 files changed, 75 insertions, 18 deletions
diff --git a/drivers/power/tps80031-charger.c b/drivers/power/tps80031-charger.c
index 17207103a75e..45ea440d8355 100644
--- a/drivers/power/tps80031-charger.c
+++ b/drivers/power/tps80031-charger.c
@@ -41,16 +41,11 @@
#define CHARGERUSB_CTRLLIMIT1 0xef
#define CHARGERUSB_VICHRG_PC 0xdd
#define CONTROLLER_WDG 0xe2
+#define LINEAR_CHRG_STS 0xde
#define TPS80031_VBUS_DET BIT(2)
#define TPS80031_VAC_DET BIT(3)
-enum charging_state {
- INIT = 0,
- PROGRESS = 1,
- DONE = 2,
-};
-
struct tps80031_charger {
int max_charge_current_mA;
int max_charge_volt_mV;
@@ -63,10 +58,14 @@ struct tps80031_charger {
void *board_data;
int irq_base;
int watch_time_sec;
- enum charging_state state;
+ enum charging_states state;
int charging_term_current_mA;
+ charging_callback_t charger_cb;
+ void *charger_cb_data;
};
+static struct tps80031_charger *charger_data;
+
static int set_charge_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
@@ -90,7 +89,10 @@ static int set_charge_current_limit(struct regulator_dev *rdev,
if (ret < 0)
dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
__func__, CONTROLLER_WDG);
- charger->state = INIT;
+ charger->state = charging_state_charging_stopped;
+ if (charger->charger_cb)
+ charger->charger_cb(charger->state,
+ charger->charger_cb_data);
return ret;
}
@@ -139,7 +141,10 @@ static int set_charge_current_limit(struct regulator_dev *rdev,
__func__, CONTROLLER_CTRL1);
return ret;
}
- charger->state = PROGRESS;
+ charger->state = charging_state_charging_in_progress;
+ if (charger->charger_cb)
+ charger->charger_cb(charger->state,
+ charger->charger_cb_data);
return 0;
}
@@ -147,6 +152,18 @@ static struct regulator_ops tegra_regulator_ops = {
.set_current_limit = set_charge_current_limit,
};
+int register_charging_state_callback(charging_callback_t cb, void *args)
+{
+ struct tps80031_charger *charger = charger_data;
+ if (!charger_data)
+ return -ENODEV;
+
+ charger->charger_cb = cb;
+ charger->charger_cb_data = args;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(register_charging_state_callback);
+
static int configure_charging_parameter(struct tps80031_charger *charger)
{
int ret;
@@ -228,7 +245,7 @@ static int configure_charging_parameter(struct tps80031_charger *charger)
}
/* set Pre Charge current to 400mA */
- ret = tps80031_write(charger->dev->parent, SLAVE_ID2, 0xDD, 0x3);
+ ret = tps80031_write(charger->dev->parent, SLAVE_ID2, 0xDE, 0x3);
if (ret < 0) {
dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
__func__, 0xDD);
@@ -255,9 +272,27 @@ static int configure_charging_parameter(struct tps80031_charger *charger)
static irqreturn_t linch_status_isr(int irq, void *dev_id)
{
struct tps80031_charger *charger = dev_id;
+ uint8_t linch_status;
+ int ret;
dev_info(charger->dev, "%s() got called\n", __func__);
- return IRQ_HANDLED;
+ ret = tps80031_read(charger->dev->parent, SLAVE_ID2,
+ LINEAR_CHRG_STS, &linch_status);
+ if (ret < 0) {
+ dev_err(charger->dev, "%s(): Failed in reading register 0x%02x\n",
+ __func__, LINEAR_CHRG_STS);
+ } else {
+ dev_info(charger->dev, "%s():The status of LINEAR_CHRG_STS is 0x%02x\n",
+ __func__, linch_status);
+ if (linch_status & 0x20) {
+ charger->state = charging_state_charging_completed;
+ if (charger->charger_cb)
+ charger->charger_cb(charger->state,
+ charger->charger_cb_data);
+ }
+ }
+
+ return IRQ_HANDLED;
}
static irqreturn_t watchdog_expire_isr(int irq, void *dev_id)
@@ -266,7 +301,7 @@ static irqreturn_t watchdog_expire_isr(int irq, void *dev_id)
int ret;
dev_info(charger->dev, "%s()\n", __func__);
- if (charger->state != PROGRESS)
+ if (charger->state != charging_state_charging_in_progress)
return IRQ_HANDLED;
/* Enable watchdog timer again*/
@@ -277,12 +312,13 @@ static irqreturn_t watchdog_expire_isr(int irq, void *dev_id)
__func__, CONTROLLER_WDG);
/* Rewrite to enable the charging */
- ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
+ if (!ret) {
+ ret = tps80031_write(charger->dev->parent, SLAVE_ID2,
CONTROLLER_CTRL1, 0x30);
- if (ret < 0) {
- dev_err(charger->dev, "%s(): Failed in writing register 0x%02x\n",
+ if (ret < 0)
+ dev_err(charger->dev, "%s(): Failed in writing "
+ "register 0x%02x\n",
__func__, CONTROLLER_CTRL1);
- return ret;
}
return IRQ_HANDLED;
}
@@ -302,7 +338,8 @@ static int tps80031_charger_probe(struct platform_device *pdev)
}
if (!pdata->num_consumer_supplies) {
- dev_err(dev, "%s() No consumer supply list, exiting..\n", __func__);
+ dev_err(dev, "%s() No consumer supply list, exiting..\n",
+ __func__);
return -ENODEV;
}
@@ -354,7 +391,7 @@ static int tps80031_charger_probe(struct platform_device *pdev)
charger->board_init = pdata->board_init;
charger->board_data = pdata->board_data;
- charger->state = INIT;
+ charger->state = charging_state_idle;
charger->rdev = regulator_register(&charger->reg_desc, &pdev->dev,
&charger->reg_init_data, charger);
@@ -386,6 +423,7 @@ static int tps80031_charger_probe(struct platform_device *pdev)
goto config_fail;
dev_set_drvdata(&pdev->dev, charger);
+ charger_data = charger;
return ret;
config_fail:
diff --git a/include/linux/tps80031-charger.h b/include/linux/tps80031-charger.h
index 6d2348d2788f..26c228edc306 100644
--- a/include/linux/tps80031-charger.h
+++ b/include/linux/tps80031-charger.h
@@ -26,6 +26,19 @@
#include <linux/regulator/machine.h>
+enum charging_states {
+ charging_state_idle,
+ charging_state_charging_in_progress,
+ charging_state_charging_completed,
+ charging_state_charging_stopped,
+};
+
+/**
+ * Callback type definition which is called when any state changed in the
+ * charging.
+ */
+typedef void (*charging_callback_t)(enum charging_states state, void *args);
+
struct tps80031_charger_platform_data {
int regulator_id;
int max_charge_volt_mV;
@@ -40,4 +53,10 @@ struct tps80031_charger_platform_data {
void *board_data;
};
+/**
+ * Register the callback function for the client. This callback gets called
+ * when there is any change in the chanrging states.
+ */
+extern int register_charging_state_callback(charging_callback_t cb, void *args);
+
#endif /*__LINUX_TPS80031_CHARGER_H */