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

Commit d6c3029f authored by Uwe Kleine-König's avatar Uwe Kleine-König Committed by Alexandre Belloni
Browse files

rtc: pcf2127: add support for accessing internal static RAM



The PCF2127 has 512 bytes of internal static RAM and this patch expands
the driver to access this memory.

Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent cd7f3a24
Loading
Loading
Loading
Loading
+62 −6
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@
#define PCF2127_REG_MO          (0x08)
#define PCF2127_REG_YR          (0x09)

/* the pcf2127 has 512 bytes nvmem, pcf2129 doesn't */
#define PCF2127_REG_RAM_addr_MSB       0x1a
#define PCF2127_REG_RAM_wrt_cmd        0x1c
#define PCF2127_REG_RAM_rd_cmd         0x1d

#define PCF2127_OSF             BIT(7)  /* Oscillator Fail flag */

struct pcf2127 {
@@ -183,10 +188,47 @@ static const struct rtc_class_ops pcf2127_rtc_ops = {
	.set_time	= pcf2127_rtc_set_time,
};

static int pcf2127_nvmem_read(void *priv, unsigned int offset,
			      void *val, size_t bytes)
{
	struct pcf2127 *pcf2127 = priv;
	int ret;
	unsigned char offsetbuf[] = { offset >> 8, offset };

	ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB,
				offsetbuf, 2);
	if (ret)
		return ret;

	ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_rd_cmd,
			       val, bytes);

	return ret ?: bytes;
}

static int pcf2127_nvmem_write(void *priv, unsigned int offset,
			       void *val, size_t bytes)
{
	struct pcf2127 *pcf2127 = priv;
	int ret;
	unsigned char offsetbuf[] = { offset >> 8, offset };

	ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB,
				offsetbuf, 2);
	if (ret)
		return ret;

	ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_wrt_cmd,
				val, bytes);

	return ret ?: bytes;
}

static int pcf2127_probe(struct device *dev, struct regmap *regmap,
			const char *name)
			const char *name, bool has_nvmem)
{
	struct pcf2127 *pcf2127;
	int ret = 0;

	dev_dbg(dev, "%s\n", __func__);

@@ -200,8 +242,21 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,

	pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops,
						THIS_MODULE);
	if (IS_ERR(pcf2127->rtc))
		return PTR_ERR(pcf2127->rtc);

	if (has_nvmem) {
		struct nvmem_config nvmem_cfg = {
			.priv = pcf2127,
			.reg_read = pcf2127_nvmem_read,
			.reg_write = pcf2127_nvmem_write,
			.size = 512,
		};

	return PTR_ERR_OR_ZERO(pcf2127->rtc);
		ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg);
	}

	return ret;
}

#ifdef CONFIG_OF
@@ -309,11 +364,11 @@ static int pcf2127_i2c_probe(struct i2c_client *client,
	}

	return pcf2127_probe(&client->dev, regmap,
				pcf2127_i2c_driver.driver.name);
			     pcf2127_i2c_driver.driver.name, id->driver_data);
}

static const struct i2c_device_id pcf2127_i2c_id[] = {
	{ "pcf2127", 0 },
	{ "pcf2127", 1 },
	{ "pcf2129", 0 },
	{ }
};
@@ -372,11 +427,12 @@ static int pcf2127_spi_probe(struct spi_device *spi)
		return PTR_ERR(regmap);
	}

	return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name);
	return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name,
			     spi_get_device_id(spi)->driver_data);
}

static const struct spi_device_id pcf2127_spi_id[] = {
	{ "pcf2127", 0 },
	{ "pcf2127", 1 },
	{ "pcf2129", 0 },
	{ }
};