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

Commit 7c241386 authored by Ashay Jaiswal's avatar Ashay Jaiswal Committed by Subbaraman Narayanamurthy
Browse files

power: qcom-charger: add OTG workaround for PM660



PM660 support configurable delay for softstart done with
minimum value of 3msec and thus OTG can be configured to
a minimum value till softstart completes. Add a PM660
specific workaround to set OTG current limit to 250mA before
enabling OTG mode and reconfigure the current back to desired
value once OTG softstart completes.

CRs-Fixed: 2016131
Change-Id: Iabb9e1c55cc59453825795e045d7fcc6caf8f33e
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
parent 93fb0f09
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -239,7 +239,6 @@ static struct smb_params pm660_params = {
struct smb_dt_props {
	int	fcc_ua;
	int	usb_icl_ua;
	int	otg_cl_ua;
	int	dc_icl_ua;
	int	boost_threshold_ua;
	int	fv_uv;
@@ -323,9 +322,9 @@ static int smb2_parse_dt(struct smb2 *chip)
		chip->dt.usb_icl_ua = -EINVAL;

	rc = of_property_read_u32(node,
				"qcom,otg-cl-ua", &chip->dt.otg_cl_ua);
				"qcom,otg-cl-ua", &chg->otg_cl_ua);
	if (rc < 0)
		chip->dt.otg_cl_ua = MICRO_1P5A;
		chg->otg_cl_ua = MICRO_1P5A;

	rc = of_property_read_u32(node,
				"qcom,dc-icl-ua", &chip->dt.dc_icl_ua);
@@ -1386,7 +1385,8 @@ static int smb2_init_hw(struct smb2 *chip)

	/* set OTG current limit */
	rc = smblib_set_charge_param(chg, &chg->param.otg_cl,
							chip->dt.otg_cl_ua);
				(chg->wa_flags & OTG_WA) ?
				chg->param.otg_cl.min_u : chg->otg_cl_ua);
	if (rc < 0) {
		pr_err("Couldn't set otg current limit rc=%d\n", rc);
		return rc;
@@ -1649,7 +1649,7 @@ static int smb2_chg_config_init(struct smb2 *chip)
		break;
	case PM660_SUBTYPE:
		chip->chg.smb_version = PM660_SUBTYPE;
		chip->chg.wa_flags |= BOOST_BACK_WA;
		chip->chg.wa_flags |= BOOST_BACK_WA | OTG_WA;
		chg->param.freq_buck = pm660_params.freq_buck;
		chg->param.freq_boost = pm660_params.freq_boost;
		chg->chg_freq.freq_5V		= 600;
+60 −3
Original line number Diff line number Diff line
@@ -1289,11 +1289,14 @@ int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev)
/*****************
 * OTG REGULATOR *
 *****************/

#define MAX_RETRY		15
#define MIN_DELAY_US		2000
#define MAX_DELAY_US		9000
static int _smblib_vbus_regulator_enable(struct regulator_dev *rdev)
{
	struct smb_charger *chg = rdev_get_drvdata(rdev);
	int rc;
	int rc, retry_count = 0, min_delay = MIN_DELAY_US;
	u8 stat;

	smblib_dbg(chg, PR_OTG, "halt 1 in 8 mode\n");
	rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
@@ -1312,6 +1315,42 @@ static int _smblib_vbus_regulator_enable(struct regulator_dev *rdev)
		return rc;
	}

	if (chg->wa_flags & OTG_WA) {
		/* check for softstart */
		do {
			usleep_range(min_delay, min_delay + 100);
			rc = smblib_read(chg, OTG_STATUS_REG, &stat);
			if (rc < 0) {
				smblib_err(chg,
					"Couldn't read OTG status rc=%d\n",
					rc);
				goto out;
			}

			if (stat & BOOST_SOFTSTART_DONE_BIT) {
				rc = smblib_set_charge_param(chg,
					&chg->param.otg_cl, chg->otg_cl_ua);
				if (rc < 0)
					smblib_err(chg,
						"Couldn't set otg limit\n");
				break;
			}

			/* increase the delay for following iterations */
			if (retry_count > 5)
				min_delay = MAX_DELAY_US;
		} while (retry_count++ < MAX_RETRY);

		if (retry_count >= MAX_RETRY) {
			smblib_dbg(chg, PR_OTG, "Boost Softstart not done\n");
			goto out;
		}
	}

	return 0;
out:
	/* disable OTG if softstart failed */
	smblib_write(chg, CMD_OTG_REG, 0);
	return rc;
}

@@ -1345,6 +1384,17 @@ static int _smblib_vbus_regulator_disable(struct regulator_dev *rdev)
			smblib_err(chg, "Couldn't disable VCONN rc=%d\n", rc);
	}

	if (chg->wa_flags & OTG_WA) {
		/* set OTG current limit to minimum value */
		rc = smblib_set_charge_param(chg, &chg->param.otg_cl,
						chg->param.otg_cl.min_u);
		if (rc < 0) {
			smblib_err(chg,
				"Couldn't set otg current limit rc=%d\n", rc);
			return rc;
		}
	}

	smblib_dbg(chg, PR_OTG, "disabling OTG\n");
	rc = smblib_write(chg, CMD_OTG_REG, 0);
	if (rc < 0) {
@@ -1353,7 +1403,6 @@ static int _smblib_vbus_regulator_disable(struct regulator_dev *rdev)
	}

	smblib_dbg(chg, PR_OTG, "start 1 in 8 mode\n");
	rc = smblib_write(chg, CMD_OTG_REG, 0);
	rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
				 ENG_BUCKBOOST_HALT1_8_MODE_BIT, 0);
	if (rc < 0) {
@@ -2954,6 +3003,14 @@ irqreturn_t smblib_handle_otg_overcurrent(int irq, void *data)
		return IRQ_HANDLED;
	}

	if (chg->wa_flags & OTG_WA) {
		if (stat & OTG_OC_DIS_SW_STS_RT_STS_BIT)
			smblib_err(chg, "OTG disabled by hw\n");

		/* not handling software based hiccups for PM660 */
		return IRQ_HANDLED;
	}

	if (stat & OTG_OVERCURRENT_RT_STS_BIT)
		schedule_work(&chg->otg_oc_work);

+2 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ enum {
	BOOST_BACK_WA			= BIT(1),
	TYPEC_CC2_REMOVAL_WA_BIT	= BIT(2),
	QC_AUTH_INTERRUPT_WA_BIT	= BIT(3),
	OTG_WA				= BIT(4),
};

enum smb_irq_index {
@@ -305,6 +306,7 @@ struct smb_charger {
	int			otg_attempts;
	int			vconn_attempts;
	int			default_icl_ua;
	int			otg_cl_ua;

	/* workaround flag */
	u32			wa_flags;