diff options
author | Sebastian Reichel <sebastian.reichel@collabora.com> | 2020-05-13 21:56:09 +0300 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2020-05-29 01:39:32 +0300 |
commit | 6f72a07aa6e9fc0f7aa08b19f960be7748bad10f (patch) | |
tree | d0365d79341d9464cc727f4184ac9d173c8cd078 /drivers/power | |
parent | 7721c2fd2668c751f9ba33b35db08b86293869e5 (diff) | |
download | linux-6f72a07aa6e9fc0f7aa08b19f960be7748bad10f.tar.xz |
power: supply: sbs-battery: add POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED support
Add support for reporting the SBS battery's condition flag
to userspace using the new "Calibration required" health status.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/supply/sbs-battery.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index 4fa553d61db2..2a2b926ad75c 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c @@ -23,6 +23,7 @@ enum { REG_MANUFACTURER_DATA, + REG_BATTERY_MODE, REG_TEMPERATURE, REG_VOLTAGE, REG_CURRENT_NOW, @@ -94,6 +95,8 @@ static const struct chip_data { } sbs_data[] = { [REG_MANUFACTURER_DATA] = SBS_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535), + [REG_BATTERY_MODE] = + SBS_DATA(-1, 0x03, 0, 65535), [REG_TEMPERATURE] = SBS_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535), [REG_VOLTAGE] = @@ -366,6 +369,17 @@ static int sbs_status_correct(struct i2c_client *client, int *intval) return 0; } +static bool sbs_bat_needs_calibration(struct i2c_client *client) +{ + int ret; + + ret = sbs_read_word_data(client, sbs_data[REG_BATTERY_MODE].addr); + if (ret < 0) + return false; + + return !!(ret & BIT(7)); +} + static int sbs_get_battery_presence_and_health( struct i2c_client *client, enum power_supply_property psp, union power_supply_propval *val) @@ -385,9 +399,14 @@ static int sbs_get_battery_presence_and_health( if (psp == POWER_SUPPLY_PROP_PRESENT) val->intval = 1; /* battery present */ - else /* POWER_SUPPLY_PROP_HEALTH */ - /* SBS spec doesn't have a general health command. */ - val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; + else { /* POWER_SUPPLY_PROP_HEALTH */ + if (sbs_bat_needs_calibration(client)) { + val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED; + } else { + /* SBS spec doesn't have a general health command. */ + val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; + } + } return 0; } @@ -441,6 +460,8 @@ static int sbs_get_ti_battery_presence_and_health( val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; else if (ret == 0x0C) val->intval = POWER_SUPPLY_HEALTH_DEAD; + else if (sbs_bat_needs_calibration(client)) + val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED; else val->intval = POWER_SUPPLY_HEALTH_GOOD; } |