aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-ab8500.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-ab8500.c')
-rw-r--r--drivers/rtc/rtc-ab8500.c138
1 files changed, 121 insertions, 17 deletions
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index e346705aae92..4bcf9ca2818a 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -15,7 +15,7 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/rtc.h> 16#include <linux/rtc.h>
17#include <linux/mfd/abx500.h> 17#include <linux/mfd/abx500.h>
18#include <linux/mfd/ab8500.h> 18#include <linux/mfd/abx500/ab8500.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20 20
21#define AB8500_RTC_SOFF_STAT_REG 0x00 21#define AB8500_RTC_SOFF_STAT_REG 0x00
@@ -90,7 +90,7 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
90 90
91 /* Early AB8500 chips will not clear the rtc read request bit */ 91 /* Early AB8500 chips will not clear the rtc read request bit */
92 if (abx500_get_chip_id(dev) == 0) { 92 if (abx500_get_chip_id(dev) == 0) {
93 msleep(1); 93 usleep_range(1000, 1000);
94 } else { 94 } else {
95 /* Wait for some cycles after enabling the rtc read in ab8500 */ 95 /* Wait for some cycles after enabling the rtc read in ab8500 */
96 while (time_before(jiffies, timeout)) { 96 while (time_before(jiffies, timeout)) {
@@ -102,7 +102,7 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
102 if (!(value & RTC_READ_REQUEST)) 102 if (!(value & RTC_READ_REQUEST))
103 break; 103 break;
104 104
105 msleep(1); 105 usleep_range(1000, 5000);
106 } 106 }
107 } 107 }
108 108
@@ -258,6 +258,109 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
258 return ab8500_rtc_irq_enable(dev, alarm->enabled); 258 return ab8500_rtc_irq_enable(dev, alarm->enabled);
259} 259}
260 260
261
262static int ab8500_rtc_set_calibration(struct device *dev, int calibration)
263{
264 int retval;
265 u8 rtccal = 0;
266
267 /*
268 * Check that the calibration value (which is in units of 0.5
269 * parts-per-million) is in the AB8500's range for RtcCalibration
270 * register. -128 (0x80) is not permitted because the AB8500 uses
271 * a sign-bit rather than two's complement, so 0x80 is just another
272 * representation of zero.
273 */
274 if ((calibration < -127) || (calibration > 127)) {
275 dev_err(dev, "RtcCalibration value outside permitted range\n");
276 return -EINVAL;
277 }
278
279 /*
280 * The AB8500 uses sign (in bit7) and magnitude (in bits0-7)
281 * so need to convert to this sort of representation before writing
282 * into RtcCalibration register...
283 */
284 if (calibration >= 0)
285 rtccal = 0x7F & calibration;
286 else
287 rtccal = ~(calibration - 1) | 0x80;
288
289 retval = abx500_set_register_interruptible(dev, AB8500_RTC,
290 AB8500_RTC_CALIB_REG, rtccal);
291
292 return retval;
293}
294
295static int ab8500_rtc_get_calibration(struct device *dev, int *calibration)
296{
297 int retval;
298 u8 rtccal = 0;
299
300 retval = abx500_get_register_interruptible(dev, AB8500_RTC,
301 AB8500_RTC_CALIB_REG, &rtccal);
302 if (retval >= 0) {
303 /*
304 * The AB8500 uses sign (in bit7) and magnitude (in bits0-7)
305 * so need to convert value from RtcCalibration register into
306 * a two's complement signed value...
307 */
308 if (rtccal & 0x80)
309 *calibration = 0 - (rtccal & 0x7F);
310 else
311 *calibration = 0x7F & rtccal;
312 }
313
314 return retval;
315}
316
317static ssize_t ab8500_sysfs_store_rtc_calibration(struct device *dev,
318 struct device_attribute *attr,
319 const char *buf, size_t count)
320{
321 int retval;
322 int calibration = 0;
323
324 if (sscanf(buf, " %i ", &calibration) != 1) {
325 dev_err(dev, "Failed to store RTC calibration attribute\n");
326 return -EINVAL;
327 }
328
329 retval = ab8500_rtc_set_calibration(dev, calibration);
330
331 return retval ? retval : count;
332}
333
334static ssize_t ab8500_sysfs_show_rtc_calibration(struct device *dev,
335 struct device_attribute *attr, char *buf)
336{
337 int retval = 0;
338 int calibration = 0;
339
340 retval = ab8500_rtc_get_calibration(dev, &calibration);
341 if (retval < 0) {
342 dev_err(dev, "Failed to read RTC calibration attribute\n");
343 sprintf(buf, "0\n");
344 return retval;
345 }
346
347 return sprintf(buf, "%d\n", calibration);
348}
349
350static DEVICE_ATTR(rtc_calibration, S_IRUGO | S_IWUSR,
351 ab8500_sysfs_show_rtc_calibration,
352 ab8500_sysfs_store_rtc_calibration);
353
354static int ab8500_sysfs_rtc_register(struct device *dev)
355{
356 return device_create_file(dev, &dev_attr_rtc_calibration);
357}
358
359static void ab8500_sysfs_rtc_unregister(struct device *dev)
360{
361 device_remove_file(dev, &dev_attr_rtc_calibration);
362}
363
261static irqreturn_t rtc_alarm_handler(int irq, void *data) 364static irqreturn_t rtc_alarm_handler(int irq, void *data)
262{ 365{
263 struct rtc_device *rtc = data; 366 struct rtc_device *rtc = data;
@@ -295,7 +398,7 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
295 return err; 398 return err;
296 399
297 /* Wait for reset by the PorRtc */ 400 /* Wait for reset by the PorRtc */
298 msleep(1); 401 usleep_range(1000, 5000);
299 402
300 err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC, 403 err = abx500_get_register_interruptible(&pdev->dev, AB8500_RTC,
301 AB8500_RTC_STAT_REG, &rtc_ctrl); 404 AB8500_RTC_STAT_REG, &rtc_ctrl);
@@ -308,6 +411,8 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
308 return -ENODEV; 411 return -ENODEV;
309 } 412 }
310 413
414 device_init_wakeup(&pdev->dev, true);
415
311 rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops, 416 rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops,
312 THIS_MODULE); 417 THIS_MODULE);
313 if (IS_ERR(rtc)) { 418 if (IS_ERR(rtc)) {
@@ -316,8 +421,8 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
316 return err; 421 return err;
317 } 422 }
318 423
319 err = request_threaded_irq(irq, NULL, rtc_alarm_handler, 0, 424 err = request_threaded_irq(irq, NULL, rtc_alarm_handler,
320 "ab8500-rtc", rtc); 425 IRQF_NO_SUSPEND, "ab8500-rtc", rtc);
321 if (err < 0) { 426 if (err < 0) {
322 rtc_device_unregister(rtc); 427 rtc_device_unregister(rtc);
323 return err; 428 return err;
@@ -325,6 +430,13 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev)
325 430
326 platform_set_drvdata(pdev, rtc); 431 platform_set_drvdata(pdev, rtc);
327 432
433
434 err = ab8500_sysfs_rtc_register(&pdev->dev);
435 if (err) {
436 dev_err(&pdev->dev, "sysfs RTC failed to register\n");
437 return err;
438 }
439
328 return 0; 440 return 0;
329} 441}
330 442
@@ -333,6 +445,8 @@ static int __devexit ab8500_rtc_remove(struct platform_device *pdev)
333 struct rtc_device *rtc = platform_get_drvdata(pdev); 445 struct rtc_device *rtc = platform_get_drvdata(pdev);
334 int irq = platform_get_irq_byname(pdev, "ALARM"); 446 int irq = platform_get_irq_byname(pdev, "ALARM");
335 447
448 ab8500_sysfs_rtc_unregister(&pdev->dev);
449
336 free_irq(irq, rtc); 450 free_irq(irq, rtc);
337 rtc_device_unregister(rtc); 451 rtc_device_unregister(rtc);
338 platform_set_drvdata(pdev, NULL); 452 platform_set_drvdata(pdev, NULL);
@@ -349,18 +463,8 @@ static struct platform_driver ab8500_rtc_driver = {
349 .remove = __devexit_p(ab8500_rtc_remove), 463 .remove = __devexit_p(ab8500_rtc_remove),
350}; 464};
351 465
352static int __init ab8500_rtc_init(void) 466module_platform_driver(ab8500_rtc_driver);
353{
354 return platform_driver_register(&ab8500_rtc_driver);
355}
356
357static void __exit ab8500_rtc_exit(void)
358{
359 platform_driver_unregister(&ab8500_rtc_driver);
360}
361 467
362module_init(ab8500_rtc_init);
363module_exit(ab8500_rtc_exit);
364MODULE_AUTHOR("Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>"); 468MODULE_AUTHOR("Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com>");
365MODULE_DESCRIPTION("AB8500 RTC Driver"); 469MODULE_DESCRIPTION("AB8500 RTC Driver");
366MODULE_LICENSE("GPL v2"); 470MODULE_LICENSE("GPL v2");