blob: 528b06cbd690584920673de98e997f13cb18abc1 [file] [log] [blame]
Ying-Chun Liu (PaulLiu)f9b87302021-01-15 13:53:02 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * A driver for the I2C members of the Abracon AB x8xx RTC family,
4 * and compatible: AB 1805 and AB 0805
5 *
6 * Copyright 2014-2015 Macq S.A.
7 * Copyright 2020 Linaro
8 *
9 * Author: Philippe De Muyter <phdm@macqel.be>
10 * Author: Alexandre Belloni <alexandre.belloni@bootlin.com>
11 * Author: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
12 *
13 */
14
15#include <common.h>
16#include <dm.h>
17#include <i2c.h>
18#include <rtc.h>
19#include <log.h>
20
21#define ABX8XX_REG_HTH 0x00
22#define ABX8XX_REG_SC 0x01
23#define ABX8XX_REG_MN 0x02
24#define ABX8XX_REG_HR 0x03
25#define ABX8XX_REG_DA 0x04
26#define ABX8XX_REG_MO 0x05
27#define ABX8XX_REG_YR 0x06
28#define ABX8XX_REG_WD 0x07
29
30#define ABX8XX_REG_AHTH 0x08
31#define ABX8XX_REG_ASC 0x09
32#define ABX8XX_REG_AMN 0x0a
33#define ABX8XX_REG_AHR 0x0b
34#define ABX8XX_REG_ADA 0x0c
35#define ABX8XX_REG_AMO 0x0d
36#define ABX8XX_REG_AWD 0x0e
37
38#define ABX8XX_REG_STATUS 0x0f
39#define ABX8XX_STATUS_AF BIT(2)
40#define ABX8XX_STATUS_BLF BIT(4)
41#define ABX8XX_STATUS_WDT BIT(6)
42
43#define ABX8XX_REG_CTRL1 0x10
44#define ABX8XX_CTRL_WRITE BIT(0)
45#define ABX8XX_CTRL_ARST BIT(2)
46#define ABX8XX_CTRL_12_24 BIT(6)
47
48#define ABX8XX_REG_CTRL2 0x11
49#define ABX8XX_CTRL2_RSVD BIT(5)
50
51#define ABX8XX_REG_IRQ 0x12
52#define ABX8XX_IRQ_AIE BIT(2)
53#define ABX8XX_IRQ_IM_1_4 (0x3 << 5)
54
55#define ABX8XX_REG_CD_TIMER_CTL 0x18
56
57#define ABX8XX_REG_OSC 0x1c
58#define ABX8XX_OSC_FOS BIT(3)
59#define ABX8XX_OSC_BOS BIT(4)
60#define ABX8XX_OSC_ACAL_512 BIT(5)
61#define ABX8XX_OSC_ACAL_1024 BIT(6)
62
63#define ABX8XX_OSC_OSEL BIT(7)
64
65#define ABX8XX_REG_OSS 0x1d
66#define ABX8XX_OSS_OF BIT(1)
67#define ABX8XX_OSS_OMODE BIT(4)
68
69#define ABX8XX_REG_WDT 0x1b
70#define ABX8XX_WDT_WDS BIT(7)
71#define ABX8XX_WDT_BMB_MASK 0x7c
72#define ABX8XX_WDT_BMB_SHIFT 2
73#define ABX8XX_WDT_MAX_TIME (ABX8XX_WDT_BMB_MASK >> ABX8XX_WDT_BMB_SHIFT)
74#define ABX8XX_WDT_WRB_MASK 0x03
75#define ABX8XX_WDT_WRB_1HZ 0x02
76
77#define ABX8XX_REG_CFG_KEY 0x1f
78#define ABX8XX_CFG_KEY_OSC 0xa1
79#define ABX8XX_CFG_KEY_MISC 0x9d
80
81#define ABX8XX_REG_ID0 0x28
82
83#define ABX8XX_REG_OUT_CTRL 0x30
84#define ABX8XX_OUT_CTRL_EXDS BIT(4)
85
86#define ABX8XX_REG_TRICKLE 0x20
87#define ABX8XX_TRICKLE_CHARGE_ENABLE 0xa0
88#define ABX8XX_TRICKLE_STANDARD_DIODE 0x8
89#define ABX8XX_TRICKLE_SCHOTTKY_DIODE 0x4
90
91static u8 trickle_resistors[] = {0, 3, 6, 11};
92
93enum abx80x_chip {AB0801, AB0803, AB0804, AB0805,
94 AB1801, AB1803, AB1804, AB1805, RV1805, ABX80X};
95
96struct abx80x_cap {
97 u16 pn;
98 bool has_tc;
99 bool has_wdog;
100};
101
102static struct abx80x_cap abx80x_caps[] = {
103 [AB0801] = {.pn = 0x0801},
104 [AB0803] = {.pn = 0x0803},
105 [AB0804] = {.pn = 0x0804, .has_tc = true, .has_wdog = true},
106 [AB0805] = {.pn = 0x0805, .has_tc = true, .has_wdog = true},
107 [AB1801] = {.pn = 0x1801},
108 [AB1803] = {.pn = 0x1803},
109 [AB1804] = {.pn = 0x1804, .has_tc = true, .has_wdog = true},
110 [AB1805] = {.pn = 0x1805, .has_tc = true, .has_wdog = true},
111 [RV1805] = {.pn = 0x1805, .has_tc = true, .has_wdog = true},
112 [ABX80X] = {.pn = 0}
113};
114
115static int abx80x_rtc_read8(struct udevice *dev, unsigned int reg)
116{
117 int ret = 0;
118 u8 buf;
119
120 if (reg > 0xff)
121 return -EINVAL;
122
123 ret = dm_i2c_read(dev, reg, &buf, sizeof(buf));
124 if (ret < 0)
125 return ret;
126
127 return buf;
128}
129
130static int abx80x_rtc_write8(struct udevice *dev, unsigned int reg, int val)
131{
132 u8 buf = (u8)val;
133
134 if (reg > 0xff)
135 return -EINVAL;
136
137 return dm_i2c_write(dev, reg, &buf, sizeof(buf));
138}
139
140static int abx80x_is_rc_mode(struct udevice *dev)
141{
142 int flags = 0;
143
144 flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSS);
145 if (flags < 0) {
146 log_err("Failed to read autocalibration attribute\n");
147 return flags;
148 }
149
150 return (flags & ABX8XX_OSS_OMODE) ? 1 : 0;
151}
152
153static int abx80x_enable_trickle_charger(struct udevice *dev, u8 trickle_cfg)
154{
155 int err;
156
157 /*
158 * Write the configuration key register to enable access to the Trickle
159 * register
160 */
161 err = dm_i2c_reg_write(dev, ABX8XX_REG_CFG_KEY, ABX8XX_CFG_KEY_MISC);
162 if (err < 0) {
163 log_err("Unable to write configuration key\n");
164 return -EIO;
165 }
166
167 err = dm_i2c_reg_write(dev, ABX8XX_REG_TRICKLE,
168 ABX8XX_TRICKLE_CHARGE_ENABLE | trickle_cfg);
169 if (err < 0) {
170 log_err("Unable to write trickle register\n");
171 return -EIO;
172 }
173
174 return 0;
175}
176
177static int abx80x_rtc_read_time(struct udevice *dev, struct rtc_time *tm)
178{
179 unsigned char buf[8];
180 int err, flags, rc_mode = 0;
181
182 /* Read the Oscillator Failure only in XT mode */
183 rc_mode = abx80x_is_rc_mode(dev);
184 if (rc_mode < 0)
185 return rc_mode;
186
187 if (!rc_mode) {
188 flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSS);
189 if (flags < 0) {
190 log_err("Unable to read oscillator status.\n");
191 return flags;
192 }
193
194 if (flags & ABX8XX_OSS_OF)
195 log_debug("Oscillator fail, data is not accurate.\n");
196 }
197
198 err = dm_i2c_read(dev, ABX8XX_REG_HTH,
199 buf, sizeof(buf));
200 if (err < 0) {
201 log_err("Unable to read date\n");
202 return -EIO;
203 }
204
205 tm->tm_sec = bcd2bin(buf[ABX8XX_REG_SC] & 0x7F);
206 tm->tm_min = bcd2bin(buf[ABX8XX_REG_MN] & 0x7F);
207 tm->tm_hour = bcd2bin(buf[ABX8XX_REG_HR] & 0x3F);
208 tm->tm_wday = buf[ABX8XX_REG_WD] & 0x7;
209 tm->tm_mday = bcd2bin(buf[ABX8XX_REG_DA] & 0x3F);
210 tm->tm_mon = bcd2bin(buf[ABX8XX_REG_MO] & 0x1F);
211 tm->tm_year = bcd2bin(buf[ABX8XX_REG_YR]) + 2000;
212
213 return 0;
214}
215
216static int abx80x_rtc_set_time(struct udevice *dev, const struct rtc_time *tm)
217{
218 unsigned char buf[8];
219 int err, flags;
220
221 if (tm->tm_year < 2000)
222 return -EINVAL;
223
224 buf[ABX8XX_REG_HTH] = 0;
225 buf[ABX8XX_REG_SC] = bin2bcd(tm->tm_sec);
226 buf[ABX8XX_REG_MN] = bin2bcd(tm->tm_min);
227 buf[ABX8XX_REG_HR] = bin2bcd(tm->tm_hour);
228 buf[ABX8XX_REG_DA] = bin2bcd(tm->tm_mday);
229 buf[ABX8XX_REG_MO] = bin2bcd(tm->tm_mon);
230 buf[ABX8XX_REG_YR] = bin2bcd(tm->tm_year - 2000);
231 buf[ABX8XX_REG_WD] = tm->tm_wday;
232
233 err = dm_i2c_write(dev, ABX8XX_REG_HTH,
234 buf, sizeof(buf));
235 if (err < 0) {
236 log_err("Unable to write to date registers\n");
237 return -EIO;
238 }
239
240 /* Clear the OF bit of Oscillator Status Register */
241 flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSS);
242 if (flags < 0) {
243 log_err("Unable to read oscillator status.\n");
244 return flags;
245 }
246
247 err = dm_i2c_reg_write(dev, ABX8XX_REG_OSS,
248 flags & ~ABX8XX_OSS_OF);
249 if (err < 0) {
250 log_err("Unable to write oscillator status register\n");
251 return err;
252 }
253
254 return 0;
255}
256
257static int abx80x_rtc_set_autocalibration(struct udevice *dev,
258 int autocalibration)
259{
260 int retval, flags = 0;
261
262 if (autocalibration != 0 && autocalibration != 1024 &&
263 autocalibration != 512) {
264 log_err("autocalibration value outside permitted range\n");
265 return -EINVAL;
266 }
267
268 flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSC);
269 if (flags < 0)
270 return flags;
271
272 if (autocalibration == 0) {
273 flags &= ~(ABX8XX_OSC_ACAL_512 | ABX8XX_OSC_ACAL_1024);
274 } else if (autocalibration == 1024) {
275 /* 1024 autocalibration is 0x10 */
276 flags |= ABX8XX_OSC_ACAL_1024;
277 flags &= ~(ABX8XX_OSC_ACAL_512);
278 } else {
279 /* 512 autocalibration is 0x11 */
280 flags |= (ABX8XX_OSC_ACAL_1024 | ABX8XX_OSC_ACAL_512);
281 }
282
283 /* Unlock write access to Oscillator Control Register */
284 retval = dm_i2c_reg_write(dev, ABX8XX_REG_CFG_KEY,
285 ABX8XX_CFG_KEY_OSC);
286 if (retval < 0) {
287 log_err("Failed to write CONFIG_KEY register\n");
288 return retval;
289 }
290
291 retval = dm_i2c_reg_write(dev, ABX8XX_REG_OSC, flags);
292
293 return retval;
294}
295
296static int abx80x_rtc_get_autocalibration(struct udevice *dev)
297{
298 int flags = 0, autocalibration;
299
300 flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSC);
301 if (flags < 0)
302 return flags;
303
304 if (flags & ABX8XX_OSC_ACAL_512)
305 autocalibration = 512;
306 else if (flags & ABX8XX_OSC_ACAL_1024)
307 autocalibration = 1024;
308 else
309 autocalibration = 0;
310
311 return autocalibration;
312}
313
314static struct rtc_time default_tm = { 0, 0, 0, 1, 1, 2000, 6, 0, 0 };
315
316static int abx80x_rtc_reset(struct udevice *dev)
317{
318 int ret = 0;
319
320 int autocalib = abx80x_rtc_get_autocalibration(dev);
321
322 if (autocalib != 0)
323 abx80x_rtc_set_autocalibration(dev, 0);
324
325 ret = abx80x_rtc_set_time(dev, &default_tm);
326 if (ret != 0) {
327 log_err("cannot set time to default_tm. error %d\n", ret);
328 return ret;
329 }
330
331 return ret;
332}
333
334static const struct rtc_ops abx80x_rtc_ops = {
335 .get = abx80x_rtc_read_time,
336 .set = abx80x_rtc_set_time,
337 .reset = abx80x_rtc_reset,
338 .read8 = abx80x_rtc_read8,
339 .write8 = abx80x_rtc_write8
340};
341
342static int abx80x_dt_trickle_cfg(struct udevice *dev)
343{
344 const char *diode;
345 int trickle_cfg = 0;
346 int i, ret = 0;
347 u32 tmp;
348
349 diode = ofnode_read_string(dev_ofnode(dev), "abracon,tc-diode");
350 if (!diode)
351 return ret;
352
353 if (!strcmp(diode, "standard")) {
354 trickle_cfg |= ABX8XX_TRICKLE_STANDARD_DIODE;
355 } else if (!strcmp(diode, "schottky")) {
356 trickle_cfg |= ABX8XX_TRICKLE_SCHOTTKY_DIODE;
357 } else {
358 log_err("Invalid tc-diode value: %s\n", diode);
359 return -EINVAL;
360 }
361
362 ret = ofnode_read_u32(dev_ofnode(dev), "abracon,tc-resistor", &tmp);
363 if (ret)
364 return ret;
365
366 for (i = 0; i < sizeof(trickle_resistors); i++)
367 if (trickle_resistors[i] == tmp)
368 break;
369
370 if (i == sizeof(trickle_resistors)) {
371 log_err("Invalid tc-resistor value: %u\n", tmp);
372 return -EINVAL;
373 }
374
375 return (trickle_cfg | i);
376}
377
378static int abx80x_probe(struct udevice *dev)
379{
380 int i, data, err, trickle_cfg = -EINVAL;
381 unsigned char buf[7];
382 unsigned int part = dev->driver_data;
383 unsigned int partnumber;
384 unsigned int majrev, minrev;
385 unsigned int lot;
386 unsigned int wafer;
387 unsigned int uid;
388
389 err = dm_i2c_read(dev, ABX8XX_REG_ID0, buf, sizeof(buf));
390 if (err < 0) {
391 log_err("Unable to read partnumber\n");
392 return -EIO;
393 }
394
395 partnumber = (buf[0] << 8) | buf[1];
396 majrev = buf[2] >> 3;
397 minrev = buf[2] & 0x7;
398 lot = ((buf[4] & 0x80) << 2) | ((buf[6] & 0x80) << 1) | buf[3];
399 uid = ((buf[4] & 0x7f) << 8) | buf[5];
400 wafer = (buf[6] & 0x7c) >> 2;
401 log_debug("model %04x, revision %u.%u, lot %x, wafer %x, uid %x\n",
402 partnumber, majrev, minrev, lot, wafer, uid);
403
404 data = dm_i2c_reg_read(dev, ABX8XX_REG_CTRL1);
405 if (data < 0) {
406 log_err("Unable to read control register\n");
407 return -EIO;
408 }
409
410 err = dm_i2c_reg_write(dev, ABX8XX_REG_CTRL1,
411 ((data & ~(ABX8XX_CTRL_12_24 |
412 ABX8XX_CTRL_ARST)) |
413 ABX8XX_CTRL_WRITE));
414 if (err < 0) {
415 log_err("Unable to write control register\n");
416 return -EIO;
417 }
418
419 /* Configure RV1805 specifics */
420 if (part == RV1805) {
421 /*
422 * Avoid accidentally entering test mode. This can happen
423 * on the RV1805 in case the reserved bit 5 in control2
424 * register is set. RV-1805-C3 datasheet indicates that
425 * the bit should be cleared in section 11h - Control2.
426 */
427 data = dm_i2c_reg_read(dev, ABX8XX_REG_CTRL2);
428 if (data < 0) {
429 log_err("Unable to read control2 register\n");
430 return -EIO;
431 }
432
433 err = dm_i2c_reg_write(dev, ABX8XX_REG_CTRL2,
434 data & ~ABX8XX_CTRL2_RSVD);
435 if (err < 0) {
436 log_err("Unable to write control2 register\n");
437 return -EIO;
438 }
439
440 /*
441 * Avoid extra power leakage. The RV1805 uses smaller
442 * 10pin package and the EXTI input is not present.
443 * Disable it to avoid leakage.
444 */
445 data = dm_i2c_reg_read(dev, ABX8XX_REG_OUT_CTRL);
446 if (data < 0) {
447 log_err("Unable to read output control register\n");
448 return -EIO;
449 }
450
451 /*
452 * Write the configuration key register to enable access to
453 * the config2 register
454 */
455 err = dm_i2c_reg_write(dev, ABX8XX_REG_CFG_KEY,
456 ABX8XX_CFG_KEY_MISC);
457 if (err < 0) {
458 log_err("Unable to write configuration key\n");
459 return -EIO;
460 }
461
462 err = dm_i2c_reg_write(dev, ABX8XX_REG_OUT_CTRL,
463 data | ABX8XX_OUT_CTRL_EXDS);
464 if (err < 0) {
465 log_err("Unable to write output control register\n");
466 return -EIO;
467 }
468 }
469
470 /* part autodetection */
471 if (part == ABX80X) {
472 for (i = 0; abx80x_caps[i].pn; i++)
473 if (partnumber == abx80x_caps[i].pn)
474 break;
475 if (abx80x_caps[i].pn == 0) {
476 log_err("Unknown part: %04x\n", partnumber);
477 return -EINVAL;
478 }
479 part = i;
480 }
481
482 if (partnumber != abx80x_caps[part].pn) {
483 log_err("partnumber mismatch %04x != %04x\n",
484 partnumber, abx80x_caps[part].pn);
485 return -EINVAL;
486 }
487
488 if (abx80x_caps[part].has_tc)
489 trickle_cfg = abx80x_dt_trickle_cfg(dev);
490
491 if (trickle_cfg > 0) {
492 log_debug("Enabling trickle charger: %02x\n", trickle_cfg);
493 abx80x_enable_trickle_charger(dev, trickle_cfg);
494 }
495
496 err = dm_i2c_reg_write(dev, ABX8XX_REG_CD_TIMER_CTL, BIT(2));
497 if (err)
498 return err;
499
500 return 0;
501}
502
503static const struct udevice_id abx80x_of_match[] = {
504 {
505 .compatible = "abracon,abx80x",
506 .data = ABX80X
507 },
508 {
509 .compatible = "abracon,ab0801",
510 .data = AB0801
511 },
512 {
513 .compatible = "abracon,ab0803",
514 .data = AB0803
515 },
516 {
517 .compatible = "abracon,ab0804",
518 .data = AB0804
519 },
520 {
521 .compatible = "abracon,ab0805",
522 .data = AB0805
523 },
524 {
525 .compatible = "abracon,ab1801",
526 .data = AB1801
527 },
528 {
529 .compatible = "abracon,ab1803",
530 .data = AB1803
531 },
532 {
533 .compatible = "abracon,ab1804",
534 .data = AB1804
535 },
536 {
537 .compatible = "abracon,ab1805",
538 .data = AB1805
539 },
540 {
541 .compatible = "microcrystal,rv1805",
542 .data = RV1805
543 },
544 { }
545};
546
547U_BOOT_DRIVER(abx80x_rtc) = {
548 .name = "rtc-abx80x",
549 .id = UCLASS_RTC,
550 .probe = abx80x_probe,
551 .of_match = abx80x_of_match,
552 .ops = &abx80x_rtc_ops,
553};