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

Commit 9e285876 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: qpnp-charger: add parallel ovp charge mode"

parents ada3ce79 1e4b318f
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));