1 /*
2  * Epson RX8010 RTC driver.
3  *
4  * Copyright (c) 2017, General Electric Company
5  *
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.
9  *
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
13  * more details.
14  *
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/>.
17  */
18 
19 #include <command.h>
20 #include <common.h>
21 #include <dm.h>
22 #include <i2c.h>
23 #include <rtc.h>
24 #include <linux/bitops.h>
25 
26 /*---------------------------------------------------------------------*/
27 /* #undef DEBUG_RTC */
28 
29 #ifdef DEBUG_RTC
30 #define DEBUGR(fmt, args...) printf(fmt, ##args)
31 #else
32 #define DEBUGR(fmt, args...)
33 #endif
34 /*---------------------------------------------------------------------*/
35 
36 #ifndef CONFIG_SYS_I2C_RTC_ADDR
37 # define CONFIG_SYS_I2C_RTC_ADDR	0x32
38 #endif
39 
40 /*
41  * RTC register addresses
42  */
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
64 
65 #define RX8010_EXT_WADA  BIT(3)
66 
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)
71 
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)
76 
77 #define RX8010_ALARM_AE  BIT(7)
78 
79 #ifdef CONFIG_DM_RTC
80 
81 #define DEV_TYPE struct udevice
82 
83 #else
84 
85 /* Local udevice */
86 struct ludevice {
87 	u8 chip;
88 };
89 
90 #define DEV_TYPE struct ludevice
91 
92 #endif
93 
rx8010sj_rtc_read8(DEV_TYPE * dev,unsigned int reg)94 static int rx8010sj_rtc_read8(DEV_TYPE *dev, unsigned int reg)
95 {
96 	u8 val;
97 	int ret;
98 
99 #ifdef CONFIG_DM_RTC
100 	ret = dm_i2c_read(dev, reg, &val, sizeof(val));
101 #else
102 	ret = i2c_read(dev->chip, reg, 1, &val, 1);
103 #endif
104 
105 	return ret < 0 ? ret : val;
106 }
107 
rx8010sj_rtc_write8(DEV_TYPE * dev,unsigned int reg,int val)108 static int rx8010sj_rtc_write8(DEV_TYPE *dev, unsigned int reg, int val)
109 {
110 	int ret;
111 	u8 lval = val;
112 
113 #ifdef CONFIG_DM_RTC
114 	ret = dm_i2c_write(dev, reg, &lval, 1);
115 #else
116 	ret = i2c_write(dev->chip, reg, 1, &lval, 1);
117 #endif
118 
119 	return ret < 0 ? ret : 0;
120 }
121 
validate_time(const struct rtc_time * tm)122 static int validate_time(const struct rtc_time *tm)
123 {
124 	if ((tm->tm_year < 2000) || (tm->tm_year > 2099))
125 		return -EINVAL;
126 
127 	if ((tm->tm_mon < 1) || (tm->tm_mon > 12))
128 		return -EINVAL;
129 
130 	if ((tm->tm_mday < 1) || (tm->tm_mday > 31))
131 		return -EINVAL;
132 
133 	if ((tm->tm_wday < 0) || (tm->tm_wday > 6))
134 		return -EINVAL;
135 
136 	if ((tm->tm_hour < 0) || (tm->tm_hour > 23))
137 		return -EINVAL;
138 
139 	if ((tm->tm_min < 0) || (tm->tm_min > 59))
140 		return -EINVAL;
141 
142 	if ((tm->tm_sec < 0) || (tm->tm_sec > 59))
143 		return -EINVAL;
144 
145 	return 0;
146 }
147 
rx8010sj_rtc_init(DEV_TYPE * dev)148 void rx8010sj_rtc_init(DEV_TYPE *dev)
149 {
150 	u8 ctrl[2];
151 	int need_clear = 0, ret = 0;
152 
153 	/* Initialize reserved registers as specified in datasheet */
154 	ret = rx8010sj_rtc_write8(dev, RX8010_RESV17, 0xD8);
155 	if (ret < 0)
156 		goto error;
157 
158 	ret = rx8010sj_rtc_write8(dev, RX8010_RESV30, 0x00);
159 	if (ret < 0)
160 		goto error;
161 
162 	ret = rx8010sj_rtc_write8(dev, RX8010_RESV31, 0x08);
163 	if (ret < 0)
164 		goto error;
165 
166 	ret = rx8010sj_rtc_write8(dev, RX8010_IRQ, 0x00);
167 	if (ret < 0)
168 		goto error;
169 
170 	for (int i = 0; i < 2; i++) {
171 		ret = rx8010sj_rtc_read8(dev, RX8010_FLAG + i);
172 		if (ret < 0)
173 			goto error;
174 
175 		ctrl[i] = ret;
176 	}
177 
178 	if (ctrl[0] & RX8010_FLAG_VLF)
179 		printf("RTC low voltage detected\n");
180 
181 	if (ctrl[0] & RX8010_FLAG_AF) {
182 		printf("Alarm was detected\n");
183 		need_clear = 1;
184 	}
185 
186 	if (ctrl[0] & RX8010_FLAG_TF)
187 		need_clear = 1;
188 
189 	if (ctrl[0] & RX8010_FLAG_UF)
190 		need_clear = 1;
191 
192 	if (need_clear) {
193 		ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
194 		ret = rx8010sj_rtc_write8(dev, RX8010_FLAG, ctrl[0]);
195 		if (ret < 0)
196 			goto error;
197 	}
198 
199 	return;
200 
201 error:
202 	printf("Error rtc init.\n");
203 }
204 
205 /* Get the current time from the RTC */
rx8010sj_rtc_get(DEV_TYPE * dev,struct rtc_time * tmp)206 static int rx8010sj_rtc_get(DEV_TYPE *dev, struct rtc_time *tmp)
207 {
208 	u8 date[7];
209 	int flagreg;
210 	int ret;
211 
212 	flagreg = rx8010sj_rtc_read8(dev, RX8010_FLAG);
213 	if (flagreg < 0) {
214 		DEBUGR("Error reading from RTC. err: %d\n", flagreg);
215 		return -EIO;
216 	}
217 
218 	if (flagreg & RX8010_FLAG_VLF) {
219 		DEBUGR("RTC low voltage detected\n");
220 		return -EINVAL;
221 	}
222 
223 	for (int i = 0; i < 7; i++) {
224 		ret = rx8010sj_rtc_read8(dev, RX8010_SEC + i);
225 		if (ret < 0) {
226 			DEBUGR("Error reading from RTC. err: %d\n", ret);
227 			return -EIO;
228 		}
229 		date[i] = ret;
230 	}
231 
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;
238 	tmp->tm_wday = 0;
239 	tmp->tm_yday = 0;
240 	tmp->tm_isdst = 0;
241 
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);
245 
246 	return 0;
247 }
248 
249 /* Set the RTC */
rx8010sj_rtc_set(DEV_TYPE * dev,const struct rtc_time * tm)250 static int rx8010sj_rtc_set(DEV_TYPE *dev, const struct rtc_time *tm)
251 {
252 	u8 date[7];
253 	int ctrl, flagreg;
254 	int ret;
255 
256 	ret = validate_time(tm);
257 	if (ret < 0)
258 		return -EINVAL;
259 
260 	/* set STOP bit before changing clock/calendar */
261 	ctrl = rx8010sj_rtc_read8(dev, RX8010_CTRL);
262 	if (ctrl < 0)
263 		return ctrl;
264 	ret = rx8010sj_rtc_write8(dev, RX8010_CTRL, ctrl | RX8010_CTRL_STOP);
265 	if (ret < 0)
266 		return ret;
267 
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);
275 
276 	for (int i = 0; i < 7; i++) {
277 		ret = rx8010sj_rtc_write8(dev, RX8010_SEC + i, date[i]);
278 		if (ret < 0) {
279 			DEBUGR("Error writing to RTC. err: %d\n", ret);
280 			return -EIO;
281 		}
282 	}
283 
284 	/* clear STOP bit after changing clock/calendar */
285 	ctrl = rx8010sj_rtc_read8(dev, RX8010_CTRL);
286 	if (ctrl < 0)
287 		return ctrl;
288 
289 	ret = rx8010sj_rtc_write8(dev, RX8010_CTRL, ctrl & ~RX8010_CTRL_STOP);
290 	if (ret < 0)
291 		return ret;
292 
293 	flagreg = rx8010sj_rtc_read8(dev, RX8010_FLAG);
294 	if (flagreg < 0)
295 		return flagreg;
296 
297 	if (flagreg & RX8010_FLAG_VLF)
298 		ret = rx8010sj_rtc_write8(dev, RX8010_FLAG,
299 					  flagreg & ~RX8010_FLAG_VLF);
300 
301 	return 0;
302 }
303 
304 /* Reset the RTC. */
rx8010sj_rtc_reset(DEV_TYPE * dev)305 static int rx8010sj_rtc_reset(DEV_TYPE *dev)
306 {
307 	/* Not needed */
308 	return 0;
309 }
310 
311 #ifndef CONFIG_DM_RTC
312 
rtc_get(struct rtc_time * tm)313 int rtc_get(struct rtc_time *tm)
314 {
315 	struct ludevice dev = {
316 			.chip = CONFIG_SYS_I2C_RTC_ADDR,
317 	};
318 
319 	return rx8010sj_rtc_get(&dev, tm);
320 }
321 
rtc_set(struct rtc_time * tm)322 int rtc_set(struct rtc_time *tm)
323 {
324 	struct ludevice dev = {
325 			.chip = CONFIG_SYS_I2C_RTC_ADDR,
326 	};
327 
328 	return rx8010sj_rtc_set(&dev, tm);
329 }
330 
rtc_reset(void)331 void rtc_reset(void)
332 {
333 	struct ludevice dev = {
334 			.chip = CONFIG_SYS_I2C_RTC_ADDR,
335 	};
336 
337 	rx8010sj_rtc_reset(&dev);
338 }
339 
rtc_init(void)340 void rtc_init(void)
341 {
342 	struct ludevice dev = {
343 			.chip = CONFIG_SYS_I2C_RTC_ADDR,
344 	};
345 
346 	rx8010sj_rtc_init(&dev);
347 }
348 
349 #else
350 
rx8010sj_probe(struct udevice * dev)351 static int rx8010sj_probe(struct udevice *dev)
352 {
353 	rx8010sj_rtc_init(dev);
354 
355 	return 0;
356 }
357 
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,
364 };
365 
366 static const struct udevice_id rx8010sj_rtc_ids[] = {
367 	{ .compatible = "epson,rx8010sj-rtc" },
368 	{ .compatible = "epson,rx8010" },
369 	{ }
370 };
371 
372 U_BOOT_DRIVER(rx8010sj_rtc) = {
373 	.name	  = "rx8010sj_rtc",
374 	.id	      = UCLASS_RTC,
375 	.probe    = rx8010sj_probe,
376 	.of_match = rx8010sj_rtc_ids,
377 	.ops	  = &rx8010sj_rtc_ops,
378 };
379 
380 #endif
381