Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 915c865b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: battery: smb1390-charger-psy: Handle CP(s) disable conditions"

parents f2f232ee 4afec022
Loading
Loading
Loading
Loading
+60 −17
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ struct pl_data {
	struct votable		*cp_ilim_votable;
	struct votable		*cp_disable_votable;
	struct votable		*fcc_main_votable;
	struct votable		*cp_slave_disable_votable;
	struct delayed_work	status_change_work;
	struct work_struct	pl_disable_forever_work;
	struct work_struct	pl_taper_work;
@@ -74,6 +75,7 @@ struct pl_data {
	struct power_supply	*usb_psy;
	struct power_supply	*dc_psy;
	struct power_supply	*cp_master_psy;
	struct power_supply	*cp_slave_psy;
	int			charge_type;
	int			total_settled_ua;
	int			pl_settled_ua;
@@ -803,7 +805,9 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data,
{
	struct pl_data *chip = data;
	int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0;
	int main_fcc_ua = 0, cp_fcc_ua = 0, fcc_thr_ua = 0, rc;
	union power_supply_propval pval = {0, };
	bool is_cc_mode = false;

	if (total_fcc_ua < 0)
		return 0;
@@ -814,22 +818,65 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data,
	if (!chip->cp_disable_votable)
		chip->cp_disable_votable = find_votable("CP_DISABLE");

	if (chip->cp_disable_votable) {
		if (cp_get_parallel_mode(chip, PARALLEL_OUTPUT_MODE)
					== POWER_SUPPLY_PL_OUTPUT_VPH) {
			power_supply_get_property(chip->cp_master_psy,
	if (!chip->cp_master_psy)
		chip->cp_master_psy =
			power_supply_get_by_name("charge_pump_master");

	if (!chip->cp_slave_psy)
		chip->cp_slave_psy = power_supply_get_by_name("cp_slave");

	if (!chip->cp_slave_disable_votable)
		chip->cp_slave_disable_votable =
			find_votable("CP_SLAVE_DISABLE");

	if (!chip->usb_psy)
		chip->usb_psy = power_supply_get_by_name("usb");

	if (chip->usb_psy) {
		rc = power_supply_get_property(chip->usb_psy,
					POWER_SUPPLY_PROP_ADAPTER_CC_MODE,
					&pval);
		if (rc < 0)
			pr_err("Couldn't get PPS CC mode status rc=%d\n", rc);
		else
			is_cc_mode = pval.intval;
	}

	if (chip->cp_master_psy) {
		rc = power_supply_get_property(chip->cp_master_psy,
					POWER_SUPPLY_PROP_MIN_ICL, &pval);
		if (rc < 0)
			pr_err("Couldn't get MIN ICL threshold rc=%d\n", rc);
		else
			fcc_thr_ua = is_cc_mode ? (3 * pval.intval) :
							(4 * pval.intval);
	}

	if (chip->fcc_main_votable)
		main_fcc_ua =
			get_effective_result_locked(chip->fcc_main_votable);

	if (main_fcc_ua < 0)
		main_fcc_ua = 0;

	cp_fcc_ua = total_fcc_ua - main_fcc_ua;
	if (cp_fcc_ua > 0) {
		if (chip->cp_slave_psy && chip->cp_slave_disable_votable) {
			/*
			 * With VPH output configuration ILIM is configured
			 * independent of battery FCC, disable CP here if FCC/2
			 * falls below MIN_ICL supported by CP.
			 * Disable Slave CP if FCC share
			 * falls below threshold.
			 */
			vote(chip->cp_slave_disable_votable, FCC_VOTER,
				(cp_fcc_ua < fcc_thr_ua), 0);
		}

		if (chip->cp_disable_votable) {
			/*
			 * Disable Master CP if FCC share
			 * falls below 2 * min ICL threshold.
			 */
			if ((total_fcc_ua / 2) < pval.intval)
				vote(chip->cp_disable_votable, FCC_VOTER,
						true, 0);
			else
			vote(chip->cp_disable_votable, FCC_VOTER,
						false, 0);
			     (cp_fcc_ua < (2 * pval.intval)), 0);
		}
	}

@@ -848,10 +895,6 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data,

	rerun_election(chip->pl_disable_votable);
	/* When FCC changes, trigger psy changed event for CC mode */
	if (!chip->cp_master_psy)
		chip->cp_master_psy =
			power_supply_get_by_name("charge_pump_master");

	if (chip->cp_master_psy)
		power_supply_changed(chip->cp_master_psy);

+56 −7
Original line number Diff line number Diff line
@@ -180,6 +180,7 @@ struct smb1390 {
	struct votable		*cp_awake_votable;
	struct votable		*slave_disable_votable;
	struct votable		*usb_icl_votable;
	struct votable		*fcc_main_votable;

	/* power supplies */
	struct power_supply	*cps_psy;
@@ -876,13 +877,38 @@ static int smb1390_slave_disable_vote_cb(struct votable *votable, void *data,
			      int disable, const char *client)
{
	struct smb1390 *chip = data;
	int rc;
	int rc = 0, ilim_ua = 0;

	rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SL_BIT,
					disable ? 0 : CMD_EN_SL_BIT);
	if (rc < 0)
	if (rc < 0) {
		pr_err("Couldn't %s slave rc=%d\n",
				disable ? "disable" : "enable", rc);
		return rc;
	}

	/* Re-distribute ILIM to Master CP when Slave is disabled */
	if (disable && (chip->ilim_votable)) {
		ilim_ua = get_effective_result_locked(chip->ilim_votable);
		if (ilim_ua > MAX_ILIM_UA)
			ilim_ua = MAX_ILIM_UA;

		if (ilim_ua < 500000) {
			smb1390_dbg(chip, PR_INFO, "ILIM too low, not re-distributing, ilim=%duA\n",
								ilim_ua);
			return 0;
		}

		rc = smb1390_set_ilim(chip,
		      DIV_ROUND_CLOSEST(ilim_ua - 500000, 100000));
		if (rc < 0) {
			pr_err("Failed to set ILIM, rc=%d\n", rc);
			return rc;
		}

		smb1390_dbg(chip, PR_INFO, "Master ILIM set to %duA\n",
								ilim_ua);
	}

	return rc;
}
@@ -893,6 +919,7 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data,
	struct smb1390 *chip = data;
	union power_supply_propval pval = {0, };
	int rc = 0;
	bool slave_enabled = false;

	if (!is_psy_voter_available(chip) || chip->suspended)
		return -EAGAIN;
@@ -911,7 +938,17 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data,
			ilim_uA);
		vote(chip->disable_votable, ILIM_VOTER, true, 0);
	} else {
		/* Disable Slave CP if ILIM is < 2 * min ILIM */
		if (is_cps_available(chip)) {
			vote(chip->slave_disable_votable, ILIM_VOTER,
				(ilim_uA < (2 * chip->min_ilim_ua)), 0);

			if (get_effective_result(chip->slave_disable_votable)
									== 0)
				slave_enabled = true;
		}

		if (slave_enabled) {
			ilim_uA /= 2;
			pval.intval = DIV_ROUND_CLOSEST(ilim_uA - 500000,
					100000);
@@ -930,7 +967,8 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data,
			return rc;
		}

		smb1390_dbg(chip, PR_INFO, "ILIM set to %duA\n", ilim_uA);
		smb1390_dbg(chip, PR_INFO, "ILIM set to %duA slave_enabled%d\n",
						ilim_uA, slave_enabled);
		vote(chip->disable_votable, ILIM_VOTER, false, 0);
	}

@@ -1167,11 +1205,20 @@ static void smb1390_taper_work(struct work_struct *work)
{
	struct smb1390 *chip = container_of(work, struct smb1390, taper_work);
	union power_supply_propval pval = {0, };
	int rc, fcc_uA, delta_fcc_uA;
	int rc, fcc_uA, delta_fcc_uA, main_fcc_ua = 0;

	if (!is_psy_voter_available(chip))
		goto out;

	if (!chip->fcc_main_votable)
		chip->fcc_main_votable = find_votable("FCC_MAIN");

	if (chip->fcc_main_votable)
		main_fcc_ua = get_effective_result(chip->fcc_main_votable);

	if (main_fcc_ua < 0)
		main_fcc_ua = 0;

	chip->taper_entry_fv = get_effective_result(chip->fv_votable);
	while (true) {
		rc = power_supply_get_property(chip->batt_psy,
@@ -1200,14 +1247,15 @@ static void smb1390_taper_work(struct work_struct *work)
			smb1390_dbg(chip, PR_INFO, "taper work reducing FCC to %duA\n",
				fcc_uA);
			vote(chip->fcc_votable, CP_VOTER, true, fcc_uA);
			rc = smb1390_validate_slave_chg_taper(chip, fcc_uA);
			rc = smb1390_validate_slave_chg_taper(chip, (fcc_uA -
							      main_fcc_ua));
			if (rc < 0) {
				pr_err("Couldn't Disable slave in Taper, rc=%d\n",
				       rc);
				goto out;
			}

			if (fcc_uA < (chip->min_ilim_ua * 2)) {
			if ((fcc_uA - main_fcc_ua) < (chip->min_ilim_ua * 2)) {
				vote(chip->disable_votable, TAPER_END_VOTER,
								true, 0);
				/*
@@ -1482,7 +1530,8 @@ static int smb1390_parse_dt(struct smb1390 *chip)
	of_property_read_u32(chip->dev->of_node, "qcom,parallel-input-mode",
			&chip->pl_input_mode);

	chip->cp_slave_thr_taper_ua = chip->min_ilim_ua * 3;
	chip->cp_slave_thr_taper_ua = smb1390_is_adapter_cc_mode(chip) ?
			(3 * chip->min_ilim_ua) : (4 * chip->min_ilim_ua);
	of_property_read_u32(chip->dev->of_node, "qcom,cp-slave-thr-taper-ua",
			      &chip->cp_slave_thr_taper_ua);