Merge current mainline tree into linux-omap tree
[pandora-kernel.git] / drivers / cbus / retu-rtc.c
1 /**
2  * drivers/cbus/retu-rtc.c
3  *
4  * Support for Retu RTC
5  *
6  * Copyright (C) 2004, 2005 Nokia Corporation
7  *
8  * Written by Paul Mundt <paul.mundt@nokia.com> and
9  *            Igor Stoppa <igor.stoppa@nokia.com>
10  *
11  * The Retu RTC is essentially a partial read-only RTC that gives us Retu's
12  * idea of what time actually is. It's left as a userspace excercise to map
13  * this back to time in the real world and ensure that calibration settings
14  * are sane to compensate for any horrible drift (on account of not being able
15  * to set the clock to anything).
16  *
17  * Days are semi-writeable. Namely, Retu will only track 255 days for us
18  * consecutively, after which the counter is explicitly stuck at 255 until
19  * someone comes along and clears it with a write. In the event that no one
20  * comes along and clears it, we no longer have any idea what day it is.
21  *
22  * This file is subject to the terms and conditions of the GNU General
23  * Public License. See the file "COPYING" in the main directory of this
24  * archive for more details.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34  */
35
36 #include <linux/device.h>
37 #include <linux/init.h>
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/completion.h>
41 #include <linux/platform_device.h>
42 #include <linux/mutex.h>
43 #include <linux/workqueue.h>
44
45 #include "cbus.h"
46 #include "retu.h"
47
48 static struct mutex retu_rtc_mutex;
49 static u16 retu_rtc_alarm_expired;
50 static u16 retu_rtc_reset_occurred;
51
52 static DECLARE_COMPLETION(retu_rtc_exited);
53 static DECLARE_COMPLETION(retu_rtc_sync);
54
55 static void retu_rtc_barrier(void);
56
57 static void retu_rtc_device_release(struct device *dev)
58 {
59         complete(&retu_rtc_exited);
60 }
61
62 static ssize_t retu_rtc_time_show(struct device *dev, struct device_attribute *attr,
63                                   char *buf)
64 {
65         u16 dsr, hmr, dsr2;
66
67         mutex_lock(&retu_rtc_mutex);
68
69         do {
70                 u16 dummy;
71
72                 /*
73                  * Not being in_interrupt() for a retu rtc IRQ, we need to
74                  * read twice for consistency..
75                  */
76                 dummy   = retu_read_reg(RETU_REG_RTCDSR);
77                 dsr     = retu_read_reg(RETU_REG_RTCDSR);
78
79                 dummy   = retu_read_reg(RETU_REG_RTCHMR);
80                 hmr     = retu_read_reg(RETU_REG_RTCHMR);
81
82                 dummy   = retu_read_reg(RETU_REG_RTCDSR);
83                 dsr2    = retu_read_reg(RETU_REG_RTCDSR);
84         } while ((dsr != dsr2));
85
86         mutex_unlock(&retu_rtc_mutex);
87
88         /*
89          * Format a 32-bit date-string for userspace
90          *
91          * days | hours | minutes | seconds
92          *
93          * 8 bits for each.
94          *
95          * This mostly sucks because days and seconds are tracked in RTCDSR
96          * while hours and minutes are tracked in RTCHMR. And yes, there
97          * really are no words that can describe an 8 bit day register (or
98          * rather, none that will be reprinted here).
99          */
100         return sprintf(buf, "0x%08x\n", (((dsr >> 8) & 0xff) << 24) |
101                                         (((hmr >> 8) & 0x1f) << 16) |
102                                          ((hmr & 0x3f) << 8) | (dsr & 0x3f));
103 }
104
105 static ssize_t retu_rtc_time_store(struct device *dev, struct device_attribute *attr,
106                                    const char *buf, size_t count)
107 {
108         mutex_lock(&retu_rtc_mutex);
109         /*
110          * Writing anything to the day counter forces it to 0
111          * The seconds counter would be cleared by resetting the minutes counter,
112          * however this won't happen, since we are using the hh:mm counters as
113          * a set of free running counters and the day counter as a multiple
114          * overflow holder.
115          */
116
117         /* Reset day counter, but keep Temperature Shutdown state */
118         retu_write_reg(RETU_REG_RTCDSR,
119                        retu_read_reg(RETU_REG_RTCDSR) & (1 << 6));
120
121         mutex_unlock(&retu_rtc_mutex);
122
123         return count;
124 }
125
126 static DEVICE_ATTR(time, S_IRUGO | S_IWUSR, retu_rtc_time_show,
127                    retu_rtc_time_store);
128
129
130 static ssize_t retu_rtc_reset_show(struct device *dev, struct device_attribute *attr, char *buf)
131 {
132         /*
133          * Returns the status of the rtc
134          *
135          * 0: no reset has occurred or the status has been cleared
136          * 1: a reset has occurred
137          *
138          * RTC needs to be reset only when both main battery
139          * _AND_ backup battery are discharged
140          */
141         return sprintf(buf, "%u\n", retu_rtc_reset_occurred);
142 }
143
144 static void retu_rtc_do_reset(void)
145 {
146         u16 ccr1;
147
148         ccr1 = retu_read_reg(RETU_REG_CC1);
149         /* RTC in reset */
150         retu_write_reg(RETU_REG_CC1, ccr1 | 0x0001);
151         /* RTC in normal operating mode */
152         retu_write_reg(RETU_REG_CC1, ccr1 & ~0x0001);
153
154         retu_rtc_barrier();
155         /* Disable alarm and RTC WD */
156         retu_write_reg(RETU_REG_RTCHMAR, 0x7f3f);
157         /* Set Calibration register to default value */
158         retu_write_reg(RETU_REG_RTCCALR, 0x00c0);
159
160         retu_rtc_alarm_expired = 0;
161         retu_rtc_reset_occurred = 1;
162 }
163
164 static ssize_t retu_rtc_reset_store(struct device *dev, struct device_attribute *attr,
165                                     const char *buf, size_t count)
166 {
167         unsigned choice;
168
169         if(sscanf(buf, "%u", &choice) != 1)
170                 return count;
171         mutex_lock(&retu_rtc_mutex);
172         if (choice == 0)
173                 retu_rtc_reset_occurred = 0;
174         else if (choice == 1)
175                 retu_rtc_do_reset();
176         mutex_unlock(&retu_rtc_mutex);
177         return count;
178 }
179
180 static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR, retu_rtc_reset_show,
181                    retu_rtc_reset_store);
182
183 static ssize_t retu_rtc_alarm_show(struct device *dev, struct device_attribute *attr,
184                                    char *buf)
185 {
186         u16 chmar;
187         ssize_t retval;
188
189         mutex_lock(&retu_rtc_mutex);
190         /*
191          * Format a 16-bit date-string for userspace
192          *
193          * hours | minutes
194          * 8 bits for each.
195          */
196         chmar = retu_read_reg(RETU_REG_RTCHMAR);
197         /* No shifting needed, only masking unrelated bits */
198         retval = sprintf(buf, "0x%04x\n", chmar & 0x1f3f);
199         mutex_unlock(&retu_rtc_mutex);
200
201         return retval;
202 }
203
204 static ssize_t retu_rtc_alarm_store(struct device *dev, struct device_attribute *attr,
205                                     const char *buf, size_t count)
206 {
207         u16 chmar;
208         unsigned alrm;
209         unsigned hours;
210         unsigned minutes;
211
212         mutex_lock(&retu_rtc_mutex);
213
214         if(sscanf(buf, "%x", &alrm) != 1)
215                 return count;
216         hours = (alrm >> 8) & 0x001f;
217         minutes = (alrm >> 0) & 0x003f;
218         if ((hours < 24 && minutes < 60) || (hours == 24 && minutes == 60)) {
219                 /*
220                  * OK, the time format for the alarm is valid (including the
221                  * disabling values)
222                  */
223                 /* Keeps the RTC watchdog status */
224                 chmar = retu_read_reg(RETU_REG_RTCHMAR) & 0x6000;
225                 chmar |= alrm & 0x1f3f; /* Stores the requested alarm */
226                 retu_rtc_barrier();
227                 retu_write_reg(RETU_REG_RTCHMAR, chmar);
228                 /* If the alarm is being disabled */
229                 if (hours == 24 && minutes == 60) {
230                         /* disable the interrupt */
231                         retu_disable_irq(RETU_INT_RTCA);
232                         retu_rtc_alarm_expired = 0;
233                 } else
234                         /* enable the interrupt */
235                         retu_enable_irq(RETU_INT_RTCA);
236         }
237         mutex_unlock(&retu_rtc_mutex);
238
239         return count;
240 }
241
242 static DEVICE_ATTR(alarm, S_IRUGO | S_IWUSR, retu_rtc_alarm_show,
243                    retu_rtc_alarm_store);
244
245 static ssize_t retu_rtc_alarm_expired_show(struct device *dev, struct device_attribute *attr,
246                                            char *buf)
247 {
248         ssize_t retval;
249
250         retval = sprintf(buf, "%u\n", retu_rtc_alarm_expired);
251
252         return retval;
253 }
254
255 static ssize_t retu_rtc_alarm_expired_store(struct device *dev, struct device_attribute *attr,
256                                             const char *buf, size_t count)
257 {
258         retu_rtc_alarm_expired = 0;
259
260         return count;
261 }
262
263 static DEVICE_ATTR(alarm_expired, S_IRUGO | S_IWUSR, retu_rtc_alarm_expired_show,
264                    retu_rtc_alarm_expired_store);
265
266
267 static ssize_t retu_rtc_cal_show(struct device *dev, struct device_attribute *attr,
268                                  char *buf)
269 {
270         u16 rtccalr1;
271
272         mutex_lock(&retu_rtc_mutex);
273         rtccalr1 = retu_read_reg(RETU_REG_RTCCALR);
274         mutex_unlock(&retu_rtc_mutex);
275
276         /*
277          * Shows the status of the Calibration Register.
278          *
279          * Default, after power loss: 0x0000
280          * Default, for R&D: 0x00C0
281          * Default, for factory: 0x00??
282          *
283          */
284         return sprintf(buf, "0x%04x\n", rtccalr1 & 0x00ff);
285 }
286
287 static ssize_t retu_rtc_cal_store(struct device *dev, struct device_attribute *attr,
288                                   const char *buf, size_t count)
289 {
290         unsigned calibration_value;
291
292         if (sscanf(buf, "%x", &calibration_value) != 1)
293                 return count;
294
295         mutex_lock(&retu_rtc_mutex);
296         retu_rtc_barrier();
297         retu_write_reg(RETU_REG_RTCCALR, calibration_value & 0x00ff);
298         mutex_unlock(&retu_rtc_mutex);
299
300         return count;
301 }
302
303 static DEVICE_ATTR(cal, S_IRUGO | S_IWUSR, retu_rtc_cal_show,
304                    retu_rtc_cal_store);
305
306 static struct platform_device retu_rtc_device;
307
308 static void retu_rtca_disable(void)
309 {
310         retu_disable_irq(RETU_INT_RTCA);
311         retu_rtc_alarm_expired = 1;
312         retu_rtc_barrier();
313         retu_write_reg(RETU_REG_RTCHMAR, (24 << 8) | 60);
314 }
315
316 static void retu_rtca_expired(struct work_struct *unused)
317 {
318         retu_rtca_disable();
319         sysfs_notify(&retu_rtc_device.dev.kobj, NULL, "alarm_expired");
320 }
321
322 DECLARE_WORK(retu_rtca_work, retu_rtca_expired);
323
324 /*
325  * RTCHMR RTCHMAR RTCCAL must be accessed within 0.9 s since the seconds
326  * interrupt has been signaled in the IDR register
327  */
328 static void retu_rtcs_interrupt(unsigned long unused)
329 {
330         retu_ack_irq(RETU_INT_RTCS);
331         complete_all(&retu_rtc_sync);
332 }
333
334 static void retu_rtca_interrupt(unsigned long unused)
335 {
336         retu_ack_irq(RETU_INT_RTCA);
337         schedule_work(&retu_rtca_work);
338 }
339
340 static int retu_rtc_init_irq(void)
341 {
342         int ret;
343
344         ret = retu_request_irq(RETU_INT_RTCS, retu_rtcs_interrupt, 0, "RTCS");
345         if (ret != 0)
346                 return ret;
347         /*
348          * We will take care of enabling and disabling the interrupt
349          * elsewhere, so leave it off by default..
350          */
351         retu_disable_irq(RETU_INT_RTCS);
352
353         ret = retu_request_irq(RETU_INT_RTCA, retu_rtca_interrupt, 0, "RTCA");
354         if (ret != 0) {
355                 retu_free_irq(RETU_INT_RTCS);
356                 return ret;
357         }
358         retu_disable_irq(RETU_INT_RTCA);
359
360         return 0;
361 }
362
363
364 static int __devinit retu_rtc_probe(struct device *dev)
365 {
366         int r;
367
368         retu_rtc_alarm_expired = retu_read_reg(RETU_REG_IDR) &
369                                                (0x1 << RETU_INT_RTCA);
370
371         if ((r = retu_rtc_init_irq()) != 0)
372                 return r;
373
374         mutex_init(&retu_rtc_mutex);
375
376         /* If the calibration register is zero, we've probably lost
377          * power */
378         if (retu_read_reg(RETU_REG_RTCCALR) & 0x00ff)
379                 retu_rtc_reset_occurred = 0;
380         else
381                 retu_rtc_do_reset();
382
383         if ((r = device_create_file(dev, &dev_attr_time)) != 0)
384                 return r;
385         else if ((r = device_create_file(dev, &dev_attr_reset)) != 0)
386                 goto err_unregister_time;
387         else if ((r = device_create_file(dev, &dev_attr_alarm)) != 0)
388                 goto err_unregister_reset;
389         else if ((r = device_create_file(dev, &dev_attr_alarm_expired)) != 0)
390                 goto err_unregister_alarm;
391         else if ((r = device_create_file(dev, &dev_attr_cal)) != 0)
392                 goto err_unregister_alarm_expired;
393         else
394                 return r;
395
396 err_unregister_alarm_expired:
397         device_remove_file(dev, &dev_attr_alarm_expired);
398 err_unregister_alarm:
399         device_remove_file(dev, &dev_attr_alarm);
400 err_unregister_reset:
401         device_remove_file(dev, &dev_attr_reset);
402 err_unregister_time:
403         device_remove_file(dev, &dev_attr_time);
404         return r;
405 }
406
407 static int __devexit retu_rtc_remove(struct device *dev)
408 {
409         retu_disable_irq(RETU_INT_RTCS);
410         retu_free_irq(RETU_INT_RTCS);
411         retu_free_irq(RETU_INT_RTCA);
412         device_remove_file(dev, &dev_attr_cal);
413         device_remove_file(dev, &dev_attr_alarm_expired);
414         device_remove_file(dev, &dev_attr_alarm);
415         device_remove_file(dev, &dev_attr_reset);
416         device_remove_file(dev, &dev_attr_time);
417         return 0;
418 }
419
420 static struct device_driver retu_rtc_driver = {
421         .name           = "retu-rtc",
422         .bus            = &platform_bus_type,
423         .probe          = retu_rtc_probe,
424         .remove         = __devexit_p(retu_rtc_remove),
425 };
426
427 static struct platform_device retu_rtc_device = {
428         .name           = "retu-rtc",
429         .id             = -1,
430         .dev            = {
431                 .release        = retu_rtc_device_release,
432         },
433 };
434
435 /* This function provides syncronization with the RTCS interrupt handler */
436 static void retu_rtc_barrier(void)
437 {
438         INIT_COMPLETION(retu_rtc_sync);
439         retu_ack_irq(RETU_INT_RTCS);
440         retu_enable_irq(RETU_INT_RTCS);
441         wait_for_completion(&retu_rtc_sync);
442         retu_disable_irq(RETU_INT_RTCS);
443 }
444
445 static int __init retu_rtc_init(void)
446 {
447         int ret;
448
449         init_completion(&retu_rtc_exited);
450
451         if ((ret = driver_register(&retu_rtc_driver)) != 0)
452                 return ret;
453
454         if ((ret = platform_device_register(&retu_rtc_device)) != 0)
455                 goto err_unregister_driver;
456
457         return 0;
458
459 err_unregister_driver:
460         driver_unregister(&retu_rtc_driver);
461         return ret;
462 }
463
464 static void __exit retu_rtc_exit(void)
465 {
466         platform_device_unregister(&retu_rtc_device);
467         driver_unregister(&retu_rtc_driver);
468
469         wait_for_completion(&retu_rtc_exited);
470 }
471
472 module_init(retu_rtc_init);
473 module_exit(retu_rtc_exit);
474
475 MODULE_DESCRIPTION("Retu RTC");
476 MODULE_LICENSE("GPL");
477 MODULE_AUTHOR("Paul Mundt and Igor Stoppa");