power: pm8921-bms: fix hkadc readings

The procedure to calculate the battery voltage from xoadc raw readings
needs to be updated. Currently the driver multiplies the readings by 3
before calibration. This step needs to be done after calibration.

Also update all battery voltage based read_xxxx functions to
return the calibrated value.

Additionally call the hkadc calibration function at probe time
so early readings of battery voltage will be accurate.

Change-Id: I19c4ae8f124f3442ddffd651445db529ceac1cfe
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 61b7608..fdbc819 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -339,25 +339,34 @@
 	return 0;
 }
 
-#define V_PER_BIT_MUL_FACTOR	293
-#define INTRINSIC_OFFSET	0x6000
-static int vbatt_to_microvolt(unsigned int a)
+#define V_PER_BIT_MUL_FACTOR	97656
+#define V_PER_BIT_DIV_FACTOR	1000
+#define XOADC_INTRINSIC_OFFSET	0x6000
+static int xoadc_reading_to_microvolt(unsigned int a)
 {
-	if (a <= INTRINSIC_OFFSET)
+	if (a <= XOADC_INTRINSIC_OFFSET)
 		return 0;
 
-	return (a - INTRINSIC_OFFSET) * V_PER_BIT_MUL_FACTOR;
+	return (a - XOADC_INTRINSIC_OFFSET)
+			* V_PER_BIT_MUL_FACTOR / V_PER_BIT_DIV_FACTOR;
 }
 
 #define XOADC_CALIB_UV		625000
-static int adjust_xo_reading(struct pm8921_bms_chip *chip, unsigned int uv)
+#define VBATT_MUL_FACTOR	3
+static int adjust_xo_vbatt_reading(struct pm8921_bms_chip *chip,
+							unsigned int uv)
 {
-	u64 numerator = ((u64)uv - chip->xoadc_v0625) * XOADC_CALIB_UV;
-	u64 denominator =  chip->xoadc_v125 - chip->xoadc_v0625;
+	u64 numerator, denominator;
 
+	if (uv == 0)
+		return 0;
+
+	numerator = ((u64)uv - chip->xoadc_v0625) * XOADC_CALIB_UV;
+	denominator =  chip->xoadc_v125 - chip->xoadc_v0625;
 	if (denominator == 0)
-		return uv;
-	return XOADC_CALIB_UV + div_u64(numerator, denominator);
+		return uv * VBATT_MUL_FACTOR;
+	return (XOADC_CALIB_UV + div_u64(numerator, denominator))
+						* VBATT_MUL_FACTOR;
 }
 
 #define CC_RESOLUTION_N_V1	1085069
@@ -425,7 +434,7 @@
 		pr_err("fail to read LAST_GOOD_OCV_VALUE rc = %d\n", rc);
 		return rc;
 	}
-	*result = vbatt_to_microvolt(reading);
+	*result = xoadc_reading_to_microvolt(reading);
 	pr_debug("raw = %04x ocv_microV = %u\n", reading, *result);
 	if (*result != 0)
 		last_ocv_uv = *result;
@@ -442,8 +451,10 @@
 		pr_err("fail to read VBATT_FOR_RBATT rc = %d\n", rc);
 		return rc;
 	}
-	*result = vbatt_to_microvolt(reading);
+	*result = xoadc_reading_to_microvolt(reading);
 	pr_debug("raw = %04x vbatt_for_r_microV = %u\n", reading, *result);
+	*result = adjust_xo_vbatt_reading(chip, *result);
+	pr_debug("after adj vbatt_for_r_uV = %u\n", *result);
 	return 0;
 }
 
@@ -472,8 +483,10 @@
 		pr_err("fail to read OCV_FOR_RBATT rc = %d\n", rc);
 		return rc;
 	}
-	*result = vbatt_to_microvolt(reading);
-	pr_debug("read = %04x ocv_for_r_microV = %u\n", reading, *result);
+	*result = xoadc_reading_to_microvolt(reading);
+	pr_debug("raw = %04x ocv_for_r_uV = %u\n", reading, *result);
+	*result = adjust_xo_vbatt_reading(chip, *result);
+	pr_debug("after adj ocv_for_r_uV = %u\n", *result);
 	return 0;
 }
 
