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 }; 496