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

Commit 665d78a1 authored by Guru Das Srinagesh's avatar Guru Das Srinagesh
Browse files

pwm: qti-lpg: Support two-nvmem PPG scheme



On PMICs such as PM8350C, the lookup table containing the pattern data
is stored in a separate nvmem device from the one where the per-channel
data is stored.

Add two separate nvmems to handle this case while maintaining backward
compatibility for those targets that use only a single nvmem device.
Differentiate between the two schemes via an enum.

Change-Id: I2826a9acc8cee4d83b6cf2bf2d4d60b1ec3b67d7
Signed-off-by: default avatarGuru Das Srinagesh <gurus@codeaurora.org>
parent f5e30025
Loading
Loading
Loading
Loading
+50 −18
Original line number Diff line number Diff line
@@ -191,7 +191,8 @@ struct qpnp_lpg_chip {
	struct qpnp_lpg_lut	*lut;
	struct mutex		bus_lock;
	u32			*lpg_group;
	struct nvmem_device	*sdam_nvmem;
	struct nvmem_device	*lpg_chan_nvmem;
	struct nvmem_device	*lut_nvmem;
	struct device_node	*pbs_dev_node;
	u32			num_lpgs;
	unsigned long		pbs_en_bitmap;
@@ -275,12 +276,13 @@ static int qpnp_lut_masked_write(struct qpnp_lpg_lut *lut,
	return rc;
}

static int qpnp_sdam_write(struct qpnp_lpg_chip *chip, u16 addr, u8 val)
static int qpnp_lpg_chan_nvmem_write(struct qpnp_lpg_chip *chip, u16 addr,
				    u8 val)
{
	int rc;

	mutex_lock(&chip->bus_lock);
	rc = nvmem_device_write(chip->sdam_nvmem, addr, 1, &val);
	rc = nvmem_device_write(chip->lpg_chan_nvmem, addr, 1, &val);
	if (rc < 0)
		dev_err(chip->dev, "write SDAM add 0x%x failed, rc=%d\n",
				addr, rc);
@@ -296,7 +298,7 @@ static int qpnp_lpg_sdam_write(struct qpnp_lpg_channel *lpg, u16 addr, u8 val)
	int rc;

	mutex_lock(&chip->bus_lock);
	rc = nvmem_device_write(chip->sdam_nvmem,
	rc = nvmem_device_write(chip->lpg_chan_nvmem,
			lpg->lpg_sdam_base + addr, 1, &val);
	if (rc < 0)
		dev_err(chip->dev, "write SDAM add 0x%x failed, rc=%d\n",
@@ -316,7 +318,7 @@ static int qpnp_lpg_sdam_masked_write(struct qpnp_lpg_channel *lpg,

	mutex_lock(&chip->bus_lock);

	rc = nvmem_device_read(chip->sdam_nvmem,
	rc = nvmem_device_read(chip->lpg_chan_nvmem,
			lpg->lpg_sdam_base + addr, 1, &tmp);
	if (rc < 0) {
		dev_err(chip->dev, "Read SDAM addr %d failed, rc=%d\n",
@@ -326,7 +328,7 @@ static int qpnp_lpg_sdam_masked_write(struct qpnp_lpg_channel *lpg,

	tmp = tmp & ~mask;
	tmp |= val & mask;
	rc = nvmem_device_write(chip->sdam_nvmem,
	rc = nvmem_device_write(chip->lpg_chan_nvmem,
			lpg->lpg_sdam_base + addr, 1, &tmp);
	if (rc < 0)
		dev_err(chip->dev, "write SDAM addr %d failed, rc=%d\n",
@@ -348,7 +350,7 @@ static int qpnp_lut_sdam_write(struct qpnp_lpg_lut *lut,
		return -EINVAL;

	mutex_lock(&chip->bus_lock);
	rc = nvmem_device_write(chip->sdam_nvmem,
	rc = nvmem_device_write(chip->lut_nvmem,
			lut->reg_base + addr, length, val);
	if (rc < 0)
		dev_err(chip->dev, "write SDAM addr %d failed, rc=%d\n",
@@ -534,7 +536,7 @@ static int qpnp_lpg_set_sdam_ramp_config(struct qpnp_lpg_channel *lpg)
	if (val > 0)
		val--;
	addr = SDAM_REG_RAMP_STEP_DURATION;
	rc = qpnp_sdam_write(lpg->chip, addr, val);
	rc = qpnp_lpg_chan_nvmem_write(lpg->chip, addr, val);
	if (rc < 0) {
		dev_err(lpg->chip->dev, "Write SDAM_REG_RAMP_STEP_DURATION failed, rc=%d\n",
				rc);
@@ -887,8 +889,8 @@ static int qpnp_lpg_pbs_trigger_enable(struct qpnp_lpg_channel *lpg, bool en)

	if (en) {
		if (chip->pbs_en_bitmap == 0) {
			rc = qpnp_sdam_write(chip, SDAM_REG_PBS_SEQ_EN,
					PBS_SW_TRG_BIT);
			rc = qpnp_lpg_chan_nvmem_write(chip,
					SDAM_REG_PBS_SEQ_EN, PBS_SW_TRG_BIT);
			if (rc < 0) {
				dev_err(chip->dev, "Write SDAM_REG_PBS_SEQ_EN failed, rc=%d\n",
						rc);
@@ -907,7 +909,8 @@ static int qpnp_lpg_pbs_trigger_enable(struct qpnp_lpg_channel *lpg, bool en)
	} else {
		clear_bit(lpg->lpg_idx, &chip->pbs_en_bitmap);
		if (chip->pbs_en_bitmap == 0) {
			rc = qpnp_sdam_write(chip, SDAM_REG_PBS_SEQ_EN, 0);
			rc = qpnp_lpg_chan_nvmem_write(chip,
					SDAM_REG_PBS_SEQ_EN, 0);
			if (rc < 0) {
				dev_err(chip->dev, "Write SDAM_REG_PBS_SEQ_EN failed, rc=%d\n",
						rc);
@@ -1449,6 +1452,40 @@ static bool lut_is_defined(struct qpnp_lpg_chip *chip, const __be32 **addr)
	return true;
}

static int qpnp_lpg_get_nvmem_dt(struct qpnp_lpg_chip *chip)
{
	int rc = 0;
	struct nvmem_device *ppg_nv, *lut_nv, *lpg_nv;

	/* Ensure backward compatibility */
	ppg_nv = devm_nvmem_device_get(chip->dev, "ppg_sdam");
	if (IS_ERR(ppg_nv)) {
		lut_nv = devm_nvmem_device_get(chip->dev, "lut_sdam");
		if (IS_ERR(lut_nv)) {
			rc = PTR_ERR(lut_nv);
			goto err;
		}

		lpg_nv = devm_nvmem_device_get(chip->dev, "lpg_chan_sdam");
		if (IS_ERR(lpg_nv)) {
			rc = PTR_ERR(lpg_nv);
			goto err;
		}

		chip->lut_nvmem = lut_nv;
		chip->lpg_chan_nvmem = lpg_nv;
	} else {
		chip->lut_nvmem = chip->lpg_chan_nvmem = ppg_nv;
	}

	return 0;
err:
	if (rc != -EPROBE_DEFER)
		dev_err(chip->dev, "Failed to get nvmem device, rc=%d\n",
				rc);
	return rc;
}

static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip)
{
	int rc = 0, i;
@@ -1483,14 +1520,9 @@ static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip)
		if (!chip->lut)
			return -ENOMEM;

		chip->sdam_nvmem = devm_nvmem_device_get(chip->dev, "ppg_sdam");
		if (IS_ERR_OR_NULL(chip->sdam_nvmem)) {
			rc = PTR_ERR(chip->sdam_nvmem);
			if (rc != -EPROBE_DEFER)
				dev_err(chip->dev, "Failed to get nvmem device, rc=%d\n",
					rc);
		rc = qpnp_lpg_get_nvmem_dt(chip);
		if (rc < 0)
			return rc;
		}

		chip->use_sdam = true;
		chip->pbs_dev_node = of_parse_phandle(chip->dev->of_node,