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