[U-Boot] [PATCH] Add Epson RX8581 RTC support
Johannes Thumshirn
johannes.thumshirn at men.de
Wed Jun 25 14:31:28 CEST 2014
Signed-off-by: Johannes Thumshirn <johannes.thumshirn at 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.truebenbach at men.de>, MEN Mikro Elektronik GmbH
+ *
+ * Based on: pcf8563.c
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd at 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
More information about the U-Boot
mailing list