Loading drivers/power/supply/qcom/fg-alg.c +96 −35 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ */ #define pr_fmt(fmt) "ALG: %s: " fmt, __func__ #define pr_fmt(fmt) "ALG: %s: " fmt, __func__ Loading Loading @@ -886,6 +886,62 @@ static int ttf_lerp(const struct ttf_pt *pts, size_t tablesize, return -EINVAL; return -EINVAL; } } static int get_step_chg_current_window(struct ttf *ttf) { struct range_data *step_chg_cfg = ttf->step_chg_cfg; int i, rc, curr_window, vbatt; if (ttf->mode == TTF_MODE_V_STEP_CHG) { rc = ttf->get_ttf_param(ttf->data, TTF_VBAT, &vbatt); if (rc < 0) { pr_err("failed to get battery voltage, rc=%d\n", rc); return rc; } } else { rc = ttf->get_ttf_param(ttf->data, TTF_OCV, &vbatt); if (rc < 0) { pr_err("failed to get battery OCV, rc=%d\n", rc); return rc; } } curr_window = ttf->step_chg_num_params - 1; for (i = 0; i < ttf->step_chg_num_params; i++) { if (is_between(step_chg_cfg[i].low_threshold, step_chg_cfg[i].high_threshold, vbatt)) curr_window = i; } return curr_window; } static int get_cc2cv_current(struct ttf *ttf, int ibatt_avg, int vbatt_avg, int float_volt_uv) { int i_cc2cv = 0; switch (ttf->mode) { case TTF_MODE_NORMAL: case TTF_MODE_V_STEP_CHG: case TTF_MODE_OCV_STEP_CHG: i_cc2cv = ibatt_avg * vbatt_avg / max(MILLI_UNIT, float_volt_uv / MILLI_UNIT); break; case TTF_MODE_QNOVO: i_cc2cv = min( ttf->cc_step.arr[MAX_CC_STEPS - 1] / MILLI_UNIT, ibatt_avg * vbatt_avg / max(MILLI_UNIT, float_volt_uv / MILLI_UNIT)); break; default: pr_err("TTF mode %d is not supported\n", ttf->mode); break; } return i_cc2cv; } static int get_time_to_full_locked(struct ttf *ttf, int *val) static int get_time_to_full_locked(struct ttf *ttf, int *val) { { struct step_chg_data *step_chg_data = ttf->step_chg_data; struct step_chg_data *step_chg_data = ttf->step_chg_data; Loading @@ -896,7 +952,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) ibatt_this_step, t_predicted_this_step, ttf_slope, ibatt_this_step, t_predicted_this_step, ttf_slope, t_predicted_cv, t_predicted = 0, charge_type = 0, i_step, t_predicted_cv, t_predicted = 0, charge_type = 0, i_step, float_volt_uv = 0; float_volt_uv = 0; int vbatt_now, multiplier, curr_window = 0, pbatt_avg; int multiplier, curr_window = 0, pbatt_avg; bool power_approx = false; bool power_approx = false; s64 delta_ms; s64 delta_ms; Loading Loading @@ -985,22 +1041,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) pr_debug("TTF: mode: %d\n", ttf->mode); pr_debug("TTF: mode: %d\n", ttf->mode); /* estimated battery current at the CC to CV transition */ /* estimated battery current at the CC to CV transition */ switch (ttf->mode) { i_cc2cv = get_cc2cv_current(ttf, ibatt_avg, vbatt_avg, float_volt_uv); case TTF_MODE_NORMAL: case TTF_MODE_V_STEP_CHG: i_cc2cv = ibatt_avg * vbatt_avg / max(MILLI_UNIT, float_volt_uv / MILLI_UNIT); break; case TTF_MODE_QNOVO: i_cc2cv = min( ttf->cc_step.arr[MAX_CC_STEPS - 1] / MILLI_UNIT, ibatt_avg * vbatt_avg / max(MILLI_UNIT, float_volt_uv / MILLI_UNIT)); break; default: pr_err("TTF mode %d is not supported\n", ttf->mode); break; } pr_debug("TTF: i_cc2cv=%d\n", i_cc2cv); pr_debug("TTF: i_cc2cv=%d\n", i_cc2cv); /* if we are already in CV state then we can skip estimating CC */ /* if we are already in CV state then we can skip estimating CC */ Loading Loading @@ -1045,23 +1086,15 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) } } break; break; case TTF_MODE_V_STEP_CHG: case TTF_MODE_V_STEP_CHG: case TTF_MODE_OCV_STEP_CHG: if (!step_chg_data || !step_chg_cfg) if (!step_chg_data || !step_chg_cfg) break; break; pbatt_avg = vbatt_avg * ibatt_avg; pbatt_avg = vbatt_avg * ibatt_avg; curr_window = get_step_chg_current_window(ttf); rc = ttf->get_ttf_param(ttf->data, TTF_VBAT, &vbatt_now); if (curr_window < 0) { if (rc < 0) { pr_err("Failed to get step charging window\n"); pr_err("failed to get battery voltage, rc=%d\n", rc); return curr_window; return rc; } curr_window = ttf->step_chg_num_params - 1; for (i = 0; i < ttf->step_chg_num_params; i++) { if (is_between(step_chg_cfg[i].low_threshold, step_chg_cfg[i].high_threshold, vbatt_now)) curr_window = i; } } pr_debug("TTF: curr_window: %d pbatt_avg: %d\n", curr_window, pr_debug("TTF: curr_window: %d pbatt_avg: %d\n", curr_window, Loading Loading @@ -1093,8 +1126,13 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) MILLI_UNIT); MILLI_UNIT); } } step_chg_data[i].ocv = step_chg_cfg[i].high_threshold - if (ttf->mode == TTF_MODE_V_STEP_CHG) step_chg_data[i].ocv = step_chg_cfg[i].high_threshold - (rbatt * i_step); (rbatt * i_step); else step_chg_data[i].ocv = step_chg_cfg[i].high_threshold; /* Calculate SOC for each window */ /* Calculate SOC for each window */ step_chg_data[i].soc = (float_volt_uv - step_chg_data[i].soc = (float_volt_uv - Loading Loading @@ -1137,7 +1175,11 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) cv_estimate: cv_estimate: pr_debug("TTF: t_predicted_cc=%d\n", t_predicted); pr_debug("TTF: t_predicted_cc=%d\n", t_predicted); if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER) iterm = max(100, abs(iterm)); else iterm = max(100, abs(iterm) + ttf->iterm_delta); iterm = max(100, abs(iterm) + ttf->iterm_delta); pr_debug("TTF: iterm=%d\n", iterm); pr_debug("TTF: iterm=%d\n", iterm); if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER) if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER) Loading Loading @@ -1211,11 +1253,12 @@ int ttf_get_time_to_full(struct ttf *ttf, int *val) return rc; return rc; } } #define DELTA_TTF_IBATT_UA 500000 static void ttf_work(struct work_struct *work) static void ttf_work(struct work_struct *work) { { struct ttf *ttf = container_of(work, struct ttf *ttf = container_of(work, struct ttf, ttf_work.work); struct ttf, ttf_work.work); int rc, ibatt_now, vbatt_now, ttf_now, charge_status; int rc, ibatt_now, vbatt_now, ttf_now, charge_status, ibatt_avg; ktime_t ktime_now; ktime_t ktime_now; mutex_lock(&ttf->lock); mutex_lock(&ttf->lock); Loading Loading @@ -1244,6 +1287,24 @@ static void ttf_work(struct work_struct *work) ttf_circ_buf_add(&ttf->vbatt, vbatt_now); ttf_circ_buf_add(&ttf->vbatt, vbatt_now); if (charge_status == POWER_SUPPLY_STATUS_CHARGING) { if (charge_status == POWER_SUPPLY_STATUS_CHARGING) { rc = ttf_circ_buf_median(&ttf->ibatt, &ibatt_avg); if (rc < 0) { pr_err("failed to get IBATT AVG rc=%d\n", rc); goto end_work; } /* * While Charging, if Ibatt_now differ from Ibatt_avg by 500mA, * clear Ibatt buffer and refill with settled Ibatt values, to * calculate accurate TTF */ if (ibatt_now < 0 && (abs(ibatt_now - ibatt_avg) >= DELTA_TTF_IBATT_UA)) { pr_debug("Clear Ibatt buffer, Ibatt_avg=%d Ibatt_now=%d\n", ibatt_avg, ibatt_now); ttf_circ_buf_clr(&ttf->ibatt); } rc = get_time_to_full_locked(ttf, &ttf_now); rc = get_time_to_full_locked(ttf, &ttf_now); if (rc < 0) { if (rc < 0) { pr_err("failed to get ttf, rc=%d\n", rc); pr_err("failed to get ttf, rc=%d\n", rc); Loading drivers/power/supply/qcom/fg-alg.h +4 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */ /* /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ */ #ifndef __FG_ALG_H__ #ifndef __FG_ALG_H__ Loading Loading @@ -69,11 +69,13 @@ enum ttf_mode { TTF_MODE_NORMAL = 0, TTF_MODE_NORMAL = 0, TTF_MODE_QNOVO, TTF_MODE_QNOVO, TTF_MODE_V_STEP_CHG, TTF_MODE_V_STEP_CHG, TTF_MODE_OCV_STEP_CHG, }; }; enum ttf_param { enum ttf_param { TTF_MSOC = 0, TTF_MSOC = 0, TTF_VBAT, TTF_VBAT, TTF_OCV, TTF_IBAT, TTF_IBAT, TTF_FCC, TTF_FCC, TTF_MODE, TTF_MODE, Loading Loading @@ -114,6 +116,7 @@ struct ttf { struct step_chg_data *step_chg_data; struct step_chg_data *step_chg_data; struct range_data *step_chg_cfg; struct range_data *step_chg_cfg; bool step_chg_cfg_valid; bool step_chg_cfg_valid; bool ocv_step_chg_cfg_valid; int step_chg_num_params; int step_chg_num_params; int mode; int mode; int last_ttf; int last_ttf; Loading drivers/power/supply/qcom/qpnp-fg-gen4.c +26 −2 Original line number Original line Diff line number Diff line Loading @@ -851,10 +851,21 @@ static int fg_gen4_get_cell_impedance(struct fg_gen4_chip *chip, int *val) { { struct fg_dev *fg = &chip->fg; struct fg_dev *fg = &chip->fg; int rc, esr_uohms, temp, vbat_term_mv, v_delta, rprot_uohms = 0; int rc, esr_uohms, temp, vbat_term_mv, v_delta, rprot_uohms = 0; int rslow_uohms; rc = fg_get_battery_resistance(fg, &esr_uohms); rc = fg_get_sram_prop(fg, FG_SRAM_ESR_ACT, &esr_uohms); if (rc < 0) if (rc < 0) { pr_err("failed to get ESR_ACT, rc=%d\n", rc); return rc; } rc = fg_get_sram_prop(fg, FG_SRAM_RSLOW, &rslow_uohms); if (rc < 0) { pr_err("failed to get Rslow, rc=%d\n", rc); return rc; return rc; } esr_uohms += rslow_uohms; if (!chip->dt.five_pin_battery) if (!chip->dt.five_pin_battery) goto out; goto out; Loading Loading @@ -1084,6 +1095,11 @@ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) case TTF_VBAT: case TTF_VBAT: rc = fg_get_battery_voltage(fg, val); rc = fg_get_battery_voltage(fg, val); break; break; case TTF_OCV: rc = fg_get_sram_prop(fg, FG_SRAM_OCV, val); if (rc < 0) pr_err("Failed to get battery OCV, rc=%d\n", rc); break; case TTF_IBAT: case TTF_IBAT: rc = fg_get_battery_current(fg, val); rc = fg_get_battery_current(fg, val); break; break; Loading Loading @@ -1117,6 +1133,8 @@ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) *val = TTF_MODE_QNOVO; *val = TTF_MODE_QNOVO; else if (chip->ttf->step_chg_cfg_valid) else if (chip->ttf->step_chg_cfg_valid) *val = TTF_MODE_V_STEP_CHG; *val = TTF_MODE_V_STEP_CHG; else if (chip->ttf->ocv_step_chg_cfg_valid) *val = TTF_MODE_OCV_STEP_CHG; else else *val = TTF_MODE_NORMAL; *val = TTF_MODE_NORMAL; break; break; Loading Loading @@ -1622,6 +1640,12 @@ static int qpnp_fg_gen4_get_step_charging_params(struct fg_gen4_chip *chip, chip->ttf->step_chg_num_params = tuple_len; chip->ttf->step_chg_num_params = tuple_len; chip->ttf->step_chg_cfg_valid = true; chip->ttf->step_chg_cfg_valid = true; if (of_property_read_bool(profile_node, "qcom,ocv-based-step-chg")) { chip->ttf->step_chg_cfg_valid = false; chip->ttf->ocv_step_chg_cfg_valid = true; } mutex_unlock(&chip->ttf->lock); mutex_unlock(&chip->ttf->lock); if (chip->ttf->step_chg_cfg_valid) { if (chip->ttf->step_chg_cfg_valid) { Loading Loading
drivers/power/supply/qcom/fg-alg.c +96 −35 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ */ #define pr_fmt(fmt) "ALG: %s: " fmt, __func__ #define pr_fmt(fmt) "ALG: %s: " fmt, __func__ Loading Loading @@ -886,6 +886,62 @@ static int ttf_lerp(const struct ttf_pt *pts, size_t tablesize, return -EINVAL; return -EINVAL; } } static int get_step_chg_current_window(struct ttf *ttf) { struct range_data *step_chg_cfg = ttf->step_chg_cfg; int i, rc, curr_window, vbatt; if (ttf->mode == TTF_MODE_V_STEP_CHG) { rc = ttf->get_ttf_param(ttf->data, TTF_VBAT, &vbatt); if (rc < 0) { pr_err("failed to get battery voltage, rc=%d\n", rc); return rc; } } else { rc = ttf->get_ttf_param(ttf->data, TTF_OCV, &vbatt); if (rc < 0) { pr_err("failed to get battery OCV, rc=%d\n", rc); return rc; } } curr_window = ttf->step_chg_num_params - 1; for (i = 0; i < ttf->step_chg_num_params; i++) { if (is_between(step_chg_cfg[i].low_threshold, step_chg_cfg[i].high_threshold, vbatt)) curr_window = i; } return curr_window; } static int get_cc2cv_current(struct ttf *ttf, int ibatt_avg, int vbatt_avg, int float_volt_uv) { int i_cc2cv = 0; switch (ttf->mode) { case TTF_MODE_NORMAL: case TTF_MODE_V_STEP_CHG: case TTF_MODE_OCV_STEP_CHG: i_cc2cv = ibatt_avg * vbatt_avg / max(MILLI_UNIT, float_volt_uv / MILLI_UNIT); break; case TTF_MODE_QNOVO: i_cc2cv = min( ttf->cc_step.arr[MAX_CC_STEPS - 1] / MILLI_UNIT, ibatt_avg * vbatt_avg / max(MILLI_UNIT, float_volt_uv / MILLI_UNIT)); break; default: pr_err("TTF mode %d is not supported\n", ttf->mode); break; } return i_cc2cv; } static int get_time_to_full_locked(struct ttf *ttf, int *val) static int get_time_to_full_locked(struct ttf *ttf, int *val) { { struct step_chg_data *step_chg_data = ttf->step_chg_data; struct step_chg_data *step_chg_data = ttf->step_chg_data; Loading @@ -896,7 +952,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) ibatt_this_step, t_predicted_this_step, ttf_slope, ibatt_this_step, t_predicted_this_step, ttf_slope, t_predicted_cv, t_predicted = 0, charge_type = 0, i_step, t_predicted_cv, t_predicted = 0, charge_type = 0, i_step, float_volt_uv = 0; float_volt_uv = 0; int vbatt_now, multiplier, curr_window = 0, pbatt_avg; int multiplier, curr_window = 0, pbatt_avg; bool power_approx = false; bool power_approx = false; s64 delta_ms; s64 delta_ms; Loading Loading @@ -985,22 +1041,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) pr_debug("TTF: mode: %d\n", ttf->mode); pr_debug("TTF: mode: %d\n", ttf->mode); /* estimated battery current at the CC to CV transition */ /* estimated battery current at the CC to CV transition */ switch (ttf->mode) { i_cc2cv = get_cc2cv_current(ttf, ibatt_avg, vbatt_avg, float_volt_uv); case TTF_MODE_NORMAL: case TTF_MODE_V_STEP_CHG: i_cc2cv = ibatt_avg * vbatt_avg / max(MILLI_UNIT, float_volt_uv / MILLI_UNIT); break; case TTF_MODE_QNOVO: i_cc2cv = min( ttf->cc_step.arr[MAX_CC_STEPS - 1] / MILLI_UNIT, ibatt_avg * vbatt_avg / max(MILLI_UNIT, float_volt_uv / MILLI_UNIT)); break; default: pr_err("TTF mode %d is not supported\n", ttf->mode); break; } pr_debug("TTF: i_cc2cv=%d\n", i_cc2cv); pr_debug("TTF: i_cc2cv=%d\n", i_cc2cv); /* if we are already in CV state then we can skip estimating CC */ /* if we are already in CV state then we can skip estimating CC */ Loading Loading @@ -1045,23 +1086,15 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) } } break; break; case TTF_MODE_V_STEP_CHG: case TTF_MODE_V_STEP_CHG: case TTF_MODE_OCV_STEP_CHG: if (!step_chg_data || !step_chg_cfg) if (!step_chg_data || !step_chg_cfg) break; break; pbatt_avg = vbatt_avg * ibatt_avg; pbatt_avg = vbatt_avg * ibatt_avg; curr_window = get_step_chg_current_window(ttf); rc = ttf->get_ttf_param(ttf->data, TTF_VBAT, &vbatt_now); if (curr_window < 0) { if (rc < 0) { pr_err("Failed to get step charging window\n"); pr_err("failed to get battery voltage, rc=%d\n", rc); return curr_window; return rc; } curr_window = ttf->step_chg_num_params - 1; for (i = 0; i < ttf->step_chg_num_params; i++) { if (is_between(step_chg_cfg[i].low_threshold, step_chg_cfg[i].high_threshold, vbatt_now)) curr_window = i; } } pr_debug("TTF: curr_window: %d pbatt_avg: %d\n", curr_window, pr_debug("TTF: curr_window: %d pbatt_avg: %d\n", curr_window, Loading Loading @@ -1093,8 +1126,13 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) MILLI_UNIT); MILLI_UNIT); } } step_chg_data[i].ocv = step_chg_cfg[i].high_threshold - if (ttf->mode == TTF_MODE_V_STEP_CHG) step_chg_data[i].ocv = step_chg_cfg[i].high_threshold - (rbatt * i_step); (rbatt * i_step); else step_chg_data[i].ocv = step_chg_cfg[i].high_threshold; /* Calculate SOC for each window */ /* Calculate SOC for each window */ step_chg_data[i].soc = (float_volt_uv - step_chg_data[i].soc = (float_volt_uv - Loading Loading @@ -1137,7 +1175,11 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) cv_estimate: cv_estimate: pr_debug("TTF: t_predicted_cc=%d\n", t_predicted); pr_debug("TTF: t_predicted_cc=%d\n", t_predicted); if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER) iterm = max(100, abs(iterm)); else iterm = max(100, abs(iterm) + ttf->iterm_delta); iterm = max(100, abs(iterm) + ttf->iterm_delta); pr_debug("TTF: iterm=%d\n", iterm); pr_debug("TTF: iterm=%d\n", iterm); if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER) if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER) Loading Loading @@ -1211,11 +1253,12 @@ int ttf_get_time_to_full(struct ttf *ttf, int *val) return rc; return rc; } } #define DELTA_TTF_IBATT_UA 500000 static void ttf_work(struct work_struct *work) static void ttf_work(struct work_struct *work) { { struct ttf *ttf = container_of(work, struct ttf *ttf = container_of(work, struct ttf, ttf_work.work); struct ttf, ttf_work.work); int rc, ibatt_now, vbatt_now, ttf_now, charge_status; int rc, ibatt_now, vbatt_now, ttf_now, charge_status, ibatt_avg; ktime_t ktime_now; ktime_t ktime_now; mutex_lock(&ttf->lock); mutex_lock(&ttf->lock); Loading Loading @@ -1244,6 +1287,24 @@ static void ttf_work(struct work_struct *work) ttf_circ_buf_add(&ttf->vbatt, vbatt_now); ttf_circ_buf_add(&ttf->vbatt, vbatt_now); if (charge_status == POWER_SUPPLY_STATUS_CHARGING) { if (charge_status == POWER_SUPPLY_STATUS_CHARGING) { rc = ttf_circ_buf_median(&ttf->ibatt, &ibatt_avg); if (rc < 0) { pr_err("failed to get IBATT AVG rc=%d\n", rc); goto end_work; } /* * While Charging, if Ibatt_now differ from Ibatt_avg by 500mA, * clear Ibatt buffer and refill with settled Ibatt values, to * calculate accurate TTF */ if (ibatt_now < 0 && (abs(ibatt_now - ibatt_avg) >= DELTA_TTF_IBATT_UA)) { pr_debug("Clear Ibatt buffer, Ibatt_avg=%d Ibatt_now=%d\n", ibatt_avg, ibatt_now); ttf_circ_buf_clr(&ttf->ibatt); } rc = get_time_to_full_locked(ttf, &ttf_now); rc = get_time_to_full_locked(ttf, &ttf_now); if (rc < 0) { if (rc < 0) { pr_err("failed to get ttf, rc=%d\n", rc); pr_err("failed to get ttf, rc=%d\n", rc); Loading
drivers/power/supply/qcom/fg-alg.h +4 −1 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */ /* /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. */ */ #ifndef __FG_ALG_H__ #ifndef __FG_ALG_H__ Loading Loading @@ -69,11 +69,13 @@ enum ttf_mode { TTF_MODE_NORMAL = 0, TTF_MODE_NORMAL = 0, TTF_MODE_QNOVO, TTF_MODE_QNOVO, TTF_MODE_V_STEP_CHG, TTF_MODE_V_STEP_CHG, TTF_MODE_OCV_STEP_CHG, }; }; enum ttf_param { enum ttf_param { TTF_MSOC = 0, TTF_MSOC = 0, TTF_VBAT, TTF_VBAT, TTF_OCV, TTF_IBAT, TTF_IBAT, TTF_FCC, TTF_FCC, TTF_MODE, TTF_MODE, Loading Loading @@ -114,6 +116,7 @@ struct ttf { struct step_chg_data *step_chg_data; struct step_chg_data *step_chg_data; struct range_data *step_chg_cfg; struct range_data *step_chg_cfg; bool step_chg_cfg_valid; bool step_chg_cfg_valid; bool ocv_step_chg_cfg_valid; int step_chg_num_params; int step_chg_num_params; int mode; int mode; int last_ttf; int last_ttf; Loading
drivers/power/supply/qcom/qpnp-fg-gen4.c +26 −2 Original line number Original line Diff line number Diff line Loading @@ -851,10 +851,21 @@ static int fg_gen4_get_cell_impedance(struct fg_gen4_chip *chip, int *val) { { struct fg_dev *fg = &chip->fg; struct fg_dev *fg = &chip->fg; int rc, esr_uohms, temp, vbat_term_mv, v_delta, rprot_uohms = 0; int rc, esr_uohms, temp, vbat_term_mv, v_delta, rprot_uohms = 0; int rslow_uohms; rc = fg_get_battery_resistance(fg, &esr_uohms); rc = fg_get_sram_prop(fg, FG_SRAM_ESR_ACT, &esr_uohms); if (rc < 0) if (rc < 0) { pr_err("failed to get ESR_ACT, rc=%d\n", rc); return rc; } rc = fg_get_sram_prop(fg, FG_SRAM_RSLOW, &rslow_uohms); if (rc < 0) { pr_err("failed to get Rslow, rc=%d\n", rc); return rc; return rc; } esr_uohms += rslow_uohms; if (!chip->dt.five_pin_battery) if (!chip->dt.five_pin_battery) goto out; goto out; Loading Loading @@ -1084,6 +1095,11 @@ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) case TTF_VBAT: case TTF_VBAT: rc = fg_get_battery_voltage(fg, val); rc = fg_get_battery_voltage(fg, val); break; break; case TTF_OCV: rc = fg_get_sram_prop(fg, FG_SRAM_OCV, val); if (rc < 0) pr_err("Failed to get battery OCV, rc=%d\n", rc); break; case TTF_IBAT: case TTF_IBAT: rc = fg_get_battery_current(fg, val); rc = fg_get_battery_current(fg, val); break; break; Loading Loading @@ -1117,6 +1133,8 @@ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) *val = TTF_MODE_QNOVO; *val = TTF_MODE_QNOVO; else if (chip->ttf->step_chg_cfg_valid) else if (chip->ttf->step_chg_cfg_valid) *val = TTF_MODE_V_STEP_CHG; *val = TTF_MODE_V_STEP_CHG; else if (chip->ttf->ocv_step_chg_cfg_valid) *val = TTF_MODE_OCV_STEP_CHG; else else *val = TTF_MODE_NORMAL; *val = TTF_MODE_NORMAL; break; break; Loading Loading @@ -1622,6 +1640,12 @@ static int qpnp_fg_gen4_get_step_charging_params(struct fg_gen4_chip *chip, chip->ttf->step_chg_num_params = tuple_len; chip->ttf->step_chg_num_params = tuple_len; chip->ttf->step_chg_cfg_valid = true; chip->ttf->step_chg_cfg_valid = true; if (of_property_read_bool(profile_node, "qcom,ocv-based-step-chg")) { chip->ttf->step_chg_cfg_valid = false; chip->ttf->ocv_step_chg_cfg_valid = true; } mutex_unlock(&chip->ttf->lock); mutex_unlock(&chip->ttf->lock); if (chip->ttf->step_chg_cfg_valid) { if (chip->ttf->step_chg_cfg_valid) { Loading