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

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

Merge "ARM: dts: msm: vote for MBG when PMI8994 5V boost is enabled on MSM8996"

parents 7dfc7cd4 27c5a16f
Loading
Loading
Loading
Loading
+21 −2
Original line number Original line Diff line number Diff line
@@ -66,12 +66,25 @@ Optional properties:
All the below properties are in the sub-node section (properties of the child
All the below properties are in the sub-node section (properties of the child
node).
node).


Sub-node required properties:
Sub-nodes (if defined) should belong to either a PON configuration or a
regulator configuration.

Regulator sub-node required properties:
- regulator-name		Regulator name for the PON regulator that
				is being configured.
- qcom,pon-spare-reg-addr	Register offset from the base address of the PON
				peripheral that needs to be configured for the
				regulator being controlled.
- qcom,pon-spare-reg-bit	Bit position in the specified register that
				needs to be configured for the regulator being
				controlled.

PON sub-node required properties:
- qcom,pon-type			The type of PON/RESET source. The driver
- qcom,pon-type			The type of PON/RESET source. The driver
				currently supports KPDPWR(0), RESIN(1) and
				currently supports KPDPWR(0), RESIN(1) and
				CBLPWR(2) pon/reset sources.
				CBLPWR(2) pon/reset sources.


Sub-node optional properties:
PON sub-node optional properties:
- qcom,pull-up			The initial state of the reset pin under
- qcom,pull-up			The initial state of the reset pin under
				consideration.
				consideration.
				0 = No pull-up
				0 = No pull-up
@@ -152,4 +165,10 @@ Example:
		compatible = "qcom,qpnp-power-on";
		compatible = "qcom,qpnp-power-on";
		reg = <0x800 0x100>;
		reg = <0x800 0x100>;
		qcom,secondary-pon-reset;
		qcom,secondary-pon-reset;

		pon_perph_reg: qcom,pon_perph_reg {
			regulator-name = "pon_spare_reg";
			qcom,pon-spare-reg-addr = <0x8c>;
			qcom,pon-spare-reg-bit = <1>;
		};
	};
	};
+5 −0
Original line number Original line Diff line number Diff line
@@ -33,6 +33,11 @@
			qcom,secondary-pon-reset;
			qcom,secondary-pon-reset;
			qcom,s3-debounce = <32>;
			qcom,s3-debounce = <32>;
			qcom,s3-src = "kpdpwr-and-resin";
			qcom,s3-src = "kpdpwr-and-resin";
			pon_perph_reg: qcom,pon_perph_reg {
				regulator-name = "pon_spare_reg";
				qcom,pon-spare-reg-addr = <0x8c>;
				qcom,pon-spare-reg-bit = <1>;
			};
		};
		};


		pmi8994_gpios: gpios {
		pmi8994_gpios: gpios {
+2 −0
Original line number Original line Diff line number Diff line
@@ -456,6 +456,7 @@
			 * control boost regulator request.
			 * control boost regulator request.
			 */
			 */
			regulator-name = "pmi8994_boost_5v";
			regulator-name = "pmi8994_boost_5v";
			parent-supply = <&pon_perph_reg>;
			status = "okay";
			status = "okay";
		};
		};
		pmi8994_boost_pin_ctrl: regulator-bst-pin-ctrl {
		pmi8994_boost_pin_ctrl: regulator-bst-pin-ctrl {
@@ -468,6 +469,7 @@
			 */
			 */
			compatible = "qcom,rpm-smd-regulator";
			compatible = "qcom,rpm-smd-regulator";
			regulator-name = "pmi8994_boost_pin_ctrl";
			regulator-name = "pmi8994_boost_pin_ctrl";
			parent-supply = <&pon_perph_reg>;
			qcom,set = <3>;
			qcom,set = <3>;
			qcom,enable-with-pin-ctrl = <0 1>;
			qcom,enable-with-pin-ctrl = <0 1>;
		};
		};
+186 −20
Original line number Original line Diff line number Diff line
@@ -25,6 +25,9 @@
#include <linux/mutex.h>
#include <linux/mutex.h>
#include <linux/input.h>
#include <linux/input.h>
#include <linux/log2.h>
#include <linux/log2.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/qpnp/power-on.h>
#include <linux/qpnp/power-on.h>


