aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2006-06-25 08:48:17 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:01:13 -0400
commit1abb0dc92d706e8c73c7a62ca813738fe2259a7f (patch)
treefb7d8d35431ba09db1c94f2211c56dad64c6687e /drivers
parent3eecd1dc57971b2beff699b3704058866c25dedc (diff)
[PATCH] "RTC-framework" driver for DS1307 and similar RTC chips
This is an "RTC-framework" driver for DS1307 and similar RTC chips, It should be a full replacement for the existing ds1337.c driver (using the older RTC glue), giving a net increase in the number of RTC chips that work out-of-the-box. There's a whole cluster of RTCs that are very similar, but the 1337 driver was a bit too picky to work with most of them. Still no support for RTC alarm IRQs (on chips that support them). Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rtc/Kconfig18
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-ds1307.c388
3 files changed, 407 insertions, 0 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 875ff5e5792a..9e249650baf0 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -86,6 +86,24 @@ config RTC_DRV_X1205
86 This driver can also be built as a module. If so, the module 86 This driver can also be built as a module. If so, the module
87 will be called rtc-x1205. 87 will be called rtc-x1205.
88 88
89config RTC_DRV_DS1307
90 tristate "Dallas/Maxim DS1307 and similar I2C RTC chips"
91 depends on RTC_CLASS && I2C
92 help
93 If you say yes here you get support for various compatible RTC
94 chips (often with battery backup) connected with I2C. This driver
95 should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
96 and probably other chips. In some cases the RTC must already
97 have been initialized (by manufacturing or a bootloader).
98
99 The first seven registers on these chips hold an RTC, and other
100 registers may add features such as NVRAM, a trickle charger for
101 the RTC/NVRAM backup power, and alarms. This driver may not
102 expose all those available chip features.
103
104 This driver can also be built as a module. If so, the module
105 will be called rtc-ds1307.
106
89config RTC_DRV_DS1672 107config RTC_DRV_DS1672
90 tristate "Dallas/Maxim DS1672" 108 tristate "Dallas/Maxim DS1672"
91 depends on RTC_CLASS && I2C 109 depends on RTC_CLASS && I2C
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 1b3f32ecec80..ca8bed53079f 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
13 13
14obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o 14obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
15obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o 15obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
16obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
16obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o 17obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
17obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o 18obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
18obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o 19obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
new file mode 100644
index 000000000000..e8afb9384786
--- /dev/null
+++ b/drivers/rtc/rtc-ds1307.c
@@ -0,0 +1,388 @@
1/*
2 * rtc-ds1307.c - RTC driver for some mostly-compatible I2C chips.
3 *
4 * Copyright (C) 2005 James Chapman (ds1337 core)
5 * Copyright (C) 2006 David Brownell
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/slab.h>
15#include <linux/i2c.h>
16#include <linux/string.h>
17#include <linux/rtc.h>
18#include <linux/bcd.h>
19
20
21
22/* We can't determine type by probing, but if we expect pre-Linux code
23 * to have set the chip up as a clock (turning on the oscillator and
24 * setting the date and time), Linux can ignore the non-clock features.
25 * That's a natural job for a factory or repair bench.
26 *
27 * If the I2C "force" mechanism is used, we assume the chip is a ds1337.
28 * (Much better would be board-specific tables of I2C devices, along with
29 * the platform_data drivers would use to sort such issues out.)
30 */
31enum ds_type {
32 unknown = 0,
33 ds_1307, /* or ds1338, ... */
34 ds_1337, /* or ds1339, ... */
35 ds_1340, /* or st m41t00, ... */
36 // rs5c372 too? different address...
37};
38
39static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END };
40
41I2C_CLIENT_INSMOD;
42
43
44
45/* RTC registers don't differ much, except for the century flag */
46#define DS1307_REG_SECS 0x00 /* 00-59 */
47# define DS1307_BIT_CH 0x80
48#define DS1307_REG_MIN 0x01 /* 00-59 */
49#define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */
50# define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */
51# define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */
52#define DS1307_REG_WDAY 0x03 /* 01-07 */
53#define DS1307_REG_MDAY 0x04 /* 01-31 */
54#define DS1307_REG_MONTH 0x05 /* 01-12 */
55# define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */
56#define DS1307_REG_YEAR 0x06 /* 00-99 */
57
58/* Other registers (control, status, alarms, trickle charge, NVRAM, etc)
59 * start at 7, and they differ a lot. Only control and status matter for RTC;
60 * be careful using them.
61 */
62#define DS1307_REG_CONTROL 0x07
63# define DS1307_BIT_OUT 0x80
64# define DS1307_BIT_SQWE 0x10
65# define DS1307_BIT_RS1 0x02
66# define DS1307_BIT_RS0 0x01
67#define DS1337_REG_CONTROL 0x0e
68# define DS1337_BIT_nEOSC 0x80
69# define DS1337_BIT_RS2 0x10
70# define DS1337_BIT_RS1 0x08
71# define DS1337_BIT_INTCN 0x04
72# define DS1337_BIT_A2IE 0x02
73# define DS1337_BIT_A1IE 0x01
74#define DS1337_REG_STATUS 0x0f
75# define DS1337_BIT_OSF 0x80
76# define DS1337_BIT_A2I 0x02
77# define DS1337_BIT_A1I 0x01
78#define DS1339_REG_TRICKLE 0x10
79
80
81
82struct ds1307 {
83 u8 reg_addr;
84 u8 regs[8];
85 enum ds_type type;
86 struct i2c_msg msg[2];
87 struct i2c_client client;
88 struct rtc_device *rtc;
89};
90
91
92static int ds1307_get_time(struct device *dev, struct rtc_time *t)
93{
94 struct ds1307 *ds1307 = dev_get_drvdata(dev);
95 int tmp;
96
97 /* read the RTC registers all at once */
98 ds1307->msg[1].flags = I2C_M_RD;
99 ds1307->msg[1].len = 7;
100
101 tmp = i2c_transfer(ds1307->client.adapter, ds1307->msg, 2);
102 if (tmp != 2) {
103 dev_err(dev, "%s error %d\n", "read", tmp);
104 return -EIO;
105 }
106
107 dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n",
108 "read",
109 ds1307->regs[0], ds1307->regs[1],
110 ds1307->regs[2], ds1307->regs[3],
111 ds1307->regs[4], ds1307->regs[5],
112 ds1307->regs[6]);
113
114 t->tm_sec = BCD2BIN(ds1307->regs[DS1307_REG_SECS] & 0x7f);
115 t->tm_min = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f);
116 tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f;
117 t->tm_hour = BCD2BIN(tmp);
118 t->tm_wday = BCD2BIN(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1;
119 t->tm_mday = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
120 tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
121 t->tm_mon = BCD2BIN(tmp) - 1;
122
123 /* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
124 t->tm_year = BCD2BIN(ds1307->regs[DS1307_REG_YEAR]) + 100;
125
126 dev_dbg(dev, "%s secs=%d, mins=%d, "
127 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
128 "read", t->tm_sec, t->tm_min,
129 t->tm_hour, t->tm_mday,
130 t->tm_mon, t->tm_year, t->tm_wday);
131
132 return 0;
133}
134
135static int ds1307_set_time(struct device *dev, struct rtc_time *t)
136{
137 struct ds1307 *ds1307 = dev_get_drvdata(dev);
138 int result;
139 int tmp;
140 u8 *buf = ds1307->regs;
141
142 dev_dbg(dev, "%s secs=%d, mins=%d, "
143 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
144 "write", dt->tm_sec, dt->tm_min,
145 dt->tm_hour, dt->tm_mday,
146 dt->tm_mon, dt->tm_year, dt->tm_wday);
147
148 *buf++ = 0; /* first register addr */
149 buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec);
150 buf[DS1307_REG_MIN] = BIN2BCD(t->tm_min);
151 buf[DS1307_REG_HOUR] = BIN2BCD(t->tm_hour);
152 buf[DS1307_REG_WDAY] = BIN2BCD(t->tm_wday + 1);
153 buf[DS1307_REG_MDAY] = BIN2BCD(t->tm_mday);
154 buf[DS1307_REG_MONTH] = BIN2BCD(t->tm_mon + 1);
155
156 /* assume 20YY not 19YY */
157 tmp = t->tm_year - 100;
158 buf[DS1307_REG_YEAR] = BIN2BCD(tmp);
159
160 if (ds1307->type == ds_1337)
161 buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
162 else if (ds1307->type == ds_1340)
163 buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
164 | DS1340_BIT_CENTURY;
165
166 ds1307->msg[1].flags = 0;
167 ds1307->msg[1].len = 8;
168
169 dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n",
170 "write", buf[0], buf[1], buf[2], buf[3],
171 buf[4], buf[5], buf[6]);
172
173 result = i2c_transfer(ds1307->client.adapter, &ds1307->msg[1], 1);
174 if (result != 1) {
175 dev_err(dev, "%s error %d\n", "write", tmp);
176 return -EIO;
177 }
178 return 0;
179}
180
181static struct rtc_class_ops ds13xx_rtc_ops = {
182 .read_time = ds1307_get_time,
183 .set_time = ds1307_set_time,
184};
185
186static struct i2c_driver ds1307_driver;
187
188static int __devinit
189ds1307_detect(struct i2c_adapter *adapter, int address, int kind)
190{
191 struct ds1307 *ds1307;
192 int err = -ENODEV;
193 struct i2c_client *client;
194 int tmp;
195
196 if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) {
197 err = -ENOMEM;
198 goto exit;
199 }
200
201 client = &ds1307->client;
202 client->addr = address;
203 client->adapter = adapter;
204 client->driver = &ds1307_driver;
205 client->flags = 0;
206
207 i2c_set_clientdata(client, ds1307);
208
209 ds1307->msg[0].addr = client->addr;
210 ds1307->msg[0].flags = 0;
211 ds1307->msg[0].len = 1;
212 ds1307->msg[0].buf = &ds1307->reg_addr;
213
214 ds1307->msg[1].addr = client->addr;
215 ds1307->msg[1].flags = I2C_M_RD;
216 ds1307->msg[1].len = sizeof(ds1307->regs);
217 ds1307->msg[1].buf = ds1307->regs;
218
219 /* HACK: "force" implies "needs ds1337-style-oscillator setup" */
220 if (kind >= 0) {
221 ds1307->type = ds_1337;
222
223 ds1307->reg_addr = DS1337_REG_CONTROL;
224 ds1307->msg[1].len = 2;
225
226 tmp = i2c_transfer(client->adapter, ds1307->msg, 2);
227 if (tmp != 2) {
228 pr_debug("read error %d\n", tmp);
229 err = -EIO;
230 goto exit_free;
231 }
232
233 ds1307->reg_addr = 0;
234 ds1307->msg[1].len = sizeof(ds1307->regs);
235
236 /* oscillator is off; need to turn it on */
237 if ((ds1307->regs[0] & DS1337_BIT_nEOSC)
238 || (ds1307->regs[1] & DS1337_BIT_OSF)) {
239 printk(KERN_ERR "no ds1337 oscillator code\n");
240 goto exit_free;
241 }
242 } else
243 ds1307->type = ds_1307;
244
245read_rtc:
246 /* read RTC registers */
247
248 tmp = i2c_transfer(client->adapter, ds1307->msg, 2);
249 if (tmp != 2) {
250 pr_debug("read error %d\n", tmp);
251 err = -EIO;
252 goto exit_free;
253 }
254
255 /* minimal sanity checking; some chips (like DS1340) don't
256 * specify the extra bits as must-be-zero, but there are
257 * still a few values that are clearly out-of-range.
258 */
259 tmp = ds1307->regs[DS1307_REG_SECS];
260 if (tmp & DS1307_BIT_CH) {
261 if (ds1307->type && ds1307->type != ds_1307) {
262 pr_debug("not a ds1307?\n");
263 goto exit_free;
264 }
265 ds1307->type = ds_1307;
266
267 /* this partial initialization should work for ds1307,
268 * ds1338, ds1340, st m41t00, and more.
269 */
270 dev_warn(&client->dev, "oscillator started; SET TIME!\n");
271 i2c_smbus_write_byte_data(client, 0, 0);
272 goto read_rtc;
273 }
274 tmp = BCD2BIN(tmp & 0x7f);
275 if (tmp > 60)
276 goto exit_free;
277 tmp = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f);
278 if (tmp > 60)
279 goto exit_free;
280
281 tmp = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
282 if (tmp == 0 || tmp > 31)
283 goto exit_free;
284
285 tmp = BCD2BIN(ds1307->regs[DS1307_REG_MONTH] & 0x1f);
286 if (tmp == 0 || tmp > 12)
287 goto exit_free;
288
289 /* force into in 24 hour mode (most chips) or
290 * disable century bit (ds1340)
291 */
292 tmp = ds1307->regs[DS1307_REG_HOUR];
293 if (tmp & (1 << 6)) {
294 if (tmp & (1 << 5))
295 tmp = BCD2BIN(tmp & 0x1f) + 12;
296 else
297 tmp = BCD2BIN(tmp);
298 i2c_smbus_write_byte_data(client,
299 DS1307_REG_HOUR,
300 BIN2BCD(tmp));
301 }
302
303 /* FIXME chips like 1337 can generate alarm irqs too; those are
304 * worth exposing through the API (especially when the irq is
305 * wakeup-capable).
306 */
307
308 switch (ds1307->type) {
309 case unknown:
310 strlcpy(client->name, "unknown", I2C_NAME_SIZE);
311 break;
312 case ds_1307:
313 strlcpy(client->name, "ds1307", I2C_NAME_SIZE);
314 break;
315 case ds_1337:
316 strlcpy(client->name, "ds1337", I2C_NAME_SIZE);
317 break;
318 case ds_1340:
319 strlcpy(client->name, "ds1340", I2C_NAME_SIZE);
320 break;
321 }
322
323 /* Tell the I2C layer a new client has arrived */
324 if ((err = i2c_attach_client(client)))
325 goto exit_free;
326
327 ds1307->rtc = rtc_device_register(client->name, &client->dev,
328 &ds13xx_rtc_ops, THIS_MODULE);
329 if (IS_ERR(ds1307->rtc)) {
330 err = PTR_ERR(ds1307->rtc);
331 dev_err(&client->dev,
332 "unable to register the class device\n");
333 goto exit_detach;
334 }
335
336 return 0;
337
338exit_detach:
339 i2c_detach_client(client);
340exit_free:
341 kfree(ds1307);
342exit:
343 return err;
344}
345
346static int __devinit
347ds1307_attach_adapter(struct i2c_adapter *adapter)
348{
349 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
350 return 0;
351 return i2c_probe(adapter, &addr_data, ds1307_detect);
352}
353
354static int __devexit ds1307_detach_client(struct i2c_client *client)
355{
356 int err;
357 struct ds1307 *ds1307 = i2c_get_clientdata(client);
358
359 rtc_device_unregister(ds1307->rtc);
360 if ((err = i2c_detach_client(client)))
361 return err;
362 kfree(ds1307);
363 return 0;
364}
365
366static struct i2c_driver ds1307_driver = {
367 .driver = {
368 .name = "ds1307",
369 .owner = THIS_MODULE,
370 },
371 .attach_adapter = ds1307_attach_adapter,
372 .detach_client = __devexit_p(ds1307_detach_client),
373};
374
375static int __init ds1307_init(void)
376{
377 return i2c_add_driver(&ds1307_driver);
378}
379module_init(ds1307_init);
380
381static void __exit ds1307_exit(void)
382{
383 i2c_del_driver(&ds1307_driver);
384}
385module_exit(ds1307_exit);
386
387MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips");
388MODULE_LICENSE("GPL");