aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-m48t59.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-m48t59.c')
-rw-r--r--drivers/rtc/rtc-m48t59.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index e085ab2c3dbe..50f9f10b32f0 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -24,8 +24,9 @@
24#define NO_IRQ (-1) 24#define NO_IRQ (-1)
25#endif 25#endif
26 26
27#define M48T59_READ(reg) pdata->read_byte(dev, reg) 27#define M48T59_READ(reg) (pdata->read_byte(dev, pdata->offset + reg))
28#define M48T59_WRITE(val, reg) pdata->write_byte(dev, reg, val) 28#define M48T59_WRITE(val, reg) \
29 (pdata->write_byte(dev, pdata->offset + reg, val))
29 30
30#define M48T59_SET_BITS(mask, reg) \ 31#define M48T59_SET_BITS(mask, reg) \
31 M48T59_WRITE((M48T59_READ(reg) | (mask)), (reg)) 32 M48T59_WRITE((M48T59_READ(reg) | (mask)), (reg))
@@ -309,6 +310,11 @@ static const struct rtc_class_ops m48t59_rtc_ops = {
309 .proc = m48t59_rtc_proc, 310 .proc = m48t59_rtc_proc,
310}; 311};
311 312
313static const struct rtc_class_ops m48t02_rtc_ops = {
314 .read_time = m48t59_rtc_read_time,
315 .set_time = m48t59_rtc_set_time,
316};
317
312static ssize_t m48t59_nvram_read(struct kobject *kobj, 318static ssize_t m48t59_nvram_read(struct kobject *kobj,
313 struct bin_attribute *bin_attr, 319 struct bin_attribute *bin_attr,
314 char *buf, loff_t pos, size_t size) 320 char *buf, loff_t pos, size_t size)
@@ -320,7 +326,7 @@ static ssize_t m48t59_nvram_read(struct kobject *kobj,
320 ssize_t cnt = 0; 326 ssize_t cnt = 0;
321 unsigned long flags; 327 unsigned long flags;
322 328
323 for (; size > 0 && pos < M48T59_NVRAM_SIZE; cnt++, size--) { 329 for (; size > 0 && pos < pdata->offset; cnt++, size--) {
324 spin_lock_irqsave(&m48t59->lock, flags); 330 spin_lock_irqsave(&m48t59->lock, flags);
325 *buf++ = M48T59_READ(cnt); 331 *buf++ = M48T59_READ(cnt);
326 spin_unlock_irqrestore(&m48t59->lock, flags); 332 spin_unlock_irqrestore(&m48t59->lock, flags);
@@ -340,7 +346,7 @@ static ssize_t m48t59_nvram_write(struct kobject *kobj,
340 ssize_t cnt = 0; 346 ssize_t cnt = 0;
341 unsigned long flags; 347 unsigned long flags;
342 348
343 for (; size > 0 && pos < M48T59_NVRAM_SIZE; cnt++, size--) { 349 for (; size > 0 && pos < pdata->offset; cnt++, size--) {
344 spin_lock_irqsave(&m48t59->lock, flags); 350 spin_lock_irqsave(&m48t59->lock, flags);
345 M48T59_WRITE(*buf++, cnt); 351 M48T59_WRITE(*buf++, cnt);
346 spin_unlock_irqrestore(&m48t59->lock, flags); 352 spin_unlock_irqrestore(&m48t59->lock, flags);
@@ -357,7 +363,6 @@ static struct bin_attribute m48t59_nvram_attr = {
357 }, 363 },
358 .read = m48t59_nvram_read, 364 .read = m48t59_nvram_read,
359 .write = m48t59_nvram_write, 365 .write = m48t59_nvram_write,
360 .size = M48T59_NVRAM_SIZE,
361}; 366};
362 367
363static int __devinit m48t59_rtc_probe(struct platform_device *pdev) 368static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
@@ -366,6 +371,8 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
366 struct m48t59_private *m48t59 = NULL; 371 struct m48t59_private *m48t59 = NULL;
367 struct resource *res; 372 struct resource *res;
368 int ret = -ENOMEM; 373 int ret = -ENOMEM;
374 char *name;
375 const struct rtc_class_ops *ops;
369 376
370 /* This chip could be memory-mapped or I/O-mapped */ 377 /* This chip could be memory-mapped or I/O-mapped */
371 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 378 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -390,6 +397,8 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
390 /* Ensure we only kmalloc platform data once */ 397 /* Ensure we only kmalloc platform data once */
391 pdev->dev.platform_data = pdata; 398 pdev->dev.platform_data = pdata;
392 } 399 }
400 if (!pdata->type)
401 pdata->type = M48T59RTC_TYPE_M48T59;
393 402
394 /* Try to use the generic memory read/write ops */ 403 /* Try to use the generic memory read/write ops */
395 if (!pdata->write_byte) 404 if (!pdata->write_byte)
@@ -419,14 +428,36 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
419 if (ret) 428 if (ret)
420 goto out; 429 goto out;
421 } 430 }
431 switch (pdata->type) {
432 case M48T59RTC_TYPE_M48T59:
433 name = "m48t59";
434 ops = &m48t59_rtc_ops;
435 pdata->offset = 0x1ff0;
436 break;
437 case M48T59RTC_TYPE_M48T02:
438 name = "m48t02";
439 ops = &m48t02_rtc_ops;
440 pdata->offset = 0x7f0;
441 break;
442 case M48T59RTC_TYPE_M48T08:
443 name = "m48t08";
444 ops = &m48t02_rtc_ops;
445 pdata->offset = 0x1ff0;
446 break;
447 default:
448 dev_err(&pdev->dev, "Unknown RTC type\n");
449 ret = -ENODEV;
450 goto out;
451 }
422 452
423 m48t59->rtc = rtc_device_register("m48t59", &pdev->dev, 453 m48t59->rtc = rtc_device_register(name, &pdev->dev, ops, THIS_MODULE);
424 &m48t59_rtc_ops, THIS_MODULE);
425 if (IS_ERR(m48t59->rtc)) { 454 if (IS_ERR(m48t59->rtc)) {
426 ret = PTR_ERR(m48t59->rtc); 455 ret = PTR_ERR(m48t59->rtc);
427 goto out; 456 goto out;
428 } 457 }
429 458
459 m48t59_nvram_attr.size = pdata->offset;
460
430 ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); 461 ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
431 if (ret) 462 if (ret)
432 goto out; 463 goto out;
@@ -489,5 +520,5 @@ module_init(m48t59_rtc_init);
489module_exit(m48t59_rtc_exit); 520module_exit(m48t59_rtc_exit);
490 521
491MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>"); 522MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>");
492MODULE_DESCRIPTION("M48T59 RTC driver"); 523MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver");
493MODULE_LICENSE("GPL"); 524MODULE_LICENSE("GPL");