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

Commit 74021fcb authored by Abhijeet Dharmapurikar's avatar Abhijeet Dharmapurikar Committed by Harry Yang
Browse files

smb-lib: manage override in icl_callback



Currently we have only one path - the pd active setting path -  where
ICL_OVERRIDE gets set.

With the upcoming changes to manage connector temperature
mitigation and usbin-usbin parallel charger, the ICL_OVERRIDE is needed
to be set from these usecases.

So instead of creating a voter for ICL_OVERRIDE and putting the onus
on callsites to set it before calling their icl settings, it is best
to handle it in icl_callback.

Update the icl_callback to manage override and suspend in this way.

- Presence of voter signifies that the driver wants to enforce a
  value different than the hw default. Force an icl override.

- No voters signifies that the hw defaults are good, undo an override.

- For USB types that command a limit aka SDP and CDP, never override.

- never suspend if there are no clients.

Change-Id: I3ed01237b0bb2c028bec572d2905cabb03ce50a3
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
parent 95670878
Loading
Loading
Loading
Loading
+3 −6
Original line number Original line Diff line number Diff line
@@ -1352,13 +1352,10 @@ static int smb2_init_hw(struct smb2 *chip)
	smblib_rerun_apsd_if_required(chg);
	smblib_rerun_apsd_if_required(chg);


	/* clear the ICL override if it is set */
	/* clear the ICL override if it is set */
	if (stat & ICL_OVERRIDE_LATCH_BIT) {
	if (smblib_icl_override(chg, false) < 0) {
		rc = smblib_write(chg, CMD_APSD_REG, ICL_OVERRIDE_BIT);
		if (rc < 0) {
		pr_err("Couldn't disable ICL override rc=%d\n", rc);
		pr_err("Couldn't disable ICL override rc=%d\n", rc);
		return rc;
		return rc;
	}
	}
	}


	/* votes must be cast before configuring software control */
	/* votes must be cast before configuring software control */
	vote(chg->usb_suspend_votable,
	vote(chg->usb_suspend_votable,
+66 −50
Original line number Original line Diff line number Diff line
@@ -151,6 +151,31 @@ static int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua)
	return 0;
	return 0;
}
}


int smblib_icl_override(struct smb_charger *chg, bool override)
{
	int rc;
	bool override_status;
	u8 stat;

	rc = smblib_read(chg, APSD_RESULT_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read APSD_RESULT_STATUS_REG rc=%d\n",
				rc);
		return rc;
	}
	override_status = (bool)(stat & ICL_OVERRIDE_LATCH_BIT);

	if (override != override_status) {
		rc = smblib_masked_write(chg, CMD_APSD_REG,
				ICL_OVERRIDE_BIT, ICL_OVERRIDE_BIT);
		if (rc < 0) {
			smblib_err(chg, "Couldn't override ICL rc=%d\n", rc);
			return rc;
		}
	}
	return 0;
}

/********************
/********************
 * REGISTER GETTERS *
 * REGISTER GETTERS *
 ********************/
 ********************/
@@ -728,19 +753,33 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
{
{
	struct smb_charger *chg = data;
	struct smb_charger *chg = data;
	int rc = 0;
	int rc = 0;
	bool suspend = (icl_ua < USBIN_25MA);
	bool suspend, override;
	u8 icl_options = 0;
	u8 icl_options = 0;


	override = true;
	/* remove override if no voters or type = SDP or CDP */
	if (client == NULL
		|| chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB
		|| chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB_CDP)
		override = false;

	suspend = false;
	if (client && (icl_ua < USBIN_25MA))
		suspend = true;

	if (suspend)
	if (suspend)
		goto out;
		goto out;


	if (chg->usb_psy_desc.type != POWER_SUPPLY_TYPE_USB) {
	if (chg->usb_psy_desc.type != POWER_SUPPLY_TYPE_USB) {
		rc = smblib_set_charge_param(chg, &chg->param.usb_icl, icl_ua);
		if (client) {
			rc = smblib_set_charge_param(chg, &chg->param.usb_icl,
					icl_ua);
			if (rc < 0) {
			if (rc < 0) {
			smblib_err(chg, "Couldn't set HC ICL rc=%d\n", rc);
				smblib_err(chg, "Couldn't set HC ICL rc=%d\n",
					rc);
				return rc;
				return rc;
			}
			}

		}
		goto out;
		goto out;
	}
	}


@@ -769,10 +808,14 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
	}
	}


