sync hh.org
[hh.org.git] / drivers / char / sa1100-rtc.c
blobb937c8855309ad5de8dd527fc41fe9010ff3df52
1 /*
2 * linux/drivers/char/sa1100-rtc.c
4 * Real Time Clock interface for Linux on StrongARM SA1x00
5 * (and XScale PXA2xx which shares the same RTC register definitions)
7 * Copyright (c) 2000 Nils Faerber
9 * Based on rtc.c by Paul Gortmaker
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
16 * 1.03 2005-07-11 Todd Blumer <todd@sdgsystems.com>
17 * - convert to device_driver / platform_device model
19 * 1.02 2002-07-15 Andrew Christian <andrew.christian@hp.com>
20 * - added pm_ routines to shut off extraneous interrupts while asleep
22 * 1.01 2002-07-09 Nils Faerber <nils@kernelconcepts.de>
23 * - fixed rtc_poll() so that select() now works
25 * 1.00 2001-06-08 Nicolas Pitre <nico@cam.org>
26 * - added periodic timer capability using OSMR1
27 * - flag compatibility with other RTC chips
28 * - permission checks for ioctls
29 * - major cleanup, partial rewrite
31 * 0.03 2001-03-07 CIH <cih@coventive.com>
32 * - Modify the bug setups RTC clock.
34 * 0.02 2001-02-27 Nils Faerber <nils@kernelconcepts.de>
35 * - removed mktime(), added alarm irq clear
37 * 0.01 2000-10-01 Nils Faerber <nils@kernelconcepts.de>
38 * - initial release
41 #include <linux/init.h>
42 #include <linux/module.h>
43 #include <linux/platform_device.h>
44 #include <linux/fs.h>
45 #include <linux/miscdevice.h>
46 #include <linux/interrupt.h>
47 #include <linux/poll.h>
48 #include <linux/proc_fs.h>
49 #include <linux/string.h>
50 #include <linux/rtc.h>
51 #include <linux/pm.h>
53 #include <asm/bitops.h>
54 #include <asm/hardware.h>
55 #include <asm/irq.h>
57 #ifdef CONFIG_ARCH_PXA
58 #include <asm/arch/pxa-regs.h>
59 #endif
61 #define DRIVER_VERSION "1.03"
62 #define DRIVER_NAME "sa-pxa-rtc"
64 #define TIMER_FREQ CLOCK_TICK_RATE
66 #define RTC_DEF_DIVIDER 32768 - 1
67 #define RTC_DEF_TRIM 0
69 /* Those are the bits from a classic RTC we want to mimic */
70 #define RTC_IRQF 0x80 /* any of the following 3 is active */
71 #define RTC_PF 0x40
72 #define RTC_AF 0x20
73 #define RTC_UF 0x10
75 static unsigned long rtc_status;
76 static unsigned long rtc_irq_data;
77 static unsigned long rtc_freq = 1024;
79 static struct fasync_struct *rtc_async_queue;
80 static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
82 extern spinlock_t rtc_lock;
84 static const unsigned char days_in_mo[] =
85 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
87 #define is_leap(year) \
88 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
90 /* Converts seconds since 1970-01-01 00:00:00 to Gregorian date. */
91 static void decodetime (unsigned long t, struct rtc_time *tval)
93 long days, month, year, rem;
95 days = t / 86400;
96 rem = t % 86400;
97 tval->tm_hour = rem / 3600;
98 rem %= 3600;
99 tval->tm_min = rem / 60;
100 tval->tm_sec = rem % 60;
101 tval->tm_wday = (4 + days) % 7;
103 #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
105 year = 1970 + days / 365;
106 days -= ((year - 1970) * 365
107 + LEAPS_THRU_END_OF (year - 1)
108 - LEAPS_THRU_END_OF (1970 - 1));
109 if (days < 0) {
110 year -= 1;
111 days += 365 + is_leap(year);
113 tval->tm_year = year - 1900;
114 tval->tm_yday = days + 1;
116 month = 0;
117 if (days >= 31) {
118 days -= 31;
119 month++;
120 if (days >= (28 + is_leap(year))) {
121 days -= (28 + is_leap(year));
122 month++;
123 while (days >= days_in_mo[month]) {
124 days -= days_in_mo[month];
125 month++;
129 tval->tm_mon = month;
130 tval->tm_mday = days + 1;
133 irqreturn_t rtc_interrupt(int irq, void *dev_id)
135 unsigned int rtsr = RTSR;
137 /* clear interrupt sources */
138 RTSR = 0;
139 RTSR = (RTSR_AL|RTSR_HZ);
141 /* clear alarm interrupt if it has occurred */
142 if (rtsr & RTSR_AL)
143 rtsr &= ~RTSR_ALE;
144 RTSR = rtsr & (RTSR_ALE|RTSR_HZE);
146 /* update irq data & counter */
147 if (rtsr & RTSR_AL)
148 rtc_irq_data |= (RTC_AF|RTC_IRQF);
149 if (rtsr & RTSR_HZ)
150 rtc_irq_data |= (RTC_UF|RTC_IRQF);
151 rtc_irq_data += 0x100;
153 /* wake up waiting process */
154 wake_up_interruptible(&rtc_wait);
155 kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
156 return IRQ_HANDLED;
159 static irqreturn_t timer1_interrupt(int irq, void *dev_id)
162 * If we match for the first time, the periodic interrupt flag won't
163 * be set. If it is, then we did wrap around (very unlikely but
164 * still possible) and compute the amount of missed periods.
165 * The match reg is updated only when the data is actually retrieved
166 * to avoid unnecessary interrupts.
168 OSSR = OSSR_M1; /* clear match on timer1 */
169 if (rtc_irq_data & RTC_PF) {
170 rtc_irq_data += (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))) << 8;
171 } else {
172 rtc_irq_data += (0x100|RTC_PF|RTC_IRQF);
175 wake_up_interruptible(&rtc_wait);
176 kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
177 return IRQ_HANDLED;
180 static int rtc_open(struct inode *inode, struct file *file)
182 if (test_and_set_bit (1, &rtc_status))
183 return -EBUSY;
184 rtc_irq_data = 0;
185 return 0;
188 static int rtc_release(struct inode *inode, struct file *file)
190 spin_lock_irq (&rtc_lock);
191 RTSR = 0;
192 RTSR = (RTSR_AL|RTSR_HZ);
193 OIER &= ~OIER_E1;
194 OSSR = OSSR_M1;
195 spin_unlock_irq (&rtc_lock);
196 rtc_status = 0;
197 return 0;
200 static int rtc_fasync (int fd, struct file *filp, int on)
202 return fasync_helper (fd, filp, on, &rtc_async_queue);
205 static unsigned int rtc_poll(struct file *file, poll_table *wait)
207 poll_wait (file, &rtc_wait, wait);
208 return (rtc_irq_data) ? POLLIN | POLLRDNORM : 0;
211 ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
213 DECLARE_WAITQUEUE(wait, current);
214 unsigned long data;
215 ssize_t retval;
217 if (count < sizeof(unsigned long))
218 return -EINVAL;
220 add_wait_queue(&rtc_wait, &wait);
221 set_current_state(TASK_INTERRUPTIBLE);
222 for (;;) {
223 spin_lock_irq (&rtc_lock);
224 data = rtc_irq_data;
225 if (data != 0) {
226 rtc_irq_data = 0;
227 break;
229 spin_unlock_irq (&rtc_lock);
231 if (file->f_flags & O_NONBLOCK) {
232 retval = -EAGAIN;
233 goto out;
236 if (signal_pending(current)) {
237 retval = -ERESTARTSYS;
238 goto out;
241 schedule();
244 if (data & RTC_PF) {
245 /* interpolate missed periods and set match for the next one */
246 unsigned long period = TIMER_FREQ/rtc_freq;
247 unsigned long oscr = OSCR;
248 unsigned long osmr1 = OSMR1;
249 unsigned long missed = (oscr - osmr1)/period;
250 data += missed << 8;
251 OSSR = OSSR_M1; /* clear match on timer 1 */
252 OSMR1 = osmr1 + (missed + 1)*period;
253 /* Ensure we didn't miss another match in the mean time.
254 Here we compare (match - OSCR) against 8 instead of 0 --
255 see comment in pxa_timer_interrupt() for explanation. */
256 while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) {
257 data += 0x100;
258 OSSR = OSSR_M1; /* clear match on timer 1 */
259 OSMR1 = osmr1 + period;
262 spin_unlock_irq (&rtc_lock);
264 data -= 0x100; /* the first IRQ wasn't actually missed */
266 retval = put_user(data, (unsigned long *)buf);
267 if (!retval)
268 retval = sizeof(unsigned long);
270 out:
271 set_current_state(TASK_RUNNING);
272 remove_wait_queue(&rtc_wait, &wait);
273 return retval;
276 static int rtc_ioctl(struct inode *inode, struct file *file,
277 unsigned int cmd, unsigned long arg)
279 struct rtc_time tm, tm2;
281 switch (cmd) {
282 case RTC_AIE_OFF:
283 spin_lock_irq(&rtc_lock);
284 RTSR &= ~RTSR_ALE;
285 rtc_irq_data = 0;
286 spin_unlock_irq(&rtc_lock);
287 return 0;
288 case RTC_AIE_ON:
289 spin_lock_irq(&rtc_lock);
290 RTSR |= RTSR_ALE;
291 rtc_irq_data = 0;
292 spin_unlock_irq(&rtc_lock);
293 return 0;
294 case RTC_UIE_OFF:
295 spin_lock_irq(&rtc_lock);
296 RTSR &= ~RTSR_HZE;
297 rtc_irq_data = 0;
298 spin_unlock_irq(&rtc_lock);
299 return 0;
300 case RTC_UIE_ON:
301 spin_lock_irq(&rtc_lock);
302 RTSR |= RTSR_HZE;
303 rtc_irq_data = 0;
304 spin_unlock_irq(&rtc_lock);
305 return 0;
306 case RTC_PIE_OFF:
307 spin_lock_irq(&rtc_lock);
308 OIER &= ~OIER_E1;
309 rtc_irq_data = 0;
310 spin_unlock_irq(&rtc_lock);
311 return 0;
312 case RTC_PIE_ON:
313 if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE))
314 return -EACCES;
315 spin_lock_irq(&rtc_lock);
316 OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
317 OIER |= OIER_E1;
318 rtc_irq_data = 0;
319 spin_unlock_irq(&rtc_lock);
320 return 0;
321 case RTC_ALM_READ:
322 decodetime (RTAR, &tm);
323 break;
324 case RTC_ALM_SET:
325 if (copy_from_user (&tm2, (struct rtc_time*)arg, sizeof (tm2)))
326 return -EFAULT;
327 decodetime (RCNR, &tm);
328 if ((unsigned)tm2.tm_hour < 24)
329 tm.tm_hour = tm2.tm_hour;
330 if ((unsigned)tm2.tm_min < 60)
331 tm.tm_min = tm2.tm_min;
332 if ((unsigned)tm2.tm_sec < 60)
333 tm.tm_sec = tm2.tm_sec;
334 RTAR = mktime ( tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
335 tm.tm_hour, tm.tm_min, tm.tm_sec);
336 return 0;
337 case RTC_RD_TIME:
338 decodetime (RCNR, &tm);
339 break;
340 case RTC_SET_TIME:
341 if (!capable(CAP_SYS_TIME))
342 return -EACCES;
343 if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm)))
344 return -EFAULT;
345 tm.tm_year += 1900;
346 if (tm.tm_year < 1970 || (unsigned)tm.tm_mon >= 12 ||
347 tm.tm_mday < 1 || tm.tm_mday > (days_in_mo[tm.tm_mon] +
348 (tm.tm_mon == 1 && is_leap(tm.tm_year))) ||
349 (unsigned)tm.tm_hour >= 24 ||
350 (unsigned)tm.tm_min >= 60 ||
351 (unsigned)tm.tm_sec >= 60)
352 return -EINVAL;
353 RCNR = mktime ( tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
354 tm.tm_hour, tm.tm_min, tm.tm_sec);
355 return 0;
356 case RTC_IRQP_READ:
357 return put_user(rtc_freq, (unsigned long *)arg);
358 case RTC_IRQP_SET:
359 if (arg < 1 || arg > TIMER_FREQ)
360 return -EINVAL;
361 if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
362 return -EACCES;
363 rtc_freq = arg;
364 return 0;
365 case RTC_EPOCH_READ:
366 return put_user (1970, (unsigned long *)arg);
367 default:
368 return -EINVAL;
370 return copy_to_user ((void *)arg, &tm, sizeof (tm)) ? -EFAULT : 0;
373 static struct file_operations rtc_fops = {
374 .owner = THIS_MODULE,
375 .llseek = no_llseek,
376 .read = rtc_read,
377 .poll = rtc_poll,
378 .ioctl = rtc_ioctl,
379 .open = rtc_open,
380 .release = rtc_release,
381 .fasync = rtc_fasync,
384 static struct miscdevice sa1100rtc_miscdev = {
385 .minor = RTC_MINOR,
386 .name = "rtc",
387 .fops = &rtc_fops
390 static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
392 char *p = page;
393 int len;
394 struct rtc_time tm;
396 decodetime (RCNR, &tm);
397 p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n"
398 "rtc_date\t: %04d-%02d-%02d\n"
399 "rtc_epoch\t: %04d\n",
400 tm.tm_hour, tm.tm_min, tm.tm_sec,
401 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1970);
402 decodetime (RTAR, &tm);
403 p += sprintf(p, "alrm_time\t: %02d:%02d:%02d\n"
404 "alrm_date\t: %04d-%02d-%02d\n",
405 tm.tm_hour, tm.tm_min, tm.tm_sec,
406 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
407 p += sprintf(p, "trim/divider\t: 0x%08x\n", RTTR);
408 p += sprintf(p, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" );
409 p += sprintf(p, "update_IRQ\t: %s\n", (RTSR & RTSR_HZE) ? "yes" : "no");
410 p += sprintf(p, "periodic_IRQ\t: %s\n", (OIER & OIER_E1) ? "yes" : "no");
411 p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq);
413 len = (p - page) - off;
414 if (len < 0)
415 len = 0;
417 *eof = (len <= count) ? 1 : 0;
418 *start = page + off;
420 return len;
423 /* let's use the write interface for modifying RTTR */
424 static int rtc_write_proc(struct file *file, const char *buffer,
425 unsigned long count, void *data)
427 if (count > 15)
428 return -EINVAL;
429 if (count > 0) {
430 char lbuf[16];
431 if (copy_from_user(lbuf, buffer, count))
432 return -EFAULT;
433 lbuf[count] = 0;
434 RTTR = simple_strtoul(lbuf, NULL, 0);
436 return count;
439 static int rtc_setup_interrupts(void)
441 int ret;
443 ret = request_irq (IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL);
444 if (ret) {
445 printk (KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_RTC1Hz);
446 goto IRQ_RTC1Hz_failed;
448 ret = request_irq (IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL);
449 if (ret) {
450 printk(KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_RTCAlrm);
451 goto IRQ_RTCAlrm_failed;
453 ret = request_irq (IRQ_OST1, timer1_interrupt, SA_INTERRUPT, "rtc timer", NULL);
454 if (ret) {
455 printk(KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_OST1);
456 goto IRQ_OST1_failed;
459 return 0;
461 IRQ_OST1_failed:
462 free_irq (IRQ_RTCAlrm, NULL);
463 IRQ_RTCAlrm_failed:
464 free_irq (IRQ_RTC1Hz, NULL);
465 IRQ_RTC1Hz_failed:
466 return ret;
469 static void rtc_free_interrupts(void)
471 free_irq (IRQ_OST1, NULL);
472 free_irq (IRQ_RTCAlrm, NULL);
473 free_irq (IRQ_RTC1Hz, NULL);
476 static int sa_rtc_probe(struct device *dev)
478 struct proc_dir_entry *entry;
479 int ret;
481 misc_register (&sa1100rtc_miscdev);
482 entry = create_proc_entry ("driver/rtc", 0, 0);
483 if (entry) {
484 entry->read_proc = rtc_read_proc;
485 entry->write_proc = rtc_write_proc;
487 ret = rtc_setup_interrupts();
488 if (ret)
489 goto IRQ_failed;
491 printk (KERN_INFO "SA1100 Real Time Clock driver v" DRIVER_VERSION "\n");
494 * According to the manual we should be able to let RTTR be zero
495 * and then a default diviser for a 32.768KHz clock is used.
496 * Apparently this doesn't work, at least for my SA1110 rev 5.
497 * If the clock divider is uninitialized then reset it to the
498 * default value to get the 1Hz clock.
500 if (RTTR == 0) {
501 RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
502 printk (KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n");
503 /* The current RTC value probably doesn't make sense either */
504 RCNR = 0;
506 return 0;
508 IRQ_failed:
509 remove_proc_entry ("driver/rtc", NULL);
510 misc_deregister (&sa1100rtc_miscdev);
511 return ret;
514 static int sa_rtc_remove(struct device *dev)
516 rtc_free_interrupts();
517 remove_proc_entry ("driver/rtc", NULL);
518 misc_deregister (&sa1100rtc_miscdev);
519 return 0;
522 #ifdef CONFIG_PM
524 static int sa_rtc_suspend(struct device *dev, pm_message_t state)
526 if (state.event == PM_EVENT_SUSPEND) {
527 disable_irq(IRQ_OST1);
528 disable_irq(IRQ_RTCAlrm);
529 disable_irq(IRQ_RTC1Hz);
531 return 0;
534 static int sa_rtc_resume(struct device *dev)
536 unsigned int rtsr = RTSR;
537 RTSR = 0;
538 RTSR = RTSR_HZ;
539 RTSR = rtsr & (RTSR_HZE|RTSR_ALE);
540 enable_irq(IRQ_OST1);
541 enable_irq(IRQ_RTCAlrm);
542 enable_irq(IRQ_RTC1Hz);
543 return 0;
546 #else
547 #define sa_rtc_suspend NULL
548 #define sa_rtc_resume NULL
549 #endif
551 static struct platform_device sa_rtc_device = {
552 .name = DRIVER_NAME,
553 .id = -1,
556 static struct device_driver sa_rtc_driver = {
557 .name = DRIVER_NAME,
558 .bus = &platform_bus_type,
559 .probe = sa_rtc_probe,
560 .remove = sa_rtc_remove,
561 .suspend = sa_rtc_suspend,
562 .resume = sa_rtc_resume,
565 static int __init rtc_init(void)
567 int result;
569 result = driver_register(&sa_rtc_driver);
570 if (result < 0) {
571 printk(KERN_ERR "SA1100/PXA RTC driver_register failed.\n");
572 return result;
575 result = platform_device_register(&sa_rtc_device);
576 if (result < 0) {
577 printk(KERN_ERR "SA1100/PXA RTC platform_device_register failed.\n");
578 return result;
580 return 0;
583 static void __exit rtc_exit(void)
585 platform_device_unregister(&sa_rtc_device);
586 driver_unregister(&sa_rtc_driver);
587 printk(KERN_INFO "SA1100/PXA RTC removed\n");
590 module_init(rtc_init);
591 module_exit(rtc_exit);
593 MODULE_AUTHOR("Nils Faerber <nils@@kernelconcepts.de>");
594 MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)");
595 MODULE_LICENSE("GPL");
596 MODULE_ALIAS_MISCDEV(RTC_MINOR);