]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
power: supply: ltc2941-battery-gauge: Add charge empty and full properties
authorLadislav Michl <ladis@linux-mips.org>
Wed, 17 Jan 2018 19:48:54 +0000 (20:48 +0100)
committerSebastian Reichel <sre@kernel.org>
Mon, 12 Feb 2018 10:23:46 +0000 (11:23 +0100)
Add properties for charge empty and charge full thresholds.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
drivers/power/supply/ltc2941-battery-gauge.c

index 4cfa3f0cd689ef8fade9c1596303963e0785b6fa..9360faca70263d4056eecf441c2df47c94098ec1 100644 (file)
@@ -34,6 +34,10 @@ enum ltc294x_reg {
        LTC294X_REG_CONTROL             = 0x01,
        LTC294X_REG_ACC_CHARGE_MSB      = 0x02,
        LTC294X_REG_ACC_CHARGE_LSB      = 0x03,
+       LTC294X_REG_CHARGE_THR_HIGH_MSB = 0x04,
+       LTC294X_REG_CHARGE_THR_HIGH_LSB = 0x05,
+       LTC294X_REG_CHARGE_THR_LOW_MSB  = 0x06,
+       LTC294X_REG_CHARGE_THR_LOW_LSB  = 0x07,
        LTC294X_REG_VOLTAGE_MSB         = 0x08,
        LTC294X_REG_VOLTAGE_LSB         = 0x09,
        LTC2942_REG_TEMPERATURE_MSB     = 0x0C,
@@ -179,21 +183,22 @@ static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
        return ret;
 }
 
-static int ltc294x_read_charge_register(const struct ltc294x_info *info)
-{
+static int ltc294x_read_charge_register(const struct ltc294x_info *info,
+                                       enum ltc294x_reg reg)
+ {
        int ret;
        u8 datar[2];
 
-       ret = ltc294x_read_regs(info->client,
-               LTC294X_REG_ACC_CHARGE_MSB, &datar[0], 2);
+       ret = ltc294x_read_regs(info->client, reg, &datar[0], 2);
        if (ret < 0)
                return ret;
        return (datar[0] << 8) + datar[1];
 }
 
-static int ltc294x_get_charge_now(const struct ltc294x_info *info, int *val)
+static int ltc294x_get_charge(const struct ltc294x_info *info,
+                               enum ltc294x_reg reg, int *val)
 {
-       int value = ltc294x_read_charge_register(info);
+       int value = ltc294x_read_charge_register(info, reg);
 
        if (value < 0)
                return value;
@@ -245,10 +250,29 @@ static int ltc294x_set_charge_now(const struct ltc294x_info *info, int val)
        return ret < 0 ? ret : 0;
 }
 
+static int ltc294x_set_charge_thr(const struct ltc294x_info *info,
+                                       enum ltc294x_reg reg, int val)
+{
+       u8 dataw[2];
+       s32 value;
+
+       value = convert_uAh_to_bin(info, val);
+       /* Direction depends on how sense+/- were connected */
+       if (info->Qlsb < 0)
+               value += 0xFFFF;
+       if ((value < 0) || (value > 0xFFFF)) /* input validation */
+               return -EINVAL;
+
+       /* Set new charge value */
+       dataw[0] = I16_MSB(value);
+       dataw[1] = I16_LSB(value);
+       return ltc294x_write_regs(info->client, reg, &dataw[0], 2);
+}
+
 static int ltc294x_get_charge_counter(
        const struct ltc294x_info *info, int *val)
 {
-       int value = ltc294x_read_charge_register(info);
+       int value = ltc294x_read_charge_register(info, LTC294X_REG_ACC_CHARGE_MSB);
 
        if (value < 0)
                return value;
@@ -336,8 +360,15 @@ static int ltc294x_get_property(struct power_supply *psy,
        struct ltc294x_info *info = power_supply_get_drvdata(psy);
 
        switch (prop) {
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+               return ltc294x_get_charge(info, LTC294X_REG_CHARGE_THR_HIGH_MSB,
+                                               &val->intval);
+       case POWER_SUPPLY_PROP_CHARGE_EMPTY:
+               return ltc294x_get_charge(info, LTC294X_REG_CHARGE_THR_LOW_MSB,
+                                               &val->intval);
        case POWER_SUPPLY_PROP_CHARGE_NOW:
-               return ltc294x_get_charge_now(info, &val->intval);
+               return ltc294x_get_charge(info, LTC294X_REG_ACC_CHARGE_MSB,
+                                               &val->intval);
        case POWER_SUPPLY_PROP_CHARGE_COUNTER:
                return ltc294x_get_charge_counter(info, &val->intval);
        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
@@ -358,6 +389,12 @@ static int ltc294x_set_property(struct power_supply *psy,
        struct ltc294x_info *info = power_supply_get_drvdata(psy);
 
        switch (psp) {
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+               return ltc294x_set_charge_thr(info,
+                       LTC294X_REG_CHARGE_THR_HIGH_MSB, val->intval);
+       case POWER_SUPPLY_PROP_CHARGE_EMPTY:
+               return ltc294x_set_charge_thr(info,
+                       LTC294X_REG_CHARGE_THR_LOW_MSB, val->intval);
        case POWER_SUPPLY_PROP_CHARGE_NOW:
                return ltc294x_set_charge_now(info, val->intval);
        default:
@@ -369,6 +406,8 @@ static int ltc294x_property_is_writeable(
        struct power_supply *psy, enum power_supply_property psp)
 {
        switch (psp) {
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+       case POWER_SUPPLY_PROP_CHARGE_EMPTY:
        case POWER_SUPPLY_PROP_CHARGE_NOW:
                return 1;
        default:
@@ -378,7 +417,7 @@ static int ltc294x_property_is_writeable(
 
 static void ltc294x_update(struct ltc294x_info *info)
 {
-       int charge = ltc294x_read_charge_register(info);
+       int charge = ltc294x_read_charge_register(info, LTC294X_REG_ACC_CHARGE_MSB);
 
        if (charge != info->charge) {
                info->charge = charge;
@@ -397,6 +436,8 @@ static void ltc294x_work(struct work_struct *work)
 
 static enum power_supply_property ltc294x_properties[] = {
        POWER_SUPPLY_PROP_CHARGE_COUNTER,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
+       POWER_SUPPLY_PROP_CHARGE_EMPTY,
        POWER_SUPPLY_PROP_CHARGE_NOW,
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
        POWER_SUPPLY_PROP_TEMP,