diff options
author | Prasanna Prapancham <prapancham@google.com> | 2022-11-09 22:31:24 +0000 |
---|---|---|
committer | Prasanna Prapancham <prapancham@google.com> | 2022-12-14 18:59:06 +0000 |
commit | 09321cdcd79779e2e9a9d82d6f58eb5c8010041e (patch) | |
tree | 0fd2ef670d1a7943ba96da811918fab64fd6c6db | |
parent | e5c439a76f383766d3b9cec2da0255ade7de5de9 (diff) | |
download | bms-09321cdcd79779e2e9a9d82d6f58eb5c8010041e.tar.gz |
wc68_driver: fix chg_mode usage
google_battery: pullback with current instead of voltage
google_charger, google_battery: use votable to indicate last tier
Bug: 227476830
Change-Id: I69cf12916bf9a495fc8b667e3d168afa4975cdef
Signed-off-by: Prasanna Prapancham <prapancham@google.com>
-rw-r--r-- | google_battery.c | 53 | ||||
-rw-r--r-- | google_bms.c | 8 | ||||
-rw-r--r-- | google_bms.h | 3 | ||||
-rw-r--r-- | google_charger.c | 63 | ||||
-rw-r--r-- | wc68_driver.c | 16 |
5 files changed, 112 insertions, 31 deletions
diff --git a/google_battery.c b/google_battery.c index 647d06b..fba785d 100644 --- a/google_battery.c +++ b/google_battery.c @@ -458,12 +458,14 @@ struct batt_drv { int cc_max; int topoff; int msc_update_interval; + int cc_max_pullback; bool disable_votes; struct gvotable_election *msc_interval_votable; struct gvotable_election *fcc_votable; struct gvotable_election *fv_votable; struct gvotable_election *temp_dryrun_votable; + struct gvotable_election *msc_last_votable; /* FAN level */ struct gvotable_election *fan_level_votable; @@ -545,6 +547,9 @@ struct batt_drv { /* irdrop for DC */ bool dc_irdrop; + bool pullback_current; + bool allow_higher_fv; + /* shutdown flag */ int boot_to_os_attempts; @@ -2569,6 +2574,7 @@ static inline void batt_reset_chg_drv_state(struct batt_drv *batt_drv) batt_drv->vbatt_idx = -1; batt_drv->fv_uv = -1; batt_drv->cc_max = -1; + batt_drv->cc_max_pullback = -1; batt_drv->msc_update_interval = -1; batt_drv->jeita_stop_charging = -1; /* timers */ @@ -2616,7 +2622,7 @@ static bool msc_logic_soft_jeita(struct batt_drv *batt_drv, int temp) static int msc_logic_irdrop(struct batt_drv *batt_drv, int vbatt, int ibatt, int temp_idx, int *vbatt_idx, int *fv_uv, - int *update_interval) + int *update_interval, int *p_cc_max_pullback) { const struct gbms_chg_profile *profile = &batt_drv->chg_profile; const int vtier = profile->volt_limits[*vbatt_idx]; @@ -2653,7 +2659,8 @@ static int msc_logic_irdrop(struct batt_drv *batt_drv, */ *fv_uv = gbms_msc_round_fv_uv(profile, vtier, *fv_uv - profile->fv_uv_resolution, - no_back_down ? cc_max : 0); + no_back_down ? cc_max : 0, + batt_drv->allow_higher_fv); if (*fv_uv < vtier) *fv_uv = vtier; @@ -2681,8 +2688,11 @@ static int msc_logic_irdrop(struct batt_drv *batt_drv, } else { /* simple pullback */ msc_state = MSC_PULLBACK; - if (no_back_down) + if (no_back_down) { *fv_uv = batt_drv->fv_uv; + if (batt_drv->pullback_current) + *p_cc_max_pullback = -ibatt; + } batt_prlog(BATT_PRLOG_ALWAYS, "MSC_PULLBACK vt=%d vb=%d ibatt=%d fv_uv=%d->%d no_back=%d\n", vtier, vbatt, ibatt, @@ -2716,7 +2726,8 @@ static int msc_logic_irdrop(struct batt_drv *batt_drv, const int cc_max = GBMS_CCCM_LIMITS(profile, temp_idx, *vbatt_idx); *fv_uv = gbms_msc_round_fv_uv(profile, vtier, vtier + (vchrg_uv - vbatt), - no_back_down ? cc_max : 0); + no_back_down ? cc_max : 0, + batt_drv->allow_higher_fv); } /* not allow to reduce fv in DC to avoid the VSWITCH */ @@ -2822,7 +2833,8 @@ static int msc_logic_irdrop(struct batt_drv *batt_drv, msc_state = MSC_RAISE; *fv_uv = gbms_msc_round_fv_uv(profile, vtier, *fv_uv + profile->fv_uv_resolution, - no_back_down ? cc_max : 0); + no_back_down ? cc_max : 0, + batt_drv->allow_higher_fv); *update_interval = profile->cv_update_interval; /* debounce next taper voltage adjustment */ @@ -3824,7 +3836,8 @@ static int msc_logic(struct batt_drv *batt_drv) msc_state = msc_logic_irdrop(batt_drv, vbatt, ibatt, temp_idx, &vbatt_idx, &fv_uv, - &update_interval); + &update_interval, + &batt_drv->cc_max_pullback); if (msc_pm_hold(msc_state) == 1 && !batt_drv->hold_taper_ws) { __pm_stay_awake(batt_drv->taper_ws); @@ -3905,6 +3918,12 @@ static int msc_logic(struct batt_drv *batt_drv) batt_drv->checked_ov_cnt = 0; } + if (!batt_drv->msc_last_votable) + batt_drv->msc_last_votable = gvotable_election_get_handle(VOTABLE_MSC_LAST); + + if (batt_drv->msc_last_votable) + gvotable_cast_int_vote(batt_drv->msc_last_votable, "BATT", + vbatt_idx == profile->volt_nb_limits - 1, 1); /* * book elapsed time to previous tier & msc_state * NOTE: temp_idx != -1 but batt_drv->msc_state could be -1 @@ -3931,7 +3950,8 @@ static int msc_logic(struct batt_drv *batt_drv) changed = batt_drv->temp_idx != temp_idx || batt_drv->vbatt_idx != vbatt_idx || - batt_drv->fv_uv != fv_uv; + batt_drv->fv_uv != fv_uv || + batt_drv->cc_max_pullback != batt_drv->cc_max; batt_prlog(batt_prlog_level(changed), "MSC_LOGIC temp_idx:%d->%d, vbatt_idx:%d->%d, fv=%d->%d, cc_max=%d, ui=%d cv_cnt=%d ov_cnt=%d\n", batt_drv->temp_idx, temp_idx, batt_drv->vbatt_idx, vbatt_idx, @@ -3940,9 +3960,16 @@ static int msc_logic(struct batt_drv *batt_drv) /* next update */ batt_drv->msc_update_interval = update_interval; + /* if tier change, reset cc_max from chg table, otherwise use pullback value */ + if (!batt_drv->pullback_current || vbatt_idx != batt_drv->vbatt_idx || + temp_idx != batt_drv->temp_idx) { + batt_drv->cc_max = GBMS_CCCM_LIMITS(profile, temp_idx, vbatt_idx); + batt_drv->cc_max_pullback = 0; + } else if (batt_drv->cc_max_pullback > 0) { + batt_drv->cc_max = batt_drv->cc_max_pullback; + } batt_drv->vbatt_idx = vbatt_idx; batt_drv->temp_idx = temp_idx; - batt_drv->cc_max = GBMS_CCCM_LIMITS(profile, temp_idx, vbatt_idx); batt_drv->topoff = profile->topoff_limits[temp_idx]; batt_drv->fv_uv = fv_uv; @@ -8658,6 +8685,16 @@ static void google_battery_init_work(struct work_struct *work) if (batt_drv->dc_irdrop) pr_info("dc irdrop is enabled\n"); + batt_drv->pullback_current = of_property_read_bool(gbms_batt_id_node(node), + "google,pullback-current"); + if (batt_drv->pullback_current) + pr_info("pullback current is enabled\n"); + + batt_drv->allow_higher_fv = of_property_read_bool(gbms_batt_id_node(node), + "google,allow-higher-fv"); + if (batt_drv->allow_higher_fv) + pr_info("allow higher fv is enabled\n"); + /* debugfs */ (void)batt_init_debugfs(batt_drv); diff --git a/google_bms.c b/google_bms.c index 3a1fd19..1259cef 100644 --- a/google_bms.c +++ b/google_bms.c @@ -455,7 +455,7 @@ EXPORT_SYMBOL_GPL(gbms_dump_raw_profile); * the vbat will not over the otv threshold. */ int gbms_msc_round_fv_uv(const struct gbms_chg_profile *profile, - int vtier, int fv_uv, int cc_ua) + int vtier, int fv_uv, int cc_ua, bool allow_higher_fv) { int result; const unsigned int fv_uv_max = (vtier / 1000) * profile->fv_uv_margin_dpct; @@ -465,7 +465,7 @@ int gbms_msc_round_fv_uv(const struct gbms_chg_profile *profile, if (cc_ua == 0) fv_max = fv_uv_max; - else if (dc_fv_uv_max >= last_fv) + else if (!allow_higher_fv && dc_fv_uv_max >= last_fv) fv_max = last_fv - profile->fv_uv_resolution; else fv_max = dc_fv_uv_max; @@ -476,8 +476,8 @@ int gbms_msc_round_fv_uv(const struct gbms_chg_profile *profile, result = fv_uv - (fv_uv % profile->fv_uv_resolution); if (fv_max != 0) - gbms_info(profile, "MSC_ROUND: fv_uv=%d vtier=%d fv_uv_max=%d -> %d\n", - fv_uv, vtier, fv_max, result); + gbms_info(profile, "MSC_ROUND: fv_uv=%d vtier=%d dc_fv_uv_max=%d fv_max=%d -> %d\n", + fv_uv, vtier, dc_fv_uv_max, fv_max, result); return result; } diff --git a/google_bms.h b/google_bms.h index 080c4da..19055fd 100644 --- a/google_bms.h +++ b/google_bms.h @@ -425,7 +425,7 @@ void gbms_dump_raw_profile(char *buff, size_t len, const struct gbms_chg_profile int gbms_msc_temp_idx(const struct gbms_chg_profile *profile, int temp); int gbms_msc_voltage_idx(const struct gbms_chg_profile *profile, int vbatt); int gbms_msc_round_fv_uv(const struct gbms_chg_profile *profile, - int vtier, int fv_uv, int cc_ua); + int vtier, int fv_uv, int cc_ua, bool allow_higher_fv); int gbms_msc_merge_tiers(const struct gbms_chg_profile *profile, int vbatt_idx, int temp_idx); @@ -456,6 +456,7 @@ const char *gbms_chg_ev_adapter_s(int adapter); #define VOTABLE_FAN_LEVEL "FAN_LEVEL" #define VOTABLE_DEAD_BATTERY "DEAD_BATTERY" #define VOTABLE_TEMP_DRYRUN "MSC_TEMP_DRYRUN" +#define VOTABLE_MSC_LAST "MSC_LAST" #define VOTABLE_CSI_STATUS "CSI_STATUS" #define VOTABLE_CSI_TYPE "CSI_TYPE" diff --git a/google_charger.c b/google_charger.c index 7d1c00a..dfc880e 100644 --- a/google_charger.c +++ b/google_charger.c @@ -270,6 +270,7 @@ struct chg_drv { struct gvotable_election *fan_level_votable; struct gvotable_election *dead_battery_votable; struct gvotable_election *tx_icl_votable; + struct gvotable_election *msc_last_votable; bool init_done; bool batt_present; @@ -283,6 +284,7 @@ struct chg_drv { int chg_mode; /* debug */ int stop_charging; /* no power source */ int egain_retries; + bool taper_last_tier; /* set taper on last tier entry */ /* retail & battery defender */ struct delayed_work bd_work; @@ -786,19 +788,22 @@ static int chg_update_charger(struct chg_drv *chg_drv, int fv_uv, int cc_max, in return 0; if (chg_drv->fv_uv != fv_uv || chg_drv->cc_max != cc_max || chg_drv->topoff != topoff) { - const int taper_limit = chg_drv->batt_profile_fv_uv >= 0 ? - chg_drv->batt_profile_fv_uv : -1; const int chg_cc_tolerance = chg_drv->chg_cc_tolerance; - int taper_ctl = GBMS_TAPER_CONTROL_OFF; int fcc = cc_max; - if (taper_limit > 0 && fv_uv >= taper_limit) - taper_ctl = GBMS_TAPER_CONTROL_ON; + if (!chg_drv->taper_last_tier) { + const int taper_limit = chg_drv->batt_profile_fv_uv >= 0 ? + chg_drv->batt_profile_fv_uv : -1; + int taper_ctl = GBMS_TAPER_CONTROL_OFF; - /* GBMS_PROP_TAPER_CONTROL is optional */ - rc = GPSY_SET_PROP(chg_psy, GBMS_PROP_TAPER_CONTROL, taper_ctl); - if (rc < 0) - pr_debug("MSC_CHG cannot set taper control rc=%d\n", rc); + if (taper_limit > 0 && fv_uv >= taper_limit) + taper_ctl = GBMS_TAPER_CONTROL_ON; + + /* GBMS_PROP_TAPER_CONTROL is optional */ + rc = GPSY_SET_PROP(chg_psy, GBMS_PROP_TAPER_CONTROL, taper_ctl); + if (rc < 0) + pr_debug("MSC_CHG cannot set taper control rc=%d\n", rc); + } /* when set cc_tolerance needs to be applied to everything */ if (chg_drv->chg_cc_tolerance) @@ -2671,6 +2676,10 @@ static int chg_init_chg_profile(struct chg_drv *chg_drv) chg_drv->chg_term.usb_5v = 0; } + chg_drv->taper_last_tier = of_property_read_bool(node, "google,chg-taper-last-tier"); + if (chg_drv->taper_last_tier) + pr_info("taper on last tier entry\n"); + pr_info("charging profile in the battery\n"); return 0; } @@ -4272,6 +4281,26 @@ static int msc_pwr_disable_cb(struct gvotable_election *el, return 0; } +static int msc_last_cb(struct gvotable_election *el, const char *reason, void *vote) +{ + struct chg_drv *chg_drv = gvotable_get_data(el); + int last_tier = GVOTABLE_PTR_TO_INT(vote); + int taper_ctl = last_tier ? GBMS_TAPER_CONTROL_ON : GBMS_TAPER_CONTROL_OFF; + struct power_supply *chg_psy = chg_drv->chg_psy; + int rc; + + if (!chg_psy || !chg_drv->taper_last_tier) + return 0; + + /* GBMS_PROP_TAPER_CONTROL is optional */ + rc = GPSY_SET_PROP(chg_psy, GBMS_PROP_TAPER_CONTROL, taper_ctl); + if (rc < 0) + pr_debug("MSC_CHG cannot set taper control rc=%d\n", rc); + + return rc; + +} + static int chg_disable_std_votables(struct chg_drv *chg_drv) { struct gvotable_election *qc_votable; @@ -4305,6 +4334,7 @@ static void chg_destroy_votables(struct chg_drv *chg_drv) gvotable_destroy_election(chg_drv->msc_chg_disable_votable); gvotable_destroy_election(chg_drv->msc_pwr_disable_votable); gvotable_destroy_election(chg_drv->msc_temp_dry_run_votable); + gvotable_destroy_election(chg_drv->msc_last_votable); chg_drv->msc_fv_votable = NULL; chg_drv->msc_fcc_votable = NULL; @@ -4314,6 +4344,7 @@ static void chg_destroy_votables(struct chg_drv *chg_drv) chg_drv->msc_temp_dry_run_votable = NULL; chg_drv->csi_status_votable = NULL; chg_drv->csi_type_votable = NULL; + chg_drv->msc_last_votable = NULL; } /* TODO: qcom/battery.c mostly handles PL charging: we don't need it. @@ -4409,6 +4440,20 @@ static int chg_create_votables(struct chg_drv *chg_drv) gvotable_election_set_name(chg_drv->msc_temp_dry_run_votable, VOTABLE_TEMP_DRYRUN); + chg_drv->msc_last_votable = + gvotable_create_int_election(NULL, gvotable_comparator_int_min, msc_last_cb, + chg_drv); + if (IS_ERR_OR_NULL(chg_drv->msc_last_votable)) { + ret = PTR_ERR(chg_drv->msc_last_votable); + chg_drv->msc_last_votable = NULL; + goto error_exit; + } + + gvotable_set_default(chg_drv->msc_last_votable, (void *)0); + gvotable_set_vote2str(chg_drv->msc_last_votable, gvotable_v2s_int); + gvotable_election_set_name(chg_drv->msc_last_votable, VOTABLE_MSC_LAST); + gvotable_use_default(chg_drv->msc_last_votable, true); + return 0; error_exit: diff --git a/wc68_driver.c b/wc68_driver.c index 44f12d9..9be8868 100644 --- a/wc68_driver.c +++ b/wc68_driver.c @@ -42,7 +42,7 @@ /* Charging Float Voltage default value */ #define WC68_VFLOAT_DFT 4350000 /* uV */ /* Charging Float Voltage max voltage for comp */ -#define WC68_COMP_VFLOAT_MAX 4450000 /* uV */ +#define WC68_COMP_VFLOAT_MAX 4700000 /* uV */ /* Charging Done Condition */ #define WC68_IIN_DONE_DFT 500000 /* uA */ @@ -75,7 +75,7 @@ /* IIN_CC adc offset for accuracy */ #define WC68_IIN_ADC_OFFSET 20000 /* uA */ /* IIN_CC compensation offset */ -#define WC68_IIN_CC_COMP_OFFSET 50000 /* uA */ +#define WC68_IIN_CC_COMP_OFFSET 25000 /* uA */ /* IIN_CC compensation offset in Power Limit Mode(Constant Power) TA */ #define WC68_IIN_CC_COMP_OFFSET_CP 20000 /* uA */ /* TA maximum voltage that can support CC in Constant Power Mode */ @@ -1744,8 +1744,8 @@ static int wc68_get_iin_limit(const struct wc68_charger *wc68) int iin_cc; iin_cc = wc68_get_iin_max(wc68, wc68->cc_max); - if (wc68->ta_max_cur * wc68->chg_mode < iin_cc) - iin_cc = wc68->ta_max_cur * wc68->chg_mode; + if (wc68->ta_max_cur < iin_cc) + iin_cc = wc68->ta_max_cur; dev_dbg(wc68->dev, "%s: iin_cc=%d ta_max_cur=%u, chg_mode=%d\n", __func__, iin_cc, wc68->ta_max_cur, wc68->chg_mode); @@ -1978,7 +1978,7 @@ static int wc68_adjust_ta_current(struct wc68_charger *wc68) */ val = wc68->iin_cc / PD_MSG_TA_CUR_STEP; wc68->iin_cc = val * PD_MSG_TA_CUR_STEP; - wc68->ta_cur = wc68->iin_cc / wc68->chg_mode; + wc68->ta_cur = wc68->iin_cc; logbuffer_prlog(wc68, LOGLEVEL_DEBUG, "adjust iin=%u ta_cur=%d chg_mode=%d", wc68->iin_cc, wc68->ta_cur, wc68->chg_mode); @@ -3145,15 +3145,13 @@ static int wc68_charge_cvmode(struct wc68_charger *wc68) /* Check the TA type */ if (wc68->ta_type == TA_TYPE_WIRELESS) { /* Decrease RX voltage */ - wc68->ta_vol = wc68->ta_vol - - WCRX_VOL_STEP; + wc68->ta_vol = wc68->ta_vol - WCRX_VOL_STEP; logbuffer_prlog(wc68, LOGLEVEL_DEBUG, "%s: CV VFLOAT, Cont: rx_vol=%u", __func__, wc68->ta_vol); } else { /* Decrease TA voltage */ - wc68->ta_vol = wc68->ta_vol - - PD_MSG_TA_VOL_STEP; + wc68->ta_vol = wc68->ta_vol - 2 * PD_MSG_TA_VOL_STEP; logbuffer_prlog(wc68, LOGLEVEL_DEBUG, "%s: CV VFLOAT, Cont: ta_vol=%u", __func__, wc68->ta_vol); |