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

Commit bf18e756 authored by Umang Agrawal's avatar Umang Agrawal Committed by Guru Das Srinagesh
Browse files

power: smb1390-psy: Modify ILIM votable callback



Currently ILIM is evaluated in status change work of charge pump driver
which limit its configurability to power_supply_changed calls.
However, change in FCC, which directly effects ILIM, does not trigger
any power supply change event, which can be problematic.

Fix this by directly casting FCC vote, independent of status change work.

Change-Id: I489076f409fb7d6be55c2ea1393ce6de34fdb54a
Signed-off-by: default avatarUmang Agrawal <uagrawal@codeaurora.org>
parent a0418486
Loading
Loading
Loading
Loading
+17 −1
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) 2017-2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
 */
 */


#define pr_fmt(fmt) "QCOM-BATT: %s: " fmt, __func__
#define pr_fmt(fmt) "QCOM-BATT: %s: " fmt, __func__
@@ -40,6 +40,7 @@
#define PL_FCC_LOW_VOTER		"PL_FCC_LOW_VOTER"
#define PL_FCC_LOW_VOTER		"PL_FCC_LOW_VOTER"
#define ICL_LIMIT_VOTER			"ICL_LIMIT_VOTER"
#define ICL_LIMIT_VOTER			"ICL_LIMIT_VOTER"
#define FCC_STEPPER_VOTER		"FCC_STEPPER_VOTER"
#define FCC_STEPPER_VOTER		"FCC_STEPPER_VOTER"
#define FCC_VOTER			"FCC_VOTER"


struct pl_data {
struct pl_data {
	int			pl_mode;
	int			pl_mode;
@@ -57,6 +58,7 @@ struct pl_data {
	struct votable		*hvdcp_hw_inov_dis_votable;
	struct votable		*hvdcp_hw_inov_dis_votable;
	struct votable		*usb_icl_votable;
	struct votable		*usb_icl_votable;
	struct votable		*pl_enable_votable_indirect;
	struct votable		*pl_enable_votable_indirect;
	struct votable		*cp_ilim_votable;
	struct delayed_work	status_change_work;
	struct delayed_work	status_change_work;
	struct work_struct	pl_disable_forever_work;
	struct work_struct	pl_disable_forever_work;
	struct work_struct	pl_taper_work;
	struct work_struct	pl_taper_work;
@@ -618,6 +620,9 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data,
	if (!chip->main_psy)
	if (!chip->main_psy)
		return 0;
		return 0;


	if (!chip->cp_ilim_votable)
		chip->cp_ilim_votable = find_votable("CP_ILIM");

	if (chip->pl_mode != POWER_SUPPLY_PL_NONE) {
	if (chip->pl_mode != POWER_SUPPLY_PL_NONE) {
		get_fcc_split(chip, total_fcc_ua, &master_fcc_ua,
		get_fcc_split(chip, total_fcc_ua, &master_fcc_ua,
				&slave_fcc_ua);
				&slave_fcc_ua);
@@ -814,6 +819,10 @@ static void fcc_stepper_work(struct work_struct *work)
	chip->main_fcc_ua = main_fcc;
	chip->main_fcc_ua = main_fcc;
	chip->slave_fcc_ua = parallel_fcc;
	chip->slave_fcc_ua = parallel_fcc;


	if (chip->cp_ilim_votable)
		vote(chip->cp_ilim_votable, FCC_VOTER, true,
					chip->main_fcc_ua / 2);

	if (reschedule_ms) {
	if (reschedule_ms) {
		schedule_delayed_work(&chip->fcc_stepper_work,
		schedule_delayed_work(&chip->fcc_stepper_work,
				msecs_to_jiffies(reschedule_ms));
				msecs_to_jiffies(reschedule_ms));
@@ -929,6 +938,9 @@ static int usb_icl_vote_callback(struct votable *votable, void *data,


	vote(chip->pl_disable_votable, ICL_CHANGE_VOTER, false, 0);
	vote(chip->pl_disable_votable, ICL_CHANGE_VOTER, false, 0);


	if (chip->cp_ilim_votable)
		vote(chip->cp_ilim_votable, ICL_CHANGE_VOTER, true, icl_ua);

	return 0;
	return 0;
}
}


@@ -1188,6 +1200,10 @@ static int pl_disable_vote_callback(struct votable *votable,
				return rc;
				return rc;
			}
			}


			if (chip->cp_ilim_votable)
				vote(chip->cp_ilim_votable, FCC_VOTER, true,
						total_fcc_ua / 2);

			/* reset parallel FCC */
			/* reset parallel FCC */
			chip->slave_fcc_ua = 0;
			chip->slave_fcc_ua = 0;
			chip->total_settled_ua = 0;
			chip->total_settled_ua = 0;
+18 −12
Original line number Original line Diff line number Diff line
@@ -435,18 +435,20 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data,
		return -EINVAL;
		return -EINVAL;
	}
	}


	rc = smb1390_masked_write(chip, CORE_FTRIM_ILIM_REG,
		CFG_ILIM_MASK,
		DIV_ROUND_CLOSEST(max(ilim_uA, 500000) - 500000, 100000));
	if (rc < 0) {
		pr_err("Failed to write ILIM Register, rc=%d\n", rc);
		return rc;
	}

	/* ILIM less than 1A is not accurate; disable charging */
	/* ILIM less than 1A is not accurate; disable charging */
	if (ilim_uA < 1000000) {
	if (ilim_uA < 1000000) {
		pr_debug("ILIM %duA is too low to allow charging\n", ilim_uA);
		pr_debug("ILIM %duA is too low to allow charging\n", ilim_uA);
		vote(chip->disable_votable, ILIM_VOTER, true, 0);
		vote(chip->disable_votable, ILIM_VOTER, true, 0);
	} else {
	} else {
		pr_debug("setting ILIM to %duA\n", ilim_uA);
		pr_debug("ILIM set to %duA\n", ilim_uA);
		rc = smb1390_masked_write(chip, CORE_FTRIM_ILIM_REG,
				CFG_ILIM_MASK,
				DIV_ROUND_CLOSEST(ilim_uA - 500000, 100000));
		if (rc < 0)
			pr_err("Failed to write ILIM Register, rc=%d\n", rc);
		if (rc >= 0)
		vote(chip->disable_votable, ILIM_VOTER, false, 0);
		vote(chip->disable_votable, ILIM_VOTER, false, 0);
	}
	}


@@ -544,10 +546,6 @@ static void smb1390_status_change_work(struct work_struct *work)
								pval.intval);
								pval.intval);
		}
		}


		/* input current is always half the charge current */
		vote(chip->ilim_votable, FCC_VOTER, true,
				get_effective_result(chip->fcc_votable) / 2);

		/*
		/*
		 * all votes that would result in disabling the charge pump have
		 * all votes that would result in disabling the charge pump have
		 * been cast; ensure the charhe pump is still enabled before
		 * been cast; ensure the charhe pump is still enabled before
@@ -810,6 +808,14 @@ static int smb1390_create_votables(struct smb1390 *chip)
	 */
	 */
	vote(chip->disable_votable, USER_VOTER, true, 0);
	vote(chip->disable_votable, USER_VOTER, true, 0);


	/*
	 * In case SMB1390 probe happens after FCC value has been configured,
	 * update ilim vote to reflect FCC / 2 value.
	 */
	if (chip->fcc_votable)
		vote(chip->ilim_votable, FCC_VOTER, true,
			get_effective_result(chip->fcc_votable) / 2);

	return 0;
	return 0;
}
}