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