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