1 /* 2 * Copyright (c) 2013 Samsung Electronics Co., Ltd 3 * http://www.samsung.com 4 * 5 * Copyright (C) 2013 Google, Inc 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 */ 17 18 #include <linux/module.h> 19 #include <linux/i2c.h> 20 #include <linux/slab.h> 21 #include <linux/bcd.h> 22 #include <linux/bitops.h> 23 #include <linux/regmap.h> 24 #include <linux/rtc.h> 25 #include <linux/delay.h> 26 #include <linux/platform_device.h> 27 #include <linux/mfd/samsung/core.h> 28 #include <linux/mfd/samsung/irq.h> 29 #include <linux/mfd/samsung/rtc.h> 30 31 struct s5m_rtc_info { 32 struct device *dev; 33 struct sec_pmic_dev *s5m87xx; 34 struct regmap *rtc; 35 struct rtc_device *rtc_dev; 36 int irq; 37 int device_type; 38 int rtc_24hr_mode; 39 bool wtsr_smpl; 40 }; 41 42 static void s5m8767_data_to_tm(u8 *data, struct rtc_time *tm, 43 int rtc_24hr_mode) 44 { 45 tm->tm_sec = data[RTC_SEC] & 0x7f; 46 tm->tm_min = data[RTC_MIN] & 0x7f; 47 if (rtc_24hr_mode) { 48 tm->tm_hour = data[RTC_HOUR] & 0x1f; 49 } else { 50 tm->tm_hour = data[RTC_HOUR] & 0x0f; 51 if (data[RTC_HOUR] & HOUR_PM_MASK) 52 tm->tm_hour += 12; 53 } 54 55 tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f); 56 tm->tm_mday = data[RTC_DATE] & 0x1f; 57 tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; 58 tm->tm_year = (data[RTC_YEAR1] & 0x7f) + 100; 59 tm->tm_yday = 0; 60 tm->tm_isdst = 0; 61 } 62 63 static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data) 64 { 65 data[RTC_SEC] = tm->tm_sec; 66 data[RTC_MIN] = tm->tm_min; 67 68 if (tm->tm_hour >= 12) 69 data[RTC_HOUR] = tm->tm_hour | HOUR_PM_MASK; 70 else 71 data[RTC_HOUR] = tm->tm_hour & ~HOUR_PM_MASK; 72 73 data[RTC_WEEKDAY] = 1 << tm->tm_wday; 74 data[RTC_DATE] = tm->tm_mday; 75 data[RTC_MONTH] = tm->tm_mon + 1; 76 data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; 77 78 if (tm->tm_year < 100) { 79 pr_err("s5m8767 RTC cannot handle the year %d.\n", 80 1900 + tm->tm_year); 81 return -EINVAL; 82 } else { 83 return 0; 84 } 85 } 86 87 static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info) 88 { 89 int ret; 90 unsigned int data; 91 92 ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data); 93 if (ret < 0) { 94 dev_err(info->dev, "failed to read update reg(%d)\n", ret); 95 return ret; 96 } 97 98 data |= RTC_TIME_EN_MASK; 99 data |= RTC_UDR_MASK; 100 101 ret = regmap_write(info->rtc, SEC_RTC_UDR_CON, data); 102 if (ret < 0) { 103 dev_err(info->dev, "failed to write update reg(%d)\n", ret); 104 return ret; 105 } 106 107 do { 108 ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data); 109 } while ((data & RTC_UDR_MASK) && !ret); 110 111 return ret; 112 } 113 114 static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) 115 { 116 int ret; 117 unsigned int data; 118 119 ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data); 120 if (ret < 0) { 121 dev_err(info->dev, "%s: fail to read update reg(%d)\n", 122 __func__, ret); 123 return ret; 124 } 125 126 data &= ~RTC_TIME_EN_MASK; 127 data |= RTC_UDR_MASK; 128 129 ret = regmap_write(info->rtc, SEC_RTC_UDR_CON, data); 130 if (ret < 0) { 131 dev_err(info->dev, "%s: fail to write update reg(%d)\n", 132 __func__, ret); 133 return ret; 134 } 135 136 do { 137 ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &data); 138 } while ((data & RTC_UDR_MASK) && !ret); 139 140 return ret; 141 } 142 143 static void s5m8763_data_to_tm(u8 *data, struct rtc_time *tm) 144 { 145 tm->tm_sec = bcd2bin(data[RTC_SEC]); 146 tm->tm_min = bcd2bin(data[RTC_MIN]); 147 148 if (data[RTC_HOUR] & HOUR_12) { 149 tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f); 150 if (data[RTC_HOUR] & HOUR_PM) 151 tm->tm_hour += 12; 152 } else { 153 tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f); 154 } 155 156 tm->tm_wday = data[RTC_WEEKDAY] & 0x07; 157 tm->tm_mday = bcd2bin(data[RTC_DATE]); 158 tm->tm_mon = bcd2bin(data[RTC_MONTH]); 159 tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100; 160 tm->tm_year -= 1900; 161 } 162 163 static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data) 164 { 165 data[RTC_SEC] = bin2bcd(tm->tm_sec); 166 data[RTC_MIN] = bin2bcd(tm->tm_min); 167 data[RTC_HOUR] = bin2bcd(tm->tm_hour); 168 data[RTC_WEEKDAY] = tm->tm_wday; 169 data[RTC_DATE] = bin2bcd(tm->tm_mday); 170 data[RTC_MONTH] = bin2bcd(tm->tm_mon); 171 data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100); 172 data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100); 173 } 174 175 static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) 176 { 177 struct s5m_rtc_info *info = dev_get_drvdata(dev); 178 u8 data[8]; 179 int ret; 180 181 ret = regmap_bulk_read(info->rtc, SEC_RTC_SEC, data, 8); 182 if (ret < 0) 183 return ret; 184 185 switch (info->device_type) { 186 case S5M8763X: 187 s5m8763_data_to_tm(data, tm); 188 break; 189 190 case S5M8767X: 191 s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode); 192 break; 193 194 default: 195 return -EINVAL; 196 } 197 198 dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, 199 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, 200 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday); 201 202 return rtc_valid_tm(tm); 203 } 204 205 static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) 206 { 207 struct s5m_rtc_info *info = dev_get_drvdata(dev); 208 u8 data[8]; 209 int ret = 0; 210 211 switch (info->device_type) { 212 case S5M8763X: 213 s5m8763_tm_to_data(tm, data); 214 break; 215 case S5M8767X: 216 ret = s5m8767_tm_to_data(tm, data); 217 break; 218 default: 219 return -EINVAL; 220 } 221 222 if (ret < 0) 223 return ret; 224 225 dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, 226 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, 227 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday); 228 229 ret = regmap_raw_write(info->rtc, SEC_RTC_SEC, data, 8); 230 if (ret < 0) 231 return ret; 232 233 ret = s5m8767_rtc_set_time_reg(info); 234 235 return ret; 236 } 237 238 static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 239 { 240 struct s5m_rtc_info *info = dev_get_drvdata(dev); 241 u8 data[8]; 242 unsigned int val; 243 int ret, i; 244 245 ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8); 246 if (ret < 0) 247 return ret; 248 249 switch (info->device_type) { 250 case S5M8763X: 251 s5m8763_data_to_tm(data, &alrm->time); 252 ret = regmap_read(info->rtc, SEC_ALARM0_CONF, &val); 253 if (ret < 0) 254 return ret; 255 256 alrm->enabled = !!val; 257 258 ret = regmap_read(info->rtc, SEC_RTC_STATUS, &val); 259 if (ret < 0) 260 return ret; 261 262 break; 263 264 case S5M8767X: 265 s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); 266 dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, 267 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon, 268 alrm->time.tm_mday, alrm->time.tm_hour, 269 alrm->time.tm_min, alrm->time.tm_sec, 270 alrm->time.tm_wday); 271 272 alrm->enabled = 0; 273 for (i = 0; i < 7; i++) { 274 if (data[i] & ALARM_ENABLE_MASK) { 275 alrm->enabled = 1; 276 break; 277 } 278 } 279 280 alrm->pending = 0; 281 ret = regmap_read(info->rtc, SEC_RTC_STATUS, &val); 282 if (ret < 0) 283 return ret; 284 break; 285 286 default: 287 return -EINVAL; 288 } 289 290 if (val & ALARM0_STATUS) 291 alrm->pending = 1; 292 else 293 alrm->pending = 0; 294 295 return 0; 296 } 297 298 static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) 299 { 300 u8 data[8]; 301 int ret, i; 302 struct rtc_time tm; 303 304 ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8); 305 if (ret < 0) 306 return ret; 307 308 s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode); 309 dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, 310 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, 311 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday); 312 313 switch (info->device_type) { 314 case S5M8763X: 315 ret = regmap_write(info->rtc, SEC_ALARM0_CONF, 0); 316 break; 317 318 case S5M8767X: 319 for (i = 0; i < 7; i++) 320 data[i] &= ~ALARM_ENABLE_MASK; 321 322 ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8); 323 if (ret < 0) 324 return ret; 325 326 ret = s5m8767_rtc_set_alarm_reg(info); 327 328 break; 329 330 default: 331 return -EINVAL; 332 } 333 334 return ret; 335 } 336 337 static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) 338 { 339 int ret; 340 u8 data[8]; 341 u8 alarm0_conf; 342 struct rtc_time tm; 343 344 ret = regmap_bulk_read(info->rtc, SEC_ALARM0_SEC, data, 8); 345 if (ret < 0) 346 return ret; 347 348 s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode); 349 dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, 350 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, 351 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday); 352 353 switch (info->device_type) { 354 case S5M8763X: 355 alarm0_conf = 0x77; 356 ret = regmap_write(info->rtc, SEC_ALARM0_CONF, alarm0_conf); 357 break; 358 359 case S5M8767X: 360 data[RTC_SEC] |= ALARM_ENABLE_MASK; 361 data[RTC_MIN] |= ALARM_ENABLE_MASK; 362 data[RTC_HOUR] |= ALARM_ENABLE_MASK; 363 data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK; 364 if (data[RTC_DATE] & 0x1f) 365 data[RTC_DATE] |= ALARM_ENABLE_MASK; 366 if (data[RTC_MONTH] & 0xf) 367 data[RTC_MONTH] |= ALARM_ENABLE_MASK; 368 if (data[RTC_YEAR1] & 0x7f) 369 data[RTC_YEAR1] |= ALARM_ENABLE_MASK; 370 371 ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8); 372 if (ret < 0) 373 return ret; 374 ret = s5m8767_rtc_set_alarm_reg(info); 375 376 break; 377 378 default: 379 return -EINVAL; 380 } 381 382 return ret; 383 } 384 385 static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 386 { 387 struct s5m_rtc_info *info = dev_get_drvdata(dev); 388 u8 data[8]; 389 int ret; 390 391 switch (info->device_type) { 392 case S5M8763X: 393 s5m8763_tm_to_data(&alrm->time, data); 394 break; 395 396 case S5M8767X: 397 s5m8767_tm_to_data(&alrm->time, data); 398 break; 399 400 default: 401 return -EINVAL; 402 } 403 404 dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__, 405 1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon, 406 alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min, 407 alrm->time.tm_sec, alrm->time.tm_wday); 408 409 ret = s5m_rtc_stop_alarm(info); 410 if (ret < 0) 411 return ret; 412 413 ret = regmap_raw_write(info->rtc, SEC_ALARM0_SEC, data, 8); 414 if (ret < 0) 415 return ret; 416 417 ret = s5m8767_rtc_set_alarm_reg(info); 418 if (ret < 0) 419 return ret; 420 421 if (alrm->enabled) 422 ret = s5m_rtc_start_alarm(info); 423 424 return ret; 425 } 426 427 static int s5m_rtc_alarm_irq_enable(struct device *dev, 428 unsigned int enabled) 429 { 430 struct s5m_rtc_info *info = dev_get_drvdata(dev); 431 432 if (enabled) 433 return s5m_rtc_start_alarm(info); 434 else 435 return s5m_rtc_stop_alarm(info); 436 } 437 438 static irqreturn_t s5m_rtc_alarm_irq(int irq, void *data) 439 { 440 struct s5m_rtc_info *info = data; 441 442 rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); 443 444 return IRQ_HANDLED; 445 } 446 447 static const struct rtc_class_ops s5m_rtc_ops = { 448 .read_time = s5m_rtc_read_time, 449 .set_time = s5m_rtc_set_time, 450 .read_alarm = s5m_rtc_read_alarm, 451 .set_alarm = s5m_rtc_set_alarm, 452 .alarm_irq_enable = s5m_rtc_alarm_irq_enable, 453 }; 454 455 static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable) 456 { 457 int ret; 458 ret = regmap_update_bits(info->rtc, SEC_WTSR_SMPL_CNTL, 459 WTSR_ENABLE_MASK, 460 enable ? WTSR_ENABLE_MASK : 0); 461 if (ret < 0) 462 dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", 463 __func__, ret); 464 } 465 466 static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable) 467 { 468 int ret; 469 ret = regmap_update_bits(info->rtc, SEC_WTSR_SMPL_CNTL, 470 SMPL_ENABLE_MASK, 471 enable ? SMPL_ENABLE_MASK : 0); 472 if (ret < 0) 473 dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", 474 __func__, ret); 475 } 476 477 static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) 478 { 479 u8 data[2]; 480 unsigned int tp_read; 481 int ret; 482 struct rtc_time tm; 483 484 ret = regmap_read(info->rtc, SEC_RTC_UDR_CON, &tp_read); 485 if (ret < 0) { 486 dev_err(info->dev, "%s: fail to read control reg(%d)\n", 487 __func__, ret); 488 return ret; 489 } 490 491 /* Set RTC control register : Binary mode, 24hour mode */ 492 data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); 493 data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); 494 495 info->rtc_24hr_mode = 1; 496 ret = regmap_raw_write(info->rtc, SEC_ALARM0_CONF, data, 2); 497 if (ret < 0) { 498 dev_err(info->dev, "%s: fail to write controlm reg(%d)\n", 499 __func__, ret); 500 return ret; 501 } 502 503 /* In first boot time, Set rtc time to 1/1/2012 00:00:00(SUN) */ 504 if ((tp_read & RTC_TCON_MASK) == 0) { 505 dev_dbg(info->dev, "rtc init\n"); 506 tm.tm_sec = 0; 507 tm.tm_min = 0; 508 tm.tm_hour = 0; 509 tm.tm_wday = 0; 510 tm.tm_mday = 1; 511 tm.tm_mon = 0; 512 tm.tm_year = 112; 513 tm.tm_yday = 0; 514 tm.tm_isdst = 0; 515 ret = s5m_rtc_set_time(info->dev, &tm); 516 } 517 518 ret = regmap_update_bits(info->rtc, SEC_RTC_UDR_CON, 519 RTC_TCON_MASK, tp_read | RTC_TCON_MASK); 520 if (ret < 0) 521 dev_err(info->dev, "%s: fail to update TCON reg(%d)\n", 522 __func__, ret); 523 524 return ret; 525 } 526 527 static int s5m_rtc_probe(struct platform_device *pdev) 528 { 529 struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent); 530 struct sec_platform_data *pdata = s5m87xx->pdata; 531 struct s5m_rtc_info *info; 532 int ret; 533 534 if (!pdata) { 535 dev_err(pdev->dev.parent, "Platform data not supplied\n"); 536 return -ENODEV; 537 } 538 539 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 540 if (!info) 541 return -ENOMEM; 542 543 info->dev = &pdev->dev; 544 info->s5m87xx = s5m87xx; 545 info->rtc = s5m87xx->rtc; 546 info->device_type = s5m87xx->device_type; 547 info->wtsr_smpl = s5m87xx->wtsr_smpl; 548 549 switch (pdata->device_type) { 550 case S5M8763X: 551 info->irq = s5m87xx->irq_base + S5M8763_IRQ_ALARM0; 552 break; 553 554 case S5M8767X: 555 info->irq = s5m87xx->irq_base + S5M8767_IRQ_RTCA1; 556 break; 557 558 default: 559 ret = -EINVAL; 560 dev_err(&pdev->dev, "Unsupported device type: %d\n", ret); 561 return ret; 562 } 563 564 platform_set_drvdata(pdev, info); 565 566 ret = s5m8767_rtc_init_reg(info); 567 568 if (info->wtsr_smpl) { 569 s5m_rtc_enable_wtsr(info, true); 570 s5m_rtc_enable_smpl(info, true); 571 } 572 573 device_init_wakeup(&pdev->dev, 1); 574 575 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc", 576 &s5m_rtc_ops, THIS_MODULE); 577 578 if (IS_ERR(info->rtc_dev)) 579 return PTR_ERR(info->rtc_dev); 580 581 ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, 582 s5m_rtc_alarm_irq, 0, "rtc-alarm0", 583 info); 584 if (ret < 0) 585 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", 586 info->irq, ret); 587 588 return ret; 589 } 590 591 static void s5m_rtc_shutdown(struct platform_device *pdev) 592 { 593 struct s5m_rtc_info *info = platform_get_drvdata(pdev); 594 int i; 595 unsigned int val = 0; 596 if (info->wtsr_smpl) { 597 for (i = 0; i < 3; i++) { 598 s5m_rtc_enable_wtsr(info, false); 599 regmap_read(info->rtc, SEC_WTSR_SMPL_CNTL, &val); 600 pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val); 601 if (val & WTSR_ENABLE_MASK) 602 pr_emerg("%s: fail to disable WTSR\n", 603 __func__); 604 else { 605 pr_info("%s: success to disable WTSR\n", 606 __func__); 607 break; 608 } 609 } 610 } 611 /* Disable SMPL when power off */ 612 s5m_rtc_enable_smpl(info, false); 613 } 614 615 static const struct platform_device_id s5m_rtc_id[] = { 616 { "s5m-rtc", 0 }, 617 }; 618 619 static struct platform_driver s5m_rtc_driver = { 620 .driver = { 621 .name = "s5m-rtc", 622 .owner = THIS_MODULE, 623 }, 624 .probe = s5m_rtc_probe, 625 .shutdown = s5m_rtc_shutdown, 626 .id_table = s5m_rtc_id, 627 }; 628 629 module_platform_driver(s5m_rtc_driver); 630 631 /* Module information */ 632 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); 633 MODULE_DESCRIPTION("Samsung S5M RTC driver"); 634 MODULE_LICENSE("GPL"); 635 MODULE_ALIAS("platform:s5m-rtc"); 636