]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/rtc/rtc-twl4030.c
minor irq-related cleanups
[linux-2.6-omap-h63xx.git] / drivers / rtc / rtc-twl4030.c
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/ioport.h>
25 #include <linux/delay.h>
26 #include <linux/types.h>
27 #include <linux/rtc.h>
28 #include <linux/bcd.h>
29 #include <linux/platform_device.h>
30 #include <linux/spinlock.h>
31 #include <linux/interrupt.h>
32 #include <linux/device.h>
33 #include <linux/i2c/twl4030.h>
34 #include <linux/i2c/twl4030-rtc.h>
35 #include <linux/io.h>
36 #include <linux/irq.h>
37
38 #include <asm/mach/time.h>
39 #include <asm/system.h>
40 #include <mach/hardware.h>
41
42 #define ALL_TIME_REGS           6
43
44 /*
45  * Supports 1 byte read from TWL4030 RTC register.
46  */
47 static int twl4030_rtc_read_u8(u8 *data, u8 reg)
48 {
49         int ret;
50
51         ret = twl4030_i2c_read_u8(TWL4030_MODULE_RTC, data, reg);
52         if (ret < 0)
53                 pr_err("twl4030_rtc: Could not read TWL4030"
54                        "register %X - error %d\n", reg, ret);
55         return ret;
56 }
57
58 /*
59  * Supports 1 byte write to TWL4030 RTC registers.
60  */
61 static int twl4030_rtc_write_u8(u8 data, u8 reg)
62 {
63         int ret;
64
65         ret = twl4030_i2c_write_u8(TWL4030_MODULE_RTC, data, reg);
66         if (ret < 0)
67                 pr_err("twl4030_rtc: Could not write TWL4030"
68                        "register %X - error %d\n", reg, ret);
69         return ret;
70 }
71
72 /*
73  * Cache the value for timer/alarm interrupts register; this is
74  * only changed by callers holding rtc ops lock (or resume).
75  */
76 static unsigned char rtc_irq_bits;
77
78 /*
79  * Enable timer and/or alarm interrupts.
80  */
81 static int set_rtc_irq_bit(unsigned char bit)
82 {
83         unsigned char val;
84         int ret;
85
86         val = rtc_irq_bits | bit;
87         ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
88         if (ret == 0)
89                 rtc_irq_bits = val;
90
91         return ret;
92 }
93
94 /*
95  * Disable timer and/or alarm interrupts.
96  */
97 static int mask_rtc_irq_bit(unsigned char bit)
98 {
99         unsigned char val;
100         int ret;
101
102         val = rtc_irq_bits & ~bit;
103         ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
104         if (ret == 0)
105                 rtc_irq_bits = val;
106
107         return ret;
108 }
109
110 static inline int twl4030_rtc_alarm_irq_set_state(int enabled)
111 {
112         int ret;
113
114         if (enabled)
115                 ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
116         else
117                 ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
118
119         return ret;
120 }
121
122 static inline int twl4030_rtc_irq_set_state(int enabled)
123 {
124         int ret;
125
126         if (enabled)
127                 ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
128         else
129                 ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
130
131         return ret;
132 }
133
134 /*
135  * Gets current TWL4030 RTC time and date parameters.
136  *
137  * The RTC's time/alarm representation is not what gmtime(3) requires
138  * Linux to use:
139  *
140  *  - Months are 1..12 vs Linux 0-11
141  *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
142  */
143 static int twl4030_rtc_read_time(struct device *dev, struct rtc_time *tm)
144 {
145         unsigned char rtc_data[ALL_TIME_REGS + 1];
146         int ret;
147         u8 save_control;
148
149         ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
150         if (ret < 0)
151                 return ret;
152
153         save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
154
155         ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
156         if (ret < 0)
157                 return ret;
158
159         ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
160                                REG_SECONDS_REG, ALL_TIME_REGS);
161
162         if (ret < 0) {
163                 dev_err(dev, "rtc_read_time error %d\n", ret);
164                 return ret;
165         }
166
167         tm->tm_sec = bcd2bin(rtc_data[0]);
168         tm->tm_min = bcd2bin(rtc_data[1]);
169         tm->tm_hour = bcd2bin(rtc_data[2]);
170         tm->tm_mday = bcd2bin(rtc_data[3]);
171         tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
172         tm->tm_year = bcd2bin(rtc_data[5]) + 100;
173
174         return ret;
175 }
176
177 static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm)
178 {
179         unsigned char save_control;
180         unsigned char rtc_data[ALL_TIME_REGS + 1];
181         int ret;
182
183         rtc_data[1] = bin2bcd(tm->tm_sec);
184         rtc_data[2] = bin2bcd(tm->tm_min);
185         rtc_data[3] = bin2bcd(tm->tm_hour);
186         rtc_data[4] = bin2bcd(tm->tm_mday);
187         rtc_data[5] = bin2bcd(tm->tm_mon + 1);
188         rtc_data[6] = bin2bcd(tm->tm_year - 100);
189
190         /* Stop RTC while updating the TC registers */
191         ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
192         if (ret < 0)
193                 goto out;
194
195         save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
196         twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
197         if (ret < 0)
198                 goto out;
199
200         /* update all the time registers in one shot */
201         ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data,
202                         REG_SECONDS_REG, ALL_TIME_REGS);
203         if (ret < 0) {
204                 dev_err(dev, "rtc_set_time error %d\n", ret);
205                 goto out;
206         }
207
208         /* Start back RTC */
209         save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
210         ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
211
212 out:
213         return ret;
214 }
215
216 /*
217  * Gets current TWL4030 RTC alarm time.
218  */
219 static int twl4030_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
220 {
221         unsigned char rtc_data[ALL_TIME_REGS + 1];
222         int ret;
223
224         ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
225                                REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
226         if (ret < 0) {
227                 dev_err(dev, "rtc_read_alarm error %d\n", ret);
228                 return ret;
229         }
230
231         /* some of these fields may be wildcard/"match all" */
232         alm->time.tm_sec = bcd2bin(rtc_data[0]);
233         alm->time.tm_min = bcd2bin(rtc_data[1]);
234         alm->time.tm_hour = bcd2bin(rtc_data[2]);
235         alm->time.tm_mday = bcd2bin(rtc_data[3]);
236         alm->time.tm_mon = bcd2bin(rtc_data[4]) - 1;
237         alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
238
239         /* report cached alarm enable state */
240         if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
241                 alm->enabled = 1;
242
243         return ret;
244 }
245
246 static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
247 {
248         unsigned char alarm_data[ALL_TIME_REGS + 1];
249         int ret;
250
251         ret = twl4030_rtc_alarm_irq_set_state(0);
252         if (ret)
253                 goto out;
254
255         alarm_data[1] = bin2bcd(alm->time.tm_sec);
256         alarm_data[2] = bin2bcd(alm->time.tm_min);
257         alarm_data[3] = bin2bcd(alm->time.tm_hour);
258         alarm_data[4] = bin2bcd(alm->time.tm_mday);
259         alarm_data[5] = bin2bcd(alm->time.tm_mon + 1);
260         alarm_data[6] = bin2bcd(alm->time.tm_year - 100);
261
262         /* update all the alarm registers in one shot */
263         ret = twl4030_i2c_write(TWL4030_MODULE_RTC, alarm_data,
264                         REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
265         if (ret) {
266                 dev_err(dev, "rtc_set_alarm error %d\n", ret);
267                 goto out;
268         }
269
270         if (alm->enabled)
271                 ret = twl4030_rtc_alarm_irq_set_state(1);
272 out:
273         return ret;
274 }
275
276 #ifdef  CONFIG_RTC_INTF_DEV
277
278 static int twl4030_rtc_ioctl(struct device *dev, unsigned int cmd,
279                              unsigned long arg)
280 {
281         switch (cmd) {
282         case RTC_AIE_OFF:
283                 return twl4030_rtc_alarm_irq_set_state(0);
284         case RTC_AIE_ON:
285                 return twl4030_rtc_alarm_irq_set_state(1);
286         case RTC_UIE_OFF:
287                 return twl4030_rtc_irq_set_state(0);
288         case RTC_UIE_ON:
289                 return twl4030_rtc_irq_set_state(1);
290
291         default:
292                 return -ENOIOCTLCMD;
293         }
294 }
295
296 #else
297 #define omap_rtc_ioctl  NULL
298 #endif
299
300 static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc)
301 {
302         unsigned long events = 0;
303         int ret = IRQ_NONE;
304         int res;
305         u8 rd_reg;
306
307         res = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
308         if (res)
309                 goto out;
310         /*
311          * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG.
312          * only one (ALARM or RTC) interrupt source may be enabled
313          * at time, we also could check our results
314          * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
315          */
316         if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
317                 events |= RTC_IRQF | RTC_AF;
318         else
319                 events |= RTC_IRQF | RTC_UF;
320
321         res = twl4030_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
322                                    REG_RTC_STATUS_REG);
323         if (res)
324                 goto out;
325
326         /* Clear on Read enabled. RTC_IT bit of REG_PWR_ISR1 needs
327          * 2 reads to clear the interrupt. One read is done in
328          * do_twl4030_pwrirq(). Doing the second read, to clear
329          * the bit.
330          */
331         res = twl4030_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, REG_PWR_ISR1);
332         if (res)
333                 goto out;
334
335         /* Notify RTC core on event */
336         rtc_update_irq(rtc, 1, events);
337
338         ret = IRQ_HANDLED;
339 out:
340         return ret;
341 }
342
343 static struct rtc_class_ops twl4030_rtc_ops = {
344         .ioctl          = twl4030_rtc_ioctl,
345         .read_time      = twl4030_rtc_read_time,
346         .set_time       = twl4030_rtc_set_time,
347         .read_alarm     = twl4030_rtc_read_alarm,
348         .set_alarm      = twl4030_rtc_set_alarm,
349 };
350
351 static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
352 {
353         struct twl4030rtc_platform_data *pdata = pdev->dev.platform_data;
354         struct rtc_device *rtc;
355         int ret = 0;
356         int irq = platform_get_irq(pdev, 0);
357         u8 rd_reg;
358
359         if (irq < 0)
360                 return irq;
361
362         if (pdata != NULL && pdata->init != NULL) {
363                 ret = pdata->init();
364                 if (ret < 0)
365                         goto out;
366         }
367
368         rtc = rtc_device_register(pdev->name,
369                                   &pdev->dev, &twl4030_rtc_ops, THIS_MODULE);
370         if (IS_ERR(rtc)) {
371                 ret = -EINVAL;
372                 dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
373                         PTR_ERR(rtc));
374                 goto out0;
375
376         }
377
378         platform_set_drvdata(pdev, rtc);
379
380         ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
381
382         if (ret < 0)
383                 goto out1;
384
385         if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
386                 dev_warn(&pdev->dev, "Power up reset detected.\n");
387
388         if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
389                 dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
390
391         /* Clear RTC Power up reset and pending alarm interrupts */
392         ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
393         if (ret < 0)
394                 goto out1;
395
396         ret = request_irq(irq, twl4030_rtc_interrupt,
397                                 0, rtc->dev.bus_id, rtc);
398         if (ret < 0) {
399                 dev_err(&pdev->dev, "IRQ is not free.\n");
400                 goto out1;
401         }
402
403         /* Check RTC module status, Enable if it is off */
404         ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
405         if (ret < 0)
406                 goto out2;
407
408         if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
409                 dev_info(&pdev->dev, "Enabling TWL4030-RTC.\n");
410                 rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
411                 ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
412                 if (ret < 0)
413                         goto out2;
414         }
415
416         ret = twl4030_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, REG_PWR_IMR1);
417         if (ret < 0)
418                 goto out2;
419
420         rd_reg &= PWR_RTC_IT_UNMASK;
421         /* MASK PWR - we will need this */
422         ret = twl4030_i2c_write_u8(TWL4030_MODULE_INT, rd_reg, REG_PWR_IMR1);
423         if (ret < 0)
424                 goto out2;
425
426         ret = twl4030_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, REG_PWR_EDR1);
427         if (ret < 0)
428                 goto out2;
429
430         /* Rising edge detection enabled, needed for RTC alarm */
431         rd_reg |= 0x80;
432         ret = twl4030_i2c_write_u8(TWL4030_MODULE_INT, rd_reg, REG_PWR_EDR1);
433         if (ret < 0)
434                 goto out2;
435
436         /* init cached IRQ enable bits */
437         ret = twl4030_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
438         if (ret < 0)
439                 goto out2;
440
441         return ret;
442
443
444 out2:
445         free_irq(irq, rtc);
446 out1:
447         rtc_device_unregister(rtc);
448 out0:
449         if (pdata != NULL && pdata->exit != NULL)
450                 pdata->exit();
451 out:
452         return ret;
453 }
454
455 /*
456  * Disable all TWL4030 RTC module interrupts.
457  * Sets status flag to free.
458  */
459 static int __devexit twl4030_rtc_remove(struct platform_device *pdev)
460 {
461         /* leave rtc running, but disable irqs */
462         struct twl4030rtc_platform_data *pdata = pdev->dev.platform_data;
463         struct rtc_device *rtc = platform_get_drvdata(pdev);
464         int irq = platform_get_irq(pdev, 0);
465
466         mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
467         mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
468
469         free_irq(irq, rtc);
470
471         if (pdata != NULL && pdata->exit != NULL)
472                 pdata->exit();
473
474         rtc_device_unregister(rtc);
475         platform_set_drvdata(pdev, NULL);
476         return 0;
477 }
478
479 static void twl4030_rtc_shutdown(struct platform_device *pdev)
480 {
481         mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
482                          BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
483 }
484
485 #ifdef CONFIG_PM
486
487 static unsigned char irqstat;
488
489 static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state)
490 {
491         irqstat = rtc_irq_bits;
492
493         /* REVISIT alarm may need to wake us from sleep */
494         mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
495                          BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
496         return 0;
497 }
498
499 static int twl4030_rtc_resume(struct platform_device *pdev)
500 {
501         set_rtc_irq_bit(irqstat);
502         return 0;
503 }
504
505 #else
506 #define twl4030_rtc_suspend NULL
507 #define twl4030_rtc_resume  NULL
508 #endif
509
510 MODULE_ALIAS("platform:twl4030_rtc");
511
512 static struct platform_driver twl4030rtc_driver = {
513         .probe          = twl4030_rtc_probe,
514         .remove         = __devexit_p(twl4030_rtc_remove),
515         .shutdown       = twl4030_rtc_shutdown,
516         .suspend        = twl4030_rtc_suspend,
517         .resume         = twl4030_rtc_resume,
518         .driver         = {
519                 .owner  = THIS_MODULE,
520                 .name   = "twl4030_rtc",
521         },
522 };
523
524 static int __init twl4030_rtc_init(void)
525 {
526         return platform_driver_register(&twl4030rtc_driver);
527 }
528 module_init(twl4030_rtc_init);
529
530 static void __exit twl4030_rtc_exit(void)
531 {
532         platform_driver_unregister(&twl4030rtc_driver);
533 }
534 module_exit(twl4030_rtc_exit);
535
536 MODULE_AUTHOR("Texas Instruments, MontaVista Software");
537 MODULE_LICENSE("GPL");