2 * Epson RX8010 RTC driver.
4 * Copyright (c) 2017, General Electric Company
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 /*---------------------------------------------------------------------*/
26 /* #undef DEBUG_RTC */
29 #define DEBUGR(fmt, args...) printf(fmt, ##args)
31 #define DEBUGR(fmt, args...)
33 /*---------------------------------------------------------------------*/
35 #ifndef CONFIG_SYS_I2C_RTC_ADDR
36 # define CONFIG_SYS_I2C_RTC_ADDR 0x32
40 * RTC register addresses
42 #define RX8010_SEC 0x10
43 #define RX8010_MIN 0x11
44 #define RX8010_HOUR 0x12
45 #define RX8010_WDAY 0x13
46 #define RX8010_MDAY 0x14
47 #define RX8010_MONTH 0x15
48 #define RX8010_YEAR 0x16
49 #define RX8010_YEAR 0x16
50 #define RX8010_RESV17 0x17
51 #define RX8010_ALMIN 0x18
52 #define RX8010_ALHOUR 0x19
53 #define RX8010_ALWDAY 0x1A
54 #define RX8010_TCOUNT0 0x1B
55 #define RX8010_TCOUNT1 0x1C
56 #define RX8010_EXT 0x1D
57 #define RX8010_FLAG 0x1E
58 #define RX8010_CTRL 0x1F
59 /* 0x20 to 0x2F are user registers */
60 #define RX8010_RESV30 0x30
61 #define RX8010_RESV31 0x32
62 #define RX8010_IRQ 0x32
64 #define RX8010_EXT_WADA BIT(3)
66 #define RX8010_FLAG_VLF BIT(1)
67 #define RX8010_FLAG_AF BIT(3)
68 #define RX8010_FLAG_TF BIT(4)
69 #define RX8010_FLAG_UF BIT(5)
71 #define RX8010_CTRL_AIE BIT(3)
72 #define RX8010_CTRL_UIE BIT(5)
73 #define RX8010_CTRL_STOP BIT(6)
74 #define RX8010_CTRL_TEST BIT(7)
76 #define RX8010_ALARM_AE BIT(7)
80 #define DEV_TYPE struct udevice
89 #define DEV_TYPE struct ludevice
93 static int rx8010sj_rtc_read8(DEV_TYPE *dev, unsigned int reg)
99 ret = dm_i2c_read(dev, reg, &val, sizeof(val));
101 ret = i2c_read(dev->chip, reg, 1, &val, 1);
104 return ret < 0 ? ret : val;
107 static int rx8010sj_rtc_write8(DEV_TYPE *dev, unsigned int reg, int val)
113 ret = dm_i2c_write(dev, reg, &lval, 1);
115 ret = i2c_write(dev->chip, reg, 1, &lval, 1);
118 return ret < 0 ? ret : 0;
121 static int validate_time(const struct rtc_time *tm)
123 if ((tm->tm_year < 2000) || (tm->tm_year > 2099))
126 if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
129 if ((tm->tm_mday < 1) || (tm->tm_mday > 31))
132 if ((tm->tm_wday < 0) || (tm->tm_wday > 6))
135 if ((tm->tm_hour < 0) || (tm->tm_hour > 23))
138 if ((tm->tm_min < 0) || (tm->tm_min > 59))
141 if ((tm->tm_sec < 0) || (tm->tm_sec > 59))
147 void rx8010sj_rtc_init(DEV_TYPE *dev)
150 int need_clear = 0, ret = 0;
152 /* Initialize reserved registers as specified in datasheet */
153 ret = rx8010sj_rtc_write8(dev, RX8010_RESV17, 0xD8);
157 ret = rx8010sj_rtc_write8(dev, RX8010_RESV30, 0x00);
161 ret = rx8010sj_rtc_write8(dev, RX8010_RESV31, 0x08);
165 ret = rx8010sj_rtc_write8(dev, RX8010_IRQ, 0x00);
169 for (int i = 0; i < 2; i++) {
170 ret = rx8010sj_rtc_read8(dev, RX8010_FLAG + i);
177 if (ctrl[0] & RX8010_FLAG_VLF)
178 printf("RTC low voltage detected\n");
180 if (ctrl[0] & RX8010_FLAG_AF) {
181 printf("Alarm was detected\n");
185 if (ctrl[0] & RX8010_FLAG_TF)
188 if (ctrl[0] & RX8010_FLAG_UF)
192 ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
193 ret = rx8010sj_rtc_write8(dev, RX8010_FLAG, ctrl[0]);
201 printf("Error rtc init.\n");
204 /* Get the current time from the RTC */
205 static int rx8010sj_rtc_get(DEV_TYPE *dev, struct rtc_time *tmp)
211 flagreg = rx8010sj_rtc_read8(dev, RX8010_FLAG);
213 DEBUGR("Error reading from RTC. err: %d\n", flagreg);
217 if (flagreg & RX8010_FLAG_VLF) {
218 DEBUGR("RTC low voltage detected\n");
222 for (int i = 0; i < 7; i++) {
223 ret = rx8010sj_rtc_read8(dev, RX8010_SEC + i);
225 DEBUGR("Error reading from RTC. err: %d\n", ret);
231 tmp->tm_sec = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f);
232 tmp->tm_min = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f);
233 tmp->tm_hour = bcd2bin(date[RX8010_HOUR - RX8010_SEC] & 0x3f);
234 tmp->tm_mday = bcd2bin(date[RX8010_MDAY - RX8010_SEC] & 0x3f);
235 tmp->tm_mon = bcd2bin(date[RX8010_MONTH - RX8010_SEC] & 0x1f);
236 tmp->tm_year = bcd2bin(date[RX8010_YEAR - RX8010_SEC]) + 2000;
241 DEBUGR("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
242 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
243 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
249 static int rx8010sj_rtc_set(DEV_TYPE *dev, const struct rtc_time *tm)
255 ret = validate_time(tm);
259 /* set STOP bit before changing clock/calendar */
260 ctrl = rx8010sj_rtc_read8(dev, RX8010_CTRL);
263 ret = rx8010sj_rtc_write8(dev, RX8010_CTRL, ctrl | RX8010_CTRL_STOP);
267 date[RX8010_SEC - RX8010_SEC] = bin2bcd(tm->tm_sec);
268 date[RX8010_MIN - RX8010_SEC] = bin2bcd(tm->tm_min);
269 date[RX8010_HOUR - RX8010_SEC] = bin2bcd(tm->tm_hour);
270 date[RX8010_MDAY - RX8010_SEC] = bin2bcd(tm->tm_mday);
271 date[RX8010_MONTH - RX8010_SEC] = bin2bcd(tm->tm_mon);
272 date[RX8010_YEAR - RX8010_SEC] = bin2bcd(tm->tm_year - 2000);
273 date[RX8010_WDAY - RX8010_SEC] = bin2bcd(tm->tm_wday);
275 for (int i = 0; i < 7; i++) {
276 ret = rx8010sj_rtc_write8(dev, RX8010_SEC + i, date[i]);
278 DEBUGR("Error writing to RTC. err: %d\n", ret);
283 /* clear STOP bit after changing clock/calendar */
284 ctrl = rx8010sj_rtc_read8(dev, RX8010_CTRL);
288 ret = rx8010sj_rtc_write8(dev, RX8010_CTRL, ctrl & ~RX8010_CTRL_STOP);
292 flagreg = rx8010sj_rtc_read8(dev, RX8010_FLAG);
296 if (flagreg & RX8010_FLAG_VLF)
297 ret = rx8010sj_rtc_write8(dev, RX8010_FLAG,
298 flagreg & ~RX8010_FLAG_VLF);
304 static int rx8010sj_rtc_reset(DEV_TYPE *dev)
310 #ifndef CONFIG_DM_RTC
312 int rtc_get(struct rtc_time *tm)
314 struct ludevice dev = {
315 .chip = CONFIG_SYS_I2C_RTC_ADDR,
318 return rx8010sj_rtc_get(&dev, tm);
321 int rtc_set(struct rtc_time *tm)
323 struct ludevice dev = {
324 .chip = CONFIG_SYS_I2C_RTC_ADDR,
327 return rx8010sj_rtc_set(&dev, tm);
332 struct ludevice dev = {
333 .chip = CONFIG_SYS_I2C_RTC_ADDR,
336 rx8010sj_rtc_reset(&dev);
341 struct ludevice dev = {
342 .chip = CONFIG_SYS_I2C_RTC_ADDR,
345 rx8010sj_rtc_init(&dev);
350 static int rx8010sj_probe(struct udevice *dev)
352 rx8010sj_rtc_init(&dev);
357 static const struct rtc_ops rx8010sj_rtc_ops = {
358 .get = rx8010sj_rtc_get,
359 .set = rx8010sj_rtc_set,
360 .read8 = rx8010sj_rtc_read8,
361 .write8 = rx8010sj_rtc_write8,
362 .reset = rx8010sj_rtc_reset,
365 static const struct udevice_id rx8010sj_rtc_ids[] = {
366 { .compatible = "epson,rx8010sj-rtc" },
370 U_BOOT_DRIVER(rx8010sj_rtc) = {
371 .name = "rx8010sj_rtc",
373 .probe = rx8010sj_probe,
374 .of_match = rx8010sj_rtc_ids,
375 .ops = &rx8010sj_rtc_ops,