aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2008-09-03 18:12:34 -0400
committerDavid S. Miller <davem@davemloft.net>2008-09-03 18:39:11 -0400
commit94fe7424a4c21940b4569200faaf0a0a5efd2924 (patch)
tree1c19837578b0774008df1e2430cf32353cf95286 /drivers
parent3ca60f6e637cee8c735a7448fd912fe1a6e42fc1 (diff)
rtc-m48t59: add support for M48T02 and M48T59 chips
Add support for two compatible RTC: - M48T08 which does not have alarm part, - M48T08 which does not have alarm part and has only 2KB of NVRAM These types covers all Mostek's RTC used in Sun UltraSparc workstations. Tested on Sun Ultra60 with M48T59 RTC. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rtc/Kconfig7
-rw-r--r--drivers/rtc/rtc-m48t59.c47
2 files changed, 44 insertions, 10 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index ecdff2002476..daf08fe980d0 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -406,10 +406,13 @@ config RTC_DRV_M48T86
406 will be called rtc-m48t86. 406 will be called rtc-m48t86.
407 407
408config RTC_DRV_M48T59 408config RTC_DRV_M48T59
409 tristate "ST M48T59" 409 tristate "ST M48T59/M48T08/M48T02"
410 help 410 help
411 If you say Y here you will get support for the 411 If you say Y here you will get support for the
412 ST M48T59 RTC chip. 412 ST M48T59 RTC chip and compatible ST M48T08 and M48T02.
413
414 These chips are usually found in Sun SPARC and UltraSPARC
415 workstations.
413 416
414 This driver can also be built as a module, if so, the module 417 This driver can also be built as a module, if so, the module
415 will be called "rtc-m48t59". 418 will be called "rtc-m48t59".
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");