forked from Minki/linux
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: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
cd7f3a249d
commit
d6c3029f32
@ -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);
|
||||
|
||||
return PTR_ERR_OR_ZERO(pcf2127->rtc);
|
||||
if (has_nvmem) {
|
||||
struct nvmem_config nvmem_cfg = {
|
||||
.priv = pcf2127,
|
||||
.reg_read = pcf2127_nvmem_read,
|
||||
.reg_write = pcf2127_nvmem_write,
|
||||
.size = 512,
|
||||
};
|
||||
|
||||
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 },
|
||||
{ }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user