1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH
4  *
5  * Based on a the Linux rtc-rv3029c2.c driver written by:
6  *   Gregory Hermant <gregory.hermant@calao-systems.com>
7  *   Michael Buesch <m@bues.ch>
8  */
9 
10 #include <common.h>
11 #include <command.h>
12 #include <dm.h>
13 #include <eeprom.h>
14 #include <i2c.h>
15 #include <log.h>
16 #include <rtc.h>
17 #include <dm/device_compat.h>
18 #include <linux/bitops.h>
19 #include <linux/delay.h>
20 
21 #define RTC_RV3029_PAGE_LEN             7
22 
23 /* control section */
24 #define RV3029_ONOFF_CTRL		0x00
25 #define RV3029_ONOFF_CTRL_WE		BIT(0)
26 #define RV3029_ONOFF_CTRL_TE		BIT(1)
27 #define RV3029_ONOFF_CTRL_TAR		BIT(2)
28 #define RV3029_ONOFF_CTRL_EERE		BIT(3)
29 #define RV3029_ONOFF_CTRL_SRON		BIT(4)
30 #define RV3029_ONOFF_CTRL_TD0		BIT(5)
31 #define RV3029_ONOFF_CTRL_TD1		BIT(6)
32 #define RV3029_ONOFF_CTRL_CLKINT	BIT(7)
33 #define RV3029_IRQ_CTRL			0x01
34 #define RV3029_IRQ_CTRL_AIE		BIT(0)
35 #define RV3029_IRQ_CTRL_TIE		BIT(1)
36 #define RV3029_IRQ_CTRL_V1IE		BIT(2)
37 #define RV3029_IRQ_CTRL_V2IE		BIT(3)
38 #define RV3029_IRQ_CTRL_SRIE		BIT(4)
39 #define RV3029_IRQ_FLAGS		0x02
40 #define RV3029_IRQ_FLAGS_AF		BIT(0)
41 #define RV3029_IRQ_FLAGS_TF		BIT(1)
42 #define RV3029_IRQ_FLAGS_V1IF		BIT(2)
43 #define RV3029_IRQ_FLAGS_V2IF		BIT(3)
44 #define RV3029_IRQ_FLAGS_SRF		BIT(4)
45 #define RV3029_STATUS			0x03
46 #define RV3029_STATUS_VLOW1		BIT(2)
47 #define RV3029_STATUS_VLOW2		BIT(3)
48 #define RV3029_STATUS_SR		BIT(4)
49 #define RV3029_STATUS_PON		BIT(5)
50 #define RV3029_STATUS_EEBUSY		BIT(7)
51 #define RV3029_RST_CTRL			0x04
52 #define RV3029_RST_CTRL_SYSR		BIT(4)
53 #define RV3029_CONTROL_SECTION_LEN	0x05
54 
55 /* watch section */
56 #define RV3029_W_SEC			0x08
57 #define RV3029_W_MINUTES		0x09
58 #define RV3029_W_HOURS			0x0A
59 #define RV3029_REG_HR_12_24		BIT(6) /* 24h/12h mode */
60 #define RV3029_REG_HR_PM		BIT(5) /* PM/AM bit in 12h mode */
61 #define RV3029_W_DATE			0x0B
62 #define RV3029_W_DAYS			0x0C
63 #define RV3029_W_MONTHS			0x0D
64 #define RV3029_W_YEARS			0x0E
65 
66 /* eeprom control section */
67 #define RV3029_CONTROL_E2P_EECTRL	0x30
68 #define RV3029_TRICKLE_1K		BIT(4) /* 1.5K resistance */
69 #define RV3029_TRICKLE_5K		BIT(5) /* 5K   resistance */
70 #define RV3029_TRICKLE_20K		BIT(6) /* 20K  resistance */
71 #define RV3029_TRICKLE_80K		BIT(7) /* 80K  resistance */
72 #define RV3029_TRICKLE_MASK		(RV3029_TRICKLE_1K |\
73 					 RV3029_TRICKLE_5K |\
74 					 RV3029_TRICKLE_20K |\
75 					 RV3029_TRICKLE_80K)
76 #define RV3029_TRICKLE_SHIFT		4
77 
78 
rv3029_rtc_get(struct udevice * dev,struct rtc_time * tm)79 static int rv3029_rtc_get(struct udevice *dev, struct rtc_time *tm)
80 {
81 	u8 regs[RTC_RV3029_PAGE_LEN];
82 	int ret;
83 
84 	ret = dm_i2c_read(dev, RV3029_W_SEC, regs, sizeof(regs));
85 	if (ret < 0) {
86 		printf("%s: error reading RTC: %x\n", __func__, ret);
87 		return -EIO;
88 	}
89 
90 	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
91 	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
92 
93 	/* HR field has a more complex interpretation */
94 	{
95 		const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
96 
97 		if (_hr & RV3029_REG_HR_12_24) {
98 			/* 12h format */
99 			tm->tm_hour = bcd2bin(_hr & 0x1f);
100 			if (_hr & RV3029_REG_HR_PM)	/* PM flag set */
101 				tm->tm_hour += 12;
102 		} else {
103 			/* 24h format */
104 			tm->tm_hour = bcd2bin(_hr & 0x3f);
105 		}
106 	}
107 
108 	tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
109 	tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
110 	/* RTC supports only years > 1999 */
111 	tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 2000;
112 	tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
113 
114 	tm->tm_yday = 0;
115 	tm->tm_isdst = 0;
116 
117 	debug("%s: %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
118 	      __func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
119 	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
120 
121 	return 0;
122 }
123 
rv3029_rtc_set(struct udevice * dev,const struct rtc_time * tm)124 static int rv3029_rtc_set(struct udevice *dev, const struct rtc_time *tm)
125 {
126 	u8 regs[RTC_RV3029_PAGE_LEN];
127 
128 	debug("%s: %4d-%02d-%02d (wday=%d( %2d:%02d:%02d\n",
129 	      __func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
130 	      tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
131 
132 
133 	if (tm->tm_year < 2000) {
134 		printf("%s: year %d (before 2000) not supported\n",
135 		       __func__, tm->tm_year);
136 		return -EINVAL;
137 	}
138 
139 	regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
140 	regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
141 	regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
142 	regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday);
143 	regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1);
144 	regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
145 	regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 2000);
146 
147 	return dm_i2c_write(dev, RV3029_W_SEC, regs, sizeof(regs));
148 }
149 
rv3029_rtc_reset(struct udevice * dev)150 static int rv3029_rtc_reset(struct udevice *dev)
151 {
152 	u8 ctrl = RV3029_RST_CTRL_SYSR;
153 	unsigned long start;
154 	const unsigned long timeout_ms = 10000;
155 	int ret;
156 
157 	/* trigger the system-reset */
158 	ret = dm_i2c_write(dev, RV3029_RST_CTRL, &ctrl, 1);
159 	if (ret < 0)
160 		return -EIO;
161 
162 	/* wait for the system-reset to complete */
163 	start = get_timer(0);
164 	do {
165 		if (get_timer(start) > timeout_ms)
166 			return -ETIMEDOUT;
167 
168 		ret = dm_i2c_read(dev, RV3029_RST_CTRL, &ctrl, 1);
169 		if (ret < 0)
170 			return -EIO;
171 	} while (ctrl & RV3029_RST_CTRL_SYSR);
172 
173 	return 0;
174 }
175 
rv3029_rtc_read8(struct udevice * dev,unsigned int reg)176 static int rv3029_rtc_read8(struct udevice *dev, unsigned int reg)
177 {
178 	u8 data;
179 	int ret;
180 
181 	ret = dm_i2c_read(dev, reg, &data, sizeof(data));
182 	return ret < 0 ? ret : data;
183 }
184 
rv3029_rtc_write8(struct udevice * dev,unsigned int reg,int val)185 static int rv3029_rtc_write8(struct udevice *dev, unsigned int reg, int val)
186 {
187 	u8 data = val;
188 
189 	return dm_i2c_write(dev, reg, &data, 1);
190 }
191 
192 #if defined(OF_CONTROL)
rv3029_get_sr(struct udevice * dev,u8 * buf)193 static int rv3029_get_sr(struct udevice *dev, u8 *buf)
194 {
195 	int ret = dm_i2c_read(dev, RV3029_STATUS, buf, 1);
196 
197 	if (ret < 0)
198 		return -EIO;
199 
200 	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
201 	return 0;
202 }
203 
rv3029_set_sr(struct udevice * dev,u8 val)204 static int rv3029_set_sr(struct udevice *dev, u8 val)
205 {
206 	int ret;
207 
208 	ret = dm_i2c_read(dev, RV3029_STATUS, &val, 1);
209 	if (ret < 0)
210 		return -EIO;
211 
212 	dev_dbg(dev, "status = 0x%.2x (%d)\n", val, val);
213 	return 0;
214 }
215 
rv3029_eeprom_busywait(struct udevice * dev)216 static int rv3029_eeprom_busywait(struct udevice *dev)
217 {
218 	int i, ret;
219 	u8 sr;
220 
221 	for (i = 100; i > 0; i--) {
222 		ret = rv3029_get_sr(dev, &sr);
223 		if (ret < 0)
224 			break;
225 		if (!(sr & RV3029_STATUS_EEBUSY))
226 			break;
227 		udelay(10000);
228 	}
229 	if (i <= 0) {
230 		dev_err(dev, "EEPROM busy wait timeout.\n");
231 		return -ETIMEDOUT;
232 	}
233 
234 	return ret;
235 }
236 
rv3029_update_bits(struct udevice * dev,u8 reg,u8 mask,u8 set)237 static int rv3029_update_bits(struct udevice *dev, u8 reg, u8 mask, u8 set)
238 {
239 	u8 buf;
240 	int ret;
241 
242 	ret = dm_i2c_read(dev, reg, &buf, 1);
243 	if (ret < 0)
244 		return ret;
245 
246 	if ((buf & mask) == (set && mask))
247 		return 0;
248 
249 	buf = (buf & ~mask) | (set & mask);
250 	ret = dm_i2c_read(dev, reg, &buf, 1);
251 	if (ret < 0)
252 		return ret;
253 
254 	return 0;
255 }
256 
rv3029_eeprom_exit(struct udevice * dev)257 static int rv3029_eeprom_exit(struct udevice *dev)
258 {
259 	/* Re-enable eeprom refresh */
260 	return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
261 				  RV3029_ONOFF_CTRL_EERE,
262 				  RV3029_ONOFF_CTRL_EERE);
263 }
264 
rv3029_eeprom_enter(struct udevice * dev)265 static int rv3029_eeprom_enter(struct udevice *dev)
266 {
267 	int ret;
268 	u8 sr;
269 
270 	/* Check whether we are in the allowed voltage range. */
271 	ret = rv3029_get_sr(dev, &sr);
272 	if (ret < 0)
273 		return ret;
274 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
275 		/* We clear the bits and retry once just in case
276 		 * we had a brown out in early startup.
277 		 */
278 		sr &= ~RV3029_STATUS_VLOW1;
279 		sr &= ~RV3029_STATUS_VLOW2;
280 		ret = rv3029_set_sr(dev, sr);
281 		if (ret < 0)
282 			return ret;
283 		udelay(10000);
284 		ret = rv3029_get_sr(dev, &sr);
285 		if (ret < 0)
286 			return ret;
287 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
288 			dev_err(dev, "Supply voltage is too low to safely access the EEPROM.\n");
289 			return -ENODEV;
290 		}
291 	}
292 
293 	/* Disable eeprom refresh. */
294 	ret = rv3029_update_bits(dev,
295 				 RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE, 0);
296 	if (ret < 0)
297 		return ret;
298 
299 	/* Wait for any previous eeprom accesses to finish. */
300 	ret = rv3029_eeprom_busywait(dev);
301 	if (ret < 0)
302 		rv3029_eeprom_exit(dev);
303 
304 	return ret;
305 }
306 
rv3029_eeprom_read(struct udevice * dev,u8 reg,u8 buf[],size_t len)307 static int rv3029_eeprom_read(struct udevice *dev, u8 reg,
308 			      u8 buf[], size_t len)
309 {
310 	int ret, err;
311 
312 	err = rv3029_eeprom_enter(dev);
313 	if (err < 0)
314 		return err;
315 
316 	ret = dm_i2c_read(dev, reg, buf, len);
317 
318 	err = rv3029_eeprom_exit(dev);
319 	if (err < 0)
320 		return err;
321 
322 	return ret;
323 }
324 
rv3029_eeprom_write(struct udevice * dev,u8 reg,u8 const buf[],size_t len)325 static int rv3029_eeprom_write(struct udevice *dev, u8 reg,
326 			       u8 const buf[], size_t len)
327 {
328 	int ret;
329 	size_t i;
330 	u8 tmp;
331 
332 	ret = rv3029_eeprom_enter(dev);
333 	if (ret < 0)
334 		return ret;
335 
336 	for (i = 0; i < len; i++, reg++) {
337 		ret = dm_i2c_read(dev, reg, &tmp, 1);
338 		if (ret < 0)
339 			break;
340 		if (tmp != buf[i]) {
341 			ret = dm_i2c_write(dev, reg, &buf[i], 1);
342 			if (ret < 0)
343 				break;
344 		}
345 		ret = rv3029_eeprom_busywait(dev);
346 		if (ret < 0)
347 			break;
348 	}
349 
350 	ret = rv3029_eeprom_exit(dev);
351 	if (ret < 0)
352 		return ret;
353 
354 	return 0;
355 }
356 
rv3029_eeprom_update_bits(struct udevice * dev,u8 reg,u8 mask,u8 set)357 static int rv3029_eeprom_update_bits(struct udevice *dev,
358 				     u8 reg, u8 mask, u8 set)
359 {
360 	u8 buf;
361 	int ret;
362 
363 	ret = rv3029_eeprom_read(dev, reg, &buf, 1);
364 	if (ret < 0)
365 		return ret;
366 
367 	/*
368 	 * If the EEPROM already reads the correct bitpattern, we don't need
369 	 * to update it.
370 	 */
371 	if ((buf & mask) == (set & mask))
372 		return 0;
373 
374 	buf = (buf & ~mask) | (set & mask);
375 	ret = rv3029_eeprom_write(dev, reg, &buf, 1);
376 	if (ret < 0)
377 		return ret;
378 
379 	return 0;
380 }
381 
rv3029_trickle_config(struct udevice * dev)382 static void rv3029_trickle_config(struct udevice *dev)
383 {
384 	static const struct rv3029_trickle_tab_elem {
385 		u32 r;		/* resistance in ohms */
386 		u8 conf;	/* trickle config bits */
387 	} rv3029_trickle_tab[] = {
388 		{
389 			.r	= 1076,
390 			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
391 				  RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
392 		}, {
393 			.r	= 1091,
394 			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
395 				  RV3029_TRICKLE_20K,
396 		}, {
397 			.r	= 1137,
398 			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
399 				  RV3029_TRICKLE_80K,
400 		}, {
401 			.r	= 1154,
402 			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K,
403 		}, {
404 			.r	= 1371,
405 			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_20K |
406 				  RV3029_TRICKLE_80K,
407 		}, {
408 			.r	= 1395,
409 			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_20K,
410 		}, {
411 			.r	= 1472,
412 			.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_80K,
413 		}, {
414 			.r	= 1500,
415 			.conf	= RV3029_TRICKLE_1K,
416 		}, {
417 			.r	= 3810,
418 			.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_20K |
419 				  RV3029_TRICKLE_80K,
420 		}, {
421 			.r	= 4000,
422 			.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_20K,
423 		}, {
424 			.r	= 4706,
425 			.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_80K,
426 		}, {
427 			.r	= 5000,
428 			.conf	= RV3029_TRICKLE_5K,
429 		}, {
430 			.r	= 16000,
431 			.conf	= RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
432 		}, {
433 			.r	= 20000,
434 			.conf	= RV3029_TRICKLE_20K,
435 		}, {
436 			.r	= 80000,
437 			.conf	= RV3029_TRICKLE_80K,
438 		},
439 	};
440 	int err;
441 	u32 ohms;
442 	u8 trickle_set_bits = 0;
443 
444 	/* Configure the trickle charger. */
445 	err = dev_read_u32(dev, "trickle-resistor-ohms", &ohms);
446 
447 	if (!err) {
448 		/* Find trickle-charger config */
449 		for (int i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++)
450 			if (rv3029_trickle_tab[i].r >= ohms) {
451 				dev_dbg(dev, "trickle charger at %d ohms\n",
452 					rv3029_trickle_tab[i].r);
453 				trickle_set_bits = rv3029_trickle_tab[i].conf;
454 				break;
455 			}
456 	}
457 
458 	dev_dbg(dev, "trickle charger config 0x%x\n", trickle_set_bits);
459 	err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
460 					RV3029_TRICKLE_MASK,
461 					trickle_set_bits);
462 	if (err < 0)
463 		dev_dbg(dev, "failed to update trickle charger\n");
464 }
465 #else
rv3029_trickle_config(struct udevice * dev)466 static inline void rv3029_trickle_config(struct udevice *dev)
467 {
468 }
469 #endif
470 
rv3029_probe(struct udevice * dev)471 static int rv3029_probe(struct udevice *dev)
472 {
473 	i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS |
474 				DM_I2C_CHIP_WR_ADDRESS);
475 
476 	rv3029_trickle_config(dev);
477 	return 0;
478 }
479 
480 static const struct rtc_ops rv3029_rtc_ops = {
481 	.get = rv3029_rtc_get,
482 	.set = rv3029_rtc_set,
483 	.read8 = rv3029_rtc_read8,
484 	.write8 = rv3029_rtc_write8,
485 	.reset = rv3029_rtc_reset,
486 };
487 
488 static const struct udevice_id rv3029_rtc_ids[] = {
489 	{ .compatible = "mc,rv3029" },
490 	{ .compatible = "mc,rv3029c2" },
491 	{ }
492 };
493 
494 U_BOOT_DRIVER(rtc_rv3029) = {
495 	.name	= "rtc-rv3029",
496 	.id	= UCLASS_RTC,
497 	.probe	= rv3029_probe,
498 	.of_match = rv3029_rtc_ids,
499 	.ops	= &rv3029_rtc_ops,
500 };
501