forked from rubenslte/android_kernel_samsung_msm8226
power: pm8921-charger: BTC override fixes
- Monitor battery health when charger is not connected - Add configurable temperature hysteresis and enable the same for BTC override - Avoid releasing wakelock when charging is not in progress and BTC override is enabled - check temperature thresholds when fully charged, to handle temperature restrictions while restarting charging CRs-Fixed: 466525 Change-Id: I8cad3f8bcf65844fc1048625d9b387ede132d3e0 Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
parent
96a4d97f60
commit
d37bc1fb63
@@ -213,6 +213,8 @@ struct bms_notify {
|
||||
* @alarm_high_mv: the battery alarm voltage high
|
||||
* @cool_temp_dc: the cool temp threshold in deciCelcius
|
||||
* @warm_temp_dc: the warm temp threshold in deciCelcius
|
||||
* @hysteresis_temp_dc: the hysteresis between temp thresholds in
|
||||
* deciCelcius
|
||||
* @resume_voltage_delta: the voltage delta from vdd max at which the
|
||||
* battery should resume charging
|
||||
* @term_current: The charging based term current
|
||||
@@ -235,6 +237,7 @@ struct pm8921_chg_chip {
|
||||
unsigned int alarm_high_mv;
|
||||
int cool_temp_dc;
|
||||
int warm_temp_dc;
|
||||
int hysteresis_temp_dc;
|
||||
unsigned int temp_check_period;
|
||||
unsigned int cool_bat_chg_current;
|
||||
unsigned int warm_bat_chg_current;
|
||||
@@ -308,6 +311,7 @@ static int charging_disabled;
|
||||
static int thermal_mitigation;
|
||||
|
||||
static struct pm8921_chg_chip *the_chip;
|
||||
static void check_temp_thresholds(struct pm8921_chg_chip *chip);
|
||||
|
||||
#define LPM_ENABLE_BIT BIT(2)
|
||||
static int pm8921_chg_set_lpm(struct pm8921_chg_chip *chip, int enable)
|
||||
@@ -3162,6 +3166,22 @@ static void update_heartbeat(struct work_struct *work)
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct pm8921_chg_chip *chip = container_of(dwork,
|
||||
struct pm8921_chg_chip, update_heartbeat_work);
|
||||
bool chg_present = chip->usb_present || chip->dc_present;
|
||||
|
||||
/* for battery health when charger is not connected */
|
||||
if (chip->btc_override && !chg_present)
|
||||
schedule_delayed_work(&chip->btc_override_work,
|
||||
round_jiffies_relative(msecs_to_jiffies
|
||||
(chip->btc_delay_ms)));
|
||||
|
||||
/*
|
||||
* check temp thresholds when charger is present and
|
||||
* and battery is FULL. The temperature here can impact
|
||||
* the charging restart conditions.
|
||||
*/
|
||||
if (chip->btc_override && chg_present &&
|
||||
!wake_lock_active(&chip->eoc_wake_lock))
|
||||
check_temp_thresholds(chip);
|
||||
|
||||
power_supply_changed(&chip->batt_psy);
|
||||
if (chip->recent_reported_soc <= 20)
|
||||
@@ -3317,7 +3337,7 @@ static void check_temp_thresholds(struct pm8921_chg_chip *chip)
|
||||
|
||||
if (chip->warm_temp_dc != INT_MIN) {
|
||||
if (chip->is_bat_warm
|
||||
&& temp < chip->warm_temp_dc - TEMP_HYSTERISIS_DECIDEGC)
|
||||
&& temp < chip->warm_temp_dc - chip->hysteresis_temp_dc)
|
||||
battery_warm(false);
|
||||
else if (!chip->is_bat_warm && temp >= chip->warm_temp_dc)
|
||||
battery_warm(true);
|
||||
@@ -3325,7 +3345,7 @@ static void check_temp_thresholds(struct pm8921_chg_chip *chip)
|
||||
|
||||
if (chip->cool_temp_dc != INT_MIN) {
|
||||
if (chip->is_bat_cool
|
||||
&& temp > chip->cool_temp_dc + TEMP_HYSTERISIS_DECIDEGC)
|
||||
&& temp > chip->cool_temp_dc + chip->hysteresis_temp_dc)
|
||||
battery_cool(false);
|
||||
else if (!chip->is_bat_cool && temp <= chip->cool_temp_dc)
|
||||
battery_cool(true);
|
||||
@@ -3543,7 +3563,8 @@ static void btc_override_worker(struct work_struct *work)
|
||||
|
||||
temp = pm_chg_get_rt_status(chip, BATTTEMP_HOT_IRQ);
|
||||
if (temp) {
|
||||
if (decidegc < chip->btc_override_hot_decidegc)
|
||||
if (decidegc < chip->btc_override_hot_decidegc -
|
||||
chip->hysteresis_temp_dc)
|
||||
/* stop forcing batt hot */
|
||||
rc = pm_chg_override_hot(chip, 0);
|
||||
if (rc)
|
||||
@@ -3558,7 +3579,8 @@ static void btc_override_worker(struct work_struct *work)
|
||||
|
||||
temp = pm_chg_get_rt_status(chip, BATTTEMP_COLD_IRQ);
|
||||
if (temp) {
|
||||
if (decidegc > chip->btc_override_cold_decidegc)
|
||||
if (decidegc > chip->btc_override_cold_decidegc +
|
||||
chip->hysteresis_temp_dc)
|
||||
/* stop forcing batt cold */
|
||||
rc = pm_chg_override_cold(chip, 0);
|
||||
if (rc)
|
||||
@@ -3622,7 +3644,8 @@ static void eoc_worker(struct work_struct *work)
|
||||
|
||||
end = is_charging_finished(chip, vbat_batt_terminal_uv, ichg_meas_ma);
|
||||
|
||||
if (end == CHG_NOT_IN_PROGRESS) {
|
||||
if (end == CHG_NOT_IN_PROGRESS && (!chip->btc_override ||
|
||||
!(chip->usb_present || chip->dc_present))) {
|
||||
count = 0;
|
||||
goto eoc_worker_stop;
|
||||
}
|
||||
@@ -3650,7 +3673,8 @@ static void eoc_worker(struct work_struct *work)
|
||||
chgdone_irq_handler(chip->pmic_chg_irq[CHGDONE_IRQ], chip);
|
||||
} else {
|
||||
check_temp_thresholds(chip);
|
||||
adjust_vdd_max_for_fastchg(chip, vbat_batt_terminal_uv);
|
||||
if (end != CHG_NOT_IN_PROGRESS)
|
||||
adjust_vdd_max_for_fastchg(chip, vbat_batt_terminal_uv);
|
||||
pr_debug("EOC count = %d\n", count);
|
||||
schedule_delayed_work(&chip->eoc_work,
|
||||
round_jiffies_relative(msecs_to_jiffies
|
||||
@@ -3659,9 +3683,9 @@ static void eoc_worker(struct work_struct *work)
|
||||
}
|
||||
|
||||
eoc_worker_stop:
|
||||
wake_unlock(&chip->eoc_wake_lock);
|
||||
/* set the vbatdet back, in case it was changed to trigger charging */
|
||||
set_appropriate_vbatdet(chip);
|
||||
wake_unlock(&chip->eoc_wake_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3795,6 +3819,11 @@ static void __devinit determine_initial_state(struct pm8921_chg_chip *chip)
|
||||
schedule_delayed_work(&chip->unplug_check_work,
|
||||
msecs_to_jiffies(UNPLUG_CHECK_WAIT_PERIOD_MS));
|
||||
pm8921_chg_enable_irq(chip, CHG_GONE_IRQ);
|
||||
|
||||
if (chip->btc_override)
|
||||
schedule_delayed_work(&chip->btc_override_work,
|
||||
round_jiffies_relative(msecs_to_jiffies
|
||||
(chip->btc_delay_ms)));
|
||||
}
|
||||
|
||||
pm8921_chg_enable_irq(chip, DCIN_VALID_IRQ);
|
||||
@@ -4600,6 +4629,8 @@ static int pm8921_charger_resume(struct device *dev)
|
||||
is_usb_chg_plugged_in(the_chip)))
|
||||
schedule_delayed_work(&chip->btc_override_work, 0);
|
||||
|
||||
schedule_delayed_work(&chip->update_heartbeat_work, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4607,6 +4638,8 @@ static int pm8921_charger_suspend(struct device *dev)
|
||||
{
|
||||
struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
cancel_delayed_work_sync(&chip->update_heartbeat_work);
|
||||
|
||||
if (chip->btc_override)
|
||||
cancel_delayed_work_sync(&chip->btc_override_work);
|
||||
|
||||
@@ -4663,6 +4696,11 @@ static int __devinit pm8921_charger_probe(struct platform_device *pdev)
|
||||
else
|
||||
chip->warm_temp_dc = INT_MIN;
|
||||
|
||||
if (pdata->hysteresis_temp)
|
||||
chip->hysteresis_temp_dc = pdata->hysteresis_temp * 10;
|
||||
else
|
||||
chip->hysteresis_temp_dc = TEMP_HYSTERISIS_DECIDEGC;
|
||||
|
||||
chip->temp_check_period = pdata->temp_check_period;
|
||||
chip->max_bat_chg_current = pdata->max_bat_chg_current;
|
||||
/* Assign to corresponding module parameter */
|
||||
|
||||
@@ -165,6 +165,7 @@ struct pm8921_charger_platform_data {
|
||||
unsigned int warm_bat_chg_current;
|
||||
unsigned int cool_bat_voltage;
|
||||
unsigned int warm_bat_voltage;
|
||||
int hysteresis_temp;
|
||||
unsigned int (*get_batt_capacity_percent) (void);
|
||||
int64_t batt_id_min;
|
||||
int64_t batt_id_max;
|
||||
|
||||
Reference in New Issue
Block a user