aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-max77686.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-max77686.c')
-rw-r--r--drivers/rtc/rtc-max77686.c167
1 files changed, 39 insertions, 128 deletions
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 9efe118a28ba..cf73e969c8cc 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -32,15 +32,6 @@
32#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) 32#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT)
33#define RTC_RBUDR_SHIFT 4 33#define RTC_RBUDR_SHIFT 4
34#define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) 34#define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT)
35/* WTSR and SMPL Register */
36#define WTSRT_SHIFT 0
37#define SMPLT_SHIFT 2
38#define WTSR_EN_SHIFT 6
39#define SMPL_EN_SHIFT 7
40#define WTSRT_MASK (3 << WTSRT_SHIFT)
41#define SMPLT_MASK (3 << SMPLT_SHIFT)
42#define WTSR_EN_MASK (1 << WTSR_EN_SHIFT)
43#define SMPL_EN_MASK (1 << SMPL_EN_SHIFT)
44/* RTC Hour register */ 35/* RTC Hour register */
45#define HOUR_PM_SHIFT 6 36#define HOUR_PM_SHIFT 6
46#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) 37#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT)
@@ -49,7 +40,6 @@
49#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) 40#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT)
50 41
51#define MAX77686_RTC_UPDATE_DELAY 16 42#define MAX77686_RTC_UPDATE_DELAY 16
52#undef MAX77686_RTC_WTSR_SMPL
53 43
54enum { 44enum {
55 RTC_SEC = 0, 45 RTC_SEC = 0,
@@ -80,16 +70,6 @@ enum MAX77686_RTC_OP {
80 MAX77686_RTC_READ, 70 MAX77686_RTC_READ,
81}; 71};
82 72
83static inline int max77686_rtc_calculate_wday(u8 shifted)
84{
85 int counter = -1;
86 while (shifted) {
87 shifted >>= 1;
88 counter++;
89 }
90 return counter;
91}
92
93static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, 73static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm,
94 int rtc_24hr_mode) 74 int rtc_24hr_mode)
95{ 75{
@@ -103,7 +83,8 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm,
103 tm->tm_hour += 12; 83 tm->tm_hour += 12;
104 } 84 }
105 85
106 tm->tm_wday = max77686_rtc_calculate_wday(data[RTC_WEEKDAY] & 0x7f); 86 /* Only a single bit is set in data[], so fls() would be equivalent */
87 tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f) - 1;
107 tm->tm_mday = data[RTC_DATE] & 0x1f; 88 tm->tm_mday = data[RTC_DATE] & 0x1f;
108 tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; 89 tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
109 tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; 90 tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100;
@@ -412,64 +393,6 @@ static const struct rtc_class_ops max77686_rtc_ops = {
412 .alarm_irq_enable = max77686_rtc_alarm_irq_enable, 393 .alarm_irq_enable = max77686_rtc_alarm_irq_enable,
413}; 394};
414 395
415#ifdef MAX77686_RTC_WTSR_SMPL
416static void max77686_rtc_enable_wtsr(struct max77686_rtc_info *info, bool enable)
417{
418 int ret;
419 unsigned int val, mask;
420
421 if (enable)
422 val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT);
423 else
424 val = 0;
425
426 mask = WTSR_EN_MASK | WTSRT_MASK;
427
428 dev_info(info->dev, "%s: %s WTSR\n", __func__,
429 enable ? "enable" : "disable");
430
431 ret = regmap_update_bits(info->max77686->rtc_regmap,
432 MAX77686_WTSR_SMPL_CNTL, mask, val);
433 if (ret < 0) {
434 dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n",
435 __func__, ret);
436 return;
437 }
438
439 max77686_rtc_update(info, MAX77686_RTC_WRITE);
440}
441
442static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable)
443{
444 int ret;
445 unsigned int val, mask;
446
447 if (enable)
448 val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT);
449 else
450 val = 0;
451
452 mask = SMPL_EN_MASK | SMPLT_MASK;
453
454 dev_info(info->dev, "%s: %s SMPL\n", __func__,
455 enable ? "enable" : "disable");
456
457 ret = regmap_update_bits(info->max77686->rtc_regmap,
458 MAX77686_WTSR_SMPL_CNTL, mask, val);
459 if (ret < 0) {
460 dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n",
461 __func__, ret);
462 return;
463 }
464
465 max77686_rtc_update(info, MAX77686_RTC_WRITE);
466
467 val = 0;
468 regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val);
469 dev_info(info->dev, "%s: WTSR_SMPL(0x%02x)\n", __func__, val);
470}
471#endif /* MAX77686_RTC_WTSR_SMPL */
472
473static int max77686_rtc_init_reg(struct max77686_rtc_info *info) 396static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
474{ 397{
475 u8 data[2]; 398 u8 data[2];
@@ -492,16 +415,11 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
492 return ret; 415 return ret;
493} 416}
494 417
495static struct regmap_config max77686_rtc_regmap_config = {
496 .reg_bits = 8,
497 .val_bits = 8,
498};
499
500static int max77686_rtc_probe(struct platform_device *pdev) 418static int max77686_rtc_probe(struct platform_device *pdev)
501{ 419{
502 struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent); 420 struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent);
503 struct max77686_rtc_info *info; 421 struct max77686_rtc_info *info;
504 int ret, virq; 422 int ret;
505 423
506 dev_info(&pdev->dev, "%s\n", __func__); 424 dev_info(&pdev->dev, "%s\n", __func__);
507 425
@@ -514,14 +432,7 @@ static int max77686_rtc_probe(struct platform_device *pdev)
514 info->dev = &pdev->dev; 432 info->dev = &pdev->dev;
515 info->max77686 = max77686; 433 info->max77686 = max77686;
516 info->rtc = max77686->rtc; 434 info->rtc = max77686->rtc;
517 info->max77686->rtc_regmap = devm_regmap_init_i2c(info->max77686->rtc, 435
518 &max77686_rtc_regmap_config);
519 if (IS_ERR(info->max77686->rtc_regmap)) {
520 ret = PTR_ERR(info->max77686->rtc_regmap);
521 dev_err(info->max77686->dev, "Failed to allocate register map: %d\n",
522 ret);
523 return ret;
524 }
525 platform_set_drvdata(pdev, info); 436 platform_set_drvdata(pdev, info);
526 437
527 ret = max77686_rtc_init_reg(info); 438 ret = max77686_rtc_init_reg(info);
@@ -531,34 +442,34 @@ static int max77686_rtc_probe(struct platform_device *pdev)
531 goto err_rtc; 442 goto err_rtc;
532 } 443 }
533 444
534#ifdef MAX77686_RTC_WTSR_SMPL
535 max77686_rtc_enable_wtsr(info, true);
536 max77686_rtc_enable_smpl(info, true);
537#endif
538
539 device_init_wakeup(&pdev->dev, 1); 445 device_init_wakeup(&pdev->dev, 1);
540 446
541 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc", 447 info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc",
542 &max77686_rtc_ops, THIS_MODULE); 448 &max77686_rtc_ops, THIS_MODULE);
543 449
544 if (IS_ERR(info->rtc_dev)) { 450 if (IS_ERR(info->rtc_dev)) {
545 dev_info(&pdev->dev, "%s: fail\n", __func__);
546
547 ret = PTR_ERR(info->rtc_dev); 451 ret = PTR_ERR(info->rtc_dev);
548 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); 452 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
549 if (ret == 0) 453 if (ret == 0)
550 ret = -EINVAL; 454 ret = -EINVAL;
551 goto err_rtc; 455 goto err_rtc;
552 } 456 }
553 virq = irq_create_mapping(max77686->irq_domain, MAX77686_RTCIRQ_RTCA1); 457
554 if (!virq) { 458 if (!max77686->rtc_irq_data) {
459 ret = -EINVAL;
460 dev_err(&pdev->dev, "%s: no RTC regmap IRQ chip\n", __func__);
461 goto err_rtc;
462 }
463
464 info->virq = regmap_irq_get_virq(max77686->rtc_irq_data,
465 MAX77686_RTCIRQ_RTCA1);
466 if (!info->virq) {
555 ret = -ENXIO; 467 ret = -ENXIO;
556 goto err_rtc; 468 goto err_rtc;
557 } 469 }
558 info->virq = virq;
559 470
560 ret = devm_request_threaded_irq(&pdev->dev, virq, NULL, 471 ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL,
561 max77686_rtc_alarm_irq, 0, "rtc-alarm0", info); 472 max77686_rtc_alarm_irq, 0, "rtc-alarm1", info);
562 if (ret < 0) 473 if (ret < 0)
563 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", 474 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
564 info->virq, ret); 475 info->virq, ret);
@@ -567,33 +478,33 @@ err_rtc:
567 return ret; 478 return ret;
568} 479}
569 480
570static void max77686_rtc_shutdown(struct platform_device *pdev) 481#ifdef CONFIG_PM_SLEEP
482static int max77686_rtc_suspend(struct device *dev)
571{ 483{
572#ifdef MAX77686_RTC_WTSR_SMPL 484 if (device_may_wakeup(dev)) {
573 struct max77686_rtc_info *info = platform_get_drvdata(pdev); 485 struct max77686_rtc_info *info = dev_get_drvdata(dev);
574 int i; 486
575 u8 val = 0; 487 return enable_irq_wake(info->virq);
576
577 for (i = 0; i < 3; i++) {
578 max77686_rtc_enable_wtsr(info, false);
579 regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val);
580 dev_info(info->dev, "%s: WTSR_SMPL reg(0x%02x)\n", __func__,
581 val);
582 if (val & WTSR_EN_MASK) {
583 dev_emerg(info->dev, "%s: fail to disable WTSR\n",
584 __func__);
585 } else {
586 dev_info(info->dev, "%s: success to disable WTSR\n",
587 __func__);
588 break;
589 }
590 } 488 }
591 489
592 /* Disable SMPL when power off */ 490 return 0;
593 max77686_rtc_enable_smpl(info, false);
594#endif /* MAX77686_RTC_WTSR_SMPL */
595} 491}
596 492
493static int max77686_rtc_resume(struct device *dev)
494{
495 if (device_may_wakeup(dev)) {
496 struct max77686_rtc_info *info = dev_get_drvdata(dev);
497
498 return disable_irq_wake(info->virq);
499 }
500
501 return 0;
502}
503#endif
504
505static SIMPLE_DEV_PM_OPS(max77686_rtc_pm_ops,
506 max77686_rtc_suspend, max77686_rtc_resume);
507
597static const struct platform_device_id rtc_id[] = { 508static const struct platform_device_id rtc_id[] = {
598 { "max77686-rtc", 0 }, 509 { "max77686-rtc", 0 },
599 {}, 510 {},
@@ -603,9 +514,9 @@ static struct platform_driver max77686_rtc_driver = {
603 .driver = { 514 .driver = {
604 .name = "max77686-rtc", 515 .name = "max77686-rtc",
605 .owner = THIS_MODULE, 516 .owner = THIS_MODULE,
517 .pm = &max77686_rtc_pm_ops,
606 }, 518 },
607 .probe = max77686_rtc_probe, 519 .probe = max77686_rtc_probe,
608 .shutdown = max77686_rtc_shutdown,
609 .id_table = rtc_id, 520 .id_table = rtc_id,
610}; 521};
611 522