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

Commit 55808922 authored by Ashay Jaiswal's avatar Ashay Jaiswal
Browse files

power: smb5-lib: apply ILIM offset only if CP is enabled



In case of QC 3.0 with SMB1390 configuration, SMB1390 input
current is restricted to 90% of the configured ILIM, to compensate
for this restriction an offset current is applied on top of main
charger's FCC configuration, add check to apply this offset only
when SMB1390 is charging. Rerun fcc_votable whenever CP ILIM is
configured to ensure main charger's FCC offset is recalculated
based on current ILIM.

Change-Id: Ibb10c6489014fcaecd767341a5c63999ab95dd1d
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
parent b99dda15
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ struct pl_data {
	bool			cp_disabled;
	int			taper_entry_fv;
	int			main_fcc_max;
	enum power_supply_type	charger_type;
	/* debugfs directory */
	struct dentry		*dfs_root;
	u32			float_voltage_uv;
@@ -191,12 +192,9 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode)

static int get_hvdcp3_icl_limit(struct pl_data *chip)
{
	int rc, main_icl, target_icl = -EINVAL;
	union power_supply_propval pval = {0, };
	int main_icl, target_icl = -EINVAL;

	rc = power_supply_get_property(chip->usb_psy,
				POWER_SUPPLY_PROP_REAL_TYPE, &pval);
	if ((rc < 0) || (pval.intval != POWER_SUPPLY_TYPE_USB_HVDCP_3))
	if (chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3)
		return target_icl;

	/*
@@ -270,6 +268,16 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim)
		else
			vote(chip->cp_ilim_votable, voter, true, ilim);

		/*
		 * Rerun FCC votable to ensure offset for ILIM compensation is
		 * recalculated based on new ILIM.
		 */
		if (!chip->fcc_main_votable)
			chip->fcc_main_votable = find_votable("FCC_MAIN");
		if ((chip->charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3)
				&& chip->fcc_main_votable)
			rerun_election(chip->fcc_main_votable);

		pl_dbg(chip, PR_PARALLEL,
			"ILIM: vote: %d voter:%s min_ilim=%d fcc = %d\n",
			ilim, voter, pval.intval, fcc);
@@ -1827,6 +1835,12 @@ static void handle_usb_change(struct pl_data *chip)
		chip->total_fcc_ua = 0;
		chip->slave_fcc_ua = 0;
		chip->main_fcc_ua = 0;
		chip->charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
	} else {
		rc = power_supply_get_property(chip->usb_psy,
				POWER_SUPPLY_PROP_REAL_TYPE, &pval);
		if (!rc)
			chip->charger_type = pval.intval;
	}
}

+12 −2
Original line number Diff line number Diff line
@@ -1060,12 +1060,22 @@ static void smb1390_configure_ilim(struct smb1390 *chip, int mode)
	/* QC3.0/Wireless adapter rely on the settled AICL for USBMID_USBMID */
	if ((chip->pl_input_mode == POWER_SUPPLY_PL_USBMID_USBMID)
			&& (mode == POWER_SUPPLY_CP_HVDCP3)) {
		if (!chip->fcc_main_votable)
			chip->fcc_main_votable = find_votable("FCC_MAIN");

		rc = power_supply_get_property(chip->usb_psy,
				POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval);
		if (rc < 0)
		if (rc < 0) {
			pr_err("Couldn't get usb aicl rc=%d\n", rc);
		else
		} else {
			vote(chip->ilim_votable, ICL_VOTER, true, pval.intval);
			/*
			 * Rerun FCC votable to ensure offset for ILIM
			 * compensation is recalculated based on new ILIM.
			 */
			if (chip->fcc_main_votable)
				rerun_election(chip->fcc_main_votable);
		}
	}
}

+39 −25
Original line number Diff line number Diff line
@@ -881,18 +881,53 @@ static bool is_cp_available(struct smb_charger *chg)
	return !!chg->cp_psy;
}

static bool is_cp_topo_vbatt(struct smb_charger *chg)
{
	int rc;
	bool is_vbatt;
	union power_supply_propval pval;

	if (!is_cp_available(chg))
		return false;

	rc = power_supply_get_property(chg->cp_psy,
				POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval);
	if (rc < 0)
		return false;

	is_vbatt = (pval.intval == POWER_SUPPLY_PL_OUTPUT_VBAT);

	smblib_dbg(chg, PR_WLS, "%s\n", is_vbatt ? "true" : "false");

	return is_vbatt;
}

#define CP_TO_MAIN_ICL_OFFSET_PC		10
int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua)
{
	union power_supply_propval pval = {0, };
	int rc;

	if ((chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3)
		|| chg->hvdcp3_standalone_config || !is_cp_available(chg)) {
		*offset_ua = 0;
		return 0;
	/*
	 * Apply ILIM offset to main charger's FCC if all of the following
	 * conditions are met:
	 * - HVDCP3 adapter with CP as parallel charger
	 * - Output connection topology is VBAT
	 */
	if (!is_cp_topo_vbatt(chg) || chg->hvdcp3_standalone_config
		|| (chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3))
		return -EINVAL;

	rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ENABLE,
					&pval);
	if (rc < 0) {
		smblib_err(chg, "Couldn't get CP ENABLE rc=%d\n", rc);
		return rc;
	}

	if (!pval.intval)
		return -EINVAL;

	rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ILIM,
					&pval);
	if (rc < 0) {
@@ -6347,27 +6382,6 @@ irqreturn_t dcin_uv_irq_handler(int irq, void *data)
	return IRQ_HANDLED;
}

static bool is_cp_topo_vbatt(struct smb_charger *chg)
{
	int rc;
	bool is_vbatt;
	union power_supply_propval pval;

	if (!is_cp_available(chg))
		return false;

	rc = power_supply_get_property(chg->cp_psy,
				POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval);
	if (rc < 0)
		return false;

	is_vbatt = (pval.intval == POWER_SUPPLY_PL_OUTPUT_VBAT);

	smblib_dbg(chg, PR_WLS, "%s\n", is_vbatt ? "true" : "false");

	return is_vbatt;
}

irqreturn_t dc_plugin_irq_handler(int irq, void *data)
{
	struct smb_irq_data *irq_data = data;