From ede666158174d24839981e4dc029d212424f60f2 Mon Sep 17 00:00:00 2001 From: Martyn Welch <martyn@welchs.me.uk> Date: Mon, 26 Feb 2018 19:00:32 +0000 Subject: [PATCH] Add support for presence detection, actual and remaining battery capacity The battery monitor firmware now has support for detecting battery presence and reporting actual and remaining battery capacity. This patch removes the current support for battery presence detection, relying in the battery monitor to provide this information instead. In adding reporting for full capacity and current capacity, the variable used for current state of charge is renamed to avoid confusion. Signed-off-by: Martyn Welch <martyn@welchs.me.uk> --- drivers/power/supply/tcl-sbs-battery.c | 58 ++++++++++++++------------ 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/drivers/power/supply/tcl-sbs-battery.c b/drivers/power/supply/tcl-sbs-battery.c index 7594d80e50ff..5d4f2cf63fd6 100644 --- a/drivers/power/supply/tcl-sbs-battery.c +++ b/drivers/power/supply/tcl-sbs-battery.c @@ -49,12 +49,17 @@ /* Battery Status, 2 bytes */ #define SBS_BATTERY_STATUS 0x74 # define BATTERY_STATUS_CHARGING 0 +# define BATTERY_STATUS_NOT_PRESENT BIT(7) # define BATTERY_STATUS_DISCHARGING BIT(6) # define BATTERY_STATUS_FULLY_CHARGED BIT(5) /* State of charge in percentage, 1 byte */ #define SBS_STATE_OF_CHARGE 0x76 /* Cycle count, 2 bytes */ #define SBS_CYCLE_COUNT 0x77 +/* Remaining capacity, 2 bytes */ +#define SBS_REM_CAPACITY 0x79 +/* Actual capcacity, 2 bytes */ +#define SBS_ACTUAL_CAPACITY 0x7b /* Firmware version, 1 byte */ #define SBS_FIRMWARE_VERSION 0x7d @@ -82,8 +87,10 @@ struct tcl_sbs_battery_data { int voltage_uvolt; /* units of uV */ int current_uamp; /* units of uA */ int rated_capacity; /* units of µAh */ + int full_capacity; /* units of µAh */ + int rem_capacity; /* units of µAh */ int cycle_count; - int rem_capacity; /* percentage */ + int charge_state; /* percentage */ int life_sec; /* units of seconds */ int status; /* state of charge */ int design_voltage; /* units of uV */ @@ -201,6 +208,16 @@ static int tcl_sbs_battery_read_status(struct tcl_sbs_battery_data *data) data->map[SBS_PACK_CAPACITY]); data->rated_capacity *= 1000; /* convert from mAh to uAh */ + data->full_capacity = (u16)((data->map[SBS_ACTUAL_CAPACITY + 1] << 8) | + data->map[SBS_ACTUAL_CAPACITY]); + data->full_capacity *= 1000; /* convert from mAh to uAh */ + + data->rem_capacity = (u16)((data->map[SBS_REM_CAPACITY + 1] << 8) | + data->map[SBS_REM_CAPACITY]); + data->rem_capacity *= 1000; /* convert from mAh to uAh */ + + data->presence = true; + uval = (u16)((data->map[SBS_BATTERY_STATUS + 1] << 8) | data->map[SBS_BATTERY_STATUS]); if (uval == BATTERY_STATUS_CHARGING) @@ -209,15 +226,17 @@ static int tcl_sbs_battery_read_status(struct tcl_sbs_battery_data *data) data->status = POWER_SUPPLY_STATUS_DISCHARGING; else if (uval == BATTERY_STATUS_FULLY_CHARGED) data->status = POWER_SUPPLY_STATUS_FULL; + else if (uval == BATTERY_STATUS_NOT_PRESENT) + data->presence = false; else data->status = POWER_SUPPLY_STATUS_UNKNOWN; data->cycle_count = (u16)((data->map[SBS_CYCLE_COUNT + 1] << 8) | data->map[SBS_CYCLE_COUNT]); - data->rem_capacity = data->map[SBS_STATE_OF_CHARGE]; + data->charge_state = data->map[SBS_STATE_OF_CHARGE]; - uval = (data->rem_capacity * (data->rated_capacity / 1000)) / 100; + uval = (data->charge_state * (data->full_capacity / 1000)) / 100; if (data->current_uamp) data->life_sec = (3600l * uval) / (data->current_uamp / 1000); @@ -247,28 +266,6 @@ static char *tcl_sbs_battery_supplied_to[] = { "tps65217-charger", }; -/* - * is_batt_present - See if the battery presents in place. - */ -static bool is_batt_present(struct tcl_sbs_battery_data *data) -{ - union power_supply_propval val; - struct power_supply *psy; - bool present = false; - int ret; - - psy = power_supply_get_by_name(tcl_sbs_battery_supplied_to[0]); - if (!psy) - return false; - - ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_PRESENT, &val); - if (ret == 0 && val.intval) - present = true; - - power_supply_put(psy); - - return present; -} static int tcl_sbs_battery_get_property(struct power_supply *psy, enum power_supply_property psp, @@ -289,7 +286,6 @@ static int tcl_sbs_battery_get_property(struct power_supply *psy, } if (!data->presence) { - data->presence = is_batt_present(data); return -ENODEV; } @@ -313,11 +309,17 @@ static int tcl_sbs_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: val->intval = data->rated_capacity; break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + val->intval = data->full_capacity; + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + val->intval = data->rem_capacity; + break; case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: val->intval = data->life_sec; break; case POWER_SUPPLY_PROP_CAPACITY: - val->intval = data->rem_capacity; + val->intval = data->charge_state; break; case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = data->technology; @@ -349,6 +351,8 @@ static enum power_supply_property tcl_sbs_battery_props[] = { POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_TECHNOLOGY, -- GitLab