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