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/>.
24 #include <linux/bitops.h>
26 /*---------------------------------------------------------------------*/
27 /* #undef DEBUG_RTC */
30 #define DEBUGR(fmt, args...) printf(fmt, ##args)
32 #define DEBUGR(fmt, args...)
34 /*---------------------------------------------------------------------*/
36 #ifndef CFG_SYS_I2C_RTC_ADDR
37 # define CFG_SYS_I2C_RTC_ADDR 0x32
41 * RTC register addresses
43 #define RX8010_SEC 0x10
44 #define RX8010_MIN 0x11
45 #define RX8010_HOUR 0x12
46 #define RX8010_WDAY 0x13
47 #define RX8010_MDAY 0x14
48 #define RX8010_MONTH 0x15
49 #define RX8010_YEAR 0x16
50 #define RX8010_YEAR 0x16
51 #define RX8010_RESV17 0x17
52 #define RX8010_ALMIN 0x18
53 #define RX8010_ALHOUR 0x19
54 #define RX8010_ALWDAY 0x1A
55 #define RX8010_TCOUNT0 0x1B
56 #define RX8010_TCOUNT1 0x1C
57 #define RX8010_EXT 0x1D
58 #define RX8010_FLAG 0x1E
59 #define RX8010_CTRL 0x1F
60 /* 0x20 to 0x2F are user registers */
61 #define RX8010_RESV30 0x30
62 #define RX8010_RESV31 0x32
63 #define RX8010_IRQ 0x32
65 #define RX8010_EXT_WADA BIT(3)
67 #define RX8010_FLAG_VLF BIT(1)
68 #define RX8010_FLAG_AF BIT(3)
69 #define RX8010_FLAG_TF BIT(4)
70 #define RX8010_FLAG_UF BIT(5)
72 #define RX8010_CTRL_AIE BIT(3)
73 #define RX8010_CTRL_UIE BIT(5)
74 #define RX8010_CTRL_STOP BIT(6)
75 #define RX8010_CTRL_TEST BIT(7)
77 #define RX8010_ALARM_AE BIT(7)
81 #define DEV_TYPE struct udevice
90 #define DEV_TYPE struct ludevice
94 static int rx8010sj_rtc_read8(DEV_TYPE *dev, unsigned int reg)
100 ret = dm_i2c_read(dev, reg, &val, sizeof(val));
102 ret = i2c_read(dev->chip, reg, 1, &val, 1);
105 return ret < 0 ? ret : val;
108 static int rx8010sj_rtc_write8(DEV_TYPE *dev, unsigned int reg, int val)
114 ret = dm_i2c_write(dev, reg, &lval, 1);
116 ret = i2c_write(dev->chip, reg, 1, &lval, 1);
119 return ret < 0 ? ret : 0;
122 static int validate_time(const struct rtc_time *tm)
124 if ((tm->tm_year < 2000) || (tm->tm_year > 2099))
127 if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
130 if ((tm->tm_mday < 1) || (tm->tm_mday > 31))
133 if ((tm->tm_wday < 0) || (tm->tm_wday > 6))
136 if ((tm->tm_hour < 0) || (tm->tm_hour > 23))
139 if ((tm->tm_min < 0) || (tm->tm_min > 59))
142 if ((tm->tm_sec < 0) || (tm->tm_sec > 59))
148 void rx8010sj_rtc_init(DEV_TYPE *dev)
151 int need_clear = 0, ret = 0;
153 /* Initialize reserved registers as specified in datasheet */
154 ret = rx8010sj_rtc_write8(dev, RX8010_RESV17, 0xD8);
158 ret = rx8010sj_rtc_write8(dev, RX8010_RESV30, 0x00);
162 ret = rx8010sj_rtc_write8(dev, RX8010_RESV31, 0x08);
166 ret = rx8010sj_rtc_write8(dev, RX8010_IRQ, 0x00);
170 for (int i = 0; i < 2; i++) {
171 ret = rx8010sj_rtc_read8(dev, RX8010_FLAG + i);
178 if (ctrl[0] & RX8010_FLAG_VLF)
179 printf("RTC low voltage detected\n");
181 if (ctrl[0] & RX8010_FLAG_AF) {
182 printf("Alarm was detected\n");
186 if (ctrl[0] & RX8010_FLAG_TF)
189 if (ctrl[0] & RX8010_FLAG_UF)
193 ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
194 ret = rx8010sj_rtc_write8(dev, RX8010_FLAG, ctrl[0]);
202 printf("Error rtc init.\n");
205 /* Get the current time from the RTC */
206 static int rx8010sj_rtc_get(DEV_TYPE *dev, struct rtc_time *tmp)
212 flagreg = rx8010sj_rtc_read8(dev, RX8010_FLAG);
214 DEBUGR("Error reading from RTC. err: %d\n", flagreg);
218 if (flagreg & RX8010_FLAG_VLF) {
219 DEBUGR("RTC low voltage detected\n");
223 for (int i = 0; i < 7; i++) {
224 ret = rx8010sj_rtc_read8(dev, RX8010_SEC + i);
226 DEBUGR("Error reading from RTC. err: %d\n", ret);
232 tmp->tm_sec = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f);
233 tmp->tm_min = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f);
234 tmp->tm_hour = bcd2bin(date[RX8010_HOUR - RX8010_SEC] & 0x3f);
235 tmp->tm_mday = bcd2bin(date[RX8010_MDAY - RX8010_SEC] & 0x3f);
236 tmp->tm_mon = bcd2bin(date[RX8010_MONTH - RX8010_SEC] & 0x1f);
237 tmp->tm_year = bcd2bin(date[RX8010_YEAR - RX8010_SEC]) + 2000;
242 DEBUGR("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
243 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
244 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
250 static int rx8010sj_rtc_set(DEV_TYPE *dev, const struct rtc_time *tm)
256 ret = validate_time(tm);
260 /* set STOP bit before changing clock/calendar */
261 ctrl = rx8010sj_rtc_read8(dev, RX8010_CTRL);
264 ret = rx8010sj_rtc_write8(dev, RX8010_CTRL, ctrl | RX8010_CTRL_STOP);
268 date[RX8010_SEC - RX8010_SEC] = bin2bcd(tm->tm_sec);
269 date[RX8010_MIN - RX8010_SEC] = bin2bcd(tm->tm_min);
270 date[RX8010_HOUR - RX8010_SEC] = bin2bcd(tm->tm_hour);
271 date[RX8010_MDAY - RX8010_SEC] = bin2bcd(tm->tm_mday);
272 date[RX8010_MONTH - RX8010_SEC] = bin2bcd(tm->tm_mon);
273 date[RX8010_YEAR - RX8010_SEC] = bin2bcd(tm->tm_year - 2000);
274 date[RX8010_WDAY - RX8010_SEC] = bin2bcd(tm->tm_wday);
276 for (int i = 0; i < 7; i++) {
277 ret = rx8010sj_rtc_write8(dev, RX8010_SEC + i, date[i]);
279 DEBUGR("Error writing to RTC. err: %d\n", ret);
284 /* clear STOP bit after changing clock/calendar */
285 ctrl = rx8010sj_rtc_read8(dev, RX8010_CTRL);
289 ret = rx8010sj_rtc_write8(dev, RX8010_CTRL, ctrl & ~RX8010_CTRL_STOP);
293 flagreg = rx8010sj_rtc_read8(dev, RX8010_FLAG);
297 if (flagreg & RX8010_FLAG_VLF)
298 ret = rx8010sj_rtc_write8(dev, RX8010_FLAG,
299 flagreg & ~RX8010_FLAG_VLF);
305 static int rx8010sj_rtc_reset(DEV_TYPE *dev)
311 #ifndef CONFIG_DM_RTC
313 int rtc_get(struct rtc_time *tm)
315 struct ludevice dev = {
316 .chip = CFG_SYS_I2C_RTC_ADDR,
319 return rx8010sj_rtc_get(&dev, tm);
322 int rtc_set(struct rtc_time *tm)
324 struct ludevice dev = {
325 .chip = CFG_SYS_I2C_RTC_ADDR,
328 return rx8010sj_rtc_set(&dev, tm);
333 struct ludevice dev = {
334 .chip = CFG_SYS_I2C_RTC_ADDR,
337 rx8010sj_rtc_reset(&dev);
342 struct ludevice dev = {
343 .chip = CFG_SYS_I2C_RTC_ADDR,
346 rx8010sj_rtc_init(&dev);
351 static int rx8010sj_probe(struct udevice *dev)
353 rx8010sj_rtc_init(dev);
358 static const struct rtc_ops rx8010sj_rtc_ops = {
359 .get = rx8010sj_rtc_get,
360 .set = rx8010sj_rtc_set,
361 .read8 = rx8010sj_rtc_read8,
362 .write8 = rx8010sj_rtc_write8,
363 .reset = rx8010sj_rtc_reset,
366 static const struct udevice_id rx8010sj_rtc_ids[] = {
367 { .compatible = "epson,rx8010sj-rtc" },
368 { .compatible = "epson,rx8010" },
372 U_BOOT_DRIVER(rx8010sj_rtc) = {
373 .name = "rx8010sj_rtc",
375 .probe = rx8010sj_probe,
376 .of_match = rx8010sj_rtc_ids,
377 .ops = &rx8010sj_rtc_ops,