summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2014-04-11 16:01:22 +0530
committerGerrit Code Review <gerrit2@nvidia.com>2014-04-11 22:03:13 -0700
commit6bb3e44cb81b0afe7fd4bf2f79ae209d80be11e6 (patch)
tree334597a949cadec1b81c6f36fa1e4daa18137c9b /drivers/power
parentaaafc83d97906b77edf78ad33b3d50d9fa0da996 (diff)
power: bq2419x: add support to emulate charger disconnect
Add support to emulate the charger disconnected through sysfs interface although charger connected physically. This will make the system to load from battery instead of input source. This helps on stress test to drain battery even if charger cable connected and enable/disable charging without physically doing this. cd /sys/bus/i2c/devices/1-006b For emulating it as disconnect say echo D > input_cable_state For disabling emulation of cable state say echo C > input_cable_state bug 1491052 Change-Id: I0f6edd0ce17a906447c0e455da15a388a4958215 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/bq2419x-charger.c81
1 files changed, 75 insertions, 6 deletions
diff --git a/drivers/power/bq2419x-charger.c b/drivers/power/bq2419x-charger.c
index 78e3a5719a1a..2bcb5a25d72a 100644
--- a/drivers/power/bq2419x-charger.c
+++ b/drivers/power/bq2419x-charger.c
@@ -79,6 +79,7 @@ struct bq2419x_chip {
int gpio_otg_iusb;
int wdt_refresh_timeout;
int wdt_time_sec;
+ bool emulate_input_disconnected;
struct mutex mutex;
int in_current_limit;
@@ -351,11 +352,14 @@ static int bq2419x_configure_charging_current(struct bq2419x_chip *bq2419x,
int floor = 0;
/* Clear EN_HIZ */
- ret = regmap_update_bits(bq2419x->regmap, BQ2419X_INPUT_SRC_REG,
+ if (!bq2419x->emulate_input_disconnected) {
+ ret = regmap_update_bits(bq2419x->regmap, BQ2419X_INPUT_SRC_REG,
BQ2419X_EN_HIZ, 0);
- if (ret < 0) {
- dev_err(bq2419x->dev, "INPUT_SRC_REG update failed %d\n", ret);
- return ret;
+ if (ret < 0) {
+ dev_err(bq2419x->dev,
+ "INPUT_SRC_REG update failed %d\n", ret);
+ return ret;
+ }
}
/* Configure input current limit in steps */
@@ -479,8 +483,12 @@ static int bq2419x_reset_wdt(struct bq2419x_chip *bq2419x, const char *from)
dev_info(bq2419x->dev, "%s() from %s()\n", __func__, from);
/* Clear EN_HIZ */
- ret = regmap_update_bits(bq2419x->regmap,
- BQ2419X_INPUT_SRC_REG, BQ2419X_EN_HIZ, 0);
+ if (bq2419x->emulate_input_disconnected)
+ ret = regmap_update_bits(bq2419x->regmap, BQ2419X_INPUT_SRC_REG,
+ BQ2419X_EN_HIZ, BQ2419X_EN_HIZ);
+ else
+ ret = regmap_update_bits(bq2419x->regmap,
+ BQ2419X_INPUT_SRC_REG, BQ2419X_EN_HIZ, 0);
if (ret < 0) {
dev_err(bq2419x->dev, "INPUT_SRC_REG update failed:%d\n", ret);
goto scrub;
@@ -970,6 +978,63 @@ static ssize_t bq2419x_set_charging_state(struct device *dev,
return count;
}
+static ssize_t bq2419x_show_input_cable_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bq2419x_chip *bq2419x = i2c_get_clientdata(client);
+ unsigned int reg_val;
+ int ret;
+
+ ret = regmap_read(bq2419x->regmap, BQ2419X_INPUT_SRC_REG, &reg_val);
+ if (ret < 0) {
+ dev_err(dev, "BQ2419X_PWR_ON register read failed: %d\n", ret);
+ return ret;
+ }
+
+ if ((reg_val & BQ2419X_EN_HIZ) == BQ2419X_EN_HIZ)
+ return snprintf(buf, MAX_STR_PRINT, "Disconnected\n");
+ else
+ return snprintf(buf, MAX_STR_PRINT, "Connected\n");
+}
+
+static ssize_t bq2419x_set_input_cable_state(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bq2419x_chip *bq2419x = i2c_get_clientdata(client);
+ bool connect;
+ int ret;
+
+ if ((*buf == 'C') || (*buf == 'c'))
+ connect = true;
+ else if ((*buf == 'D') || (*buf == 'd'))
+ connect = false;
+ else
+ return -EINVAL;
+
+ if (connect) {
+ bq2419x->emulate_input_disconnected = false;
+ ret = regmap_update_bits(bq2419x->regmap, BQ2419X_INPUT_SRC_REG,
+ BQ2419X_EN_HIZ, 0);
+ } else {
+ bq2419x->emulate_input_disconnected = true;
+ ret = regmap_update_bits(bq2419x->regmap, BQ2419X_INPUT_SRC_REG,
+ BQ2419X_EN_HIZ, BQ2419X_EN_HIZ);
+ }
+ if (ret < 0) {
+ dev_err(bq2419x->dev, "register update failed, %d\n", ret);
+ return ret;
+ }
+ if (connect)
+ dev_info(bq2419x->dev,
+ "Emulation of charger cable disconnect disabled\n");
+ else
+ dev_info(bq2419x->dev,
+ "Emulated as charger cable Disconnected\n");
+ return count;
+}
+
static ssize_t bq2419x_show_output_charging_current(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1038,11 +1103,15 @@ static DEVICE_ATTR(input_charging_current_mA, (S_IRUGO | (S_IWUSR | S_IWGRP)),
static DEVICE_ATTR(charging_state, (S_IRUGO | (S_IWUSR | S_IWGRP)),
bq2419x_show_charging_state, bq2419x_set_charging_state);
+static DEVICE_ATTR(input_cable_state, (S_IRUGO | (S_IWUSR | S_IWGRP)),
+ bq2419x_show_input_cable_state, bq2419x_set_input_cable_state);
+
static struct attribute *bq2419x_attributes[] = {
&dev_attr_output_charging_current.attr,
&dev_attr_output_current_allowed_values.attr,
&dev_attr_input_charging_current_mA.attr,
&dev_attr_charging_state.attr,
+ &dev_attr_input_cable_state.attr,
NULL
};