power: pm8921-bms: disable ocv updates for flat portion of the curve
An issue is observed when an OCV is updated while the device is
sleeping. When it wakes up the SOC calculations are run on the new OCV
which result in a drastically different SOC than previously reported.
The root cause of this issue is PON OCV likely was unsettled.
Provide a feature where OCV updates can be disabled between certain
SOC range.
Change-Id: I54a75a7e9d05ff2c8ccd484850f02a0190d6a3b7
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 981fde6..de656fc 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -162,6 +162,9 @@
int low_voltage_calc_ms;
int imax_ua;
struct wake_lock soc_wake_lock;
+ int disable_flat_portion_ocv;
+ int ocv_dis_high_soc;
+ int ocv_dis_low_soc;
};
/*
@@ -748,7 +751,7 @@
pr_err("BMS driver has not been initialized yet!\n");
return -EINVAL;
}
- pr_debug("stopping ocv updates\n");
+ pr_debug("starting ocv updates\n");
return pm_bms_masked_write(the_chip, BMS_TOLERANCES,
OCV_TOL_MASK, OCV_TOL_DEFAULT);
}
@@ -2154,6 +2157,15 @@
calculated_soc = new_calculated_soc;
firsttime = 0;
get_current_time(&chip->last_recalc_time);
+
+ if (chip->disable_flat_portion_ocv) {
+ if (is_between(chip->ocv_dis_high_soc, chip->ocv_dis_low_soc,
+ calculated_soc)) {
+ pm8921_bms_stop_ocv_updates();
+ } else {
+ pm8921_bms_start_ocv_updates();
+ }
+ }
return calculated_soc;
}
@@ -3130,6 +3142,10 @@
chip->revision = pm8xxx_get_revision(chip->dev->parent);
chip->enable_fcc_learning = pdata->enable_fcc_learning;
+ chip->disable_flat_portion_ocv = pdata->disable_flat_portion_ocv;
+ chip->ocv_dis_high_soc = pdata->ocv_dis_high_soc;
+ chip->ocv_dis_low_soc = pdata->ocv_dis_low_soc;
+
mutex_init(&chip->calib_mutex);
INIT_WORK(&chip->calib_hkadc_work, calibrate_hkadc_work);
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 12214d9..d670732 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -41,6 +41,9 @@
* voltage higher than cutoff voltage
* @low_voltage_calc_ms: The period of soc calculation in ms when battery
* voltage is near cutoff voltage
+ * @disable_flat_portion_ocv: feature to disable ocv updates while in sleep
+ * @ocv_dis_high_soc: the high soc percent when ocv should be disabled
+ * @ocv_dis_low_soc: the low soc percent when ocv should be enabled
*/
struct pm8921_bms_platform_data {
struct pm8xxx_bms_core_data bms_cdata;
@@ -57,6 +60,9 @@
int chg_term_ua;
int normal_voltage_calc_ms;
int low_voltage_calc_ms;
+ int disable_flat_portion_ocv;
+ int ocv_dis_high_soc;
+ int ocv_dis_low_soc;
};
#if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)