diff options
author | Simon Glass <sjg@chromium.org> | 2015-04-20 12:37:25 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2015-05-05 20:58:40 -0600 |
commit | 5871416640a5ef93ccdfaf391dc6321c5fc2f50a (patch) | |
tree | 7e43decee7a706b0afa01871bafefb60a80920e5 | |
parent | dd18e5d8441e12e4ed084dfe7400112851b807f8 (diff) | |
download | u-boot-5871416640a5ef93ccdfaf391dc6321c5fc2f50a.zip u-boot-5871416640a5ef93ccdfaf391dc6321c5fc2f50a.tar.gz u-boot-5871416640a5ef93ccdfaf391dc6321c5fc2f50a.tar.bz2 |
dm: rtc: sandbox: Add a driver for the sandbox I2C RTC
Add a driver which communicates with the sandbox I2C emulation RTC device
and permits it to be used in U-Boot. This driver is very simple - it just
reads and writes selected I2C registers in the device.
Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | drivers/rtc/Makefile | 3 | ||||
-rw-r--r-- | drivers/rtc/sandbox_rtc.c | 106 |
2 files changed, 109 insertions, 0 deletions
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index aeb705a..9077bb3 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -52,4 +52,7 @@ obj-$(CONFIG_RTC_RTC4543) += rtc4543.o obj-$(CONFIG_RTC_RV3029) += rv3029.o obj-$(CONFIG_RTC_RX8025) += rx8025.o obj-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o +ifdef CONFIG_DM_RTC +obj-$(CONFIG_SANDBOX) += sandbox_rtc.o +endif obj-$(CONFIG_RTC_X1205) += x1205.o diff --git a/drivers/rtc/sandbox_rtc.c b/drivers/rtc/sandbox_rtc.c new file mode 100644 index 0000000..f292fbe --- /dev/null +++ b/drivers/rtc/sandbox_rtc.c @@ -0,0 +1,106 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <i2c.h> +#include <rtc.h> +#include <asm/rtc.h> + +#define REG_COUNT 0x80 + +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; + + return 0; +} + +static int sandbox_rtc_set(struct udevice *dev, const struct rtc_time *time) +{ + 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); + if (ret < 0) + return ret; + + return 0; +} + +static int sandbox_rtc_reset(struct udevice *dev) +{ + return dm_i2c_reg_write(dev, REG_RESET, 0); +} + +static int sandbox_rtc_read8(struct udevice *dev, unsigned int reg) +{ + return dm_i2c_reg_read(dev, reg); +} + +static int sandbox_rtc_write8(struct udevice *dev, unsigned int reg, int val) +{ + return dm_i2c_reg_write(dev, reg, val); +} + +static const struct rtc_ops sandbox_rtc_ops = { + .get = sandbox_rtc_get, + .set = sandbox_rtc_set, + .reset = sandbox_rtc_reset, + .read8 = sandbox_rtc_read8, + .write8 = sandbox_rtc_write8, +}; + +static const struct udevice_id sandbox_rtc_ids[] = { + { .compatible = "sandbox-rtc" }, + { } +}; + +U_BOOT_DRIVER(rtc_sandbox) = { + .name = "rtc-sandbox", + .id = UCLASS_RTC, + .of_match = sandbox_rtc_ids, + .ops = &sandbox_rtc_ops, +}; |