summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrasanna Prapancham <prapancham@google.com>2022-11-09 22:31:24 +0000
committerPrasanna Prapancham <prapancham@google.com>2022-12-14 18:59:06 +0000
commit09321cdcd79779e2e9a9d82d6f58eb5c8010041e (patch)
tree0fd2ef670d1a7943ba96da811918fab64fd6c6db
parente5c439a76f383766d3b9cec2da0255ade7de5de9 (diff)
downloadbms-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.c53
-rw-r--r--google_bms.c8
-rw-r--r--google_bms.h3
-rw-r--r--google_charger.c63
-rw-r--r--wc68_driver.c16
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);