blob: 60400235dd0ffc39aea45e2208ba50868857d949 [file] [log] [blame]
Chris Packham0798a1c2023-03-20 10:23:44 +13001// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Analog Devices MAX313XX series I2C RTC driver
4 *
5 * Copyright 2022 Analog Devices Inc.
6 */
7#include <bcd.h>
8#include <dm.h>
9#include <i2c.h>
10#include <rtc.h>
11#include <dm/device_compat.h>
12#include <linux/bitfield.h>
13#include <linux/delay.h>
14#include <linux/kernel.h>
15
16/* common registers */
17#define MAX313XX_INT_ALARM1 BIT(0)
18#define MAX313XX_INT_ALARM2 BIT(1)
19#define MAX313XX_HRS_F_12_24 BIT(6)
20#define MAX313XX_HRS_F_AM_PM BIT(5)
21#define MAX313XX_MONTH_CENTURY BIT(7)
22
23#define MAX313XX_TMR_CFG_ENABLE BIT(4)
24#define MAX313XX_TMR_CFG_FREQ_MASK GENMASK(1, 0)
25#define MAX313XX_TMR_CFG_FREQ_16HZ 0x03
26
27#define MAX313XX_REG_MINUTE 0x01
28#define MAX313XX_REG_HOUR 0x02
29
30#define MAX313XX_TIME_SIZE 0x07
31
32/* device specific registers */
33#define MAX3134X_CFG2_REG 0x01
34#define MAX3134X_CFG2_SET_RTC BIT(1)
35
36#define MAX31341_TRICKLE_RES_MASK GENMASK(1, 0)
37#define MAX31341_TRICKLE_DIODE_EN BIT(2)
38#define MAX31341_TRICKLE_ENABLE_BIT BIT(3)
39#define MAX31341_POWER_MGMT_REG 0x56
40#define MAX31341_POWER_MGMT_TRICKLE_BIT BIT(0)
41
42#define MAX3133X_TRICKLE_RES_MASK GENMASK(2, 1)
43#define MAX3133X_TRICKLE_DIODE_EN BIT(3)
44#define MAX3133X_TRICKLE_ENABLE_BIT BIT(0)
45
46#define MAX31329_TRICKLE_ENABLE_BIT BIT(7)
47#define MAX31343_TRICKLE_ENABLE_MASK GENMASK(7, 4)
48#define MAX31343_TRICKLE_ENABLE_CODE 5
49#define MAX31329_43_TRICKLE_RES_MASK GENMASK(1, 0)
50#define MAX31329_43_TRICKLE_DIODE_EN BIT(2)
51
52#define MAX31329_CONFIG2_REG 0x04
53#define MAX31329_CONFIG2_CLKIN_EN BIT(2)
54#define MAX31329_CONFIG2_CLKIN_FREQ GENMASK(1, 0)
55
56#define MAX31341_42_CONFIG1_REG 0x00
57#define MAX31341_42_CONFIG1_CLKIN_EN BIT(7)
58#define MAX31341_42_CONFIG1_CLKIN_FREQ GENMASK(5, 4)
59#define MAX31341_42_CONFIG1_OSC_DISABLE BIT(3)
60#define MAX31341_42_CONFIG1_SWRST BIT(0)
61
62enum max313xx_ids {
63 ID_MAX31328,
64 ID_MAX31329,
65 ID_MAX31331,
66 ID_MAX31334,
67 ID_MAX31341,
68 ID_MAX31342,
69 ID_MAX31343,
70 MAX313XX_ID_NR
71};
72
73/**
74 * struct chip_desc - descriptor for MAX313xx variants
75 * @sec_reg: Offset to seconds register. Used to denote the start of the
76 * current time registers.
77 * @alarm1_sec_reg: Offset to Alarm1 seconds register. Used to denote the
78 * start of the alarm registers.
79 * @int_en_reg: Offset to the interrupt enable register.
80 * @int_status_reg: Offset to the interrupt status register.
81 * @ram_reg: Offset to the timestamp RAM (which can be used as SRAM).
82 * @ram_size: Size of the timestamp RAM.
83 * @temp_reg: Offset to the temperature register (or 0 if temperature
84 * sensor is not supported).
85 * @trickle_reg: Offset to the trickle charger configuration register (or
86 * 0 if trickle charger is not supported).
87 * @rst_reg: Offset to the reset register.
88 * @rst_bit: Bit within the reset register for the software reset.
89 */
90struct chip_desc {
91 u8 sec_reg;
92 u8 alarm1_sec_reg;
93
94 u8 int_en_reg;
95 u8 int_status_reg;
96
97 u8 ram_reg;
98 u8 ram_size;
99
100 u8 temp_reg;
101
102 u8 trickle_reg;
103
104 u8 rst_reg;
105 u8 rst_bit;
106};
107
108struct max313xx_priv {
109 enum max313xx_ids id;
110 const struct chip_desc *chip;
111};
112
113static const struct chip_desc chip[MAX313XX_ID_NR] = {
114 [ID_MAX31328] = {
115 .int_en_reg = 0x0E,
116 .int_status_reg = 0x0F,
117 .sec_reg = 0x00,
118 .alarm1_sec_reg = 0x07,
119 .temp_reg = 0x11,
120 },
121 [ID_MAX31329] = {
122 .int_en_reg = 0x01,
123 .int_status_reg = 0x00,
124 .sec_reg = 0x06,
125 .alarm1_sec_reg = 0x0D,
126 .ram_reg = 0x22,
127 .ram_size = 64,
128 .trickle_reg = 0x19,
129 .rst_reg = 0x02,
130 .rst_bit = BIT(0),
131 },
132 [ID_MAX31331] = {
133 .int_en_reg = 0x01,
134 .int_status_reg = 0x00,
135 .sec_reg = 0x08,
136 .alarm1_sec_reg = 0x0F,
137 .ram_reg = 0x20,
138 .ram_size = 32,
139 .trickle_reg = 0x1B,
140 .rst_reg = 0x02,
141 .rst_bit = BIT(0),
142 },
143 [ID_MAX31334] = {
144 .int_en_reg = 0x01,
145 .int_status_reg = 0x00,
146 .sec_reg = 0x09,
147 .alarm1_sec_reg = 0x10,
148 .ram_reg = 0x30,
149 .ram_size = 32,
150 .trickle_reg = 0x1E,
151 .rst_reg = 0x02,
152 .rst_bit = BIT(0),
153 },
154 [ID_MAX31341] = {
155 .int_en_reg = 0x04,
156 .int_status_reg = 0x05,
157 .sec_reg = 0x06,
158 .alarm1_sec_reg = 0x0D,
159 .ram_reg = 0x16,
160 .ram_size = 64,
161 .trickle_reg = 0x57,
162 .rst_reg = 0x00,
163 .rst_bit = BIT(0),
164 },
165 [ID_MAX31342] = {
166 .int_en_reg = 0x04,
167 .int_status_reg = 0x05,
168 .sec_reg = 0x06,
169 .alarm1_sec_reg = 0x0D,
170 .rst_reg = 0x00,
171 .rst_bit = BIT(0),
172 },
173 [ID_MAX31343] = {
174 .int_en_reg = 0x01,
175 .int_status_reg = 0x00,
176 .sec_reg = 0x06,
177 .alarm1_sec_reg = 0x0D,
178 .ram_reg = 0x22,
179 .ram_size = 64,
180 .temp_reg = 0x1A,
181 .trickle_reg = 0x19,
182 .rst_reg = 0x02,
183 .rst_bit = BIT(0),
184 },
185};
186
187static const u32 max313xx_trickle_ohms[] = { 3000, 6000, 11000 };
188
189static int max313xx_set_bits(struct udevice *dev, unsigned int reg, unsigned int bits)
190{
191 int ret;
192
193 ret = dm_i2c_reg_read(dev, reg);
194 if (ret < 0)
195 return ret;
196
197 return dm_i2c_reg_write(dev, reg, ret | bits);
198}
199
200static int max313xx_clear_bits(struct udevice *dev, unsigned int reg, unsigned int bits)
201{
202 int ret;
203
204 ret = dm_i2c_reg_read(dev, reg);
205 if (ret < 0)
206 return ret;
207
208 return dm_i2c_reg_write(dev, reg, ret & ~bits);
209}
210
211static int max313xx_get_hour(u8 hour_reg)
212{
213 int hour;
214
215 /* 24Hr mode */
216 if (!FIELD_GET(MAX313XX_HRS_F_12_24, hour_reg))
217 return bcd2bin(hour_reg & 0x3f);
218
219 /* 12Hr mode */
220 hour = bcd2bin(hour_reg & 0x1f);
221 if (hour == 12)
222 hour = 0;
223
224 if (FIELD_GET(MAX313XX_HRS_F_AM_PM, hour_reg))
225 hour += 12;
226
227 return hour;
228}
229
230static int max313xx_read_time(struct udevice *dev, struct rtc_time *t)
231{
232 struct max313xx_priv *rtc = dev_get_priv(dev);
233 u8 regs[7];
234 int ret;
235
236 ret = dm_i2c_read(dev, rtc->chip->sec_reg, regs, 7);
237 if (ret)
238 return ret;
239
240 t->tm_sec = bcd2bin(regs[0] & 0x7f);
241 t->tm_min = bcd2bin(regs[1] & 0x7f);
242 t->tm_hour = max313xx_get_hour(regs[2]);
243 t->tm_wday = bcd2bin(regs[3] & 0x07) - 1;
244 t->tm_mday = bcd2bin(regs[4] & 0x3f);
245 t->tm_mon = bcd2bin(regs[5] & 0x1f);
246 t->tm_year = bcd2bin(regs[6]) + 2000;
247
248 if (FIELD_GET(MAX313XX_MONTH_CENTURY, regs[5]))
249 t->tm_year += 100;
250
251 dev_dbg(dev, "read %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
252 t->tm_year, t->tm_mon, t->tm_mday,
253 t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec);
254
255 return 0;
256}
257
258static int max313xx_set_time(struct udevice *dev, const struct rtc_time *t)
259{
260 struct max313xx_priv *rtc = dev_get_priv(dev);
261 u8 regs[7];
262 int ret;
263
264 dev_dbg(dev, "set %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
265 t->tm_year, t->tm_mon, t->tm_mday,
266 t->tm_wday, t->tm_hour, t->tm_min, t->tm_sec);
267
268 if (t->tm_year < 2000) {
269 dev_err(dev, "year %d (before 2000) not supported\n",
270 t->tm_year);
271 return -EINVAL;
272 }
273
274 if (rtc->chip->rst_bit) {
275 ret = max313xx_clear_bits(dev, rtc->chip->rst_reg, rtc->chip->rst_bit);
276 if (ret)
277 return ret;
278 }
279
280 regs[0] = bin2bcd(t->tm_sec);
281 regs[1] = bin2bcd(t->tm_min);
282 regs[2] = bin2bcd(t->tm_hour);
283 regs[3] = bin2bcd(t->tm_wday + 1);
284 regs[4] = bin2bcd(t->tm_mday);
285 regs[5] = bin2bcd(t->tm_mon);
286 regs[6] = bin2bcd((t->tm_year - 2000) % 100);
287
288 if ((t->tm_year - 2000) >= 200)
289 regs[5] |= FIELD_PREP(MAX313XX_MONTH_CENTURY, 1);
290
291 ret = dm_i2c_write(dev, rtc->chip->sec_reg, regs, 7);
292 if (ret)
293 return ret;
294
295 switch (rtc->id) {
296 case ID_MAX31341:
297 case ID_MAX31342:
298 ret = max313xx_set_bits(dev, MAX3134X_CFG2_REG,
299 MAX3134X_CFG2_SET_RTC);
300 if (ret)
301 return ret;
302
303 udelay(10000);
304
305 ret = max313xx_clear_bits(dev, MAX3134X_CFG2_REG,
306 MAX3134X_CFG2_SET_RTC);
307 if (ret)
308 return ret;
309
310 break;
311 default:
312 break;
313 }
314
315 return ret;
316}
317
318static int max313xx_reset(struct udevice *dev)
319{
320 struct max313xx_priv *rtc = dev_get_priv(dev);
321 int ret = -EINVAL;
322
323 if (rtc->chip->rst_bit)
324 ret = max313xx_set_bits(dev, rtc->chip->rst_reg, rtc->chip->rst_bit);
325
326 return ret;
327}
328
Chris Packhamd6c0d702023-07-12 11:30:44 +1200329static int max313xx_read8(struct udevice *dev, unsigned int reg)
330{
331 return dm_i2c_reg_read(dev, reg);
332}
333
334static int max313xx_write8(struct udevice *dev, unsigned int reg, int val)
335{
336 return dm_i2c_reg_write(dev, reg, val);
337}
338
Chris Packham0798a1c2023-03-20 10:23:44 +1300339static const struct rtc_ops max3133x_rtc_ops = {
340 .get = max313xx_read_time,
341 .set = max313xx_set_time,
342 .reset = max313xx_reset,
Chris Packhamd6c0d702023-07-12 11:30:44 +1200343 .read8 = max313xx_read8,
344 .write8 = max313xx_write8,
Chris Packham0798a1c2023-03-20 10:23:44 +1300345};
346
347static int max313xx_init(struct udevice *dev)
348{
349 struct max313xx_priv *rtc = dev_get_priv(dev);
350 int ret;
351
352 switch (rtc->id) {
353 case ID_MAX31341:
354 case ID_MAX31342:
355 ret = max313xx_clear_bits(dev, MAX31341_42_CONFIG1_REG,
356 MAX31341_42_CONFIG1_OSC_DISABLE);
357 if (ret)
358 return ret;
359
360 return max313xx_set_bits(dev, MAX31341_42_CONFIG1_REG,
361 MAX31341_42_CONFIG1_SWRST);
362 default:
363 return 0;
364 }
365}
366
367static int max313xx_trickle_charger_setup(struct udevice *dev)
368{
369 struct max313xx_priv *rtc = dev_get_priv(dev);
370 bool diode;
371 int index, reg;
372 u32 ohms;
373 u32 chargeable;
374 int ret;
375
376 if (dev_read_u32(dev, "trickle-resistor-ohms", &ohms) ||
377 dev_read_u32(dev, "aux-voltage-chargeable", &chargeable))
378 return 0;
379
380 switch (chargeable) {
381 case 0:
382 diode = false;
383 break;
384 case 1:
385 diode = true;
386 break;
387 default:
388 dev_dbg(dev, "unsupported aux-voltage-chargeable value\n");
389 return -EINVAL;
390 }
391
392 if (!rtc->chip->trickle_reg) {
393 dev_warn(dev, "device does not have trickle charger\n");
394 return -ENOTSUPP;
395 }
396
397 index = find_closest(ohms, max313xx_trickle_ohms,
398 ARRAY_SIZE(max313xx_trickle_ohms)) + 1;
399
400 switch (rtc->id) {
401 case ID_MAX31329:
402 reg = FIELD_PREP(MAX31329_TRICKLE_ENABLE_BIT, 1) |
403 FIELD_PREP(MAX31329_43_TRICKLE_RES_MASK, index) |
404 FIELD_PREP(MAX31329_43_TRICKLE_DIODE_EN, diode);
405 break;
406 case ID_MAX31331:
407 case ID_MAX31334:
408 reg = FIELD_PREP(MAX3133X_TRICKLE_ENABLE_BIT, 1) |
409 FIELD_PREP(MAX3133X_TRICKLE_DIODE_EN, diode) |
410 FIELD_PREP(MAX3133X_TRICKLE_RES_MASK, index);
411 break;
412 case ID_MAX31341:
413 if (index == 1)
414 index = 0;
415 reg = FIELD_PREP(MAX31341_TRICKLE_ENABLE_BIT, 1) |
416 FIELD_PREP(MAX31341_TRICKLE_DIODE_EN, diode) |
417 FIELD_PREP(MAX31341_TRICKLE_RES_MASK, index);
418
419 ret = max313xx_set_bits(dev, MAX31341_POWER_MGMT_REG,
420 MAX31341_POWER_MGMT_TRICKLE_BIT);
421 if (ret)
422 return ret;
423
424 break;
425 case ID_MAX31343:
426 reg = FIELD_PREP(MAX31329_43_TRICKLE_RES_MASK, index) |
427 FIELD_PREP(MAX31329_43_TRICKLE_DIODE_EN, diode) |
428 FIELD_PREP(MAX31343_TRICKLE_ENABLE_MASK,
429 MAX31343_TRICKLE_ENABLE_CODE);
430 break;
431 default:
432 return -EOPNOTSUPP;
433 }
434
435 return dm_i2c_reg_write(dev, rtc->chip->trickle_reg, reg);
436}
437
438static int max313xx_probe(struct udevice *dev)
439{
440 struct max313xx_priv *max313xx = dev_get_priv(dev);
441 int ret;
442
443 max313xx->id = dev_get_driver_data(dev);
444 max313xx->chip = &chip[max313xx->id];
445
446 ret = max313xx_init(dev);
447 if (ret)
448 return ret;
449
450 return max313xx_trickle_charger_setup(dev);
451}
452
453static const struct udevice_id max313xx_of_id[] = {
454 { .compatible = "adi,max31328", .data = ID_MAX31328 },
455 { .compatible = "adi,max31329", .data = ID_MAX31329 },
456 { .compatible = "adi,max31331", .data = ID_MAX31331 },
457 { .compatible = "adi,max31334", .data = ID_MAX31334 },
458 { .compatible = "adi,max31341", .data = ID_MAX31341 },
459 { .compatible = "adi,max31342", .data = ID_MAX31342 },
460 { .compatible = "adi,max31343", .data = ID_MAX31343 },
461 { }
462};
463
464U_BOOT_DRIVER(rtc_max313xx) = {
465 .name = "rtc-max313xx",
466 .id = UCLASS_RTC,
467 .probe = max313xx_probe,
468 .of_match = max313xx_of_id,
469 .priv_auto = sizeof(struct max313xx_priv),
470 .ops = &max3133x_rtc_ops,
471};