drivers/char/Kconfig | 4 + drivers/char/Makefile | 1 drivers/char/x1205-rtc.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) --- linux-2.6.15/drivers/char/Kconfig 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.15/drivers/char/Kconfig 1970-01-01 00:00:00.000000000 +0000 @@ -783,6 +783,10 @@ config RTC_VR41XX tristate "NEC VR4100 series Real Time Clock Support" depends on CPU_VR41XX +config RTC_X1205 + tristate "X1205 I2C RTC Support" + depends on I2C && RTC_X1205_I2C + config COBALT_LCD bool "Support for Cobalt LCD" depends on MIPS_COBALT --- linux-2.6.15/drivers/char/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.15/drivers/char/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -65,6 +65,7 @@ obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o obj-$(CONFIG_DS1302) += ds1302.o obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o obj-$(CONFIG_RTC_VR41XX) += vr41xx_rtc.o +obj-$(CONFIG_RTC_X1205) += x1205-rtc.o ifeq ($(CONFIG_GENERIC_NVRAM),y) obj-$(CONFIG_NVRAM) += generic_nvram.o else --- linux-2.6.15/drivers/char/x1205-rtc.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.15/drivers/char/x1205-rtc.c 1970-01-01 00:00:00.000000000 +0000 @@ -0,0 +1,162 @@ +/* + * drivers/char/x1205-rtc.c + * + * NSLU2 RTC driver + * + * Copyright (C) 2005 Tower Technologies + * + * based on the original X1205 NSLU2 driver + * Copyright (C) 2004 Karen Spearel + * + * Author: Alessandro Zummo + * Maintainers: http://www.nslu2-linux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define DRV_VERSION "0.9" + +extern int (*set_rtc)(void); + +static int x1205_set_rtc(void) +{ + int err; + + struct rtc_time new_tm, old_tm; + unsigned long cur_secs = xtime.tv_sec; + + if ((err = x1205_do_command(X1205_CMD_GETDATETIME, &old_tm) == 0)) + return err; + + /* FIXME xtime.tv_nsec = old_tm.tm_sec * 10000000; */ + new_tm.tm_sec = cur_secs % 60; + cur_secs /= 60; + new_tm.tm_min = cur_secs % 60; + cur_secs /= 60; + new_tm.tm_hour = cur_secs % 24; + + /* + * avoid writing when we're going to change the day + * of the month. We will retry in the next minute. + * This basically means that if the RTC must not drift + * by more than 1 minute in 11 minutes. + */ + if ((old_tm.tm_hour == 23 && old_tm.tm_min == 59) || + (new_tm.tm_hour == 23 && new_tm.tm_min == 59)) + return 1; + + return x1205_do_command(X1205_CMD_SETTIME, &new_tm); +} + +static int x1205_rtc_read_alarm(struct rtc_wkalrm *alrm) +{ + return x1205_do_command(X1205_CMD_GETALARM, &alrm->time); +} + +static int x1205_rtc_set_alarm(struct rtc_wkalrm *alrm) +{ + return x1205_do_command(X1205_CMD_SETALARM, &alrm->time); +} + +static int x1205_rtc_read_time(struct rtc_time *tm) +{ + return x1205_do_command(X1205_CMD_GETDATETIME, tm); +} + +static int x1205_rtc_set_time(struct rtc_time *tm) +{ + return x1205_do_command(X1205_CMD_SETDATETIME, tm); +} + +static int x1205_rtc_proc(char *buf) +{ + int err, dtrim, atrim; + char *p = buf; + + p += sprintf(p, "24hr\t\t: yes\n"); + + err = x1205_do_command(X1205_CMD_GETDTRIM, &dtrim); + if (err == 0) + p += sprintf(p, "digital_trim\t: %d ppm\n", dtrim); + + err = x1205_do_command(X1205_CMD_GETATRIM, &atrim); + if (err == 0) + p += sprintf(p, "analog_trim\t: %d.%02d pF\n", + atrim / 1000, atrim % 1000); + + return p - buf; +} + +static struct rtc_ops x1205_rtc_ops = { + .owner = THIS_MODULE, + .proc = x1205_rtc_proc, + .read_time = x1205_rtc_read_time, + .set_time = x1205_rtc_set_time, + .read_alarm = x1205_rtc_read_alarm, + .set_alarm = x1205_rtc_set_alarm, +}; + +static int x1205_rtc_probe(struct device *dev) +{ + int ret; + + if ((ret = register_rtc(&x1205_rtc_ops)) != 0) + return ret; + + set_rtc = x1205_set_rtc; + + printk(KERN_INFO "x1205-rtc: real time clock\n"); + + return 0; +} + +static int x1205_rtc_remove(struct device *dev) +{ + set_rtc = NULL; + + unregister_rtc(&x1205_rtc_ops); + + return 0; +} + +static struct device_driver x1205_rtc_driver = { + .name = "x1205-rtc", + .bus = &platform_bus_type, + .probe = x1205_rtc_probe, + .remove = x1205_rtc_remove, +}; + +static int __init x1205_rtc_init(void) +{ + return driver_register(&x1205_rtc_driver); +} + +static void __exit x1205_rtc_exit(void) +{ + driver_unregister(&x1205_rtc_driver); +} + +module_init(x1205_rtc_init); +module_exit(x1205_rtc_exit); + +MODULE_AUTHOR( + "Karen Spearel , " + "Alessandro Zummo "); +MODULE_DESCRIPTION("Xicor X1205 RTC platform driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION);