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 /drivers/rtc/sandbox_rtc.c | |
parent | dd18e5d8441e12e4ed084dfe7400112851b807f8 (diff) |
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>
Diffstat (limited to 'drivers/rtc/sandbox_rtc.c')
-rw-r--r-- | drivers/rtc/sandbox_rtc.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/drivers/rtc/sandbox_rtc.c b/drivers/rtc/sandbox_rtc.c new file mode 100644 index 0000000000..f292fbe9b6 --- /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, +}; |