aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-twl4030.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-28 11:26:12 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-28 11:26:12 -0400
commit7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch)
treee730a4565e0318140d2fbd2f0415d18a339d7336 /drivers/rtc/rtc-twl4030.c
parent41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff)
parent0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff)
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
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");