@@ -741,14 +754,12 @@
 		pr_err("fail to read ocv_for_rbatt rc = %d\n", rc);
 		ocv = 0;
 	}
-	ocv = adjust_xo_reading(chip, ocv);
 
 	rc = read_vbatt_for_rbatt(chip, &vbatt);
 	if (rc) {
 		pr_err("fail to read vbatt_for_rbatt rc = %d\n", rc);
 		ocv = 0;
 	}
-	vbatt = adjust_xo_reading(chip, vbatt);
 
 	rc = read_vsense_for_rbatt(chip, &vsense);
 	if (rc) {
@@ -1036,7 +1047,8 @@
 #define HKADC_V_PER_BIT_DIV_FACTOR	10
 static int calib_hkadc_convert_microvolt(unsigned int phy)
 {
-	return phy * HKADC_V_PER_BIT_MUL_FACTOR / HKADC_V_PER_BIT_DIV_FACTOR;
+	return (phy - 0x6000) *
+			HKADC_V_PER_BIT_MUL_FACTOR / HKADC_V_PER_BIT_DIV_FACTOR;
 }
 
 static void calib_hkadc(struct pm8921_bms_chip *chip)
@@ -1049,10 +1061,10 @@
 		pr_err("ADC failed for 1.25volts rc = %d\n", rc);
 		return;
 	}
-	voltage = calib_hkadc_convert_microvolt(result.physical);
+	voltage = calib_hkadc_convert_microvolt(result.adc_code);
 
-	pr_debug("result 1.25v = 0x%llx, voltage = %dmV adc_meas = %lld\n",
-				result.physical, voltage, result.measurement);
+	pr_debug("result 1.25v = 0x%x, voltage = %duV adc_meas = %lld\n",
+				result.adc_code, voltage, result.measurement);
 
 	/* check for valid range */
 	if (voltage > XOADC_MAX_1P25V)
@@ -1066,9 +1078,9 @@
 		pr_err("ADC failed for 1.25volts rc = %d\n", rc);
 		return;
 	}
-	voltage = calib_hkadc_convert_microvolt(result.physical);
-	pr_debug("result 0.625V = 0x%llx, voltage = %dmV adc_mead = %lld\n",
-				result.physical, voltage, result.measurement);
+	voltage = calib_hkadc_convert_microvolt(result.adc_code);
+	pr_debug("result 0.625V = 0x%x, voltage = %duV adc_mead = %lld\n",
+				result.adc_code, voltage, result.measurement);
 	/* check for valid range */
 	if (voltage > XOADC_MAX_0P625V)
 		voltage = XOADC_MAX_0P625V;
@@ -1373,6 +1385,7 @@
 	 * if not compute it here at boot time and save it
 	 * in the last_ocv_uv.
 	 */
+	ocv = 0;
 	rc = read_last_good_ocv(chip, &ocv);
 	if (rc || ocv == 0) {
 		rc = adc_based_ocv(chip, &ocv);
@@ -1677,9 +1690,11 @@
 static int __devinit pm8921_bms_probe(struct platform_device *pdev)
 {
 	int rc = 0;
+	int vbatt;
 	struct pm8921_bms_chip *chip;
 	const struct pm8921_bms_platform_data *pdata
 				= pdev->dev.platform_data;
+
 	if (!pdata) {
 		pr_err("missing platform data\n");
 		return -EINVAL;
@@ -1728,12 +1743,16 @@
 
 	check_initial_ocv(chip);
 
+	/* initial hkadc calibration */
+	schedule_work(&chip->calib_hkadc_work);
 	/* enable the vbatt reading interrupts for scheduling hkadc calib */
 	pm8921_bms_enable_irq(chip, PM8921_BMS_GOOD_OCV);
 	pm8921_bms_enable_irq(chip, PM8921_BMS_OCV_FOR_R);
 
-	pr_info("OK battery_capacity_at_boot=%d\n",
-				pm8921_bms_get_percent_charge());
+	get_battery_uvolts(chip, &vbatt);
+	pr_info("OK battery_capacity_at_boot=%d volt = %d ocv = %d\n",
+				pm8921_bms_get_percent_charge(),
+				vbatt, last_ocv_uv);
 	return 0;
 
 free_chip: