summaryrefslogtreecommitdiff
path: root/packages/linux/nslu2-kernel/2.6.15/55-rtc-x1205.patch
blob: 70befe5fe4dbb57e3ce93450b37d6fa1b9432a26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
 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 <a.zummo@towertech.it>
+ * 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 <linux/module.h>
+#include <linux/device.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c.h>
+#include <linux/x1205.h>
+
+#include <asm/rtc.h>
+
+#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 <kas11@tampabay.rr.com>, "
+        "Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("Xicor X1205 RTC platform driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);