aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2013-02-21 19:44:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 20:22:28 -0500
commit36d6182411b9f597f9f85ec0c4bb00909fd16d59 (patch)
treeaa86752a0ad00906b66e978b150013cebfba004c /drivers/rtc
parent38ae176e01f6f9ef8159325703ef5985dee40034 (diff)
rtc: add RTC driver for TPS80031/TPS80032
Add an RTC driver for TPS80031/TPS80032 chips by TI. This driver supports: - Setting and getting time and date. - Setting and reading alarm time. - Alarm and interrupt functionlity. [akpm@linux-foundation.org: remove obsolete __devinit/__devexit] Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-by: Devendra Naga <devendra.aaru@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig8
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-tps80031.c349
3 files changed, 358 insertions, 0 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e94ae65af171..d52183440691 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -396,6 +396,14 @@ config RTC_DRV_TPS65910
396 This driver can also be built as a module. If so, the module 396 This driver can also be built as a module. If so, the module
397 will be called rtc-tps65910. 397 will be called rtc-tps65910.
398 398
399config RTC_DRV_TPS80031
400 tristate "TI TPS80031/TPS80032 RTC driver"
401 depends on MFD_TPS80031
402 help
403 TI Power Managment IC TPS80031 supports RTC functionality
404 along with alarm. This driver supports the RTC driver for
405 the TPS80031 RTC module.
406
399config RTC_DRV_RC5T583 407config RTC_DRV_RC5T583
400 tristate "RICOH 5T583 RTC driver" 408 tristate "RICOH 5T583 RTC driver"
401 depends on MFD_RC5T583 409 depends on MFD_RC5T583
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 1a837767b68d..cd03fb33c14c 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -116,6 +116,7 @@ obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o
116obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o 116obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
117obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o 117obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o
118obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o 118obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o
119obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o
119obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o 120obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
120obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o 121obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
121obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o 122obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
diff --git a/drivers/rtc/rtc-tps80031.c b/drivers/rtc/rtc-tps80031.c
new file mode 100644
index 000000000000..97406411d58c
--- /dev/null
+++ b/drivers/rtc/rtc-tps80031.c
@@ -0,0 +1,349 @@
1/*
2 * rtc-tps80031.c -- TI TPS80031/TPS80032 RTC driver
3 *
4 * RTC driver for TI TPS80031/TPS80032 Fully Integrated
5 * Power Management with Power Path and Battery Charger
6 *
7 * Copyright (c) 2012, NVIDIA Corporation.
8 *
9 * Author: Laxman Dewangan <ldewangan@nvidia.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation version 2.
14 *
15 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
16 * whether express or implied; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 * 02111-1307, USA
24 */
25
26#include <linux/bcd.h>
27#include <linux/device.h>
28#include <linux/err.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/mfd/tps80031.h>
33#include <linux/platform_device.h>
34#include <linux/pm.h>
35#include <linux/rtc.h>
36#include <linux/slab.h>
37
38#define ENABLE_ALARM_INT 0x08
39#define ALARM_INT_STATUS 0x40
40
41/**
42 * Setting bit to 1 in STOP_RTC will run the RTC and
43 * setting this bit to 0 will freeze RTC.
44 */
45#define STOP_RTC 0x1
46
47/* Power on reset Values of RTC registers */
48#define TPS80031_RTC_POR_YEAR 0
49#define TPS80031_RTC_POR_MONTH 1
50#define TPS80031_RTC_POR_DAY 1
51
52/* Numbers of registers for time and alarms */
53#define TPS80031_RTC_TIME_NUM_REGS 7
54#define TPS80031_RTC_ALARM_NUM_REGS 6
55
56/**
57 * PMU RTC have only 2 nibbles to store year information, so using an
58 * offset of 100 to set the base year as 2000 for our driver.
59 */
60#define RTC_YEAR_OFFSET 100
61
62struct tps80031_rtc {
63 struct rtc_device *rtc;
64 int irq;
65};
66
67static int tps80031_rtc_read_time(struct device *dev, struct rtc_time *tm)
68{
69 u8 buff[TPS80031_RTC_TIME_NUM_REGS];
70 int ret;
71
72 ret = tps80031_reads(dev->parent, TPS80031_SLAVE_ID1,
73 TPS80031_SECONDS_REG, TPS80031_RTC_TIME_NUM_REGS, buff);
74 if (ret < 0) {
75 dev_err(dev, "reading RTC_SECONDS_REG failed, err = %d\n", ret);
76 return ret;
77 }
78
79 tm->tm_sec = bcd2bin(buff[0]);
80 tm->tm_min = bcd2bin(buff[1]);
81 tm->tm_hour = bcd2bin(buff[2]);
82 tm->tm_mday = bcd2bin(buff[3]);
83 tm->tm_mon = bcd2bin(buff[4]) - 1;
84 tm->tm_year = bcd2bin(buff[5]) + RTC_YEAR_OFFSET;
85 tm->tm_wday = bcd2bin(buff[6]);
86 return 0;
87}
88
89static int tps80031_rtc_set_time(struct device *dev, struct rtc_time *tm)
90{
91 u8 buff[7];
92 int ret;
93
94 buff[0] = bin2bcd(tm->tm_sec);
95 buff[1] = bin2bcd(tm->tm_min);
96 buff[2] = bin2bcd(tm->tm_hour);
97 buff[3] = bin2bcd(tm->tm_mday);
98 buff[4] = bin2bcd(tm->tm_mon + 1);
99 buff[5] = bin2bcd(tm->tm_year % RTC_YEAR_OFFSET);
100 buff[6] = bin2bcd(tm->tm_wday);
101
102 /* Stop RTC while updating the RTC time registers */
103 ret = tps80031_clr_bits(dev->parent, TPS80031_SLAVE_ID1,
104 TPS80031_RTC_CTRL_REG, STOP_RTC);
105 if (ret < 0) {
106 dev_err(dev->parent, "Stop RTC failed, err = %d\n", ret);
107 return ret;
108 }
109
110 ret = tps80031_writes(dev->parent, TPS80031_SLAVE_ID1,
111 TPS80031_SECONDS_REG,
112 TPS80031_RTC_TIME_NUM_REGS, buff);
113 if (ret < 0) {
114 dev_err(dev, "writing RTC_SECONDS_REG failed, err %d\n", ret);
115 return ret;
116 }
117
118 ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1,
119 TPS80031_RTC_CTRL_REG, STOP_RTC);
120 if (ret < 0)
121 dev_err(dev->parent, "Start RTC failed, err = %d\n", ret);
122 return ret;
123}
124
125static int tps80031_rtc_alarm_irq_enable(struct device *dev,
126 unsigned int enable)
127{
128 int ret;
129
130 if (enable)
131 ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1,
132 TPS80031_RTC_INTERRUPTS_REG, ENABLE_ALARM_INT);
133 else
134 ret = tps80031_clr_bits(dev->parent, TPS80031_SLAVE_ID1,
135 TPS80031_RTC_INTERRUPTS_REG, ENABLE_ALARM_INT);
136 if (ret < 0) {
137 dev_err(dev, "Update on RTC_INT failed, err = %d\n", ret);
138 return ret;
139 }
140 return 0;
141}
142
143static int tps80031_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
144{
145 u8 buff[TPS80031_RTC_ALARM_NUM_REGS];
146 int ret;
147
148 buff[0] = bin2bcd(alrm->time.tm_sec);
149 buff[1] = bin2bcd(alrm->time.tm_min);
150 buff[2] = bin2bcd(alrm->time.tm_hour);
151 buff[3] = bin2bcd(alrm->time.tm_mday);
152 buff[4] = bin2bcd(alrm->time.tm_mon + 1);
153 buff[5] = bin2bcd(alrm->time.tm_year % RTC_YEAR_OFFSET);
154 ret = tps80031_writes(dev->parent, TPS80031_SLAVE_ID1,
155 TPS80031_ALARM_SECONDS_REG,
156 TPS80031_RTC_ALARM_NUM_REGS, buff);
157 if (ret < 0) {
158 dev_err(dev, "Writing RTC_ALARM failed, err %d\n", ret);
159 return ret;
160 }
161 return tps80031_rtc_alarm_irq_enable(dev, alrm->enabled);
162}
163
164static int tps80031_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
165{
166 u8 buff[6];
167 int ret;
168
169 ret = tps80031_reads(dev->parent, TPS80031_SLAVE_ID1,
170 TPS80031_ALARM_SECONDS_REG,
171 TPS80031_RTC_ALARM_NUM_REGS, buff);
172 if (ret < 0) {
173 dev_err(dev->parent,
174 "reading RTC_ALARM failed, err = %d\n", ret);
175 return ret;
176 }
177
178 alrm->time.tm_sec = bcd2bin(buff[0]);
179 alrm->time.tm_min = bcd2bin(buff[1]);
180 alrm->time.tm_hour = bcd2bin(buff[2]);
181 alrm->time.tm_mday = bcd2bin(buff[3]);
182 alrm->time.tm_mon = bcd2bin(buff[4]) - 1;
183 alrm->time.tm_year = bcd2bin(buff[5]) + RTC_YEAR_OFFSET;
184 return 0;
185}
186
187static int clear_alarm_int_status(struct device *dev, struct tps80031_rtc *rtc)
188{
189 int ret;
190 u8 buf;
191
192 /**
193 * As per datasheet, A dummy read of this RTC_STATUS_REG register
194 * is necessary before each I2C read in order to update the status
195 * register value.
196 */
197 ret = tps80031_read(dev->parent, TPS80031_SLAVE_ID1,
198 TPS80031_RTC_STATUS_REG, &buf);
199 if (ret < 0) {
200 dev_err(dev, "reading RTC_STATUS failed. err = %d\n", ret);
201 return ret;
202 }
203
204 /* clear Alarm status bits.*/
205 ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1,
206 TPS80031_RTC_STATUS_REG, ALARM_INT_STATUS);
207 if (ret < 0) {
208 dev_err(dev, "clear Alarm INT failed, err = %d\n", ret);
209 return ret;
210 }
211 return 0;
212}
213
214static irqreturn_t tps80031_rtc_irq(int irq, void *data)
215{
216 struct device *dev = data;
217 struct tps80031_rtc *rtc = dev_get_drvdata(dev);
218 int ret;
219
220 ret = clear_alarm_int_status(dev, rtc);
221 if (ret < 0)
222 return ret;
223
224 rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
225 return IRQ_HANDLED;
226}
227
228static const struct rtc_class_ops tps80031_rtc_ops = {
229 .read_time = tps80031_rtc_read_time,
230 .set_time = tps80031_rtc_set_time,
231 .set_alarm = tps80031_rtc_set_alarm,
232 .read_alarm = tps80031_rtc_read_alarm,
233 .alarm_irq_enable = tps80031_rtc_alarm_irq_enable,
234};
235
236static int tps80031_rtc_probe(struct platform_device *pdev)
237{
238 struct tps80031_rtc *rtc;
239 struct rtc_time tm;
240 int ret;
241
242 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
243 if (!rtc)
244 return -ENOMEM;
245
246 rtc->irq = platform_get_irq(pdev, 0);
247 platform_set_drvdata(pdev, rtc);
248
249 /* Start RTC */
250 ret = tps80031_set_bits(pdev->dev.parent, TPS80031_SLAVE_ID1,
251 TPS80031_RTC_CTRL_REG, STOP_RTC);
252 if (ret < 0) {
253 dev_err(&pdev->dev, "failed to start RTC. err = %d\n", ret);
254 return ret;
255 }
256
257 /* If RTC have POR values, set time 01:01:2000 */
258 tps80031_rtc_read_time(&pdev->dev, &tm);
259 if ((tm.tm_year == RTC_YEAR_OFFSET + TPS80031_RTC_POR_YEAR) &&
260 (tm.tm_mon == (TPS80031_RTC_POR_MONTH - 1)) &&
261 (tm.tm_mday == TPS80031_RTC_POR_DAY)) {
262 tm.tm_year = 2000;
263 tm.tm_mday = 1;
264 tm.tm_mon = 1;
265 ret = tps80031_rtc_set_time(&pdev->dev, &tm);
266 if (ret < 0) {
267 dev_err(&pdev->dev,
268 "RTC set time failed, err = %d\n", ret);
269 return ret;
270 }
271 }
272
273 /* Clear alarm intretupt status if it is there */
274 ret = clear_alarm_int_status(&pdev->dev, rtc);
275 if (ret < 0) {
276 dev_err(&pdev->dev, "Clear alarm int failed, err = %d\n", ret);
277 return ret;
278 }
279
280 rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
281 &tps80031_rtc_ops, THIS_MODULE);
282 if (IS_ERR(rtc->rtc)) {
283 ret = PTR_ERR(rtc->rtc);
284 dev_err(&pdev->dev, "RTC registration failed, err %d\n", ret);
285 return ret;
286 }
287
288 ret = request_threaded_irq(rtc->irq, NULL, tps80031_rtc_irq,
289 IRQF_ONESHOT | IRQF_EARLY_RESUME,
290 dev_name(&pdev->dev), rtc);
291 if (ret < 0) {
292 dev_err(&pdev->dev, "request IRQ:%d failed, err = %d\n",
293 rtc->irq, ret);
294 rtc_device_unregister(rtc->rtc);
295 return ret;
296 }
297 device_set_wakeup_capable(&pdev->dev, 1);
298 return 0;
299}
300
301static int tps80031_rtc_remove(struct platform_device *pdev)
302{
303 struct tps80031_rtc *rtc = platform_get_drvdata(pdev);
304
305 free_irq(rtc->irq, rtc);
306 rtc_device_unregister(rtc->rtc);
307 return 0;
308}
309
310#ifdef CONFIG_PM_SLEEP
311static int tps80031_rtc_suspend(struct device *dev)
312{
313 struct tps80031_rtc *rtc = dev_get_drvdata(dev);
314
315 if (device_may_wakeup(dev))
316 enable_irq_wake(rtc->irq);
317 return 0;
318}
319
320static int tps80031_rtc_resume(struct device *dev)
321{
322 struct tps80031_rtc *rtc = dev_get_drvdata(dev);
323
324 if (device_may_wakeup(dev))
325 disable_irq_wake(rtc->irq);
326 return 0;
327};
328#endif
329
330static const struct dev_pm_ops tps80031_pm_ops = {
331 SET_SYSTEM_SLEEP_PM_OPS(tps80031_rtc_suspend, tps80031_rtc_resume)
332};
333
334static struct platform_driver tps80031_rtc_driver = {
335 .driver = {
336 .name = "tps80031-rtc",
337 .owner = THIS_MODULE,
338 .pm = &tps80031_pm_ops,
339 },
340 .probe = tps80031_rtc_probe,
341 .remove = tps80031_rtc_remove,
342};
343
344module_platform_driver(tps80031_rtc_driver);
345
346MODULE_ALIAS("platform:tps80031-rtc");
347MODULE_DESCRIPTION("TI TPS80031/TPS80032 RTC driver");
348MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
349MODULE_LICENSE("GPL v2");