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

Commit 1e4b318f authored by David Keitel's avatar David Keitel
Browse files

power: qpnp-charger: add parallel ovp charge mode



This enables the parallel OVP charge mode for PM8941 devices.
This feature specific to PM8941 allows DC_IN and USB_IN to be
shorted on the device to allowing both input paths to be leveraged
and put more current into the battery.

Note that the feature is only enabled when fast charging
and disabled once fast charging is disabled.

Change-Id: Id76ef10c75eae267149437391f4e9fa6bfede18b
CRs-Fixed: 607941
Signed-off-by: default avatarDavid Keitel <dkeitel@codeaurora.org>
parent 92a9b32c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -106,6 +106,10 @@ Parent node optional properties:
- qcom,vbatdet-maxerr-mv		This property in mV is a hystersis value for the charge
					resume voltage property qcom,vbatdet-delta-mv. If this
					property is not defined it defaults to 50 mV.
- qcom,parallel-ovp-mode		When this option is enabled, it allows charging through both
					DC and USB OVP FETs. Please note that this should only
					be enabled in board designs with PM8941 which have DC_IN
					and USB_IN connected via a short.

Sub node required structure:
- A qcom,chg node must be a child of an SPMI node that has specified
+73 −0
Original line number Diff line number Diff line
@@ -116,6 +116,8 @@
#define USB_OCP_CLR				0x53
#define BAT_IF_TEMP_STATUS			0x09
#define BOOST_ILIM				0x78
#define USB_SPARE				0xDF
#define DC_COMP_OVR1				0xE9

#define REG_OFFSET_PERP_SUBTYPE			0x05

@@ -321,6 +323,7 @@ struct qpnp_chg_chip {
	bool				aicl_settled;
	bool				use_external_rsense;
	bool				fastchg_on;
	bool				parallel_ovp_mode;
	unsigned int			bpd_detection;
	unsigned int			max_bat_chg_current;
	unsigned int			warm_bat_chg_ma;
@@ -1013,10 +1016,68 @@ qpnp_chg_usb_iusbmax_get(struct qpnp_chg_chip *chip)
	return iusbmax_ma;
}

#define ILIMIT_OVR_0	0x02
static int
override_dcin_ilimit(struct qpnp_chg_chip *chip, bool override)
{
	int rc;

	pr_debug("override %d\n", override);
	rc = qpnp_chg_masked_write(chip,
			chip->dc_chgpth_base + SEC_ACCESS,
			0xA5,
			0xA5, 1);
	rc |= qpnp_chg_masked_write(chip,
			chip->dc_chgpth_base + DC_COMP_OVR1,
			0xFF,
			override ? ILIMIT_OVR_0 : 0, 1);
	if (rc) {
		pr_err("Failed to override dc ilimit rc = %d\n", rc);
		return rc;
	}

	return rc;
}

#define DUAL_PATH_EN	BIT(7)
static int
switch_parallel_ovp_mode(struct qpnp_chg_chip *chip, bool enable)
{
	int rc = 0;

	if (!chip->usb_chgpth_base || !chip->dc_chgpth_base)
		return rc;

	pr_debug("enable %d\n", enable);
	rc = override_dcin_ilimit(chip, 1);
	udelay(10);

	/* enable/disable dual path mode */
	rc = qpnp_chg_masked_write(chip,
			chip->usb_chgpth_base + SEC_ACCESS,
			0xA5,
			0xA5, 1);
	rc |= qpnp_chg_masked_write(chip,
			chip->usb_chgpth_base + USB_SPARE,
			0xFF,
			enable ? DUAL_PATH_EN : 0, 1);
	if (rc) {
		pr_err("Failed to turn on usb ovp rc = %d\n", rc);
		return rc;
	}

	rc = override_dcin_ilimit(chip, 0);
	return rc;
}

#define USB_SUSPEND_BIT	BIT(0)
static int
qpnp_chg_usb_suspend_enable(struct qpnp_chg_chip *chip, int enable)
{
	/* Turn off DC OVP FET when going into USB suspend */
	if (chip->parallel_ovp_mode && enable)
		switch_parallel_ovp_mode(chip, 0);

	return qpnp_chg_masked_write(chip,
			chip->usb_chgpth_base + CHGR_USB_USB_SUSP,
			USB_SUSPEND_BIT,
@@ -1835,6 +1896,11 @@ qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
					msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
				pm_stay_awake(chip->dev);
			}
			if (chip->parallel_ovp_mode)
				switch_parallel_ovp_mode(chip, 1);
		} else {
			if (chip->parallel_ovp_mode)
				switch_parallel_ovp_mode(chip, 0);
		}
	}

@@ -1951,6 +2017,9 @@ switch_usb_to_host_mode(struct qpnp_chg_chip *chip)
	if (qpnp_chg_is_otg_en_set(chip))
		return 0;

	if (chip->parallel_ovp_mode)
		switch_parallel_ovp_mode(chip, 0);

	if (chip->type == SMBBP) {
		rc = qpnp_chg_masked_write(chip,
				chip->boost_base + BOOST_ILIM,
@@ -4657,6 +4726,10 @@ qpnp_charger_read_dt_props(struct qpnp_chg_chip *chip)
			of_property_read_bool(chip->spmi->dev.of_node,
					"qcom,power-stage-reduced");

	chip->parallel_ovp_mode =
			of_property_read_bool(chip->spmi->dev.of_node,
					"qcom,parallel-ovp-mode");

	of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
		&(chip->thermal_levels));