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);