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
,