829 lines
34 KiB
C
Executable File
829 lines
34 KiB
C
Executable File
/*
|
|
* sec_battery_thermal.c
|
|
* Samsung Mobile Battery Driver
|
|
*
|
|
* Copyright (C) 2019 Samsung Electronics
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
#include "include/sec_battery.h"
|
|
|
|
#if defined(CONFIG_PREVENT_USB_CONN_OVERHEAT)
|
|
extern int muic_set_hiccup_mode(int on_off);
|
|
#endif
|
|
|
|
char *sec_bat_thermal_zone[] = {
|
|
"COLD",
|
|
"COOL3",
|
|
"COOL2",
|
|
"COOL1",
|
|
"NORMAL",
|
|
"WARM",
|
|
"OVERHEAT",
|
|
"OVERHEATLIMIT",
|
|
};
|
|
|
|
//#if defined(CONFIG_DUAL_BATTERY)
|
|
int sec_bat_get_high_priority_temp(struct sec_battery_info *battery)
|
|
{
|
|
int standard_temp = 250;
|
|
int priority_temp = battery->temperature;
|
|
|
|
if (is_wireless_type(battery->cable_type) && battery->temperature >= 400)
|
|
priority_temp -= 5;
|
|
|
|
if((battery->temperature > standard_temp) && (battery->sub_bat_temp > standard_temp)) {
|
|
if(battery->temperature < battery->sub_bat_temp)
|
|
priority_temp = battery->sub_bat_temp;
|
|
} else {
|
|
if(battery->temperature > battery->sub_bat_temp)
|
|
priority_temp = battery->sub_bat_temp;
|
|
}
|
|
|
|
pr_info("%s priority_temp = %d \n", __func__, priority_temp);
|
|
return priority_temp;
|
|
}
|
|
//#endif
|
|
|
|
void sec_bat_check_mix_temp(struct sec_battery_info *battery)
|
|
{
|
|
int temperature = battery->pdata->blkt_temp_check_type ? battery->blkt_temp : battery->temperature;
|
|
int chg_temp;
|
|
int input_current = 0;
|
|
|
|
if (battery->pdata->temp_check_type == SEC_BATTERY_TEMP_CHECK_NONE ||
|
|
battery->pdata->chg_temp_check_type == SEC_BATTERY_TEMP_CHECK_NONE)
|
|
return;
|
|
#if defined(CONFIG_DIRECT_CHARGING)
|
|
if (is_pd_apdo_wire_type(battery->wire_status) && battery->pd_list.now_isApdo)
|
|
chg_temp = battery->dchg_temp;
|
|
else
|
|
chg_temp = battery->chg_temp;
|
|
#else
|
|
chg_temp = battery->chg_temp;
|
|
#endif
|
|
|
|
#if defined(CONFIG_DUAL_BATTERY)
|
|
temperature = sec_bat_get_high_priority_temp(battery);
|
|
#endif
|
|
|
|
if (battery->siop_level >= 100 && !battery->lcd_status && is_not_wireless_type(battery->cable_type)) {
|
|
if ((!battery->mix_limit && (temperature >= battery->pdata->mix_high_temp) &&
|
|
(chg_temp >= battery->pdata->mix_high_chg_temp)) ||
|
|
(battery->mix_limit && (temperature > battery->pdata->mix_high_temp_recovery))) {
|
|
int max_input_current = battery->pdata->full_check_current_1st + 50;
|
|
|
|
/* input current = float voltage * (topoff_current_1st + 50mA(margin)) / (vbus_level * 0.9) */
|
|
input_current = ((battery->pdata->chg_float_voltage / battery->pdata->chg_float_voltage_conv) *
|
|
max_input_current) / (battery->input_voltage * 90) / 10;
|
|
|
|
if (input_current > max_input_current)
|
|
input_current = max_input_current;
|
|
|
|
battery->mix_limit = true;
|
|
/* skip other heating control */
|
|
sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_SKIP_HEATING_CONTROL,
|
|
SEC_BAT_CURRENT_EVENT_SKIP_HEATING_CONTROL);
|
|
sec_vote(battery->input_vote, VOTER_MIX_LIMIT, true, input_current);
|
|
|
|
#if defined(CONFIG_WIRELESS_TX_MODE)
|
|
if (battery->wc_tx_enable) {
|
|
pr_info("%s @Tx_Mode enter mix_temp_limit, TX mode should turn off \n", __func__);
|
|
sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_HIGH_TEMP,
|
|
BATT_TX_EVENT_WIRELESS_TX_HIGH_TEMP);
|
|
battery->tx_retry_case |= SEC_BAT_TX_RETRY_MIX_TEMP;
|
|
sec_wireless_set_tx_enable(battery, false);
|
|
}
|
|
#endif
|
|
} else if (battery->mix_limit) {
|
|
battery->mix_limit = false;
|
|
sec_vote(battery->input_vote, VOTER_MIX_LIMIT, false, 0);
|
|
if (battery->tx_retry_case & SEC_BAT_TX_RETRY_MIX_TEMP) {
|
|
pr_info("%s @Tx_Mode recovery mix_temp_limit, TX mode should be retried \n", __func__);
|
|
if ((battery->tx_retry_case & ~SEC_BAT_TX_RETRY_MIX_TEMP) == 0)
|
|
sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_RETRY,
|
|
BATT_TX_EVENT_WIRELESS_TX_RETRY);
|
|
battery->tx_retry_case &= ~SEC_BAT_TX_RETRY_MIX_TEMP;
|
|
}
|
|
}
|
|
|
|
pr_info("%s: mix_limit(%d), temp(%d), chg_temp(%d), input_current(%d)\n",
|
|
__func__, battery->mix_limit, temperature, chg_temp, input_current);
|
|
} else {
|
|
if (battery->mix_limit) {
|
|
battery->mix_limit = false;
|
|
sec_vote(battery->input_vote, VOTER_MIX_LIMIT, false, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static int sec_bat_get_temp_by_temp_control_source(struct sec_battery_info *battery, int tcs)
|
|
{
|
|
switch (tcs) {
|
|
case TEMP_CONTROL_SOURCE_CHG_THM:
|
|
return battery->chg_temp;
|
|
case TEMP_CONTROL_SOURCE_USB_THM:
|
|
return battery->usb_temp;
|
|
case TEMP_CONTROL_SOURCE_WPC_THM:
|
|
return battery->wpc_temp;
|
|
case TEMP_CONTROL_SOURCE_NONE:
|
|
case TEMP_CONTROL_SOURCE_BAT_THM:
|
|
default:
|
|
return battery->temperature;
|
|
}
|
|
}
|
|
|
|
void sec_bat_check_wpc_temp(struct sec_battery_info *battery)
|
|
{
|
|
int input_current = INT_MAX, charging_current = INT_MAX;
|
|
|
|
if (battery->pdata->wpc_temp_check_type == SEC_BATTERY_TEMP_CHECK_NONE)
|
|
return;
|
|
|
|
if (is_wireless_type(battery->cable_type)) {
|
|
union power_supply_propval value = {0, };
|
|
int wpc_vout_level = WIRELESS_VOUT_10V;
|
|
|
|
mutex_lock(&battery->voutlock);
|
|
|
|
/* get vout level */
|
|
psy_do_property(battery->pdata->wireless_charger_name, get,
|
|
POWER_SUPPLY_EXT_PROP_WIRELESS_RX_VOUT, value);
|
|
|
|
if(is_hv_wireless_type(battery->cable_type) &&
|
|
value.intval == WIRELESS_VOUT_5_5V_STEP &&
|
|
battery->wpc_vout_level != WIRELESS_VOUT_5_5V_STEP) {
|
|
pr_info("%s: real vout was not 10V \n", __func__);
|
|
battery->wpc_vout_level = WIRELESS_VOUT_5_5V_STEP;
|
|
}
|
|
|
|
if (battery->siop_level >= 100 && !battery->lcd_status) {
|
|
int temp_val = sec_bat_get_temp_by_temp_control_source(battery,
|
|
battery->pdata->wpc_temp_control_source);
|
|
|
|
if ((!battery->chg_limit && temp_val >= battery->pdata->wpc_high_temp) ||
|
|
(battery->chg_limit && temp_val > battery->pdata->wpc_high_temp_recovery)) {
|
|
battery->chg_limit = true;
|
|
if(input_current > battery->pdata->wpc_input_limit_current) {
|
|
if (battery->cable_type == SEC_BATTERY_CABLE_WIRELESS_TX &&
|
|
battery->pdata->wpc_input_limit_by_tx_check)
|
|
input_current = battery->pdata->wpc_input_limit_current_by_tx;
|
|
else
|
|
input_current = battery->pdata->wpc_input_limit_current;
|
|
}
|
|
if(charging_current > battery->pdata->wpc_charging_limit_current)
|
|
charging_current = battery->pdata->wpc_charging_limit_current;
|
|
wpc_vout_level = WIRELESS_VOUT_5_5V_STEP;
|
|
} else if (battery->chg_limit) {
|
|
battery->chg_limit = false;
|
|
}
|
|
} else {
|
|
if ((is_hv_wireless_type(battery->cable_type) &&
|
|
battery->cable_type != SEC_BATTERY_CABLE_WIRELESS_HV_VEHICLE) ||
|
|
battery->cable_type == SEC_BATTERY_CABLE_PREPARE_WIRELESS_HV ||
|
|
battery->cable_type == SEC_BATTERY_CABLE_PREPARE_WIRELESS_20) {
|
|
int temp_val = sec_bat_get_temp_by_temp_control_source(battery,
|
|
battery->pdata->wpc_temp_lcd_on_control_source);
|
|
|
|
if ((!battery->chg_limit &&
|
|
temp_val >= battery->pdata->wpc_lcd_on_high_temp) ||
|
|
(battery->chg_limit &&
|
|
temp_val > battery->pdata->wpc_lcd_on_high_temp_rec)) {
|
|
if(input_current > battery->pdata->wpc_lcd_on_input_limit_current)
|
|
input_current = battery->pdata->wpc_lcd_on_input_limit_current;
|
|
if(charging_current > battery->pdata->wpc_charging_limit_current)
|
|
charging_current = battery->pdata->wpc_charging_limit_current;
|
|
battery->chg_limit = true;
|
|
wpc_vout_level = (battery->capacity < 95) ?
|
|
WIRELESS_VOUT_5_5V_STEP : WIRELESS_VOUT_10V;
|
|
} else if (battery->chg_limit) {
|
|
battery->chg_limit = false;
|
|
}
|
|
} else if (battery->chg_limit) {
|
|
battery->chg_limit = false;
|
|
}
|
|
}
|
|
|
|
if (is_hv_wireless_type(battery->cable_type)) {
|
|
#if defined(CONFIG_ISDB_CHARGING_CONTROL)
|
|
if ((battery->current_event & SEC_BAT_CURRENT_EVENT_HIGH_TEMP_SWELLING) ||
|
|
(battery->current_event & SEC_BAT_CURRENT_EVENT_ISDB))
|
|
#else
|
|
if (battery->current_event & SEC_BAT_CURRENT_EVENT_HIGH_TEMP_SWELLING)
|
|
#endif
|
|
wpc_vout_level = WIRELESS_VOUT_5_5V_STEP;
|
|
|
|
if (wpc_vout_level != battery->wpc_vout_level) {
|
|
battery->wpc_vout_level = wpc_vout_level;
|
|
if (battery->current_event & SEC_BAT_CURRENT_EVENT_WPC_VOUT_LOCK) {
|
|
pr_info("%s: block to set wpc vout level(%d) because otg on\n",
|
|
__func__, wpc_vout_level);
|
|
} else {
|
|
value.intval = wpc_vout_level;
|
|
psy_do_property(battery->pdata->wireless_charger_name, set,
|
|
POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, value);
|
|
pr_info("%s: change vout level(%d)",
|
|
__func__, battery->wpc_vout_level);
|
|
sec_vote(battery->input_vote, VOTER_AICL, false, 0);
|
|
}
|
|
} else if (battery->wpc_vout_level == WIRELESS_VOUT_10V && !battery->chg_limit)
|
|
/* reset aicl current to recover current for unexpected aicl during */
|
|
/* before vout boosting completion */
|
|
sec_vote(battery->input_vote, VOTER_AICL, false, 0);
|
|
}
|
|
mutex_unlock(&battery->voutlock);
|
|
pr_info("%s: vout_level(%d), chg_limit(%d)\n",
|
|
__func__, battery->wpc_vout_level, battery->chg_limit);
|
|
if (battery->chg_limit) {
|
|
if ((battery->siop_level >= 100 && !battery->lcd_status) &&
|
|
(input_current > battery->pdata->wpc_input_limit_current))
|
|
input_current = battery->pdata->wpc_input_limit_current;
|
|
else if ((battery->siop_level < 100 || battery->lcd_status) &&
|
|
(input_current > battery->pdata->wpc_lcd_on_input_limit_current))
|
|
input_current = battery->pdata->wpc_lcd_on_input_limit_current;
|
|
}
|
|
if (input_current != INT_MAX) {
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, true, input_current);
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, true, charging_current);
|
|
} else {
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, false, 0);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, false, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sec_bat_check_tx_temperature(struct sec_battery_info *battery)
|
|
{
|
|
if (battery->wc_tx_enable) {
|
|
if(battery->temperature >= battery->pdata->tx_high_threshold) {
|
|
pr_info("@Tx_Mode : %s: Battery temperature is too high. Tx mode should turn off \n", __func__);
|
|
/* set tx event */
|
|
sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_HIGH_TEMP, BATT_TX_EVENT_WIRELESS_TX_HIGH_TEMP);
|
|
battery->tx_retry_case |= SEC_BAT_TX_RETRY_HIGH_TEMP;
|
|
sec_wireless_set_tx_enable(battery, false);
|
|
} else if (battery->temperature <= battery->pdata->tx_low_threshold) {
|
|
pr_info("@Tx_Mode : %s: Battery temperature is too low. Tx mode should turn off \n", __func__);
|
|
/* set tx event */
|
|
sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_LOW_TEMP, BATT_TX_EVENT_WIRELESS_TX_LOW_TEMP);
|
|
battery->tx_retry_case |= SEC_BAT_TX_RETRY_LOW_TEMP;
|
|
sec_wireless_set_tx_enable(battery, false);
|
|
}
|
|
} else if (battery->tx_retry_case & SEC_BAT_TX_RETRY_HIGH_TEMP) {
|
|
if (battery->temperature <= battery->pdata->tx_high_recovery) {
|
|
pr_info("@Tx_Mode : %s: Battery temperature goes to normal(High). Retry TX mode\n", __func__);
|
|
battery->tx_retry_case &= ~SEC_BAT_TX_RETRY_HIGH_TEMP;
|
|
if (!battery->tx_retry_case)
|
|
sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_RETRY, BATT_TX_EVENT_WIRELESS_TX_RETRY);
|
|
}
|
|
} else if (battery->tx_retry_case & SEC_BAT_TX_RETRY_LOW_TEMP) {
|
|
if (battery->temperature >= battery->pdata->tx_low_recovery) {
|
|
pr_info("@Tx_Mode : %s: Battery temperature goes to normal(Low). Retry TX mode\n", __func__);
|
|
battery->tx_retry_case &= ~SEC_BAT_TX_RETRY_LOW_TEMP;
|
|
if (!battery->tx_retry_case)
|
|
sec_bat_set_tx_event(battery, BATT_TX_EVENT_WIRELESS_TX_RETRY, BATT_TX_EVENT_WIRELESS_TX_RETRY);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if defined(CONFIG_DIRECT_CHARGING) && defined(CONFIG_CCIC_NOTIFIER)
|
|
void sec_bat_check_direct_chg_temp(struct sec_battery_info *battery)
|
|
{
|
|
int input_current = 0, charging_current = 0;
|
|
|
|
if (battery->pdata->dchg_temp_check_type == SEC_BATTERY_TEMP_CHECK_NONE)
|
|
return;
|
|
|
|
if (battery->siop_level >= 100 && !battery->lcd_status) {
|
|
if (!battery->chg_limit && battery->pd_list.now_isApdo &&
|
|
(battery->dchg_temp >= battery->pdata->dchg_high_temp)) {
|
|
input_current = battery->pdata->dchg_input_limit_current;
|
|
charging_current = battery->pdata->dchg_charging_limit_current;
|
|
battery->chg_limit = true;
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, battery->chg_limit, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, battery->chg_limit, input_current);
|
|
} else if (!battery->chg_limit && (!battery->pd_list.now_isApdo) &&
|
|
(battery->chg_temp >= battery->pdata->chg_high_temp)) {
|
|
if (battery->input_voltage == SEC_INPUT_VOLTAGE_5V) {
|
|
input_current = battery->pdata->default_input_current;
|
|
charging_current = battery->pdata->default_charging_current;
|
|
} else {
|
|
input_current = battery->pdata->chg_input_limit_current;
|
|
charging_current = battery->pdata->chg_charging_limit_current;
|
|
}
|
|
battery->chg_limit = true;
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, battery->chg_limit, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, battery->chg_limit, input_current);
|
|
} else if (battery->chg_limit) {
|
|
if (((battery->dchg_temp <= battery->pdata->dchg_high_temp_recovery) &&
|
|
battery->pd_list.now_isApdo) || ((battery->chg_temp <= battery->pdata->chg_high_temp_recovery) &&
|
|
(!battery->pd_list.now_isApdo))) {
|
|
battery->chg_limit = false;
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, battery->chg_limit, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, battery->chg_limit, input_current);
|
|
} else {
|
|
if (battery->pd_list.now_isApdo) {
|
|
input_current = battery->pdata->dchg_input_limit_current;
|
|
charging_current = battery->pdata->dchg_charging_limit_current;
|
|
} else {
|
|
if (battery->input_voltage == SEC_INPUT_VOLTAGE_5V) {
|
|
input_current = battery->pdata->default_input_current;
|
|
charging_current = battery->pdata->default_charging_current;
|
|
} else {
|
|
input_current = battery->pdata->chg_input_limit_current;
|
|
charging_current = battery->pdata->chg_charging_limit_current;
|
|
}
|
|
}
|
|
battery->chg_limit = true;
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, battery->chg_limit, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, battery->chg_limit, input_current);
|
|
}
|
|
}
|
|
pr_info("%s: cable_type(%d), chg_limit(%d) vbus_by_siop(%d)\n", __func__,
|
|
battery->cable_type, battery->chg_limit, battery->vbus_chg_by_siop);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_CCIC_NOTIFIER)
|
|
void sec_bat_check_pdic_temp(struct sec_battery_info *battery)
|
|
{
|
|
int input_current, charging_current;
|
|
|
|
if (battery->pdata->chg_temp_check_type == SEC_BATTERY_TEMP_CHECK_NONE)
|
|
return;
|
|
|
|
if (battery->pdic_ps_rdy && battery->siop_level >= 100 && !battery->lcd_status) {
|
|
if ((!battery->chg_limit && (battery->chg_temp >= battery->pdata->chg_high_temp)) ||
|
|
(battery->chg_limit && (battery->chg_temp >= battery->pdata->chg_high_temp_recovery))) {
|
|
input_current =
|
|
(battery->pdata->chg_input_limit_current * SEC_INPUT_VOLTAGE_9V) / battery->input_voltage;
|
|
charging_current = battery->pdata->chg_charging_limit_current;
|
|
sec_vote(battery->fcc_vote, VOTER_PDIC_TEMP, true, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_PDIC_TEMP, true, input_current);
|
|
battery->chg_limit = true;
|
|
} else if (battery->chg_limit && battery->chg_temp <= battery->pdata->chg_high_temp_recovery) {
|
|
sec_vote(battery->fcc_vote, VOTER_PDIC_TEMP, false, 0);
|
|
sec_vote(battery->input_vote, VOTER_PDIC_TEMP, false, 0);
|
|
battery->chg_limit = false;
|
|
}
|
|
pr_info("%s: cable_type(%d), chg_limit(%d)\n", __func__,
|
|
battery->cable_type, battery->chg_limit);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void sec_bat_check_afc_temp(struct sec_battery_info *battery)
|
|
{
|
|
int input_current = 0, charging_current = 0;
|
|
|
|
if (battery->pdata->chg_temp_check_type == SEC_BATTERY_TEMP_CHECK_NONE)
|
|
return;
|
|
|
|
#if defined(CONFIG_SUPPORT_HV_CTRL)
|
|
if (battery->siop_level >= 100 && !battery->lcd_status) {
|
|
if (!battery->chg_limit && is_hv_wire_type(battery->cable_type) &&
|
|
(battery->chg_temp >= battery->pdata->chg_high_temp)) {
|
|
input_current = battery->pdata->chg_input_limit_current;
|
|
charging_current = battery->pdata->chg_charging_limit_current;
|
|
battery->chg_limit = true;
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, battery->chg_limit, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, battery->chg_limit, input_current);
|
|
} else if (!battery->chg_limit && battery->max_charge_power >= (battery->pdata->pd_charging_charge_power - 500) &&
|
|
(battery->chg_temp >= battery->pdata->chg_high_temp)) {
|
|
input_current = battery->pdata->default_input_current;
|
|
charging_current = battery->pdata->default_charging_current;
|
|
battery->chg_limit = true;
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, battery->chg_limit, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, battery->chg_limit, input_current);
|
|
} else if (battery->chg_limit && is_hv_wire_type(battery->cable_type)) {
|
|
if (battery->chg_temp <= battery->pdata->chg_high_temp_recovery) {
|
|
battery->chg_limit = false;
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, battery->chg_limit, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, battery->chg_limit, input_current);
|
|
}
|
|
} else if (battery->chg_limit && battery->max_charge_power >= (battery->pdata->pd_charging_charge_power - 500)) {
|
|
if (battery->chg_temp <= battery->pdata->chg_high_temp_recovery) {
|
|
battery->chg_limit = false;
|
|
sec_vote(battery->fcc_vote, VOTER_CHG_TEMP, battery->chg_limit, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_CHG_TEMP, battery->chg_limit, input_current);
|
|
}
|
|
}
|
|
pr_info("%s: cable_type(%d), chg_limit(%d) vbus_by_siop(%d)\n", __func__,
|
|
battery->cable_type, battery->chg_limit, battery->vbus_chg_by_siop);
|
|
}
|
|
#else
|
|
if ((!battery->chg_limit && is_hv_wire_type(battery->cable_type) &&
|
|
(battery->chg_temp >= battery->pdata->chg_high_temp)) ||
|
|
(battery->chg_limit && is_hv_wire_type(battery->cable_type) &&
|
|
(battery->chg_temp > battery->pdata->chg_high_temp_recovery))) {
|
|
if (!battery->chg_limit) {
|
|
input_current = battery->pdata->chg_input_limit_current;
|
|
charging_current = battery->pdata->chg_charging_limit_current;
|
|
sec_vote(battery->fcc_vote, VOTER_AFC_TEMP, true, charging_current);
|
|
sec_vote(battery->input_vote, VOTER_AFC_TEMP, true, input_current);
|
|
battery->chg_limit = true;
|
|
}
|
|
} else if (battery->chg_limit && is_hv_wire_type(battery->cable_type) &&
|
|
(battery->chg_temp <= battery->pdata->chg_high_temp_recovery)) {
|
|
sec_vote(battery->fcc_vote, VOTER_AFC_TEMP, false, 0);
|
|
sec_vote(battery->input_vote, VOTER_AFC_TEMP, false, 0);
|
|
battery->chg_limit = false;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void sec_bat_set_threshold(struct sec_battery_info *battery)
|
|
{
|
|
if (is_wireless_type(battery->cable_type) || battery->cable_type == SEC_BATTERY_CABLE_WIRELESS_FAKE) {
|
|
battery->cold_cool3_thresh = battery->pdata->wireless_cold_cool3_thresh;
|
|
battery->cool3_cool2_thresh = battery->pdata->wireless_cool3_cool2_thresh;
|
|
battery->cool2_cool1_thresh = battery->pdata->wireless_cool2_cool1_thresh;
|
|
battery->cool1_normal_thresh = battery->pdata->wireless_cool1_normal_thresh;
|
|
battery->normal_warm_thresh = battery->pdata->wireless_normal_warm_thresh;
|
|
battery->warm_overheat_thresh = battery->pdata->wireless_warm_overheat_thresh;
|
|
} else {
|
|
battery->cold_cool3_thresh = battery->pdata->wire_cold_cool3_thresh;
|
|
battery->cool3_cool2_thresh = battery->pdata->wire_cool3_cool2_thresh;
|
|
battery->cool2_cool1_thresh = battery->pdata->wire_cool2_cool1_thresh;
|
|
battery->cool1_normal_thresh = battery->pdata->wire_cool1_normal_thresh;
|
|
battery->normal_warm_thresh = battery->pdata->wire_normal_warm_thresh;
|
|
battery->warm_overheat_thresh = battery->pdata->wire_warm_overheat_thresh;
|
|
|
|
}
|
|
}
|
|
|
|
bool sec_usb_thm_overheatlimit(struct sec_battery_info *battery)
|
|
{
|
|
#if defined(CONFIG_PREVENT_USB_CONN_OVERHEAT)
|
|
int gap = 0;
|
|
int bat_thm = battery->temperature;
|
|
#endif
|
|
|
|
if (battery->pdata->usb_temp_check_type == SEC_BATTERY_TEMP_CHECK_NONE) {
|
|
pr_err("%s: USB_THM, Invalid Temp Check Type, usb_thm <- bat_thm\n", __func__);
|
|
battery->usb_temp = battery->temperature;
|
|
}
|
|
|
|
if (battery->usb_thm_status == USB_THM_NORMAL) {
|
|
#if defined(CONFIG_PREVENT_USB_CONN_OVERHEAT)
|
|
#if defined(CONFIG_DUAL_BATTERY)
|
|
/* select low temp thermistor */
|
|
if (battery->temperature > battery->sub_bat_temp)
|
|
bat_thm = battery->sub_bat_temp;
|
|
#endif
|
|
if (battery->usb_temp > bat_thm)
|
|
gap = battery->usb_temp - bat_thm;
|
|
#endif
|
|
|
|
if (battery->usb_temp >= battery->overheatlimit_threshold) {
|
|
pr_info("%s: Usb Temp over than %d (usb_thm : %d)\n", __func__,
|
|
battery->overheatlimit_threshold, battery->usb_temp);
|
|
battery->usb_thm_status = USB_THM_OVERHEATLIMIT;
|
|
return true;
|
|
#if defined(CONFIG_PREVENT_USB_CONN_OVERHEAT)
|
|
} else if ((battery->usb_temp >= battery->usb_protection_temp) &&
|
|
(gap >= battery->temp_gap_bat_usb)) {
|
|
pr_info("%s: Temp gap between Usb temp and Bat temp : %d\n", __func__, gap);
|
|
#if defined(CONFIG_BATTERY_CISD)
|
|
if (gap > battery->cisd.data[CISD_DATA_USB_OVERHEAT_ALONE_PER_DAY])
|
|
battery->cisd.data[CISD_DATA_USB_OVERHEAT_ALONE_PER_DAY] = gap;
|
|
#endif
|
|
battery->usb_thm_status = USB_THM_GAP_OVER;
|
|
return true;
|
|
#endif
|
|
} else {
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
return false;
|
|
}
|
|
} else if (battery->usb_thm_status == USB_THM_OVERHEATLIMIT) {
|
|
if (battery->usb_temp <= battery->overheatlimit_recovery) {
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
#if defined(CONFIG_PREVENT_USB_CONN_OVERHEAT)
|
|
} else if (battery->usb_thm_status == USB_THM_GAP_OVER) {
|
|
if (battery->usb_temp < battery->usb_protection_temp) {
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
#endif
|
|
} else {
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
return false;
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
#define THERMAL_HYSTERESIS_2 19
|
|
#define THERMAL_HYSTERESIS_5 49
|
|
void sec_bat_thermal_check(struct sec_battery_info *battery)
|
|
{
|
|
int bat_thm = battery->temperature;
|
|
int pre_thermal_zone = battery->thermal_zone;
|
|
int voter_swelling_status = SEC_BAT_CHG_MODE_CHARGING;
|
|
|
|
#if defined(CONFIG_DUAL_BATTERY)
|
|
bat_thm = sec_bat_get_high_priority_temp(battery);
|
|
#endif
|
|
|
|
pr_err("%s: co_c3: %d, c3_c2: %d, c2_c1: %d, c1_no: %d, no_wa: %d, wa_ov: %d, tz(%s)\n", __func__,
|
|
battery->cold_cool3_thresh, battery->cool3_cool2_thresh, battery->cool2_cool1_thresh,
|
|
battery->cool1_normal_thresh, battery->normal_warm_thresh, battery->warm_overheat_thresh,
|
|
sec_bat_thermal_zone[battery->thermal_zone]);
|
|
if (battery->status == POWER_SUPPLY_STATUS_DISCHARGING ||
|
|
battery->skip_swelling) {
|
|
battery->health_change = false;
|
|
pr_debug("%s: DISCHARGING or 15 test mode. stop thermal check\n", __func__);
|
|
battery->thermal_zone = BAT_THERMAL_NORMAL;
|
|
sec_vote(battery->topoff_vote, VOTER_SWELLING, false, 0);
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, false, 0);
|
|
sec_vote(battery->fv_vote, VOTER_SWELLING, false, 0);
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, false, 0);
|
|
sec_bat_set_current_event(battery, 0, SEC_BAT_CURRENT_EVENT_SWELLING_MODE);
|
|
sec_bat_set_threshold(battery);
|
|
return;
|
|
}
|
|
|
|
if (battery->pdata->temp_check_type == SEC_BATTERY_TEMP_CHECK_NONE) {
|
|
pr_err("%s: BAT_THM, Invalid Temp Check Type\n", __func__);
|
|
return;
|
|
} else {
|
|
/* COLD - COOL3 - COOL2 - COOL1 - NORMAL - WARM - OVERHEAT - OVERHEATLIMIT*/
|
|
if (sec_usb_thm_overheatlimit(battery)) {
|
|
battery->thermal_zone = BAT_THERMAL_OVERHEATLIMIT;
|
|
} else if (bat_thm >= battery->normal_warm_thresh) {
|
|
if (bat_thm >= battery->warm_overheat_thresh) {
|
|
battery->thermal_zone = BAT_THERMAL_OVERHEAT;
|
|
} else {
|
|
battery->thermal_zone = BAT_THERMAL_WARM;
|
|
}
|
|
} else if (bat_thm <= battery->cool1_normal_thresh) {
|
|
if (bat_thm <= battery->cold_cool3_thresh) {
|
|
battery->thermal_zone = BAT_THERMAL_COLD;
|
|
} else if (bat_thm <= battery->cool3_cool2_thresh) {
|
|
battery->thermal_zone = BAT_THERMAL_COOL3;
|
|
} else if (bat_thm <= battery->cool2_cool1_thresh) {
|
|
battery->thermal_zone = BAT_THERMAL_COOL2;
|
|
} else {
|
|
battery->thermal_zone = BAT_THERMAL_COOL1;
|
|
}
|
|
} else {
|
|
battery->thermal_zone = BAT_THERMAL_NORMAL;
|
|
}
|
|
}
|
|
|
|
if (pre_thermal_zone != battery->thermal_zone) {
|
|
battery->bat_thm_count++;
|
|
|
|
if (battery->bat_thm_count < battery->pdata->temp_check_count) {
|
|
pr_info("%s : bat_thm_count %d/%d\n", __func__,
|
|
battery->bat_thm_count, battery->pdata->temp_check_count);
|
|
battery->thermal_zone = pre_thermal_zone;
|
|
return;
|
|
}
|
|
|
|
pr_info("%s: thermal zone update (%s -> %s), bat_thm(%d), usb_thm(%d)\n", __func__,
|
|
sec_bat_thermal_zone[pre_thermal_zone],
|
|
sec_bat_thermal_zone[battery->thermal_zone], bat_thm, battery->usb_temp);
|
|
battery->health_change = true;
|
|
battery->bat_thm_count = 0;
|
|
|
|
pr_info("%s : SAFETY TIME RESET!\n", __func__);
|
|
battery->expired_time = battery->pdata->expired_time;
|
|
battery->prev_safety_time = 0;
|
|
|
|
sec_bat_set_threshold(battery);
|
|
sec_bat_set_current_event(battery, 0, SEC_BAT_CURRENT_EVENT_SWELLING_MODE);
|
|
|
|
switch (battery->thermal_zone) {
|
|
case BAT_THERMAL_OVERHEATLIMIT:
|
|
battery->warm_overheat_thresh -= THERMAL_HYSTERESIS_2;
|
|
battery->normal_warm_thresh -= THERMAL_HYSTERESIS_2;
|
|
if (battery->usb_thm_status == USB_THM_OVERHEATLIMIT) {
|
|
pr_info("%s: USB_THM_OVERHEATLIMIT\n", __func__);
|
|
#if defined(CONFIG_BATTERY_CISD)
|
|
battery->cisd.data[CISD_DATA_USB_OVERHEAT_CHARGING]++;
|
|
battery->cisd.data[CISD_DATA_USB_OVERHEAT_CHARGING_PER_DAY]++;
|
|
#endif
|
|
#if defined(CONFIG_PREVENT_USB_CONN_OVERHEAT)
|
|
} else if (battery->usb_thm_status == USB_THM_GAP_OVER) {
|
|
pr_info("%s: USB_THM_GAP_OVER : %d\n", __func__, gap);
|
|
#if defined(CONFIG_BATTERY_CISD)
|
|
battery->cisd.data[CISD_DATA_USB_OVERHEAT_RAPID_CHANGE]++;
|
|
battery->cisd.data[CISD_DATA_USB_OVERHEAT_RAPID_CHANGE_PER_DAY]++;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
battery->health = POWER_SUPPLY_HEALTH_OVERHEATLIMIT;
|
|
sec_bat_set_charging_status(battery, POWER_SUPPLY_STATUS_NOT_CHARGING);
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true, SEC_BAT_CHG_MODE_BUCK_OFF);
|
|
#if defined(CONFIG_BATTERY_CISD)
|
|
battery->cisd.data[CISD_DATA_UNSAFETY_TEMPERATURE]++;
|
|
battery->cisd.data[CISD_DATA_UNSAFE_TEMPERATURE_PER_DAY]++;
|
|
#endif
|
|
|
|
#if defined(CONFIG_PREVENT_USB_CONN_OVERHEAT)
|
|
if (lpcharge) {
|
|
if (is_hv_afc_wire_type(battery->cable_type) && !battery->vbus_limit) {
|
|
#if defined(CONFIG_MUIC_HV) || defined(CONFIG_SUPPORT_HV_CTRL)
|
|
battery->vbus_chg_by_siop = SEC_INPUT_VOLTAGE_0V;
|
|
muic_afc_set_voltage(SEC_INPUT_VOLTAGE_0V);
|
|
#endif
|
|
battery->vbus_limit = true;
|
|
pr_info("%s: Set AFC TA to 0V\n", __func__);
|
|
} else if (is_pd_wire_type(battery->cable_type)) {
|
|
select_pdo(1);
|
|
pr_info("%s: Set PD TA to PDO 0\n", __func__);
|
|
}
|
|
} else if (is_pd_wire_type(battery->cable_type)) {
|
|
select_pdo(1);
|
|
muic_set_hiccup_mode(1);
|
|
} else {
|
|
muic_set_hiccup_mode(1);
|
|
}
|
|
#endif
|
|
break;
|
|
case BAT_THERMAL_OVERHEAT:
|
|
battery->swelling_mode = true;
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
battery->warm_overheat_thresh -= THERMAL_HYSTERESIS_2;
|
|
battery->normal_warm_thresh -= THERMAL_HYSTERESIS_2;
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true, SEC_BAT_CHG_MODE_CHARGING_OFF);
|
|
battery->health = POWER_SUPPLY_HEALTH_OVERHEAT;
|
|
sec_bat_set_charging_status(battery, POWER_SUPPLY_STATUS_NOT_CHARGING);
|
|
#if defined(CONFIG_BATTERY_CISD)
|
|
battery->cisd.data[CISD_DATA_UNSAFETY_TEMPERATURE]++;
|
|
battery->cisd.data[CISD_DATA_UNSAFE_TEMPERATURE_PER_DAY]++;
|
|
#endif
|
|
sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_HIGH_TEMP_SWELLING,
|
|
SEC_BAT_CURRENT_EVENT_SWELLING_MODE);
|
|
break;
|
|
case BAT_THERMAL_WARM:
|
|
battery->swelling_mode = true;
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
battery->normal_warm_thresh -= THERMAL_HYSTERESIS_2;
|
|
if (is_wireless_type(battery->cable_type) ||
|
|
battery->cable_type == SEC_BATTERY_CABLE_WIRELESS_FAKE) {
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, true, battery->pdata->wireless_warm_current);
|
|
#if defined(CONFIG_BATTERY_CISD)
|
|
battery->cisd.data[CISD_DATA_WC_HIGH_TEMP_SWELLING]++;
|
|
battery->cisd.data[CISD_DATA_WC_HIGH_TEMP_SWELLING_PER_DAY]++;
|
|
#endif
|
|
} else {
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, true, battery->pdata->wire_warm_current);
|
|
#if defined(CONFIG_BATTERY_CISD)
|
|
battery->cisd.data[CISD_DATA_HIGH_TEMP_SWELLING]++;
|
|
battery->cisd.data[CISD_DATA_HIGH_TEMP_SWELLING_PER_DAY]++;
|
|
#endif
|
|
}
|
|
sec_vote(battery->topoff_vote, VOTER_SWELLING, true, battery->pdata->high_temp_topoff);
|
|
if (battery->voltage_now > battery->pdata->high_temp_float) {
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true, SEC_BAT_CHG_MODE_CHARGING_OFF);
|
|
} else {
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true, SEC_BAT_CHG_MODE_CHARGING);
|
|
sec_vote(battery->fv_vote, VOTER_SWELLING, true, battery->pdata->high_temp_float);
|
|
}
|
|
battery->health = POWER_SUPPLY_HEALTH_GOOD;
|
|
sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_HIGH_TEMP_SWELLING,
|
|
SEC_BAT_CURRENT_EVENT_SWELLING_MODE);
|
|
break;
|
|
case BAT_THERMAL_COOL1:
|
|
battery->swelling_mode = true;
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
battery->cool1_normal_thresh += THERMAL_HYSTERESIS_2;
|
|
if (is_wireless_type(battery->cable_type) ||
|
|
battery->cable_type == SEC_BATTERY_CABLE_WIRELESS_FAKE) {
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, true, battery->pdata->wireless_cool1_current);
|
|
} else {
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, true, battery->pdata->wire_cool1_current);
|
|
}
|
|
sec_vote(battery->fv_vote, VOTER_SWELLING, true, battery->pdata->low_temp_float);
|
|
sec_vote(battery->topoff_vote, VOTER_SWELLING, true, battery->pdata->low_temp_topoff);
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true, SEC_BAT_CHG_MODE_CHARGING);
|
|
battery->health = POWER_SUPPLY_HEALTH_GOOD;
|
|
sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_LOW_TEMP_SWELLING_COOL1,
|
|
SEC_BAT_CURRENT_EVENT_SWELLING_MODE);
|
|
break;
|
|
case BAT_THERMAL_COOL2:
|
|
battery->swelling_mode = true;
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
battery->cool2_cool1_thresh += THERMAL_HYSTERESIS_2;
|
|
battery->cool1_normal_thresh += THERMAL_HYSTERESIS_2;
|
|
if (is_wireless_type(battery->cable_type) ||
|
|
battery->cable_type == SEC_BATTERY_CABLE_WIRELESS_FAKE) {
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, true, battery->pdata->wireless_cool2_current);
|
|
} else {
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, true, battery->pdata->wire_cool2_current);
|
|
}
|
|
sec_vote(battery->fv_vote, VOTER_SWELLING, true, battery->pdata->low_temp_float);
|
|
sec_vote(battery->topoff_vote, VOTER_SWELLING, true, battery->pdata->low_temp_topoff);
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true, SEC_BAT_CHG_MODE_CHARGING);
|
|
battery->health = POWER_SUPPLY_HEALTH_GOOD;
|
|
sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_LOW_TEMP_SWELLING_COOL2,
|
|
SEC_BAT_CURRENT_EVENT_SWELLING_MODE);
|
|
break;
|
|
case BAT_THERMAL_COOL3:
|
|
battery->swelling_mode = true;
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
battery->cool3_cool2_thresh += THERMAL_HYSTERESIS_2;
|
|
battery->cool2_cool1_thresh += THERMAL_HYSTERESIS_2;
|
|
battery->cool1_normal_thresh += THERMAL_HYSTERESIS_2;
|
|
if (is_wireless_type(battery->cable_type) ||
|
|
battery->cable_type == SEC_BATTERY_CABLE_WIRELESS_FAKE) {
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, true, battery->pdata->wireless_cool3_current);
|
|
} else {
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, true, battery->pdata->wire_cool3_current);
|
|
}
|
|
sec_vote(battery->fv_vote, VOTER_SWELLING, true, battery->pdata->low_temp_float);
|
|
sec_vote(battery->topoff_vote, VOTER_SWELLING, true, battery->pdata->low_temp_topoff);
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true, SEC_BAT_CHG_MODE_CHARGING);
|
|
battery->health = POWER_SUPPLY_HEALTH_GOOD;
|
|
sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_LOW_TEMP_SWELLING_COOL3,
|
|
SEC_BAT_CURRENT_EVENT_SWELLING_MODE);
|
|
break;
|
|
case BAT_THERMAL_COLD:
|
|
battery->swelling_mode = true;
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
battery->cold_cool3_thresh += THERMAL_HYSTERESIS_2;
|
|
battery->cool3_cool2_thresh += THERMAL_HYSTERESIS_2;
|
|
battery->cool2_cool1_thresh += THERMAL_HYSTERESIS_2;
|
|
battery->cool1_normal_thresh += THERMAL_HYSTERESIS_2;
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true, SEC_BAT_CHG_MODE_CHARGING_OFF);
|
|
battery->health = POWER_SUPPLY_HEALTH_COLD;
|
|
sec_bat_set_charging_status(battery, POWER_SUPPLY_STATUS_NOT_CHARGING);
|
|
#if defined(CONFIG_BATTERY_CISD)
|
|
battery->cisd.data[CISD_DATA_UNSAFETY_TEMPERATURE]++;
|
|
battery->cisd.data[CISD_DATA_UNSAFE_TEMPERATURE_PER_DAY]++;
|
|
#endif
|
|
sec_bat_set_current_event(battery, SEC_BAT_CURRENT_EVENT_LOW_TEMP_SWELLING_COOL3,
|
|
SEC_BAT_CURRENT_EVENT_SWELLING_MODE);
|
|
break;
|
|
case BAT_THERMAL_NORMAL:
|
|
default:
|
|
battery->swelling_mode = false;
|
|
battery->usb_thm_status = USB_THM_NORMAL;
|
|
sec_vote(battery->fcc_vote, VOTER_SWELLING, false, 0);
|
|
sec_vote(battery->fv_vote, VOTER_SWELLING, false, 0);
|
|
sec_vote(battery->topoff_vote, VOTER_SWELLING, false, 0);
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, false, 0);
|
|
battery->health = POWER_SUPPLY_HEALTH_GOOD;
|
|
break;
|
|
}
|
|
if ((battery->thermal_zone >= BAT_THERMAL_COOL3) && (battery->thermal_zone <= BAT_THERMAL_WARM)) {
|
|
#if defined(CONFIG_ENABLE_FULL_BY_SOC)
|
|
if ((battery->capacity >= 100) || (battery->status == POWER_SUPPLY_STATUS_FULL))
|
|
sec_bat_set_charging_status(battery, POWER_SUPPLY_STATUS_FULL);
|
|
else
|
|
sec_bat_set_charging_status(battery, POWER_SUPPLY_STATUS_CHARGING);
|
|
#else
|
|
if (battery->status != POWER_SUPPLY_STATUS_FULL)
|
|
sec_bat_set_charging_status(battery, POWER_SUPPLY_STATUS_CHARGING);
|
|
#endif
|
|
}
|
|
} else { /* pre_thermal_zone == battery->thermal_zone */
|
|
battery->health_change = false;
|
|
|
|
switch (battery->thermal_zone) {
|
|
case BAT_THERMAL_WARM:
|
|
if (battery->health == POWER_SUPPLY_HEALTH_GOOD) {
|
|
voter_swelling_status = get_sec_vote_result(battery->chgen_vote);
|
|
|
|
if (voter_swelling_status == SEC_BAT_CHG_MODE_CHARGING) {
|
|
if (sec_bat_check_full(battery, battery->pdata->full_check_type)) {
|
|
pr_info("%s: battery thermal zone WARM. Full charged.\n", __func__);
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true,
|
|
SEC_BAT_CHG_MODE_CHARGING_OFF);
|
|
}
|
|
} else if (voter_swelling_status == SEC_BAT_CHG_MODE_CHARGING_OFF) {
|
|
if (battery->voltage_now <= battery->pdata->swelling_high_rechg_voltage) {
|
|
pr_info("%s: thermal zone WARM. charging recovery. Vnow: %d\n",
|
|
__func__, battery->voltage_now);
|
|
battery->expired_time = battery->pdata->expired_time;
|
|
battery->prev_safety_time = 0;
|
|
sec_vote(battery->fv_vote, VOTER_SWELLING, true,
|
|
battery->pdata->high_temp_float);
|
|
sec_vote(battery->chgen_vote, VOTER_FULL_CHARGE, false, 0);
|
|
sec_vote(battery->chgen_vote, VOTER_SWELLING, true,
|
|
SEC_BAT_CHG_MODE_CHARGING);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|