#define CREATE_MASK(NUM_BITS, POS) \
#define CREATE_MASK(NUM_BITS, POS) \
@@ -151,19 +154,31 @@ struct qpnp_pon_config {
	bool config_reset;
	bool config_reset;
};
};


struct pon_regulator {
	struct qpnp_pon		*pon;
	struct regulator_dev	*rdev;
	struct regulator_desc	rdesc;
	u32			addr;
	u32			bit;
	bool			enabled;
};

struct qpnp_pon {
struct qpnp_pon {
	struct spmi_device	*spmi;
	struct spmi_device	*spmi;
	struct input_dev	*pon_input;
	struct input_dev	*pon_input;
	struct qpnp_pon_config	*pon_cfg;
	struct qpnp_pon_config	*pon_cfg;
	struct pon_regulator	*pon_reg_cfg;
	struct list_head	list;
	struct list_head	list;
	int num_pon_config;
	u16 base;
	struct delayed_work	bark_work;
	struct delayed_work	bark_work;
	u32 dbc;
	struct dentry		*debugfs;
	int			pon_trigger_reason;
	int			pon_trigger_reason;
	int			pon_power_off_reason;
	int			pon_power_off_reason;
	int			num_pon_reg;
	int			num_pon_config;
	int			reg_count;
	u32			dbc;
	u32			uvlo;
	u32			uvlo;
	struct dentry *debugfs;
	u16			base;
	u8			warm_reset_reason1;
	u8			warm_reset_reason1;
	u8			warm_reset_reason2;
	u8			warm_reset_reason2;
	bool			is_spon;
	bool			is_spon;
@@ -1093,7 +1108,9 @@ static int qpnp_pon_config_init(struct qpnp_pon *pon)
	}
	}


	/* iterate through the list of pon configs */
	/* iterate through the list of pon configs */
	while ((pp = of_get_next_child(pon->spmi->dev.of_node, pp))) {
	for_each_available_child_of_node(pon->spmi->dev.of_node, pp) {
		if (!of_find_property(pp, "qcom,pon-type", NULL))
			continue;


		cfg = &pon->pon_cfg[i++];
		cfg = &pon->pon_cfg[i++];


@@ -1436,6 +1453,137 @@ free_input_dev:
	return rc;
	return rc;
}
}


static int pon_spare_regulator_enable(struct regulator_dev *rdev)
{
	int rc = 0;
	u8 value;
	struct pon_regulator *pon_reg = rdev_get_drvdata(rdev);

	pr_debug("reg %s enable addr: %x bit: %d\n", rdev->desc->name,
		pon_reg->addr, pon_reg->bit);

	value = BIT(pon_reg->bit) & 0xFF;
	rc = qpnp_pon_masked_write(pon_reg->pon, pon_reg->pon->base +
				pon_reg->addr, value, value);
	if (rc)
		dev_err(&pon_reg->pon->spmi->dev, "Unable to write to %x\n",
			pon_reg->pon->base + pon_reg->addr);
	else
		pon_reg->enabled = true;
	return rc;
}

static int pon_spare_regulator_disable(struct regulator_dev *rdev)
{
	int rc = 0;
	u8 mask;
	struct pon_regulator *pon_reg = rdev_get_drvdata(rdev);

	pr_debug("reg %s disable addr: %x bit: %d\n", rdev->desc->name,
		pon_reg->addr, pon_reg->bit);

	mask = BIT(pon_reg->bit) & 0xFF;
	rc = qpnp_pon_masked_write(pon_reg->pon, pon_reg->pon->base +
				pon_reg->addr, mask, 0);
	if (rc)
		dev_err(&pon_reg->pon->spmi->dev, "Unable to write to %x\n",
			pon_reg->pon->base + pon_reg->addr);
	else
		pon_reg->enabled = false;
	return rc;
}

static int pon_spare_regulator_is_enable(struct regulator_dev *rdev)
{
	struct pon_regulator *pon_reg = rdev_get_drvdata(rdev);

	return pon_reg->enabled;
}

struct regulator_ops pon_spare_reg_ops = {
	.enable		= pon_spare_regulator_enable,
	.disable	= pon_spare_regulator_disable,
	.is_enabled	= pon_spare_regulator_is_enable,
};

