aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/supply/ab8500_chargalg.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2022-02-26 00:27:56 +0100
committerSebastian Reichel <sebastian.reichel@collabora.com>2022-02-28 11:34:31 +0100
commit0e8b903b522b5a3cb473035cea085d396dd7150a (patch)
treeb0227cb217d7ba2c4787386a47cfdd80b1f707f1 /drivers/power/supply/ab8500_chargalg.c
parentd72ce7d324786257410bec6b36e3756647dd76fd (diff)
downloadlinux-0e8b903b522b5a3cb473035cea085d396dd7150a.tar.gz
power: supply: ab8500: Standardize alert mode charging
The AB8500 code is using a special current and voltage setting when the battery is in "alert mode", i.e. when it is starting to go outside normal operating conditions so it is too cold or too hot. This makes sense as a way for the charging algorithm to deal with hostile environments. Add the needed members to the struct power_supply_battery_info, and switch the AB8500 charging code over to using this. Reviewed-by: Matti Vaittineen <matti.vaittinen@fi.rohmeurope.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power/supply/ab8500_chargalg.c')
-rw-r--r--drivers/power/supply/ab8500_chargalg.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c
index 6054996b6260..c9c7f7028af6 100644
--- a/drivers/power/supply/ab8500_chargalg.c
+++ b/drivers/power/supply/ab8500_chargalg.c
@@ -149,7 +149,8 @@ struct ab8500_chargalg_events {
bool batt_ovv;
bool batt_rem;
bool btemp_underover;
- bool btemp_lowhigh;
+ bool btemp_low;
+ bool btemp_high;
bool main_thermal_prot;
bool usb_thermal_prot;
bool main_ovv;
@@ -684,26 +685,31 @@ static void ab8500_chargalg_check_temp(struct ab8500_chargalg *di)
di->batt_data.temp < (bi->temp_alert_max - di->t_hyst_norm)) {
/* Temp OK! */
di->events.btemp_underover = false;
- di->events.btemp_lowhigh = false;
+ di->events.btemp_low = false;
+ di->events.btemp_high = false;
di->t_hyst_norm = 0;
di->t_hyst_lowhigh = 0;
} else {
- if (((di->batt_data.temp >= bi->temp_alert_max) &&
- (di->batt_data.temp <
- (bi->temp_max - di->t_hyst_lowhigh))) ||
- ((di->batt_data.temp >
- (bi->temp_min + di->t_hyst_lowhigh)) &&
- (di->batt_data.temp <= bi->temp_alert_min))) {
- /* TEMP minor!!!!! */
+ if ((di->batt_data.temp >= bi->temp_alert_max) &&
+ (di->batt_data.temp < (bi->temp_max - di->t_hyst_lowhigh))) {
+ /* Alert zone for high temperature */
di->events.btemp_underover = false;
- di->events.btemp_lowhigh = true;
+ di->events.btemp_high = true;
+ di->t_hyst_norm = di->bm->temp_hysteresis;
+ di->t_hyst_lowhigh = 0;
+ } else if ((di->batt_data.temp > (bi->temp_min + di->t_hyst_lowhigh)) &&
+ (di->batt_data.temp <= bi->temp_alert_min)) {
+ /* Alert zone for low temperature */
+ di->events.btemp_underover = false;
+ di->events.btemp_low = true;
di->t_hyst_norm = di->bm->temp_hysteresis;
di->t_hyst_lowhigh = 0;
} else if (di->batt_data.temp <= bi->temp_min ||
di->batt_data.temp >= bi->temp_max) {
/* TEMP major!!!!! */
di->events.btemp_underover = true;
- di->events.btemp_lowhigh = false;
+ di->events.btemp_low = false;
+ di->events.btemp_high = false;
di->t_hyst_norm = 0;
di->t_hyst_lowhigh = di->bm->temp_hysteresis;
} else {
@@ -1313,7 +1319,7 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
ab8500_chargalg_state_to(di, STATE_WD_EXPIRED_INIT);
}
/* Battery temp high/low */
- else if (di->events.btemp_lowhigh) {
+ else if (di->events.btemp_low || di->events.btemp_high) {
if (di->charge_state != STATE_TEMP_LOWHIGH)
ab8500_chargalg_state_to(di, STATE_TEMP_LOWHIGH_INIT);
}
@@ -1510,9 +1516,19 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
break;
case STATE_TEMP_LOWHIGH_INIT:
- ab8500_chargalg_start_charging(di,
- di->bm->bat_type->low_high_vol_lvl,
- di->bm->bat_type->low_high_cur_lvl);
+ if (di->events.btemp_low) {
+ ab8500_chargalg_start_charging(di,
+ bi->alert_low_temp_charge_voltage_uv,
+ bi->alert_low_temp_charge_current_ua);
+ } else if (di->events.btemp_high) {
+ ab8500_chargalg_start_charging(di,
+ bi->alert_high_temp_charge_voltage_uv,
+ bi->alert_high_temp_charge_current_ua);
+ } else {
+ dev_err(di->dev, "neither low or high temp event occured\n");
+ ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
+ break;
+ }
ab8500_chargalg_stop_maintenance_timer(di);
di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
ab8500_chargalg_state_to(di, STATE_TEMP_LOWHIGH);
@@ -1520,7 +1536,7 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
fallthrough;
case STATE_TEMP_LOWHIGH:
- if (!di->events.btemp_lowhigh)
+ if (!di->events.btemp_low && !di->events.btemp_high)
ab8500_chargalg_state_to(di, STATE_NORMAL_INIT);
break;