This patch adds the option to activate/deactivate the charging voltage limit. If activated, the charger prevents charging until the battery voltage drops below the VCHG_VLIM threshold.
This option is not configurable via the power_supply properties, therefore, access via sysfs was provided to examine and modify this attribute on the fly. Signed-off-by: Stefan Popa <stefan.p...@analog.com> --- .../ABI/testing/sysfs-class-power-adp5061 | 13 ++++++ drivers/power/supply/adp5061.c | 46 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-class-power-adp5061 b/Documentation/ABI/testing/sysfs-class-power-adp5061 index 0d056aa..25064c1 100644 --- a/Documentation/ABI/testing/sysfs-class-power-adp5061 +++ b/Documentation/ABI/testing/sysfs-class-power-adp5061 @@ -8,3 +8,16 @@ Description: Valid values: - 1: enabled - 0: disabled + +What: /sys/class/power_supply/adp5061/charging_vlim_enabled +Description: + Enable/disable charging voltage limit + + The ADP5061 charging voltage limit can be enabled by setting + this attribute to 1. When enabled, the charger prevents charging + until the battery voltage drops bellow the VCHG_VLIM threshold. + See device datasheet for details. + + Valid values: + - 1: enabled + - 0: disabled diff --git a/drivers/power/supply/adp5061.c b/drivers/power/supply/adp5061.c index 7cd2e67..5931e45 100644 --- a/drivers/power/supply/adp5061.c +++ b/drivers/power/supply/adp5061.c @@ -83,6 +83,10 @@ #define ADP5061_FUNC_SET_1_EN_CHG_MSK BIT(0) #define ADP5061_FUNC_SET_1_EN_CHG_MODE(x) (((x) & 0x01) << 0) +/* ADP5061_FUNC_SET_2 */ +#define ADP5061_FUNC_SET_2_EN_CHG_VLIM_MSK BIT(5) +#define ADP5061_FUNC_SET_2_EN_CHG_VLIM_MODE(x) (((x) & 0x01) << 5) + #define ADP5061_NO_BATTERY 0x01 #define ADP5061_ICHG_MAX 1300 // mA @@ -736,10 +740,52 @@ static int charging_enabled_store(struct device *dev, return count; } +static int charging_vlim_enabled_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct power_supply *psy = dev_get_drvdata(dev); + struct adp5061_state *st = power_supply_get_drvdata(psy); + unsigned int regval; + int ret; + + ret = regmap_read(st->regmap, ADP5061_FUNC_SET_2, ®val); + if (ret < 0) + return ret; + + regval = (regval & ADP5061_FUNC_SET_2_EN_CHG_VLIM_MSK) >> 5; + return sprintf(buf, "%d\n", regval); +} + +static int charging_vlim_enabled_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct power_supply *psy = dev_get_drvdata(dev); + struct adp5061_state *st = power_supply_get_drvdata(psy); + u8 chg_vlim_en; + int ret; + + ret = kstrtou8(buf, 0, &chg_vlim_en); + if (ret < 0) + return ret; + + ret = regmap_update_bits(st->regmap, ADP5061_FUNC_SET_2, + ADP5061_FUNC_SET_2_EN_CHG_VLIM_MSK, + ADP5061_FUNC_SET_2_EN_CHG_VLIM_MODE(!!chg_vlim_en)); + + if (ret < 0) + return ret; + + return count; +} + static DEVICE_ATTR_RW(charging_enabled); +static DEVICE_ATTR_RW(charging_vlim_enabled); static struct attribute *adp5061_attributes[] = { &dev_attr_charging_enabled.attr, + &dev_attr_charging_vlim_enabled.attr, NULL }; -- 2.7.4