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

Commit b6d59001 authored by David Collins's avatar David Collins
Browse files

regulator: spm-regulator: add support for bypassing spm APIs



Add support in the spm-regulator driver to configure the PMIC
regulator voltage via SPMI instead of via SPM.  This can be used
when simulated chips do not have fully functional SPM models.

Change-Id: Id75b3dd580ed267dfc5c647d36756690d32b774f
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent 09c37939
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ Optional properties:
		    in whatever mode hardware or bootloaders set it to.
- qcom,cpu-num:    Specifies which CPU this regulator powers.  This property is
		    not need when the SPM regulator is shared between all CPUs.
- qcom,bypass-spm: Boolean flag which indicates that voltage control should not
		    be managed by an SPM.  Instead, the voltage should be
		    controlled via SPMI.

All properties specified within the core regulator framework can also be used.
These bindings can be found in regulator.txt.
+33 −10
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ struct spm_vreg {
	int				step_rate;
	enum qpnp_regulator_uniq_type	regulator_type;
	u32				cpu_num;
	bool				bypass_spm;
};

static int qpnp_fts2_set_mode(struct spm_vreg *vreg, u8 mode)
@@ -138,6 +139,7 @@ static int _spm_regulator_set_voltage(struct regulator_dev *rdev)
{
	struct spm_vreg *vreg = rdev_get_drvdata(rdev);
	int rc;
	u8 reg;

	if (vreg->vlevel == vreg->last_set_vlevel)
		return 0;
@@ -151,11 +153,27 @@ static int _spm_regulator_set_voltage(struct regulator_dev *rdev)
			return rc;
	}

	if (likely(!vreg->bypass_spm)) {
		/* Set voltage control register via SPM. */
		rc = msm_spm_set_vdd(vreg->cpu_num, vreg->vlevel);
		if (rc) {
		pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->rdesc.name, rc);
			pr_err("%s: msm_spm_set_vdd failed %d\n",
				vreg->rdesc.name, rc);
			return rc;
		}
	} else {
		/* Set voltage control register via SPMI. */
		reg = vreg->vlevel;
		rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl,
			vreg->spmi_dev->sid,
			vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
			&reg, 1);
		if (rc) {
			pr_err("%s: spmi_ext_register_writel failed %d\n",
				vreg->rdesc.name, rc);
			return rc;
		}
	}

	if (vreg->uV > vreg->last_set_uV) {
		/* Wait for voltage stepping to complete. */
@@ -476,6 +494,7 @@ static int spm_regulator_probe(struct spmi_device *spmi)
	struct regulator_init_data *init_data;
	struct spm_vreg *vreg;
	struct resource *res;
	bool bypass_spm;
	int rc;

	if (!node) {
@@ -483,6 +502,8 @@ static int spm_regulator_probe(struct spmi_device *spmi)
		return -ENODEV;
	}

	bypass_spm = of_property_read_bool(node, "qcom,bypass-spm");
	if (!bypass_spm) {
		rc = msm_spm_probe_done();
		if (rc) {
			if (rc != -EPROBE_DEFER)
@@ -490,6 +511,7 @@ static int spm_regulator_probe(struct spmi_device *spmi)
					__func__, rc);
			return rc;
		}
	}

	vreg = devm_kzalloc(&spmi->dev, sizeof(*vreg), GFP_KERNEL);
	if (!vreg) {
@@ -497,6 +519,7 @@ static int spm_regulator_probe(struct spmi_device *spmi)
		return -ENOMEM;
	}
	vreg->spmi_dev = spmi;
	vreg->bypass_spm = bypass_spm;

	res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!res) {