aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2016-03-06 10:27:48 -0500
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2016-03-14 12:08:35 -0400
commit080481f54ef621211d6c75a03dc652fb6ed04222 (patch)
treefec4fb13bc3670f85568f650a13ac936a34d2914 /drivers/rtc
parent370927c4b651539c65dd8d17dd5079526cd8401d (diff)
rtc: merge ds3232 and ds3234
According to "Feature Comparison of the DS323x Real-Time Clocks" (http://pdfserv.maximintegrated.com/en/an/AN5143.pdf), DS3232 and DS3234 are very similar. This merges rtc-ds3232 and rtc-ds3234 with using regmap. This change also enables to support alarm for ds3234. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Suggested-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig44
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-ds3232.c167
-rw-r--r--drivers/rtc/rtc-ds3234.c171
4 files changed, 189 insertions, 194 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 9babb4ccd65b..987c50168fd8 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -247,16 +247,6 @@ config RTC_DRV_DS1672
247 This driver can also be built as a module. If so, the module 247 This driver can also be built as a module. If so, the module
248 will be called rtc-ds1672. 248 will be called rtc-ds1672.
249 249
250config RTC_DRV_DS3232
251 tristate "Dallas/Maxim DS3232"
252 help
253 If you say yes here you get support for Dallas Semiconductor
254 DS3232 real-time clock chips. If an interrupt is associated
255 with the device, the alarm functionality is supported.
256
257 This driver can also be built as a module. If so, the module
258 will be called rtc-ds3232.
259
260config RTC_DRV_HYM8563 250config RTC_DRV_HYM8563
261 tristate "Haoyu Microelectronics HYM8563" 251 tristate "Haoyu Microelectronics HYM8563"
262 depends on OF 252 depends on OF
@@ -733,15 +723,6 @@ config RTC_DRV_MAX6902
733 This driver can also be built as a module. If so, the module 723 This driver can also be built as a module. If so, the module
734 will be called rtc-max6902. 724 will be called rtc-max6902.
735 725
736config RTC_DRV_DS3234
737 tristate "Maxim/Dallas DS3234"
738 help
739 If you say yes here you get support for the
740 Maxim/Dallas DS3234 SPI RTC chip.
741
742 This driver can also be built as a module. If so, the module
743 will be called rtc-ds3234.
744
745config RTC_DRV_PCF2123 726config RTC_DRV_PCF2123
746 tristate "NXP PCF2123" 727 tristate "NXP PCF2123"
747 help 728 help
@@ -761,6 +742,31 @@ config RTC_DRV_MCP795
761 742
762endif # SPI_MASTER 743endif # SPI_MASTER
763 744
745#
746# Helper to resolve issues with configs that have SPI enabled but I2C
747# modular. See SND_SOC_I2C_AND_SPI for more information
748#
749config RTC_I2C_AND_SPI
750 tristate
751 default m if I2C=m
752 default y if I2C=y
753 default y if SPI_MASTER=y
754 select REGMAP_I2C if I2C
755 select REGMAP_SPI if SPI_MASTER
756
757comment "SPI and I2C RTC drivers"
758
759config RTC_DRV_DS3232
760 tristate "Dallas/Maxim DS3232/DS3234"
761 depends on RTC_I2C_AND_SPI
762 help
763 If you say yes here you get support for Dallas Semiconductor
764 DS3232 and DS3234 real-time clock chips. If an interrupt is associated
765 with the device, the alarm functionality is supported.
766
767 This driver can also be built as a module. If so, the module
768 will be called rtc-ds3232.
769
764comment "Platform RTC drivers" 770comment "Platform RTC drivers"
765 771
766# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h> 772# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 27229d2a466b..ea2833723fa9 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -60,7 +60,6 @@ obj-$(CONFIG_RTC_DRV_DS1685_FAMILY) += rtc-ds1685.o
60obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o 60obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
61obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o 61obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o
62obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o 62obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o
63obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o
64obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o 63obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o
65obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o 64obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o
66obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o 65obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 5791f996fa32..ca43bfcbb846 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C 2 * RTC client/driver for the Maxim/Dallas DS3232/DS3234 Real-Time Clock
3 * 3 *
4 * Copyright (C) 2009-2011 Freescale Semiconductor. 4 * Copyright (C) 2009-2011 Freescale Semiconductor.
5 * Author: Jack Lan <jack.lan@freescale.com> 5 * Author: Jack Lan <jack.lan@freescale.com>
6 * Copyright (C) 2008 MIMOMax Wireless Ltd.
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
@@ -16,6 +17,7 @@
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/interrupt.h> 18#include <linux/interrupt.h>
18#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/spi/spi.h>
19#include <linux/rtc.h> 21#include <linux/rtc.h>
20#include <linux/bcd.h> 22#include <linux/bcd.h>
21#include <linux/workqueue.h> 23#include <linux/workqueue.h>
@@ -481,6 +483,8 @@ static const struct dev_pm_ops ds3232_pm_ops = {
481 SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume) 483 SET_SYSTEM_SLEEP_PM_OPS(ds3232_suspend, ds3232_resume)
482}; 484};
483 485
486#if IS_ENABLED(CONFIG_I2C)
487
484static int ds3232_i2c_probe(struct i2c_client *client, 488static int ds3232_i2c_probe(struct i2c_client *client,
485 const struct i2c_device_id *id) 489 const struct i2c_device_id *id)
486{ 490{
@@ -520,8 +524,165 @@ static struct i2c_driver ds3232_driver = {
520 .remove = ds3232_i2c_remove, 524 .remove = ds3232_i2c_remove,
521 .id_table = ds3232_id, 525 .id_table = ds3232_id,
522}; 526};
523module_i2c_driver(ds3232_driver); 527
528static int ds3232_register_driver(void)
529{
530 return i2c_add_driver(&ds3232_driver);
531}
532
533static void ds3232_unregister_driver(void)
534{
535 i2c_del_driver(&ds3232_driver);
536}
537
538#else
539
540static int ds3232_register_driver(void)
541{
542 return 0;
543}
544
545static void ds3232_unregister_driver(void)
546{
547}
548
549#endif
550
551#if IS_ENABLED(CONFIG_SPI_MASTER)
552
553static int ds3234_probe(struct spi_device *spi)
554{
555 int res;
556 unsigned int tmp;
557 static const struct regmap_config config = {
558 .reg_bits = 8,
559 .val_bits = 8,
560 .write_flag_mask = 0x80,
561 };
562 struct regmap *regmap;
563
564 regmap = devm_regmap_init_spi(spi, &config);
565 if (IS_ERR(regmap)) {
566 dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
567 __func__, PTR_ERR(regmap));
568 return PTR_ERR(regmap);
569 }
570
571 spi->mode = SPI_MODE_3;
572 spi->bits_per_word = 8;
573 spi_setup(spi);
574
575 res = regmap_read(regmap, DS3232_REG_SECONDS, &tmp);
576 if (res)
577 return res;
578
579 /* Control settings
580 *
581 * CONTROL_REG
582 * BIT 7 6 5 4 3 2 1 0
583 * EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE
584 *
585 * 0 0 0 1 1 1 0 0
586 *
587 * CONTROL_STAT_REG
588 * BIT 7 6 5 4 3 2 1 0
589 * OSF BB32kHz CRATE1 CRATE0 EN32kHz BSY A2F A1F
590 *
591 * 1 0 0 0 1 0 0 0
592 */
593 res = regmap_read(regmap, DS3232_REG_CR, &tmp);
594 if (res)
595 return res;
596 res = regmap_write(regmap, DS3232_REG_CR, tmp & 0x1c);
597 if (res)
598 return res;
599
600 res = regmap_read(regmap, DS3232_REG_SR, &tmp);
601 if (res)
602 return res;
603 res = regmap_write(regmap, DS3232_REG_SR, tmp & 0x88);
604 if (res)
605 return res;
606
607 /* Print our settings */
608 res = regmap_read(regmap, DS3232_REG_CR, &tmp);
609 if (res)
610 return res;
611 dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
612
613 res = regmap_read(regmap, DS3232_REG_SR, &tmp);
614 if (res)
615 return res;
616 dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
617
618 return ds3232_probe(&spi->dev, regmap, spi->irq, "ds3234");
619}
620
621static int ds3234_remove(struct spi_device *spi)
622{
623 return ds3232_remove(&spi->dev);
624}
625
626static struct spi_driver ds3234_driver = {
627 .driver = {
628 .name = "ds3234",
629 },
630 .probe = ds3234_probe,
631 .remove = ds3234_remove,
632};
633
634static int ds3234_register_driver(void)
635{
636 return spi_register_driver(&ds3234_driver);
637}
638
639static void ds3234_unregister_driver(void)
640{
641 spi_unregister_driver(&ds3234_driver);
642}
643
644#else
645
646static int ds3234_register_driver(void)
647{
648 return 0;
649}
650
651static void ds3234_unregister_driver(void)
652{
653}
654
655#endif
656
657static int __init ds323x_init(void)
658{
659 int ret;
660
661 ret = ds3232_register_driver();
662 if (ret) {
663 pr_err("Failed to register ds3232 driver: %d\n", ret);
664 return ret;
665 }
666
667 ret = ds3234_register_driver();
668 if (ret) {
669 pr_err("Failed to register ds3234 driver: %d\n", ret);
670 ds3232_unregister_driver();
671 }
672
673 return ret;
674}
675module_init(ds323x_init)
676
677static void __exit ds323x_exit(void)
678{
679 ds3234_unregister_driver();
680 ds3232_unregister_driver();
681}
682module_exit(ds323x_exit)
524 683
525MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>"); 684MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
526MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver"); 685MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
686MODULE_DESCRIPTION("Maxim/Dallas DS3232/DS3234 RTC Driver");
527MODULE_LICENSE("GPL"); 687MODULE_LICENSE("GPL");
688MODULE_ALIAS("spi:ds3234");
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c
deleted file mode 100644
index 570ab28fc354..000000000000
--- a/drivers/rtc/rtc-ds3234.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/* rtc-ds3234.c
2 *
3 * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal
4 * and SRAM.
5 *
6 * Copyright (C) 2008 MIMOMax Wireless Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/platform_device.h>
18#include <linux/rtc.h>
19#include <linux/spi/spi.h>
20#include <linux/bcd.h>
21
22#define DS3234_REG_SECONDS 0x00
23#define DS3234_REG_MINUTES 0x01
24#define DS3234_REG_HOURS 0x02
25#define DS3234_REG_DAY 0x03
26#define DS3234_REG_DATE 0x04
27#define DS3234_REG_MONTH 0x05
28#define DS3234_REG_YEAR 0x06
29#define DS3234_REG_CENTURY (1 << 7) /* Bit 7 of the Month register */
30
31#define DS3234_REG_CONTROL 0x0E
32#define DS3234_REG_CONT_STAT 0x0F
33
34static int ds3234_set_reg(struct device *dev, unsigned char address,
35 unsigned char data)
36{
37 struct spi_device *spi = to_spi_device(dev);
38 unsigned char buf[2];
39
40 /* MSB must be '1' to indicate write */
41 buf[0] = address | 0x80;
42 buf[1] = data;
43
44 return spi_write_then_read(spi, buf, 2, NULL, 0);
45}
46
47static int ds3234_get_reg(struct device *dev, unsigned char address,
48 unsigned char *data)
49{
50 struct spi_device *spi = to_spi_device(dev);
51
52 *data = address & 0x7f;
53
54 return spi_write_then_read(spi, data, 1, data, 1);
55}
56
57static int ds3234_read_time(struct device *dev, struct rtc_time *dt)
58{
59 int err;
60 unsigned char buf[8];
61 struct spi_device *spi = to_spi_device(dev);
62
63 buf[0] = 0x00; /* Start address */
64
65 err = spi_write_then_read(spi, buf, 1, buf, 8);
66 if (err != 0)
67 return err;
68
69 /* Seconds, Minutes, Hours, Day, Date, Month, Year */
70 dt->tm_sec = bcd2bin(buf[0]);
71 dt->tm_min = bcd2bin(buf[1]);
72 dt->tm_hour = bcd2bin(buf[2] & 0x3f);
73 dt->tm_wday = bcd2bin(buf[3]) - 1; /* 0 = Sun */
74 dt->tm_mday = bcd2bin(buf[4]);
75 dt->tm_mon = bcd2bin(buf[5] & 0x1f) - 1; /* 0 = Jan */
76 dt->tm_year = bcd2bin(buf[6] & 0xff) + 100; /* Assume 20YY */
77
78 return rtc_valid_tm(dt);
79}
80
81static int ds3234_set_time(struct device *dev, struct rtc_time *dt)
82{
83 ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec));
84 ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min));
85 ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f);
86
87 /* 0 = Sun */
88 ds3234_set_reg(dev, DS3234_REG_DAY, bin2bcd(dt->tm_wday + 1));
89 ds3234_set_reg(dev, DS3234_REG_DATE, bin2bcd(dt->tm_mday));
90
91 /* 0 = Jan */
92 ds3234_set_reg(dev, DS3234_REG_MONTH, bin2bcd(dt->tm_mon + 1));
93
94 /* Assume 20YY although we just want to make sure not to go negative. */
95 if (dt->tm_year > 100)
96 dt->tm_year -= 100;
97
98 ds3234_set_reg(dev, DS3234_REG_YEAR, bin2bcd(dt->tm_year));
99
100 return 0;
101}
102
103static const struct rtc_class_ops ds3234_rtc_ops = {
104 .read_time = ds3234_read_time,
105 .set_time = ds3234_set_time,
106};
107
108static int ds3234_probe(struct spi_device *spi)
109{
110 struct rtc_device *rtc;
111 unsigned char tmp;
112 int res;
113
114 spi->mode = SPI_MODE_3;
115 spi->bits_per_word = 8;
116 spi_setup(spi);
117
118 res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp);
119 if (res != 0)
120 return res;
121
122 /* Control settings
123 *
124 * CONTROL_REG
125 * BIT 7 6 5 4 3 2 1 0
126 * EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE
127 *
128 * 0 0 0 1 1 1 0 0
129 *
130 * CONTROL_STAT_REG
131 * BIT 7 6 5 4 3 2 1 0
132 * OSF BB32kHz CRATE1 CRATE0 EN32kHz BSY A2F A1F
133 *
134 * 1 0 0 0 1 0 0 0
135 */
136 ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp);
137 ds3234_set_reg(&spi->dev, DS3234_REG_CONTROL, tmp & 0x1c);
138
139 ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
140 ds3234_set_reg(&spi->dev, DS3234_REG_CONT_STAT, tmp & 0x88);
141
142 /* Print our settings */
143 ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp);
144 dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
145
146 ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
147 dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
148
149 rtc = devm_rtc_device_register(&spi->dev, "ds3234",
150 &ds3234_rtc_ops, THIS_MODULE);
151 if (IS_ERR(rtc))
152 return PTR_ERR(rtc);
153
154 spi_set_drvdata(spi, rtc);
155
156 return 0;
157}
158
159static struct spi_driver ds3234_driver = {
160 .driver = {
161 .name = "ds3234",
162 },
163 .probe = ds3234_probe,
164};
165
166module_spi_driver(ds3234_driver);
167
168MODULE_DESCRIPTION("DS3234 SPI RTC driver");
169MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
170MODULE_LICENSE("GPL");
171MODULE_ALIAS("spi:ds3234");