static int pon_regulator_init(struct qpnp_pon *pon)
{
	int rc = 0, i = 0;
	struct regulator_init_data *init_data;
	struct regulator_config reg_cfg = {};
	struct device_node *node = NULL;
	struct device *dev = &pon->spmi->dev;
	struct pon_regulator *pon_reg;

	if (!pon->num_pon_reg)
		return 0;

	pon->pon_reg_cfg = devm_kcalloc(dev, pon->num_pon_reg,
					sizeof(*(pon->pon_reg_cfg)),
					GFP_KERNEL);

	if (!pon->pon_reg_cfg)
		return -ENOMEM;

	for_each_available_child_of_node(dev->of_node, node) {
		if (!of_find_property(node, "regulator-name", NULL))
			continue;

		pon_reg = &pon->pon_reg_cfg[i++];
		pon_reg->pon = pon;

		rc = of_property_read_u32(node, "qcom,pon-spare-reg-addr",
			&pon_reg->addr);
		if (rc) {
			dev_err(dev, "Unable to read address for regulator, rc=%d\n",
				rc);
			return rc;
		}

		rc = of_property_read_u32(node, "qcom,pon-spare-reg-bit",
			&pon_reg->bit);
		if (rc) {
			dev_err(dev, "Unable to read bit for regulator, rc=%d\n",
				rc);
			return rc;
		}

		init_data = of_get_regulator_init_data(dev, node);
		if (!init_data) {
			dev_err(dev, "regulator init data is missing\n");
			return -EINVAL;
		}
		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_STATUS;

		if (!init_data->constraints.name) {
			dev_err(dev, "regulator-name is missing\n");
			return -EINVAL;
		}

		pon_reg->rdesc.owner = THIS_MODULE;
		pon_reg->rdesc.type = REGULATOR_VOLTAGE;
		pon_reg->rdesc.ops = &pon_spare_reg_ops;
		pon_reg->rdesc.name = init_data->constraints.name;

		reg_cfg.dev = dev;
		reg_cfg.init_data = init_data;
		reg_cfg.driver_data = pon_reg;
		reg_cfg.of_node = node;

		pon_reg->rdev = regulator_register(&pon_reg->rdesc, &reg_cfg);
		if (IS_ERR(pon_reg->rdev)) {
			rc = PTR_ERR(pon_reg->rdev);
			pon_reg->rdev = NULL;
			if (rc != -EPROBE_DEFER)
				dev_err(dev, "regulator_register failed, rc=%d\n",
					rc);
			return rc;
		}
	}
	return rc;
}

static bool dload_on_uvlo;
static bool dload_on_uvlo;


static int qpnp_pon_debugfs_uvlo_dload_get(char *buf,
static int qpnp_pon_debugfs_uvlo_dload_get(char *buf,
@@ -1572,7 +1720,7 @@ static int qpnp_pon_probe(struct spmi_device *spmi)
{
{
	struct qpnp_pon *pon;
	struct qpnp_pon *pon;
	struct resource *pon_resource;
	struct resource *pon_resource;
	struct device_node *itr = NULL;
	struct device_node *node = NULL;
	u32 delay = 0, s3_debounce = 0;
	u32 delay = 0, s3_debounce = 0;
	int rc, sys_reset, index;
	int rc, sys_reset, index;
	u8 pon_sts = 0, buf[2];
	u8 pon_sts = 0, buf[2];
@@ -1607,8 +1755,26 @@ static int qpnp_pon_probe(struct spmi_device *spmi)
	pon->base = pon_resource->start;
	pon->base = pon_resource->start;


	/* get the total number of pon configurations */
	/* get the total number of pon configurations */
	while ((itr = of_get_next_child(spmi->dev.of_node, itr)))
	for_each_available_child_of_node(spmi->dev.of_node, node) {
		if (of_find_property(node, "regulator-name", NULL)) {
			pon->num_pon_reg++;
		} else if (of_find_property(node, "qcom,pon-type", NULL)) {
			pon->num_pon_config++;
			pon->num_pon_config++;
		} else {
			pr_err("Unknown sub-node\n");
			return -EINVAL;
		}
	}

	pr_debug("PON@SID %d: num_pon_config: %d num_pon_reg: %d\n",
		pon->spmi->sid, pon->num_pon_config, pon->num_pon_reg);

	rc = pon_regulator_init(pon);
	if (rc) {
		dev_err(&pon->spmi->dev, "Error in pon_regulator_init rc: %d\n",
			rc);
		return rc;
	}


	if (!pon->num_pon_config)
	if (!pon->num_pon_config)
		/* No PON config., do not register the driver */
		/* No PON config., do not register the driver */