summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/supply/ab8500-bm.h4
-rw-r--r--drivers/power/supply/ab8500_bmdata.c15
-rw-r--r--drivers/power/supply/ab8500_chargalg.c48
-rw-r--r--drivers/power/supply/power_supply_core.c4
4 files changed, 49 insertions, 22 deletions
diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h
index 4d74d21cf1eb..91ef9d4a5222 100644
--- a/drivers/power/supply/ab8500-bm.h
+++ b/drivers/power/supply/ab8500-bm.h
@@ -331,14 +331,10 @@ struct ab8500_maxim_parameters {
* struct ab8500_battery_type - different batteries supported
* @resis_high: battery upper resistance limit
* @resis_low: battery lower resistance limit
- * @low_high_cur_lvl: charger current in temp low/high state in mA
- * @low_high_vol_lvl: charger voltage in temp low/high state in mV'
*/
struct ab8500_battery_type {
int resis_high;
int resis_low;
- int low_high_cur_lvl;
- int low_high_vol_lvl;
};
/**
diff --git a/drivers/power/supply/ab8500_bmdata.c b/drivers/power/supply/ab8500_bmdata.c
index 66a454942c7c..bf0b74773eee 100644
--- a/drivers/power/supply/ab8500_bmdata.c
+++ b/drivers/power/supply/ab8500_bmdata.c
@@ -77,8 +77,6 @@ static struct power_supply_maintenance_charge_table ab8500_maint_charg_table[] =
static struct ab8500_battery_type bat_type_thermistor_unknown = {
.resis_high = 0,
.resis_low = 0,
- .low_high_cur_lvl = 300,
- .low_high_vol_lvl = 4000,
};
static const struct ab8500_bm_capacity_levels cap_levels = {
@@ -192,6 +190,19 @@ int ab8500_bm_of_probe(struct power_supply *psy,
bi->maintenance_charge_size = ARRAY_SIZE(ab8500_maint_charg_table);
}
+ if (bi->alert_low_temp_charge_current_ua < 0 ||
+ bi->alert_low_temp_charge_voltage_uv < 0)
+ {
+ bi->alert_low_temp_charge_current_ua = 300000;
+ bi->alert_low_temp_charge_voltage_uv = 4000000;
+ }
+ if (bi->alert_high_temp_charge_current_ua < 0 ||
+ bi->alert_high_temp_charge_voltage_uv < 0)
+ {
+ bi->alert_high_temp_charge_current_ua = 300000;
+ bi->alert_high_temp_charge_voltage_uv = 4000000;
+ }
+
/*
* Internal resistance and factory resistance are tightly coupled
* so both MUST be defined or we fall back to defaults.
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;
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index accbbd36bfe7..e3d6d3ff492a 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -596,6 +596,10 @@ int power_supply_get_battery_info(struct power_supply *psy,
info->charge_restart_voltage_uv = -EINVAL;
info->overvoltage_limit_uv = -EINVAL;
info->maintenance_charge = NULL;
+ info->alert_low_temp_charge_current_ua = -EINVAL;
+ info->alert_low_temp_charge_voltage_uv = -EINVAL;
+ info->alert_high_temp_charge_current_ua = -EINVAL;
+ info->alert_high_temp_charge_voltage_uv = -EINVAL;
info->temp_ambient_alert_min = INT_MIN;
info->temp_ambient_alert_max = INT_MAX;
info->temp_alert_min = INT_MIN;