hwmon: qpnp-current: Use ideal gain for PM8026

The IADC on PM8026 has been found to have improved accuracy
if the gain compensation is removed from the conversion equation.
Implement this in the IADC driver by faking a gain read of
offset + ideal gain during calibration.

Change-Id: I85abf713e796666946674e5ae603c918cfa9ae5a
Signed-off-by: Xiaozhe Shi <xiaozhes@codeaurora.org>
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 490a5ce..30adc19 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -134,7 +134,8 @@
 	bool	ext_rsense;
 	u8	id;
 	u8	sys_gain;
-	u8	revision;
+	u8	revision_dig_major;
+	u8	revision_ana_minor;
 };
 
 struct qpnp_iadc_chip {
@@ -332,13 +333,13 @@
 	old = *result;
 	*result = *result * 1000000;
 
-	if (comp.revision == QPNP_IADC_VER_3_1) {
+	if (comp.revision_dig_major == QPNP_IADC_VER_3_1) {
 		/* revision 3.1 */
 		if (comp.sys_gain > 127)
 			sys_gain_coeff = -QPNP_COEFF_6 * (comp.sys_gain - 128);
 		else
 			sys_gain_coeff = QPNP_COEFF_6 * comp.sys_gain;
-	} else if (comp.revision != QPNP_IADC_VER_3_0) {
+	} else if (comp.revision_dig_major != QPNP_IADC_VER_3_0) {
 		/* unsupported revision, do not compensate */
 		*result = old;
 		return 0;
@@ -358,9 +359,9 @@
 		break;
 		}
 		temp_var = div64_s64(temp_var, QPNP_COEFF_4);
-		if (comp.revision == QPNP_IADC_VER_3_0)
+		if (comp.revision_dig_major == QPNP_IADC_VER_3_0)
 			temp_var = QPNP_COEFF_1 * (1000000 - temp_var);
-		else if (comp.revision == QPNP_IADC_VER_3_1)
+		else if (comp.revision_dig_major == QPNP_IADC_VER_3_1)
 			temp_var = 1000000 * (1000000 - temp_var);
 		*result = div64_s64(*result * 1000000, temp_var);
 	}
@@ -371,7 +372,7 @@
 		temp_var = div64_s64((-sign_coeff * die_temp) + QPNP_COEFF_8,
 						QPNP_COEFF_4);
 		temp_var = 1000000000 - temp_var;
-		if (comp.revision == QPNP_IADC_VER_3_1) {
+		if (comp.revision_dig_major == QPNP_IADC_VER_3_1) {
 			sys_gain_coeff = (1000000 +
 				div64_s64(sys_gain_coeff, QPNP_COEFF_4));
 			temp_var = div64_s64(temp_var * sys_gain_coeff,
@@ -401,9 +402,16 @@
 	}
 
 	rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_REVISION2,
-						&iadc->iadc_comp.revision);
+					&iadc->iadc_comp.revision_dig_major);
 	if (rc < 0) {
-		pr_err("qpnp adc revision read failed with %d\n", rc);
+		pr_err("qpnp adc revision2 read failed with %d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_REVISION3,
+					&iadc->iadc_comp.revision_ana_minor);
+	if (rc < 0) {
+		pr_err("qpnp adc revision3 read failed with %d\n", rc);
 		return rc;
 	}
 
@@ -417,9 +425,10 @@
 	if (iadc->external_rsense)
 		iadc->iadc_comp.ext_rsense = true;
 
-	pr_debug("fab id = %u, revision = %u, sys gain = %u, external_rsense = %d\n",
+	pr_debug("fab id = %u, revision_dig_major = %u, revision_ana_minor = %u sys gain = %u, external_rsense = %d\n",
 			iadc->iadc_comp.id,
-			iadc->iadc_comp.revision,
+			iadc->iadc_comp.revision_dig_major,
+			iadc->iadc_comp.revision_ana_minor,
 			iadc->iadc_comp.sys_gain,
 			iadc->iadc_comp.ext_rsense);
 	return rc;
@@ -571,6 +580,9 @@
 	return 0;
 }
 
+#define IADC_IDEAL_RAW_GAIN	3291
+#define QPNP_IADC_PM8026_REV2	0x4
+#define QPNP_IADC_PM8026_REV3	0x2
 int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *iadc,
 							bool batfet_closed)
 {
@@ -629,6 +641,11 @@
 		goto fail;
 	}
 
+	if (iadc->iadc_comp.revision_dig_major == QPNP_IADC_PM8026_REV2
+		&& iadc->iadc_comp.revision_ana_minor == QPNP_IADC_PM8026_REV3)
+		iadc->adc->calib.gain_raw =
+			iadc->adc->calib.offset_raw + IADC_IDEAL_RAW_GAIN;
+
 	pr_debug("raw gain:0x%x, raw offset:0x%x\n",
 		iadc->adc->calib.gain_raw, iadc->adc->calib.offset_raw);