aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-twl4030.c
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2008-10-20 17:50:05 -0400
committerSamuel Ortiz <samuel@sortiz.org>2008-10-21 19:19:38 -0400
commitf96411ab73647ebf9485d77546c0c1f554bafcd7 (patch)
tree284723cf28ee6dbafcd4b0edba309606d13d3d43 /drivers/rtc/rtc-twl4030.c
parenta30d46c042c8a17ef25de02f439fbd120ab8a8de (diff)
mfd: rtc-twl4030 driver
This adds a driver for the RTC inside the TWL4030 multi-function device. It's a fairly basic RTC, with a wake-capable alarm. Note that many of the pre-release Overo boards now in circulation can't effectively use this RTC, because of a wiring error that puts its TWL chip into "secure" mode. (As in "secure yourself against tampering".) This isn't an issue on other OMAP3 boards now supported in mainline, such as Beagle and Labrador. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Tony Lindgren <tony@atomide.com> Acked-by: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
Diffstat (limited to 'drivers/rtc/rtc-twl4030.c')
-rw-r--r--drivers/rtc/rtc-twl4030.c564
1 files changed, 564 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c
new file mode 100644
index 000000000000..abe87a4d2665
--- /dev/null
+++ b/drivers/rtc/rtc-twl4030.c
@@ -0,0 +1,564 @@
1/*
2 * rtc-twl4030.c -- TWL4030 Real Time Clock interface
3 *
4 * Copyright (C) 2007 MontaVista Software, Inc
5 * Author: Alexandre Rusev <source@mvista.com>
6 *
7 * Based on original TI driver twl4030-rtc.c
8 * Copyright (C) 2006 Texas Instruments, Inc.
9 *
10 * Based on rtc-omap.c
11 * Copyright (C) 2003 MontaVista Software, Inc.
12 * Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
13 * Copyright (C) 2006 David Brownell
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/types.h>
25#include <linux/rtc.h>
26#include <linux/bcd.h>
27#include <linux/platform_device.h>
28#include <linux/interrupt.h>
29
30#include <linux/i2c/twl4030.h>
31
32
33/*
34 * RTC block register offsets (use TWL_MODULE_RTC)
35 */
36#define REG_SECONDS_REG 0x00
37#define REG_MINUTES_REG 0x01
38#define REG_HOURS_REG 0x02
39#define REG_DAYS_REG 0x03
40#define REG_MONTHS_REG 0x04
41#define REG_YEARS_REG 0x05
42#define REG_WEEKS_REG 0x06
43
44#define REG_ALARM_SECONDS_REG 0x07
45#define REG_ALARM_MINUTES_REG 0x08
46#define REG_ALARM_HOURS_REG 0x09
47#define REG_ALARM_DAYS_REG 0x0A
48#define REG_ALARM_MONTHS_REG 0x0B
49#define REG_ALARM_YEARS_REG 0x0C
50
51#define REG_RTC_CTRL_REG 0x0D
52#define REG_RTC_STATUS_REG 0x0E
53#define REG_RTC_INTERRUPTS_REG 0x0F
54
55#define REG_RTC_COMP_LSB_REG 0x10
56#define REG_RTC_COMP_MSB_REG 0x11
57
58/* RTC_CTRL_REG bitfields */
59#define BIT_RTC_CTRL_REG_STOP_RTC_M 0x01
60#define BIT_RTC_CTRL_REG_ROUND_30S_M 0x02
61#define BIT_RTC_CTRL_REG_AUTO_COMP_M 0x04
62#define BIT_RTC_CTRL_REG_MODE_12_24_M 0x08
63#define BIT_RTC_CTRL_REG_TEST_MODE_M 0x10
64#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M 0x20
65#define BIT_RTC_CTRL_REG_GET_TIME_M 0x40
66
67/* RTC_STATUS_REG bitfields */
68#define BIT_RTC_STATUS_REG_RUN_M 0x02
69#define BIT_RTC_STATUS_REG_1S_EVENT_M 0x04
70#define BIT_RTC_STATUS_REG_1M_EVENT_M 0x08
71#define BIT_RTC_STATUS_REG_1H_EVENT_M 0x10
72#define BIT_RTC_STATUS_REG_1D_EVENT_M 0x20
73#define BIT_RTC_STATUS_REG_ALARM_M 0x40
74#define BIT_RTC_STATUS_REG_POWER_UP_M 0x80
75
76/* RTC_INTERRUPTS_REG bitfields */
77#define BIT_RTC_INTERRUPTS_REG_EVERY_M 0x03
78#define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M 0x04
79#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M 0x08
80
81
82/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
83#define ALL_TIME_REGS 6
84
85/*----------------------------------------------------------------------*/
86
87/*
88 * Supports 1 byte read from TWL4030 RTC register.
89 */
90static int twl4030_rtc_read_u8(u8 *data, u8 reg)
91{
92 int ret;
93
94 ret = twl4030_i2c_read_u8(TWL4030_MODULE_RTC, data, reg);
95 if (ret < 0)
96 pr_err("twl4030_rtc: Could not read TWL4030"
97 "register %X - error %d\n", reg, ret);
98 return ret;
99}
100
101/*
102 * Supports 1 byte write to TWL4030 RTC registers.
103 */
104static int twl4030_rtc_write_u8(u8 data, u8 reg)
105{
106 int ret;
107
108 ret = twl4030_i2c_write_u8(TWL4030_MODULE_RTC, data, reg);
109 if (ret < 0)
110 pr_err("twl4030_rtc: Could not write TWL4030"
111 "register %X - error %d\n", reg, ret);
112 return ret;
113}
114
115/*
116 * Cache the value for timer/alarm interrupts register; this is
117 * only changed by callers holding rtc ops lock (or resume).
118 */
119static unsigned char rtc_irq_bits;
120
121/*
122 * Enable timer and/or alarm interrupts.
123 */
124static int set_rtc_irq_bit(unsigned char bit)
125{
126 unsigned char val;
127 int ret;
128
129 val = rtc_irq_bits | bit;
130 ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
131 if (ret == 0)
132 rtc_irq_bits = val;
133
134 return ret;
135}
136
137/*
138 * Disable timer and/or alarm interrupts.
139 */
140static int mask_rtc_irq_bit(unsigned char bit)
141{
142 unsigned char val;
143 int ret;
144
145 val = rtc_irq_bits & ~bit;
146 ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
147 if (ret == 0)
148 rtc_irq_bits = val;
149
150 return ret;
151}
152
153static inline int twl4030_rtc_alarm_irq_set_state(int enabled)
154{
155 int ret;
156
157 if (enabled)
158 ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
159 else
160 ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
161
162 return ret;
163}
164
165static inline int twl4030_rtc_irq_set_state(int enabled)
166{
167 int ret;
168
169 if (enabled)
170 ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
171 else
172 ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
173
174 return ret;
175}
176
177/*
178 * Gets current TWL4030 RTC time and date parameters.
179 *
180 * The RTC's time/alarm representation is not what gmtime(3) requires
181 * Linux to use:
182 *
183 * - Months are 1..12 vs Linux 0-11
184 * - Years are 0..99 vs Linux 1900..N (we assume 21st century)
185 */
186static int twl4030_rtc_read_time(struct device *dev, struct rtc_time *tm)
187{
188 unsigned char rtc_data[ALL_TIME_REGS + 1];
189 int ret;
190 u8 save_control;
191
192 ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
193 if (ret < 0)
194 return ret;
195
196 save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
197
198 ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
199 if (ret < 0)
200 return ret;
201
202 ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
203 REG_SECONDS_REG, ALL_TIME_REGS);
204
205 if (ret < 0) {
206 dev_err(dev, "rtc_read_time error %d\n", ret);
207 return ret;
208 }
209
210 tm->tm_sec = bcd2bin(rtc_data[0]);
211 tm->tm_min = bcd2bin(rtc_data[1]);
212 tm->tm_hour = bcd2bin(rtc_data[2]);
213 tm->tm_mday = bcd2bin(rtc_data[3]);
214 tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
215 tm->tm_year = bcd2bin(rtc_data[5]) + 100;
216
217 return ret;
218}
219
220static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm)
221{
222 unsigned char save_control;
223 unsigned char rtc_data[ALL_TIME_REGS + 1];
224 int ret;
225
226 rtc_data[1] = bin2bcd(tm->tm_sec);
227 rtc_data[2] = bin2bcd(tm->tm_min);
228 rtc_data[3] = bin2bcd(tm->tm_hour);
229 rtc_data[4] = bin2bcd(tm->tm_mday);
230 rtc_data[5] = bin2bcd(tm->tm_mon + 1);
231 rtc_data[6] = bin2bcd(tm->tm_year - 100);
232
233 /* Stop RTC while updating the TC registers */
234 ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
235 if (ret < 0)
236 goto out;
237
238 save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
239 twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
240 if (ret < 0)
241 goto out;
242
243 /* update all the time registers in one shot */
244 ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data,
245 REG_SECONDS_REG, ALL_TIME_REGS);
246 if (ret < 0) {
247 dev_err(dev, "rtc_set_time error %d\n", ret);
248 goto out;
249 }
250
251 /* Start back RTC */
252 save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
253 ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
254
255out:
256 return ret;
257}
258
259/*
260 * Gets current TWL4030 RTC alarm time.
261 */
262static int twl4030_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
263{
264 unsigned char rtc_data[ALL_TIME_REGS + 1];
265 int ret;
266
267 ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
268 REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
269 if (ret < 0) {
270 dev_err(dev, "rtc_read_alarm error %d\n", ret);
271 return ret;
272 }
273
274 /* some of these fields may be wildcard/"match all" */
275 alm->time.tm_sec = bcd2bin(rtc_data[0]);
276 alm->time.tm_min = bcd2bin(rtc_data[1]);
277 alm->time.tm_hour = bcd2bin(rtc_data[2]);
278 alm->time.tm_mday = bcd2bin(rtc_data[3]);
279 alm->time.tm_mon = bcd2bin(rtc_data[4]) - 1;
280 alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
281
282 /* report cached alarm enable state */
283 if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
284 alm->enabled = 1;
285
286 return ret;
287}
288
289static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
290{
291 unsigned char alarm_data[ALL_TIME_REGS + 1];
292 int ret;
293
294 ret = twl4030_rtc_alarm_irq_set_state(0);
295 if (ret)
296 goto out;
297
298 alarm_data[1] = bin2bcd(alm->time.tm_sec);
299 alarm_data[2] = bin2bcd(alm->time.tm_min);
300 alarm_data[3] = bin2bcd(alm->time.tm_hour);
301 alarm_data[4] = bin2bcd(alm->time.tm_mday);
302 alarm_data[5] = bin2bcd(alm->time.tm_mon + 1);
303 alarm_data[6] = bin2bcd(alm->time.tm_year - 100);
304
305 /* update all the alarm registers in one shot */
306 ret = twl4030_i2c_write(TWL4030_MODULE_RTC, alarm_data,
307 REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
308 if (ret) {
309 dev_err(dev, "rtc_set_alarm error %d\n", ret);
310 goto out;
311 }
312
313 if (alm->enabled)
314 ret = twl4030_rtc_alarm_irq_set_state(1);
315out:
316 return ret;
317}
318
319#ifdef CONFIG_RTC_INTF_DEV
320
321static int twl4030_rtc_ioctl(struct device *dev, unsigned int cmd,
322 unsigned long arg)
323{
324 switch (cmd) {
325 case RTC_AIE_OFF:
326 return twl4030_rtc_alarm_irq_set_state(0);
327 case RTC_AIE_ON:
328 return twl4030_rtc_alarm_irq_set_state(1);
329 case RTC_UIE_OFF:
330 return twl4030_rtc_irq_set_state(0);
331 case RTC_UIE_ON:
332 return twl4030_rtc_irq_set_state(1);
333
334 default:
335 return -ENOIOCTLCMD;
336 }
337}
338
339#else
340#define omap_rtc_ioctl NULL
341#endif
342
343static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc)
344{
345 unsigned long events = 0;
346 int ret = IRQ_NONE;
347 int res;
348 u8 rd_reg;
349
350#ifdef CONFIG_LOCKDEP
351 /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
352 * we don't want and can't tolerate. Although it might be
353 * friendlier not to borrow this thread context...
354 */
355 local_irq_enable();
356#endif
357
358 res = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
359 if (res)
360 goto out;
361 /*
362 * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG.
363 * only one (ALARM or RTC) interrupt source may be enabled
364 * at time, we also could check our results
365 * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
366 */
367 if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
368 events |= RTC_IRQF | RTC_AF;
369 else
370 events |= RTC_IRQF | RTC_UF;
371
372 res = twl4030_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
373 REG_RTC_STATUS_REG);
374 if (res)
375 goto out;
376
377 /* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1
378 * needs 2 reads to clear the interrupt. One read is done in
379 * do_twl4030_pwrirq(). Doing the second read, to clear
380 * the bit.
381 *
382 * FIXME the reason PWR_ISR1 needs an extra read is that
383 * RTC_IF retriggered until we cleared REG_ALARM_M above.
384 * But re-reading like this is a bad hack; by doing so we
385 * risk wrongly clearing status for some other IRQ (losing
386 * the interrupt). Be smarter about handling RTC_UF ...
387 */
388 res = twl4030_i2c_read_u8(TWL4030_MODULE_INT,
389 &rd_reg, TWL4030_INT_PWR_ISR1);
390 if (res)
391 goto out;
392
393 /* Notify RTC core on event */
394 rtc_update_irq(rtc, 1, events);
395
396 ret = IRQ_HANDLED;
397out:
398 return ret;
399}
400
401static struct rtc_class_ops twl4030_rtc_ops = {
402 .ioctl = twl4030_rtc_ioctl,
403 .read_time = twl4030_rtc_read_time,
404 .set_time = twl4030_rtc_set_time,
405 .read_alarm = twl4030_rtc_read_alarm,
406 .set_alarm = twl4030_rtc_set_alarm,
407};
408
409/*----------------------------------------------------------------------*/
410
411static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
412{
413 struct rtc_device *rtc;
414 int ret = 0;
415 int irq = platform_get_irq(pdev, 0);
416 u8 rd_reg;
417
418 if (irq < 0)
419 return irq;
420
421 rtc = rtc_device_register(pdev->name,
422 &pdev->dev, &twl4030_rtc_ops, THIS_MODULE);
423 if (IS_ERR(rtc)) {
424 ret = -EINVAL;
425 dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
426 PTR_ERR(rtc));
427 goto out0;
428
429 }
430
431 platform_set_drvdata(pdev, rtc);
432
433 ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
434
435 if (ret < 0)
436 goto out1;
437
438 if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
439 dev_warn(&pdev->dev, "Power up reset detected.\n");
440
441 if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
442 dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
443
444 /* Clear RTC Power up reset and pending alarm interrupts */
445 ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
446 if (ret < 0)
447 goto out1;
448
449 ret = request_irq(irq, twl4030_rtc_interrupt,
450 IRQF_TRIGGER_RISING,
451 rtc->dev.bus_id, rtc);
452 if (ret < 0) {
453 dev_err(&pdev->dev, "IRQ is not free.\n");
454 goto out1;
455 }
456
457 /* Check RTC module status, Enable if it is off */
458 ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
459 if (ret < 0)
460 goto out2;
461
462 if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
463 dev_info(&pdev->dev, "Enabling TWL4030-RTC.\n");
464 rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
465 ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
466 if (ret < 0)
467 goto out2;
468 }
469
470 /* init cached IRQ enable bits */
471 ret = twl4030_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
472 if (ret < 0)
473 goto out2;
474
475 return ret;
476
477
478out2:
479 free_irq(irq, rtc);
480out1:
481 rtc_device_unregister(rtc);
482out0:
483 return ret;
484}
485
486/*
487 * Disable all TWL4030 RTC module interrupts.
488 * Sets status flag to free.
489 */
490static int __devexit twl4030_rtc_remove(struct platform_device *pdev)
491{
492 /* leave rtc running, but disable irqs */
493 struct rtc_device *rtc = platform_get_drvdata(pdev);
494 int irq = platform_get_irq(pdev, 0);
495
496 mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
497 mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
498
499 free_irq(irq, rtc);
500
501 rtc_device_unregister(rtc);
502 platform_set_drvdata(pdev, NULL);
503 return 0;
504}
505
506static void twl4030_rtc_shutdown(struct platform_device *pdev)
507{
508 mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
509 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
510}
511
512#ifdef CONFIG_PM
513
514static unsigned char irqstat;
515
516static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state)
517{
518 irqstat = rtc_irq_bits;
519
520 /* REVISIT alarm may need to wake us from sleep */
521 mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
522 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
523 return 0;
524}
525
526static int twl4030_rtc_resume(struct platform_device *pdev)
527{
528 set_rtc_irq_bit(irqstat);
529 return 0;
530}
531
532#else
533#define twl4030_rtc_suspend NULL
534#define twl4030_rtc_resume NULL
535#endif
536
537MODULE_ALIAS("platform:twl4030_rtc");
538
539static struct platform_driver twl4030rtc_driver = {
540 .probe = twl4030_rtc_probe,
541 .remove = __devexit_p(twl4030_rtc_remove),
542 .shutdown = twl4030_rtc_shutdown,
543 .suspend = twl4030_rtc_suspend,
544 .resume = twl4030_rtc_resume,
545 .driver = {
546 .owner = THIS_MODULE,
547 .name = "twl4030_rtc",
548 },
549};
550
551static int __init twl4030_rtc_init(void)
552{
553 return platform_driver_register(&twl4030rtc_driver);
554}
555module_init(twl4030_rtc_init);
556
557static void __exit twl4030_rtc_exit(void)
558{
559 platform_driver_unregister(&twl4030rtc_driver);
560}
561module_exit(twl4030_rtc_exit);
562
563MODULE_AUTHOR("Texas Instruments, MontaVista Software");
564MODULE_LICENSE("GPL");