out:
out:
	if (override)
		icl_options |= USBIN_MODE_CHG_BIT;

	rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG,
	rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG,
			CFG_USB3P0_SEL_BIT | USB51_MODE_BIT, icl_options);
		CFG_USB3P0_SEL_BIT | USB51_MODE_BIT | USBIN_MODE_CHG_BIT,
		icl_options);
	if (rc < 0) {
	if (rc < 0) {
		smblib_err(chg, "Couldn't set ICL opetions rc=%d\n", rc);
		smblib_err(chg, "Couldn't set ICL options rc=%d\n", rc);
		return rc;
		return rc;
	}
	}


@@ -783,6 +826,12 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
		return rc;
		return rc;
	}
	}


	rc = smblib_icl_override(chg, override);
	if (rc < 0) {
		smblib_err(chg, "Couldn't set ICL override rc=%d\n", rc);
		return rc;
	}

	return rc;
	return rc;
}
}


@@ -2162,38 +2211,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
			smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc);
			smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc);
			return rc;
			return rc;
		}
		}

		rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG,
				USBIN_MODE_CHG_BIT, USBIN_MODE_CHG_BIT);
		if (rc < 0) {
			smblib_err(chg,
				"Couldn't change USB mode rc=%d\n", rc);
			return rc;
		}

		rc = smblib_masked_write(chg, CMD_APSD_REG,
				ICL_OVERRIDE_BIT, ICL_OVERRIDE_BIT);
		if (rc < 0) {
			smblib_err(chg,
				"Couldn't override APSD rc=%d\n", rc);
			return rc;
		}
	} else {
		rc = smblib_masked_write(chg, CMD_APSD_REG,
				ICL_OVERRIDE_BIT, 0);
		if (rc < 0) {
			smblib_err(chg,
				"Couldn't override APSD rc=%d\n", rc);
			return rc;
		}

		rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG,
				USBIN_MODE_CHG_BIT, 0);
		if (rc < 0) {
			smblib_err(chg,
				"Couldn't change USB mode rc=%d\n", rc);
			return rc;
		}
	}
	}


	/* CC pin selection s/w override in PD session; h/w otherwise. */
	/* CC pin selection s/w override in PD session; h/w otherwise. */
@@ -2803,17 +2820,16 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg,
		if (get_effective_result(chg->pd_disallowed_votable_indirect))
		if (get_effective_result(chg->pd_disallowed_votable_indirect))
			/* could be a legacy cable, try doing hvdcp */
			/* could be a legacy cable, try doing hvdcp */
			try_rerun_apsd_for_hvdcp(chg);
			try_rerun_apsd_for_hvdcp(chg);
	}

		/*
		/*
		 * HVDCP detection timeout done
		 * HVDCP detection timeout done
		 * If adapter is not QC2.0/QC3.0 - it is a plain old DCP.
		 * If adapter is not QC2.0/QC3.0 - it is a plain old DCP.
	 * Otherwise if adapter is QC2.0/QC3.0 wait for authentication
	 * to complete.
		 */
		 */
		if (!qc_charger && (apsd_result->bit & DCP_CHARGER_BIT))
		if (!qc_charger && (apsd_result->bit & DCP_CHARGER_BIT))
			/* enforce DCP ICL if specified */
			/* enforce DCP ICL if specified */
			vote(chg->usb_icl_votable, DCP_VOTER,
			vote(chg->usb_icl_votable, DCP_VOTER,
				chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua);
				chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua);
	}


	smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n",
	smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n",
		   rising ? "rising" : "falling");
		   rising ? "rising" : "falling");
+1 −0
Original line number Original line Diff line number Diff line
@@ -405,6 +405,7 @@ void smblib_suspend_on_debug_battery(struct smb_charger *chg);
int smblib_rerun_apsd_if_required(struct smb_charger *chg);
int smblib_rerun_apsd_if_required(struct smb_charger *chg);
int smblib_get_prop_fcc_delta(struct smb_charger *chg,
int smblib_get_prop_fcc_delta(struct smb_charger *chg,
			       union power_supply_propval *val);
			       union power_supply_propval *val);
int smblib_icl_override(struct smb_charger *chg, bool override);


int smblib_init(struct smb_charger *chg);
int smblib_init(struct smb_charger *chg);
int smblib_deinit(struct smb_charger *chg);
int smblib_deinit(struct smb_charger *chg);