From 811a8bd2ef12b0ca589714823ea6d85381d250b6 Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Wed, 21 Jun 2017 11:10:40 -0700 Subject: [PATCH] power: qpnp-fg-gen3: optimize TTF for QNOVO QNOVO provides a table of expected charge current settings across the charge cycle. Use this table to calculate the time it will take to charge in each step. The sum of these steps is the total time it will take to fully charge a battery. Change-Id: I0ed48a2a63886531e761e7ce1d175a600060eaf8 Signed-off-by: Nicholas Troast Signed-off-by: Abhijeet Dharmapurikar --- drivers/power/supply/qcom/fg-core.h | 1 + drivers/power/supply/qcom/qpnp-fg-gen3.c | 45 +++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h index dea107c602c3..a49d96463dbf 100644 --- a/drivers/power/supply/qcom/fg-core.h +++ b/drivers/power/supply/qcom/fg-core.h @@ -233,6 +233,7 @@ enum esr_timer_config { enum ttf_mode { TTF_MODE_NORMAL = 0, + TTF_MODE_QNOVO, }; /* DT parameters for FG device */ diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index eefadd9412b2..cce03d3b1432 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -2822,7 +2822,9 @@ module_param_cb(restart, &fg_restart_ops, &fg_restart, 0644); static int fg_get_time_to_full_locked(struct fg_chip *chip, int *val) { int rc, ibatt_avg, vbatt_avg, rbatt, msoc, full_soc, act_cap_mah, - i_cc2cv, soc_cc2cv, tau, divisor, iterm, + i_cc2cv, soc_cc2cv, tau, divisor, iterm, ttf_mode, + i, soc_per_step, msoc_this_step, msoc_next_step, + ibatt_this_step, t_predicted_this_step, t_predicted_cv, t_predicted = 0; if (chip->bp.float_volt_uv <= 0) { @@ -2848,6 +2850,18 @@ static int fg_get_time_to_full_locked(struct fg_chip *chip, int *val) return 0; } + if (is_qnovo_en(chip)) + ttf_mode = TTF_MODE_QNOVO; + else + ttf_mode = TTF_MODE_NORMAL; + + /* when switching TTF algorithms the TTF needs to be reset */ + if (chip->ttf.mode != ttf_mode) { + fg_circ_buf_clr(&chip->ttf.ibatt); + fg_circ_buf_clr(&chip->ttf.vbatt); + chip->ttf.mode = ttf_mode; + } + /* at least 10 samples are required to produce a stable IBATT */ if (chip->ttf.ibatt.size < 10) { *val = -1; @@ -2907,6 +2921,12 @@ static int fg_get_time_to_full_locked(struct fg_chip *chip, int *val) i_cc2cv = ibatt_avg * vbatt_avg / max(MILLI_UNIT, chip->bp.float_volt_uv / MILLI_UNIT); break; + case TTF_MODE_QNOVO: + i_cc2cv = min( + chip->ttf.cc_step.arr[MAX_CC_STEPS - 1] / MILLI_UNIT, + ibatt_avg * vbatt_avg / + max(MILLI_UNIT, chip->bp.float_volt_uv / MILLI_UNIT)); + break; default: pr_err("TTF mode %d is not supported\n", chip->ttf.mode); break; @@ -2931,6 +2951,29 @@ static int fg_get_time_to_full_locked(struct fg_chip *chip, int *val) t_predicted = div_s64((s64)act_cap_mah * (soc_cc2cv - msoc) * HOURS_TO_SECONDS, divisor); break; + case TTF_MODE_QNOVO: + soc_per_step = 100 / MAX_CC_STEPS; + for (i = msoc / soc_per_step; i < MAX_CC_STEPS - 1; ++i) { + msoc_next_step = (i + 1) * soc_per_step; + if (i == msoc / soc_per_step) + msoc_this_step = msoc; + else + msoc_this_step = i * soc_per_step; + + /* scale ibatt by 85% to account for discharge pulses */ + ibatt_this_step = min( + chip->ttf.cc_step.arr[i] / MILLI_UNIT, + ibatt_avg) * 85 / 100; + divisor = max(100, ibatt_this_step * 100); + t_predicted_this_step = div_s64((s64)act_cap_mah * + (msoc_next_step - msoc_this_step) * + HOURS_TO_SECONDS, divisor); + t_predicted += t_predicted_this_step; + fg_dbg(chip, FG_TTF, "[%d, %d] ma=%d t=%d\n", + msoc_this_step, msoc_next_step, + ibatt_this_step, t_predicted_this_step); + } + break; default: pr_err("TTF mode %d is not supported\n", chip->ttf.mode); break;