]> Git Repo - J-u-boot.git/blob - drivers/rtc/rv3029.c
Merge patch series "Cleanup dma device in spl and move dma channel[0]"
[J-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 <[email protected]>
7  *   Michael Buesch <[email protected]>
8  */
9
10 #include <command.h>
11 #include <dm.h>
12 #include <i2c.h>
13 #include <log.h>
14 #include <rtc.h>
15 #include <dm/device_compat.h>
16 #include <linux/bitops.h>
17 #include <linux/delay.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 static int rv3029_rtc_get(struct udevice *dev, struct rtc_time *tm)
77 {
78         u8 regs[RTC_RV3029_PAGE_LEN];
79         int ret;
80
81         ret = dm_i2c_read(dev, RV3029_W_SEC, regs, sizeof(regs));
82         if (ret < 0) {
83                 printf("%s: error reading RTC: %x\n", __func__, ret);
84                 return -EIO;
85         }
86
87         tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
88         tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
89
90         /* HR field has a more complex interpretation */
91         {
92                 const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
93
94                 if (_hr & RV3029_REG_HR_12_24) {
95                         /* 12h format */
96                         tm->tm_hour = bcd2bin(_hr & 0x1f);
97                         if (_hr & RV3029_REG_HR_PM)     /* PM flag set */
98                                 tm->tm_hour += 12;
99                 } else {
100                         /* 24h format */
101                         tm->tm_hour = bcd2bin(_hr & 0x3f);
102                 }
103         }
104
105         tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
106         tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
107         /* RTC supports only years > 1999 */
108         tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 2000;
109         tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
110
111         tm->tm_yday = 0;
112         tm->tm_isdst = 0;
113
114         debug("%s: %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
115               __func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
116               tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
117
118         return 0;
119 }
120
121 static int rv3029_rtc_set(struct udevice *dev, const struct rtc_time *tm)
122 {
123         u8 regs[RTC_RV3029_PAGE_LEN];
124
125         debug("%s: %4d-%02d-%02d (wday=%d( %2d:%02d:%02d\n",
126               __func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
127               tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
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
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
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
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)
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
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
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
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
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
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
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
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
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
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
462 static inline void rv3029_trickle_config(struct udevice *dev)
463 {
464 }
465 #endif
466
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 };
This page took 0.055016 seconds and 4 git commands to generate.