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