aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Xuewen <zhaoxuewen@huawei.com>2015-07-31 15:25:34 -0700
committerZhao Xuewen <zhaoxuewen@huawei.com>2015-07-31 16:43:27 -0700
commitf184a0052faf382aace2365917137e328e8e22b7 (patch)
tree2886037f38f2bcaa2979ea5a605fcd684fa7f1a4
parentb83ded752c5327533a983dd5088a24621b416088 (diff)
power:qpnp-charger:when charger out,wait for a moment to enable soc changeandroid-wear-5.1.1_r0.11
when usb charger in ,do not allow capacity decrease. This may cause unplugin charger, the soc will decrease immediately, such as from 100% to 99%. So when charger out, wait for a moment to enable soc change. This includes the time spent in suspend. BUG:22880388 Change-Id: I27ec309ae025ed5e5b5a81c6e6289b8899724037 Signed-off-by: libing <l00228880@notesmail.huawei.com>
-rw-r--r--drivers/power/qpnp-charger.c99
1 files changed, 69 insertions, 30 deletions
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index ccf69f8a4071..5e4889953758 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -262,7 +262,7 @@
#define BATTERY_TEMP_LO -100 //battery low temp threshold
#define WARM_VOL_BUFFER 100 //warm_bat_mv need have a 100mV buffer
#define WARM_TEMP_THR 380 //battery warm temp threshold for running test
-#define HOT_MAX_TEMP_THR 60 //battery hot max temp threshold for running test
+#define HOT_MAX_TEMP_THR 60 //battery hot max temp threshold for running test
#define BATT_FULL 100 //battery full capactiy
#define USB_CHG_VALID_MASK 0xC0
#define USB_CHG_VALID_OVP_VALUE 0x40
@@ -457,6 +457,9 @@ struct qpnp_chg_chip {
struct work_struct lower_power_usb_workaround;
bool hw_low_power_usb_workaround_enable;
struct wake_lock led_wake_lock;
+ struct timespec charger_gone_begin_time;
+ struct timespec charger_gone_current_time;
+ bool charger_gone_soc_change_enable;
#endif
};
@@ -986,7 +989,7 @@ qpnp_chg_check_usbin_health(struct qpnp_chg_chip *chip)
/*check if usb or charger present*/
int is_usb_chg_exist(void)
{
- if (!global_chip)
+ if (!global_chip)
{
pr_err("called before init\n");
return -EINVAL;
@@ -1002,7 +1005,7 @@ int is_otg_host_mode(void)
if(!global_chip)
{
pr_err("called before init\n");
- return -EINVAL;
+ return -EINVAL;
}
return qpnp_chg_is_otg_en_set(global_chip);
}
@@ -1198,7 +1201,7 @@ qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
/*==========================================
FUNCTION: huawei_hot_design_iusb_set
-DESCRIPTION: set hot_design_current
+DESCRIPTION: set hot_design_current
(1)the min current is allowed to set is 500mA
(2)only write current into the register when usb chg_type is dcp
INPUT: int mA (input current)
@@ -1923,9 +1926,9 @@ static void hw_bad_tm_check_correct(struct qpnp_chg_chip *chip)
{
return;
}
-
+
temp = get_prop_batt_temp(chip);
- if(temp > chip->cold_bat_decidegc + HW_HYSTERISIS_DECIDEGC
+ if(temp > chip->cold_bat_decidegc + HW_HYSTERISIS_DECIDEGC
&& temp < chip->hot_bat_decidegc - HW_HYSTERISIS_DECIDEGC)
{
pr_info("bad_temp_flag is correct right \n ");
@@ -1992,16 +1995,25 @@ qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
return IRQ_HANDLED;
#ifdef CONFIG_HUAWEI_BATTERY_SETTING
- /*avoid the battery can not be charged when usb do not report any port*/
- if(usb_present)
- {
- qpnp_chg_iusbmax_set(chip, USB_WALL_THRESHOLD_MA);
- }
+ /*avoid the battery can not be charged when usb do not report any port*/
+ if(usb_present)
+ {
+ qpnp_chg_iusbmax_set(chip, USB_WALL_THRESHOLD_MA);
+ memset(&chip->charger_gone_begin_time, 0, sizeof(struct timespec));
+ memset(&chip->charger_gone_current_time, 0, sizeof(struct timespec));
+ chip->charger_gone_soc_change_enable = true;
+ }
+ else
+ {
+ /*when charger out, wait for a moment to enable soc change*/
+ get_monotonic_boottime(&chip->charger_gone_begin_time);
+ chip->charger_gone_soc_change_enable = false;
+ }
#endif
if (chip->usb_present ^ usb_present) {
/* irq_handler do not allow call function who has use mutex ,it will cause crash*/
#ifdef CONFIG_HUAWEI_BATTERY_SETTING
- if(bad_temp_flag && usb_present)
+ if(bad_temp_flag && usb_present)
{
check_temp_flag = true;
}
@@ -2009,7 +2021,7 @@ qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
{
force_ps_but_not_chg = false;
qpnp_chg_charge_en(chip, !force_ps_but_not_chg);
- qpnp_chg_force_run_on_batt(chip, force_ps_but_not_chg);
+ qpnp_chg_force_run_on_batt(chip, force_ps_but_not_chg);
pr_info("force_ps_but_not_chg is changed to false\n");
}
#endif
@@ -3068,7 +3080,10 @@ get_prop_charge_full(struct qpnp_chg_chip *chip)
return 0;
}
-#define MAX_FAKE_REDUCE_VALUE 6
+#define MAX_FAKE_REDUCE_VALUE 6
+#ifdef CONFIG_HUAWEI_BATTERY_SETTING
+#define CHARGER_GONE_DISABLE_SOC_CHANGE_TIME 10
+#endif
static int
get_prop_capacity(struct qpnp_chg_chip *chip)
{
@@ -3077,7 +3092,7 @@ get_prop_capacity(struct qpnp_chg_chip *chip)
#ifdef CONFIG_HUAWEI_BATTERY_SETTING
static int last_soc = -1;
if(!get_prop_batt_present(chip))
- return capacity_based_voltage(chip);
+ return capacity_based_voltage(chip);
#endif
if (chip->fake_battery_soc >= 0)
@@ -3124,7 +3139,7 @@ get_prop_capacity(struct qpnp_chg_chip *chip)
pr_warn_ratelimited("Battery 0, CHG absent\n");
}
/* when usb charger in ,do not allow capacity decrease */
-#ifdef CONFIG_HUAWEI_BATTERY_SETTING
+#ifdef CONFIG_HUAWEI_BATTERY_SETTING
if(last_soc < 0 || running_test_soc_enable || soc < DEFAULT_CAPACITY)
{
@@ -3136,6 +3151,24 @@ get_prop_capacity(struct qpnp_chg_chip *chip)
pr_debug("charger in,fake capacity from soc %d to last_soc %d \n",soc, last_soc);
soc = last_soc;
}
+ else if(!charger_in && (last_soc > soc) && !chip->charger_gone_soc_change_enable)
+ {
+ get_monotonic_boottime(&chip->charger_gone_current_time);
+ pr_debug("charger_gone_current_time.tv_sec = %ld, charger_gone_begin_time.tv_sec = %ld\n",
+ (long)(chip->charger_gone_current_time.tv_sec),
+ (long)(chip->charger_gone_begin_time.tv_sec));
+ if((chip->charger_gone_current_time.tv_sec - chip->charger_gone_begin_time.tv_sec)
+ < CHARGER_GONE_DISABLE_SOC_CHANGE_TIME)
+ {
+ pr_debug("charger out,fake capacity from soc %d to last_soc %d \n",soc, last_soc);
+ soc = last_soc;
+ }
+ else
+ {
+ chip->charger_gone_soc_change_enable = true;
+ last_soc = soc;
+ }
+ }
else
{
last_soc = soc;
@@ -3272,7 +3305,7 @@ qpnp_batt_external_power_changed(struct power_supply *psy)
}
} else {
#ifdef CONFIG_HUAWEI_BATTERY_SETTING
- if(chip->hw_low_power_usb_workaround_enable
+ if(chip->hw_low_power_usb_workaround_enable
&& (ret.intval / 1000) == USB_WALL_THRESHOLD_MA)
{
schedule_work(&chip->lower_power_usb_workaround);
@@ -3317,7 +3350,7 @@ static void poweroff_delay(struct work_struct *work)
static void poweroff_batt_level_check(struct qpnp_chg_chip *chip,union power_supply_propval *val)
{
- if((val->intval <= CUTOFF_BATTERY_LEVEL)
+ if((val->intval <= CUTOFF_BATTERY_LEVEL)
&& (!qpnp_chg_is_usb_chg_plugged_in(chip))
&& (!qpnp_chg_is_dc_chg_plugged_in(chip))
&&(get_prop_batt_present(chip))
@@ -3327,7 +3360,7 @@ static void poweroff_batt_level_check(struct qpnp_chg_chip *chip,union power_sup
{
pr_debug("start poweroff delay\n");
wake_lock(&chip->poweroff_wake_lock);
- schedule_delayed_work(&chip->poweroff_delay_work,
+ schedule_delayed_work(&chip->poweroff_delay_work,
round_jiffies_relative(msecs_to_jiffies(POWEROFF_DELAY_MS)));
chip->poweroff_delay_work_flag = true;
}
@@ -3468,10 +3501,10 @@ static int get_running_test_result(struct qpnp_chg_chip *chip)
return result;
}else{
pr_info("other else\n");
- if((POWER_SUPPLY_STATUS_NOT_CHARGING == cur_status)
- && (HOT_MAX_TEMP_THR >= temp)){
- result |= CHARGE_STATUS_PASS;
- pr_info("cur_status = %d temp = %d\n", cur_status, temp);
+ if((POWER_SUPPLY_STATUS_NOT_CHARGING == cur_status)
+ && (HOT_MAX_TEMP_THR >= temp)){
+ result |= CHARGE_STATUS_PASS;
+ pr_info("cur_status = %d temp = %d\n", cur_status, temp);
return result;
}
@@ -4658,8 +4691,8 @@ qpnp_chg_soc_check_work(struct work_struct *work)
/*====================================================================================
FUNCTION: hw_tm_warm_notification_zone
-DESCRIPTION: when qpnp_tm_state is warm, call this function.to acquire the
- temperature zone type
+DESCRIPTION: when qpnp_tm_state is warm, call this function.to acquire the
+ temperature zone type
INPUT: temperature,struct qpnp_chg_chip *chip
OUTPUT: NULL
@@ -4701,8 +4734,8 @@ static int hw_tm_warm_notification_zone(int temp,struct qpnp_chg_chip *chip)
/*====================================================================================
FUNCTION: hw_tm_cool_notification_zone
-DESCRIPTION: when qpnp_tm_state is cool, call this function.to acquire the
- temperature zone type
+DESCRIPTION: when qpnp_tm_state is cool, call this function.to acquire the
+ temperature zone type
INPUT: temperature,struct qpnp_chg_chip *chip
OUTPUT: NULL
@@ -4820,8 +4853,8 @@ static void hw_tm_set_configure(enum hw_high_low_temp_configure_type zone,struct
pr_info("bad_temp_flag is %d,qpnp_chg_charge_en is %d\n",bad_temp_flag,!bad_temp_flag);
qpnp_chg_charge_en(chip,!bad_temp_flag);
}
-
- if (chip->bat_is_cool ^ bat_cool || chip->bat_is_warm ^ bat_warm)
+
+ if (chip->bat_is_cool ^ bat_cool || chip->bat_is_warm ^ bat_warm)
{
chip->bat_is_cool = bat_cool;
chip->bat_is_warm = bat_warm;
@@ -6304,6 +6337,9 @@ qpnp_charger_probe(struct spmi_device *spmi)
chip->running_test_settled_status = POWER_SUPPLY_STATUS_CHARGING;
INIT_WORK(&chip->lower_power_usb_workaround,
qpnp_chg_usb_low_power_work);
+ memset(&chip->charger_gone_begin_time, 0, sizeof(struct timespec));
+ memset(&chip->charger_gone_current_time, 0, sizeof(struct timespec));
+ chip->charger_gone_soc_change_enable = true;
#endif
mutex_init(&chip->jeita_configure_lock);
mutex_init(&chip->batfet_vreg_lock);
@@ -6716,7 +6752,10 @@ qpnp_charger_remove(struct spmi_device *spmi)
#ifdef CONFIG_HUAWEI_BATTERY_SETTING
cancel_work_sync(&chip->lower_power_usb_workaround);
-#endif
+ memset(&chip->charger_gone_begin_time, 0, sizeof(struct timespec));
+ memset(&chip->charger_gone_current_time, 0, sizeof(struct timespec));
+ chip->charger_gone_soc_change_enable = true;
+ #endif
mutex_destroy(&chip->batfet_vreg_lock);
mutex_destroy(&chip->jeita_configure_lock);