[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