2 * drivers/cbus/retu-rtc.c
6 * Copyright (C) 2004, 2005 Nokia Corporation
8 * Written by Paul Mundt <paul.mundt@nokia.com> and
9 * Igor Stoppa <igor.stoppa@nokia.com>
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).
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.
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.
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.
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
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>
48 static struct mutex retu_rtc_mutex;
49 static u16 retu_rtc_alarm_expired;
50 static u16 retu_rtc_reset_occurred;
52 static DECLARE_COMPLETION(retu_rtc_exited);
53 static DECLARE_COMPLETION(retu_rtc_sync);
55 static void retu_rtc_barrier(void);
57 static void retu_rtc_device_release(struct device *dev)
59 complete(&retu_rtc_exited);
62 static ssize_t retu_rtc_time_show(struct device *dev, struct device_attribute *attr,
67 mutex_lock(&retu_rtc_mutex);
73 * Not being in_interrupt() for a retu rtc IRQ, we need to
74 * read twice for consistency..
76 dummy = retu_read_reg(RETU_REG_RTCDSR);
77 dsr = retu_read_reg(RETU_REG_RTCDSR);
79 dummy = retu_read_reg(RETU_REG_RTCHMR);
80 hmr = retu_read_reg(RETU_REG_RTCHMR);
82 dummy = retu_read_reg(RETU_REG_RTCDSR);
83 dsr2 = retu_read_reg(RETU_REG_RTCDSR);
84 } while ((dsr != dsr2));
86 mutex_unlock(&retu_rtc_mutex);
89 * Format a 32-bit date-string for userspace
91 * days | hours | minutes | seconds
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).
100 return sprintf(buf, "0x%08x\n", (((dsr >> 8) & 0xff) << 24) |
101 (((hmr >> 8) & 0x1f) << 16) |
102 ((hmr & 0x3f) << 8) | (dsr & 0x3f));
105 static ssize_t retu_rtc_time_store(struct device *dev, struct device_attribute *attr,
106 const char *buf, size_t count)
108 mutex_lock(&retu_rtc_mutex);
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
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));
121 mutex_unlock(&retu_rtc_mutex);
126 static DEVICE_ATTR(time, S_IRUGO | S_IWUSR, retu_rtc_time_show,
127 retu_rtc_time_store);
130 static ssize_t retu_rtc_reset_show(struct device *dev, struct device_attribute *attr, char *buf)
133 * Returns the status of the rtc
135 * 0: no reset has occurred or the status has been cleared
136 * 1: a reset has occurred
138 * RTC needs to be reset only when both main battery
139 * _AND_ backup battery are discharged
141 return sprintf(buf, "%u\n", retu_rtc_reset_occurred);
144 static void retu_rtc_do_reset(void)
148 ccr1 = retu_read_reg(RETU_REG_CC1);
150 retu_write_reg(RETU_REG_CC1, ccr1 | 0x0001);
151 /* RTC in normal operating mode */
152 retu_write_reg(RETU_REG_CC1, ccr1 & ~0x0001);
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);
160 retu_rtc_alarm_expired = 0;
161 retu_rtc_reset_occurred = 1;
164 static ssize_t retu_rtc_reset_store(struct device *dev, struct device_attribute *attr,
165 const char *buf, size_t count)
169 if(sscanf(buf, "%u", &choice) != 1)
171 mutex_lock(&retu_rtc_mutex);
173 retu_rtc_reset_occurred = 0;
174 else if (choice == 1)
176 mutex_unlock(&retu_rtc_mutex);
180 static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR, retu_rtc_reset_show,
181 retu_rtc_reset_store);
183 static ssize_t retu_rtc_alarm_show(struct device *dev, struct device_attribute *attr,
189 mutex_lock(&retu_rtc_mutex);
191 * Format a 16-bit date-string for userspace
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);
204 static ssize_t retu_rtc_alarm_store(struct device *dev, struct device_attribute *attr,
205 const char *buf, size_t count)
212 mutex_lock(&retu_rtc_mutex);
214 if(sscanf(buf, "%x", &alrm) != 1)
216 hours = (alrm >> 8) & 0x001f;
217 minutes = (alrm >> 0) & 0x003f;
218 if ((hours < 24 && minutes < 60) || (hours == 24 && minutes == 60)) {
220 * OK, the time format for the alarm is valid (including the
223 /* Keeps the RTC watchdog status */
224 chmar = retu_read_reg(RETU_REG_RTCHMAR) & 0x6000;
225 chmar |= alrm & 0x1f3f; /* Stores the requested alarm */
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;
234 /* enable the interrupt */
235 retu_enable_irq(RETU_INT_RTCA);
237 mutex_unlock(&retu_rtc_mutex);
242 static DEVICE_ATTR(alarm, S_IRUGO | S_IWUSR, retu_rtc_alarm_show,
243 retu_rtc_alarm_store);
245 static ssize_t retu_rtc_alarm_expired_show(struct device *dev, struct device_attribute *attr,
250 retval = sprintf(buf, "%u\n", retu_rtc_alarm_expired);
255 static ssize_t retu_rtc_alarm_expired_store(struct device *dev, struct device_attribute *attr,
256 const char *buf, size_t count)
258 retu_rtc_alarm_expired = 0;
263 static DEVICE_ATTR(alarm_expired, S_IRUGO | S_IWUSR, retu_rtc_alarm_expired_show,
264 retu_rtc_alarm_expired_store);
267 static ssize_t retu_rtc_cal_show(struct device *dev, struct device_attribute *attr,
272 mutex_lock(&retu_rtc_mutex);
273 rtccalr1 = retu_read_reg(RETU_REG_RTCCALR);
274 mutex_unlock(&retu_rtc_mutex);
277 * Shows the status of the Calibration Register.
279 * Default, after power loss: 0x0000
280 * Default, for R&D: 0x00C0
281 * Default, for factory: 0x00??
284 return sprintf(buf, "0x%04x\n", rtccalr1 & 0x00ff);
287 static ssize_t retu_rtc_cal_store(struct device *dev, struct device_attribute *attr,
288 const char *buf, size_t count)
290 unsigned calibration_value;
292 if (sscanf(buf, "%x", &calibration_value) != 1)
295 mutex_lock(&retu_rtc_mutex);
297 retu_write_reg(RETU_REG_RTCCALR, calibration_value & 0x00ff);
298 mutex_unlock(&retu_rtc_mutex);
303 static DEVICE_ATTR(cal, S_IRUGO | S_IWUSR, retu_rtc_cal_show,
306 static struct device_driver retu_rtc_driver;
308 static void retu_rtca_disable(void)
310 retu_disable_irq(RETU_INT_RTCA);
311 retu_rtc_alarm_expired = 1;
313 retu_write_reg(RETU_REG_RTCHMAR, (24 << 8) | 60);
316 static void retu_rtca_expired(struct work_struct *unused)
319 sysfs_notify(&retu_rtc_driver.kobj, NULL, "alarm_expired");
322 DECLARE_WORK(retu_rtca_work, retu_rtca_expired);
325 * RTCHMR RTCHMAR RTCCAL must be accessed within 0.9 s since the seconds
326 * interrupt has been signaled in the IDR register
328 static void retu_rtcs_interrupt(unsigned long unused)
330 retu_ack_irq(RETU_INT_RTCS);
331 complete(&retu_rtc_sync);
334 static void retu_rtca_interrupt(unsigned long unused)
336 retu_ack_irq(RETU_INT_RTCA);
337 schedule_work(&retu_rtca_work);
340 static int retu_rtc_init_irq(void)
344 ret = retu_request_irq(RETU_INT_RTCS, retu_rtcs_interrupt, 0, "RTCS");
348 * We will take care of enabling and disabling the interrupt
349 * elsewhere, so leave it off by default..
351 retu_disable_irq(RETU_INT_RTCS);
353 ret = retu_request_irq(RETU_INT_RTCA, retu_rtca_interrupt, 0, "RTCA");
355 retu_free_irq(RETU_INT_RTCS);
358 retu_disable_irq(RETU_INT_RTCA);
364 static int __devinit retu_rtc_probe(struct device *dev)
368 retu_rtc_alarm_expired = retu_read_reg(RETU_REG_IDR) &
369 (0x1 << RETU_INT_RTCA);
371 if ((r = retu_rtc_init_irq()) != 0)
374 mutex_init(&retu_rtc_mutex);
376 /* If the calibration register is zero, we've probably lost
378 if (retu_read_reg(RETU_REG_RTCCALR) & 0x00ff)
379 retu_rtc_reset_occurred = 0;
383 if ((r = device_create_file(dev, &dev_attr_time)) != 0)
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;
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);
403 device_remove_file(dev, &dev_attr_time);
407 static int __devexit retu_rtc_remove(struct device *dev)
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);
420 static struct device_driver retu_rtc_driver = {
422 .bus = &platform_bus_type,
423 .probe = retu_rtc_probe,
424 .remove = __devexit_p(retu_rtc_remove),
427 static struct platform_device retu_rtc_device = {
431 .release = retu_rtc_device_release,
435 /* This function provides syncronization with the RTCS interrupt handler */
436 static void retu_rtc_barrier(void)
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);
445 static int __init retu_rtc_init(void)
449 init_completion(&retu_rtc_exited);
451 if ((ret = driver_register(&retu_rtc_driver)) != 0)
454 if ((ret = platform_device_register(&retu_rtc_device)) != 0)
455 goto err_unregister_driver;
459 err_unregister_driver:
460 driver_unregister(&retu_rtc_driver);
464 static void __exit retu_rtc_exit(void)
466 platform_device_unregister(&retu_rtc_device);
467 driver_unregister(&retu_rtc_driver);
469 wait_for_completion(&retu_rtc_exited);
472 module_init(retu_rtc_init);
473 module_exit(retu_rtc_exit);
475 MODULE_DESCRIPTION("Retu RTC");
476 MODULE_LICENSE("GPL");
477 MODULE_AUTHOR("Paul Mundt and Igor Stoppa");