power: pm8921-bms: add api to stop/start ocv updates

OCV (open circuit voltage) updates could cause the state of charge
to drift by a considerable amount. There are cases where an OCV
update is undesirable. Provide facility to disable OCV updates.

Change-Id: If660c2004abf65e26db21f85bc1646388f2a10cd
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index f8135dc..b0439bc 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1760,6 +1760,8 @@
 #define OCV_TOL_MASK			0xF0
 #define IBAT_TOL_DEFAULT	0x03
 #define IBAT_TOL_NOCHG		0x0F
+#define OCV_TOL_DEFAULT		0x20
+#define OCV_TOL_NO_OCV		0x00
 void pm8921_bms_charging_began(void)
 {
 	int batt_temp, rc;
@@ -1897,6 +1899,22 @@
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_charging_end);
 
+int pm8921_bms_stop_ocv_updates(struct pm8921_bms_chip *chip)
+{
+	pr_debug("stopping ocv updates\n");
+	return pm_bms_masked_write(chip, BMS_TOLERANCES,
+			OCV_TOL_MASK, OCV_TOL_NO_OCV);
+}
+EXPORT_SYMBOL_GPL(pm8921_bms_stop_ocv_updates);
+
+int pm8921_bms_start_ocv_updates(struct pm8921_bms_chip *chip)
+{
+	pr_debug("stopping ocv updates\n");
+	return pm_bms_masked_write(chip, BMS_TOLERANCES,
+			OCV_TOL_MASK, OCV_TOL_DEFAULT);
+}
+EXPORT_SYMBOL_GPL(pm8921_bms_start_ocv_updates);
+
 static irqreturn_t pm8921_bms_sbi_write_ok_handler(int irq, void *data)
 {
 	pr_debug("irq = %d triggered", irq);
@@ -2231,6 +2249,8 @@
 	CALIB_HKADC,
 	CALIB_CCADC,
 	GET_VBAT_VSENSE_SIMULTANEOUS,
+	STOP_OCV,
+	START_OCV,
 };
 
 static int test_batt_temp = 5;
@@ -2323,13 +2343,30 @@
 		pm8921_bms_get_simultaneous_battery_voltage_and_current(
 			&ibat_ua,
 			&vbat_uv);
+	default:
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int set_calc(void *data, u64 val)
+{
+	int param = (int)data;
+	int ret = 0;
+
+	switch (param) {
+	case STOP_OCV:
+		pm8921_bms_stop_ocv_updates(the_chip);
+		break;
+	case START_OCV:
+		pm8921_bms_start_ocv_updates(the_chip);
 		break;
 	default:
 		ret = -EINVAL;
 	}
 	return ret;
 }
-DEFINE_SIMPLE_ATTRIBUTE(calc_fops, get_calc, NULL, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(calc_fops, get_calc, set_calc, "%llu\n");
 
 static int get_reading(void *data, u64 * val)
 {
@@ -2467,6 +2504,10 @@
 				(void *)CALIB_HKADC, &calc_fops);
 	debugfs_create_file("calib_ccadc", 0644, chip->dent,
 				(void *)CALIB_CCADC, &calc_fops);
+	debugfs_create_file("stop_ocv", 0644, chip->dent,
+				(void *)STOP_OCV, &calc_fops);
+	debugfs_create_file("start_ocv", 0644, chip->dent,
+				(void *)START_OCV, &calc_fops);
 
 	debugfs_create_file("simultaneous", 0644, chip->dent,
 			(void *)GET_VBAT_VSENSE_SIMULTANEOUS, &calc_fops);