summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrent Piepho <tpiepho@impinj.com>2019-02-11 21:34:05 -0500
committerAlexandre Belloni <alexandre.belloni@bootlin.com>2019-02-17 15:29:10 -0500
commitc3544f6f51edcac4040dd78b9e9d2ece48e2ac0b (patch)
tree4cabd8f0d1245697abcdad339cfea6da14f4493d
parent5909b87db8ef0df4e11363afc53ed788b7ea17cb (diff)
rtc: isl1208: Add new style nvmem support to driver
Add support for the RTC's NVRAM using the standard nvmem support that is part of the Linux RTC framework. This driver already has a sysfs attribute that provides access to the RTC's NVRAM as a single 16-bit value. Some chips have more than two bytes of NVRAM, so this will not work for them. It's also non-standard. This sysfs attribute is left in for backward compatibility, but will only be able to read the first two bytes of NVRAM. The nvmem interface will allow access to all NVRAM, e.g. eight bytes on the isl1218. Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Trent Piepho <tpiepho@impinj.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-rw-r--r--drivers/rtc/rtc-isl1208.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index 036e5fc148d4..471e395b20db 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -115,6 +115,7 @@ MODULE_DEVICE_TABLE(of, isl1208_of_match);
115 115
116/* Device state */ 116/* Device state */
117struct isl1208_state { 117struct isl1208_state {
118 struct nvmem_config nvmem_config;
118 struct rtc_device *rtc; 119 struct rtc_device *rtc;
119 const struct isl1208_config *config; 120 const struct isl1208_config *config;
120}; 121};
@@ -742,6 +743,46 @@ static const struct attribute_group isl1219_rtc_sysfs_files = {
742 .attrs = isl1219_rtc_attrs, 743 .attrs = isl1219_rtc_attrs,
743}; 744};
744 745
746static int isl1208_nvmem_read(void *priv, unsigned int off, void *buf,
747 size_t count)
748{
749 struct isl1208_state *isl1208 = priv;
750 struct i2c_client *client = to_i2c_client(isl1208->rtc->dev.parent);
751 int ret;
752
753 /* nvmem sanitizes offset/count for us, but count==0 is possible */
754 if (!count)
755 return count;
756 ret = isl1208_i2c_read_regs(client, ISL1208_REG_USR1 + off, buf,
757 count);
758 return ret == 0 ? count : ret;
759}
760
761static int isl1208_nvmem_write(void *priv, unsigned int off, void *buf,
762 size_t count)
763{
764 struct isl1208_state *isl1208 = priv;
765 struct i2c_client *client = to_i2c_client(isl1208->rtc->dev.parent);
766 int ret;
767
768 /* nvmem sanitizes off/count for us, but count==0 is possible */
769 if (!count)
770 return count;
771 ret = isl1208_i2c_set_regs(client, ISL1208_REG_USR1 + off, buf,
772 count);
773
774 return ret == 0 ? count : ret;
775}
776
777static const struct nvmem_config isl1208_nvmem_config = {
778 .name = "isl1208_nvram",
779 .word_size = 1,
780 .stride = 1,
781 /* .size from chip specific config */
782 .reg_read = isl1208_nvmem_read,
783 .reg_write = isl1208_nvmem_write,
784};
785
745static int isl1208_setup_irq(struct i2c_client *client, int irq) 786static int isl1208_setup_irq(struct i2c_client *client, int irq)
746{ 787{
747 int rc = devm_request_threaded_irq(&client->dev, irq, NULL, 788 int rc = devm_request_threaded_irq(&client->dev, irq, NULL,
@@ -796,6 +837,11 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
796 837
797 isl1208->rtc->ops = &isl1208_rtc_ops; 838 isl1208->rtc->ops = &isl1208_rtc_ops;
798 839
840 /* Setup nvmem configuration in driver state struct */
841 isl1208->nvmem_config = isl1208_nvmem_config;
842 isl1208->nvmem_config.size = isl1208->config->nvmem_length;
843 isl1208->nvmem_config.priv = isl1208;
844
799 rc = isl1208_i2c_get_sr(client); 845 rc = isl1208_i2c_get_sr(client);
800 if (rc < 0) { 846 if (rc < 0) {
801 dev_err(&client->dev, "reading status failed\n"); 847 dev_err(&client->dev, "reading status failed\n");
@@ -849,6 +895,10 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
849 if (rc) 895 if (rc)
850 return rc; 896 return rc;
851 897
898 rc = rtc_nvmem_register(isl1208->rtc, &isl1208->nvmem_config);
899 if (rc)
900 return rc;
901
852 return rtc_register_device(isl1208->rtc); 902 return rtc_register_device(isl1208->rtc);
853} 903}
854 904