Signed-off-by: Johannes Thumshirn <johannes.thumsh...@men.de>
---
 drivers/rtc/Makefile |   1 +
 drivers/rtc/rx8581.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 181 insertions(+)
 create mode 100644 drivers/rtc/rx8581.c

diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index d5a2725..1502166 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -48,5 +48,6 @@ obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o
 obj-$(CONFIG_RTC_RTC4543) += rtc4543.o
 obj-$(CONFIG_RTC_RV3029) += rv3029.o
 obj-$(CONFIG_RTC_RX8025) += rx8025.o
+obj-$(CONFIG_RTC_RX8581) += rx8581.o
 obj-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o
 obj-$(CONFIG_RTC_X1205) += x1205.o
diff --git a/drivers/rtc/rx8581.c b/drivers/rtc/rx8581.c
new file mode 100644
index 0000000..71466d6
--- /dev/null
+++ b/drivers/rtc/rx8581.c
@@ -0,0 +1,180 @@
+ /*
+ * (C) Copyright 2011
+ * Ralf Truebenbach <ralf.truebenb...@men.de>, MEN Mikro Elektronik GmbH
+ *
+ * Based on: pcf8563.c
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, w...@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Date & Time support for Epson RX8581 RTC
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read(uchar reg);
+static void  rtc_write(uchar reg, uchar val);
+
+/* registers */
+#define RX8581_SEC             0x00
+#define RX8581_MIN             0x01
+#define RX8581_HOUR    0x02
+#define RX8581_WEEK    0x03
+#define RX8581_DAY             0x04
+#define RX8581_MONTH   0x05
+#define RX8581_YEAR    0x06
+#define RX8581_FLAG    0x0E
+#define RX8581_CONTROL 0x0F
+
+/* masks */
+#define RX8581_SEC_MSK         0x7f
+#define RX8581_MIN_MSK         0x7f
+#define RX8581_HOUR_MSK        0x3f
+#define RX8581_WEEK_MSK        0x7f
+#define RX8581_DAY_MSK         0x3f
+#define RX8581_MONTH_MSK       0x1f
+
+/* bits */
+#define RX8581_FLAG_VLF        0x02
+
+#define RX8581_CONTROL_STOP    0x02
+#define RX8581_CONTROL_RESET   0x01
+
+/* ------------------------------------------------------------------------- */
+
+int rtc_get(struct rtc_time *tmp)
+{
+       int rel = 0;
+       uchar sec, min, hour, day, week, month, year, flag;
+
+       sec = rtc_read(RX8581_SEC);
+       min = rtc_read(RX8581_MIN);
+       hour = rtc_read(RX8581_HOUR);
+       week = rtc_read(RX8581_WEEK);
+       day = rtc_read(RX8581_DAY);
+       month = rtc_read(RX8581_MONTH);
+       year = rtc_read(RX8581_YEAR);
+       flag = rtc_read(RX8581_FLAG);
+
+       debug("Get RTC YEAR: 0x%02x MONTH: 0x%02x DAY: 0x%02x WEEK: 0x%02x ",
+             year, month, day, week);
+       debug("HOUR: 0x%02x MIN: 0x%02x SEC: 0x%02x Flag: 0x%02x\n",
+             hour, min, sec, flag);
+       debug("Alarms: MIN: 0x%02x HOUR: 0x%02x WEEK/DAY: 0x%02x\n",
+             rtc_read(0x08), rtc_read(0x09), rtc_read(0x0A));
+
+       if (flag & RX8581_FLAG_VLF) {
+               puts("## Warning: RTC Low Voltage - date/time not reliable\n");
+               rel = -1;
+       }
+
+       tmp->tm_sec   = bcd2bin(sec & RX8581_SEC_MSK);
+       tmp->tm_min   = bcd2bin(min & RX8581_MIN_MSK);
+       tmp->tm_hour  = bcd2bin(hour & RX8581_HOUR_MSK);
+       tmp->tm_mday  = bcd2bin(day & RX8581_DAY_MSK);
+       tmp->tm_mon   = bcd2bin(month & RX8581_MONTH_MSK);
+       tmp->tm_year  = bcd2bin(year) + (bcd2bin(year) >= 70 ? 1900 : 2000);
+       tmp->tm_wday  = __ilog2(week & RX8581_WEEK_MSK);
+       tmp->tm_yday  = 0;
+       tmp->tm_isdst = 0;
+
+       debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+             tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+             tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       return rel;
+}
+
+int rtc_set(struct rtc_time *tmp)
+{
+       uchar reg;
+
+       debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+             tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+             tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+       if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+               puts("## Warning: year should be between 1970 and 2069!\n");
+
+       /* stop */
+       reg = rtc_read(RX8581_CONTROL);
+       rtc_write(RX8581_CONTROL, reg | RX8581_CONTROL_STOP);
+
+       /* write data */
+       rtc_write(RX8581_SEC, bin2bcd(tmp->tm_sec));
+       rtc_write(RX8581_MIN, bin2bcd(tmp->tm_min));
+       rtc_write(RX8581_HOUR, bin2bcd(tmp->tm_hour));
+       rtc_write(RX8581_WEEK, bin2bcd(0x1 << tmp->tm_wday));
+       rtc_write(RX8581_DAY, bin2bcd(tmp->tm_mday));
+       rtc_write(RX8581_MONTH, bin2bcd(tmp->tm_mon));
+       rtc_write(RX8581_YEAR, bin2bcd(tmp->tm_year % 100));
+
+       /* clear VLF */
+       reg = rtc_read(RX8581_FLAG);
+       rtc_write(RX8581_FLAG, reg & ~RX8581_FLAG_VLF);
+
+       /* restart */
+       reg = rtc_read(RX8581_CONTROL);
+       rtc_write(RX8581_CONTROL, reg & ~RX8581_CONTROL_STOP);
+
+       return 0;
+}
+
+void rtc_reset(void)
+{
+       struct rtc_time tmp;
+
+       /* reset device */
+       rtc_write(0x0F, 0x03);
+       rtc_write(0x0F, 0x00);
+
+       /* reset time */
+       tmp.tm_year = 1970;
+       tmp.tm_mon = 1;
+       tmp.tm_mday = 1;
+       tmp.tm_hour = 0;
+       tmp.tm_min = 0;
+       tmp.tm_sec = 0;
+
+       rtc_set(&tmp);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read(uchar reg)
+{
+       return i2c_reg_read(CONFIG_SYS_I2C_RTC_ADDR, reg);
+}
+
+static void rtc_write(uchar reg, uchar val)
+{
+       i2c_reg_write(CONFIG_SYS_I2C_RTC_ADDR, reg, val);
+}
+
+#endif
-- 
1.9.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to