From c6adea8631425f9533cff3444dcad83a7de68fb9 Mon Sep 17 00:00:00 2001
From: "choongryeol.lee" <choongryeol.lee@lge.com>
Date: Fri, 26 Sep 2014 16:48:40 -0700
Subject: [PATCH] power: qpnp-charger: guarantee minimum retry of ibat trim

For the accurate ibat error compensation, the current
should be measured at ibat loop state. However, the current
might not be settled right after ibat loop activation or
ibat trim change. So clear the vbat_low_count when ibat loop
is not active or ibat trim is updated to guarantee minimum
retry of ibat error compensation after ibat loop activation
and ibat trimming.

Change-Id: If434bf5cc199db0b22125c7b7a3180fd8b3e96cb
Signed-off-by: choongryeol.lee <choongryeol.lee@lge.com>
---
 drivers/power/qpnp-charger.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 0b96ca6fe4bc..86f656131ae5 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -3103,7 +3103,7 @@ qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
 						chip->ibat_offset_ma;
 
 	if (chip->ext_set_ibat_ma)
-		chg_current = min (chg_current, chip->ext_set_ibat_ma);
+		chg_current = min(chg_current, chip->ext_set_ibat_ma);
 
 	if (chip->bat_is_cool)
 		chg_current = min(chg_current, chip->cool_bat_chg_ma);
@@ -3511,19 +3511,19 @@ qpnp_chg_adjust_vddmax(struct qpnp_chg_chip *chip, int vbat_mv)
 	qpnp_chg_set_appropriate_vddmax(chip);
 }
 
-static void qpnp_chg_compensate_ibat_error(struct qpnp_chg_chip *chip)
+static int qpnp_chg_compensate_ibat_error(struct qpnp_chg_chip *chip)
 {
 	int ibat_ma, ibat_max_ma, ibat_diff_ma, trim, rc;
 	u8 ibat_trim;
 
 	ibat_ma = get_prop_current_now(chip) / 1000;
 	if (ibat_ma >= 0)
-		return;
+		return -EINVAL;
 
 	rc = qpnp_chg_ibatmax_get(chip, &ibat_max_ma);
 	if (rc) {
-		pr_debug("failed to get ibatmax rc=%d\n", rc);
-		return;
+		pr_err("failed to get ibatmax rc=%d\n", rc);
+		return -EIO;
 	}
 
 	ibat_diff_ma = -1 * ibat_ma
@@ -3531,7 +3531,7 @@ static void qpnp_chg_compensate_ibat_error(struct qpnp_chg_chip *chip)
 
 	if (abs(ibat_diff_ma) > QPNP_CHG_I_STEP_MA * 2) {
 		pr_err("ibat diff is out of range\n");
-		return;
+		return -EINVAL;
 	}
 
 	if (ibat_diff_ma > 0)
@@ -3544,20 +3544,20 @@ static void qpnp_chg_compensate_ibat_error(struct qpnp_chg_chip *chip)
 				chip->buck_base + BUCK_CTRL_TRIM3, 1);
 		if (rc) {
 			pr_err("failed to read BUCK_CTRL_TRIM3 rc=%d\n", rc);
-			return;
+			return -EIO;
 		}
 
 		ibat_trim += trim;
 		ibat_trim &= IBAT_TRIM_OFFSET_MASK;
 		if (!is_within_range(ibat_trim, IBAT_TRIM_LOW_LIM,
 					IBAT_TRIM_HIGH_LIM))
-			return;
+			return -EINVAL;
 
 		rc = qpnp_chg_masked_write(chip,
 				chip->buck_base + SEC_ACCESS, 0xFF, 0xA5, 1);
 		if (rc) {
 			pr_err("failed to write SEC_ACCESS rc=%d\n", rc);
-			return;
+			return -EIO;
 		}
 
 		ibat_trim |= IBAT_TRIM_GOOD_BIT;
@@ -3565,11 +3565,14 @@ static void qpnp_chg_compensate_ibat_error(struct qpnp_chg_chip *chip)
 				chip->buck_base + BUCK_CTRL_TRIM3, 1);
 		if (rc) {
 			pr_err("failed to set IBAT_TRIM rc=%d\n", rc);
-			return;
+			return -EIO;
 		}
 
 		pr_debug("ibat trim: %dmA\n", trim * IBAT_TRIM_LOW_LIM);
+		return 0;
 	}
+
+	return -EINVAL;
 }
 
 #define CONSECUTIVE_COUNT	3
@@ -3625,22 +3628,22 @@ qpnp_eoc_work(struct work_struct *work)
 				ibat_ma, vbat_mv, chip->term_current);
 
 		if (buck_sts & IBAT_LOOP_IRQ)
-			qpnp_chg_compensate_ibat_error(chip);
+			if (!qpnp_chg_compensate_ibat_error(chip))
+				vbat_low_count = 0;
 
 		vbat_lower_than_vbatdet = !(chg_sts & VBAT_DET_LOW_IRQ);
 		if (vbat_lower_than_vbatdet && vbat_mv <
 				(chip->max_voltage_mv - chip->resume_delta_mv
-				 - chip->vbatdet_max_err_mv)) {
+				 - chip->vbatdet_max_err_mv) &&
+				(buck_sts & IBAT_LOOP_IRQ)) {
 			vbat_low_count++;
 			pr_debug("woke up too early vbat_mv = %d, max_mv = %d, resume_mv = %d tolerance_mv = %d low_count = %d\n",
 					vbat_mv, chip->max_voltage_mv,
 					chip->resume_delta_mv,
 					chip->vbatdet_max_err_mv,
 					vbat_low_count);
-			if ((vbat_low_count >= CONSECUTIVE_COUNT) &&
-						(buck_sts & IBAT_LOOP_IRQ)) {
+			if (vbat_low_count >= CONSECUTIVE_COUNT) {
 				pr_debug("woke up too early stopping\n");
-
 				qpnp_chg_enable_irq(chip, &chip->chg_vbatdet_lo);
 				goto stop_eoc;
 			} else {
-- 
GitLab