From fdbd5c763e1cb510f22e4aa6b94e62cc4b087a9a Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Tue, 16 Jul 2013 19:25:35 -0700 Subject: [PATCH] power: pm8921-bms: fix calibration and UVLO issues The bms is not running a hkadc calibration before calculating the first SOC. This causes accuracy issues with the power on SOC. Also when the battery gets in the low voltage range, don't limit the corrections. We have seen UVLO where even though the BMS was calculating SOC quickly it was not lowering the SOC fast enough. Skip limiting ocv change when battery is near cutoff voltage. Change-Id: I07747546867dcc90ccf7cb353c4e7a2c2c42520d Signed-off-by: Abhijeet Dharmapurikar --- drivers/power/pm8921-bms.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c index a9af9749852..233832fac25 100644 --- a/drivers/power/pm8921-bms.c +++ b/drivers/power/pm8921-bms.c @@ -1970,6 +1970,11 @@ static int adjust_soc(struct pm8921_bms_chip *chip, int soc, pr_debug("new delta ocv = %d\n", delta_ocv_uv); } + if (wake_lock_active(&chip->low_voltage_wake_lock)) { + pr_debug("Low Voltage, apply only ibat limited corrections\n"); + goto skip_limiting_corrections; + } + if (chip->last_ocv_uv > 3800000) correction_limit_uv = the_chip->high_ocv_correction_limit_uv; else @@ -1986,6 +1991,7 @@ static int adjust_soc(struct pm8921_bms_chip *chip, int soc, pr_debug("new delta ocv = %d\n", delta_ocv_uv); } +skip_limiting_corrections: chip->last_ocv_uv -= delta_ocv_uv; if (chip->last_ocv_uv >= chip->max_voltage_uv) @@ -2278,7 +2284,6 @@ static int calculate_state_of_charge(struct pm8921_bms_chip *chip, int new_calculated_soc; static int firsttime = 1; - calib_hkadc_check(chip, batt_temp); calculate_soc_params(chip, raw, batt_temp, chargecycles, &fcc_uah, &unusable_charge_uah, @@ -2426,6 +2431,7 @@ static int recalculate_soc(struct pm8921_bms_chip *chip) get_batt_temp(chip, &batt_temp); mutex_lock(&chip->last_ocv_uv_mutex); + calib_hkadc_check(chip, batt_temp); read_soc_params_raw(chip, &raw, batt_temp); soc = calculate_state_of_charge(chip, &raw, @@ -2762,6 +2768,7 @@ void pm8921_bms_charging_began(void) get_batt_temp(the_chip, &batt_temp); mutex_lock(&the_chip->last_ocv_uv_mutex); + calib_hkadc_check(the_chip, batt_temp); read_soc_params_raw(the_chip, &raw, batt_temp); mutex_unlock(&the_chip->last_ocv_uv_mutex); @@ -2907,6 +2914,7 @@ void pm8921_bms_charging_end(int is_battery_full) mutex_lock(&the_chip->last_ocv_uv_mutex); + calib_hkadc_check(the_chip, batt_temp); read_soc_params_raw(the_chip, &raw, batt_temp); calculate_cc_uah(the_chip, raw.cc, &bms_end_cc_uah);