aboutsummaryrefslogtreecommitdiff
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/i2c_rtc_emul.c3
-rw-r--r--drivers/rtc/pcf2127.c13
-rw-r--r--drivers/rtc/rtc-uclass.c59
-rw-r--r--drivers/rtc/sandbox_rtc.c65
4 files changed, 91 insertions, 49 deletions
diff --git a/drivers/rtc/i2c_rtc_emul.c b/drivers/rtc/i2c_rtc_emul.c
index a010af411b..7f78ff83cb 100644
--- a/drivers/rtc/i2c_rtc_emul.c
+++ b/drivers/rtc/i2c_rtc_emul.c
@@ -197,7 +197,8 @@ static int sandbox_i2c_rtc_xfer(struct udevice *emul, struct i2c_msg *msg,
/* Write the register */
memcpy(plat->reg + offset, ptr, len);
- if (offset == REG_RESET)
+ /* If the reset register was written to, do reset. */
+ if (offset <= REG_RESET && REG_RESET < offset + len)
reset_time(emul);
}
}
diff --git a/drivers/rtc/pcf2127.c b/drivers/rtc/pcf2127.c
index c423960b34..88ff8c52c3 100644
--- a/drivers/rtc/pcf2127.c
+++ b/drivers/rtc/pcf2127.c
@@ -23,8 +23,7 @@
#define PCF2127_REG_MO 0x08
#define PCF2127_REG_YR 0x09
-static int pcf2127_read_reg(struct udevice *dev, uint offset,
- u8 *buffer, int len)
+static int pcf2127_rtc_read(struct udevice *dev, uint offset, u8 *buffer, uint len)
{
struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
struct i2c_msg msg;
@@ -44,6 +43,12 @@ static int pcf2127_read_reg(struct udevice *dev, uint offset,
return dm_i2c_xfer(dev, &msg, 1);
}
+static int pcf2127_rtc_write(struct udevice *dev, uint offset,
+ const u8 *buffer, uint len)
+{
+ return dm_i2c_write(dev, offset, buffer, len);
+}
+
static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm)
{
uchar buf[7] = {0};
@@ -73,7 +78,7 @@ static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm)
int ret = 0;
uchar buf[10] = { PCF2127_REG_CTRL1 };
- ret = pcf2127_read_reg(dev, PCF2127_REG_CTRL1, buf, sizeof(buf));
+ ret = pcf2127_rtc_read(dev, PCF2127_REG_CTRL1, buf, sizeof(buf));
if (ret < 0)
return ret;
@@ -110,6 +115,8 @@ static const struct rtc_ops pcf2127_rtc_ops = {
.get = pcf2127_rtc_get,
.set = pcf2127_rtc_set,
.reset = pcf2127_rtc_reset,
+ .read = pcf2127_rtc_read,
+ .write = pcf2127_rtc_write,
};
static const struct udevice_id pcf2127_rtc_ids[] = {
diff --git a/drivers/rtc/rtc-uclass.c b/drivers/rtc/rtc-uclass.c
index 926cca234e..8035f7fe9c 100644
--- a/drivers/rtc/rtc-uclass.c
+++ b/drivers/rtc/rtc-uclass.c
@@ -40,24 +40,75 @@ int dm_rtc_reset(struct udevice *dev)
return ops->reset(dev);
}
-int rtc_read8(struct udevice *dev, unsigned int reg)
+int dm_rtc_read(struct udevice *dev, unsigned int reg, u8 *buf, unsigned int len)
{
struct rtc_ops *ops = rtc_get_ops(dev);
assert(ops);
+ if (ops->read)
+ return ops->read(dev, reg, buf, len);
if (!ops->read8)
return -ENOSYS;
- return ops->read8(dev, reg);
+ while (len--) {
+ int ret = ops->read8(dev, reg++);
+
+ if (ret < 0)
+ return ret;
+ *buf++ = ret;
+ }
+ return 0;
}
-int rtc_write8(struct udevice *dev, unsigned int reg, int val)
+int dm_rtc_write(struct udevice *dev, unsigned int reg,
+ const u8 *buf, unsigned int len)
{
struct rtc_ops *ops = rtc_get_ops(dev);
assert(ops);
+ if (ops->write)
+ return ops->write(dev, reg, buf, len);
if (!ops->write8)
return -ENOSYS;
- return ops->write8(dev, reg, val);
+ while (len--) {
+ int ret = ops->write8(dev, reg++, *buf++);
+
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+int rtc_read8(struct udevice *dev, unsigned int reg)
+{
+ struct rtc_ops *ops = rtc_get_ops(dev);
+
+ assert(ops);
+ if (ops->read8)
+ return ops->read8(dev, reg);
+ if (ops->read) {
+ u8 buf[1];
+ int ret = ops->read(dev, reg, buf, 1);
+
+ if (ret < 0)
+ return ret;
+ return buf[0];
+ }
+ return -ENOSYS;
+}
+
+int rtc_write8(struct udevice *dev, unsigned int reg, int val)
+{
+ struct rtc_ops *ops = rtc_get_ops(dev);
+
+ assert(ops);
+ if (ops->write8)
+ return ops->write8(dev, reg, val);
+ if (ops->write) {
+ u8 buf[1] = { val };
+
+ return ops->write(dev, reg, buf, 1);
+ }
+ return -ENOSYS;
}
int rtc_read16(struct udevice *dev, unsigned int reg, u16 *valuep)
diff --git a/drivers/rtc/sandbox_rtc.c b/drivers/rtc/sandbox_rtc.c
index b08d758a74..77065e49c7 100644
--- a/drivers/rtc/sandbox_rtc.c
+++ b/drivers/rtc/sandbox_rtc.c
@@ -14,55 +14,38 @@
static int sandbox_rtc_get(struct udevice *dev, struct rtc_time *time)
{
- time->tm_sec = dm_i2c_reg_read(dev, REG_SEC);
- if (time->tm_sec < 0)
- return time->tm_sec;
- time->tm_min = dm_i2c_reg_read(dev, REG_MIN);
- if (time->tm_min < 0)
- return time->tm_min;
- time->tm_hour = dm_i2c_reg_read(dev, REG_HOUR);
- if (time->tm_hour < 0)
- return time->tm_hour;
- time->tm_mday = dm_i2c_reg_read(dev, REG_MDAY);
- if (time->tm_mday < 0)
- return time->tm_mday;
- time->tm_mon = dm_i2c_reg_read(dev, REG_MON);
- if (time->tm_mon < 0)
- return time->tm_mon;
- time->tm_year = dm_i2c_reg_read(dev, REG_YEAR);
- if (time->tm_year < 0)
- return time->tm_year;
- time->tm_year += 1900;
- time->tm_wday = dm_i2c_reg_read(dev, REG_WDAY);
- if (time->tm_wday < 0)
- return time->tm_wday;
+ u8 buf[7];
+ int ret;
+
+ ret = dm_i2c_read(dev, REG_SEC, buf, sizeof(buf));
+ if (ret < 0)
+ return ret;
+
+ time->tm_sec = buf[REG_SEC - REG_SEC];
+ time->tm_min = buf[REG_MIN - REG_SEC];
+ time->tm_hour = buf[REG_HOUR - REG_SEC];
+ time->tm_mday = buf[REG_MDAY - REG_SEC];
+ time->tm_mon = buf[REG_MON - REG_SEC];
+ time->tm_year = buf[REG_YEAR - REG_SEC] + 1900;
+ time->tm_wday = buf[REG_WDAY - REG_SEC];
return 0;
}
static int sandbox_rtc_set(struct udevice *dev, const struct rtc_time *time)
{
+ u8 buf[7];
int ret;
- ret = dm_i2c_reg_write(dev, REG_SEC, time->tm_sec);
- if (ret < 0)
- return ret;
- ret = dm_i2c_reg_write(dev, REG_MIN, time->tm_min);
- if (ret < 0)
- return ret;
- ret = dm_i2c_reg_write(dev, REG_HOUR, time->tm_hour);
- if (ret < 0)
- return ret;
- ret = dm_i2c_reg_write(dev, REG_MDAY, time->tm_mday);
- if (ret < 0)
- return ret;
- ret = dm_i2c_reg_write(dev, REG_MON, time->tm_mon);
- if (ret < 0)
- return ret;
- ret = dm_i2c_reg_write(dev, REG_YEAR, time->tm_year - 1900);
- if (ret < 0)
- return ret;
- ret = dm_i2c_reg_write(dev, REG_WDAY, time->tm_wday);
+ buf[REG_SEC - REG_SEC] = time->tm_sec;
+ buf[REG_MIN - REG_SEC] = time->tm_min;
+ buf[REG_HOUR - REG_SEC] = time->tm_hour;
+ buf[REG_MDAY - REG_SEC] = time->tm_mday;
+ buf[REG_MON - REG_SEC] = time->tm_mon;
+ buf[REG_YEAR - REG_SEC] = time->tm_year - 1900;
+ buf[REG_WDAY - REG_SEC] = time->tm_wday;
+
+ ret = dm_i2c_write(dev, REG_SEC, buf, sizeof(buf));
if (ret < 0)
return ret;