aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2007-07-17 07:04:55 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:08 -0400
commit045e0e85f2f6ee6621d8f7bab3059e9c74076738 (patch)
tree6656256d46b5a3d06b2426e128cf21a0cb143653 /drivers/rtc
parent5d91192e667ae34733b9daf6dd5f1d4496d2f441 (diff)
rtc-ds1307 cleanups
This updates the rtc-ds1307 driver so that converting it to a "new style" driver (driver model, not legacy i2c model) will involve fewer changes. - Use pointer to i2c_client almost everywhere, so that it's easy to let the i2c core create that object; - Avoid using i2c_client.adapter, since that field is redundant and thus may go away (same object as i2c_client.dev.parent). - Extend type enum to include various RTCs this is expected to work with, and include register support for them. It also cleans up the support for multiple chip types, and fixes a glitch that could appear with an un-initialized RTC. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-ds1307.c176
1 files changed, 124 insertions, 52 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 3f0f7b8fa813..75e30c6a7d5d 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -24,15 +24,22 @@
24 * setting the date and time), Linux can ignore the non-clock features. 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. 25 * That's a natural job for a factory or repair bench.
26 * 26 *
27 * This is currently a simple no-alarms driver. If your board has the
28 * alarm irq wired up on a ds1337 or ds1339, and you want to use that,
29 * then look at the rtc-rs5c372 driver for code to steal...
30 *
27 * If the I2C "force" mechanism is used, we assume the chip is a ds1337. 31 * 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 32 * (Much better would be board-specific tables of I2C devices, along with
29 * the platform_data drivers would use to sort such issues out.) 33 * the platform_data drivers would use to sort such issues out.)
30 */ 34 */
31enum ds_type { 35enum ds_type {
32 unknown = 0, 36 unknown = 0,
33 ds_1307, /* or ds1338, ... */ 37 ds_1307,
34 ds_1337, /* or ds1339, ... */ 38 ds_1337,
35 ds_1340, /* or st m41t00, ... */ 39 ds_1338,
40 ds_1339,
41 ds_1340,
42 m41t00,
36 // rs5c372 too? different address... 43 // rs5c372 too? different address...
37}; 44};
38 45
@@ -56,11 +63,12 @@ I2C_CLIENT_INSMOD;
56#define DS1307_REG_YEAR 0x06 /* 00-99 */ 63#define DS1307_REG_YEAR 0x06 /* 00-99 */
57 64
58/* Other registers (control, status, alarms, trickle charge, NVRAM, etc) 65/* 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; 66 * start at 7, and they differ a LOT. Only control and status matter for
60 * be careful using them. 67 * basic RTC date and time functionality; be careful using them.
61 */ 68 */
62#define DS1307_REG_CONTROL 0x07 69#define DS1307_REG_CONTROL 0x07 /* or ds1338 */
63# define DS1307_BIT_OUT 0x80 70# define DS1307_BIT_OUT 0x80
71# define DS1338_BIT_STOP 0x20
64# define DS1307_BIT_SQWE 0x10 72# define DS1307_BIT_SQWE 0x10
65# define DS1307_BIT_RS1 0x02 73# define DS1307_BIT_RS1 0x02
66# define DS1307_BIT_RS0 0x01 74# define DS1307_BIT_RS0 0x01
@@ -71,6 +79,13 @@ I2C_CLIENT_INSMOD;
71# define DS1337_BIT_INTCN 0x04 79# define DS1337_BIT_INTCN 0x04
72# define DS1337_BIT_A2IE 0x02 80# define DS1337_BIT_A2IE 0x02
73# define DS1337_BIT_A1IE 0x01 81# define DS1337_BIT_A1IE 0x01
82#define DS1340_REG_CONTROL 0x07
83# define DS1340_BIT_OUT 0x80
84# define DS1340_BIT_FT 0x40
85# define DS1340_BIT_CALIB_SIGN 0x20
86# define DS1340_M_CALIBRATION 0x1f
87#define DS1338_REG_FLAG 0x09
88# define DS1338_BIT_OSF 0x80
74#define DS1337_REG_STATUS 0x0f 89#define DS1337_REG_STATUS 0x0f
75# define DS1337_BIT_OSF 0x80 90# define DS1337_BIT_OSF 0x80
76# define DS1337_BIT_A2I 0x02 91# define DS1337_BIT_A2I 0x02
@@ -84,21 +99,63 @@ struct ds1307 {
84 u8 regs[8]; 99 u8 regs[8];
85 enum ds_type type; 100 enum ds_type type;
86 struct i2c_msg msg[2]; 101 struct i2c_msg msg[2];
87 struct i2c_client client; 102 struct i2c_client *client;
103 struct i2c_client dev;
88 struct rtc_device *rtc; 104 struct rtc_device *rtc;
89}; 105};
90 106
107struct chip_desc {
108 char name[9];
109 unsigned nvram56:1;
110 unsigned alarm:1;
111 enum ds_type type;
112};
113
114static const struct chip_desc chips[] = { {
115 .name = "ds1307",
116 .type = ds_1307,
117 .nvram56 = 1,
118}, {
119 .name = "ds1337",
120 .type = ds_1337,
121 .alarm = 1,
122}, {
123 .name = "ds1338",
124 .type = ds_1338,
125 .nvram56 = 1,
126}, {
127 .name = "ds1339",
128 .type = ds_1339,
129 .alarm = 1,
130}, {
131 .name = "ds1340",
132 .type = ds_1340,
133}, {
134 .name = "m41t00",
135 .type = m41t00,
136}, };
137
138static inline const struct chip_desc *find_chip(const char *s)
139{
140 unsigned i;
141
142 for (i = 0; i < ARRAY_SIZE(chips); i++)
143 if (strnicmp(s, chips[i].name, sizeof chips[i].name) == 0)
144 return &chips[i];
145 return NULL;
146}
91 147
92static int ds1307_get_time(struct device *dev, struct rtc_time *t) 148static int ds1307_get_time(struct device *dev, struct rtc_time *t)
93{ 149{
94 struct ds1307 *ds1307 = dev_get_drvdata(dev); 150 struct ds1307 *ds1307 = dev_get_drvdata(dev);
95 int tmp; 151 int tmp;
96 152
97 /* read the RTC registers all at once */ 153 /* read the RTC date and time registers all at once */
98 ds1307->msg[1].flags = I2C_M_RD; 154 ds1307->msg[1].flags = I2C_M_RD;
99 ds1307->msg[1].len = 7; 155 ds1307->msg[1].len = 7;
100 156
101 tmp = i2c_transfer(ds1307->client.adapter, ds1307->msg, 2); 157 tmp = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent),
158 ds1307->msg, 2);
102 if (tmp != 2) { 159 if (tmp != 2) {
103 dev_err(dev, "%s error %d\n", "read", tmp); 160 dev_err(dev, "%s error %d\n", "read", tmp);
104 return -EIO; 161 return -EIO;
@@ -129,7 +186,8 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
129 t->tm_hour, t->tm_mday, 186 t->tm_hour, t->tm_mday,
130 t->tm_mon, t->tm_year, t->tm_wday); 187 t->tm_mon, t->tm_year, t->tm_wday);
131 188
132 return 0; 189 /* initial clock setting can be undefined */
190 return rtc_valid_tm(t);
133} 191}
134 192
135static int ds1307_set_time(struct device *dev, struct rtc_time *t) 193static int ds1307_set_time(struct device *dev, struct rtc_time *t)
@@ -170,7 +228,8 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
170 "write", buf[0], buf[1], buf[2], buf[3], 228 "write", buf[0], buf[1], buf[2], buf[3],
171 buf[4], buf[5], buf[6]); 229 buf[4], buf[5], buf[6]);
172 230
173 result = i2c_transfer(ds1307->client.adapter, &ds1307->msg[1], 1); 231 result = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent),
232 &ds1307->msg[1], 1);
174 if (result != 1) { 233 if (result != 1) {
175 dev_err(dev, "%s error %d\n", "write", tmp); 234 dev_err(dev, "%s error %d\n", "write", tmp);
176 return -EIO; 235 return -EIO;
@@ -192,18 +251,34 @@ ds1307_detect(struct i2c_adapter *adapter, int address, int kind)
192 int err = -ENODEV; 251 int err = -ENODEV;
193 struct i2c_client *client; 252 struct i2c_client *client;
194 int tmp; 253 int tmp;
254 const struct chip_desc *chip;
195 255
196 if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) { 256 if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) {
197 err = -ENOMEM; 257 err = -ENOMEM;
198 goto exit; 258 goto exit;
199 } 259 }
200 260
201 client = &ds1307->client; 261 /* REVISIT: pending driver model conversion, set up "client"
262 * ourselves, and use a hack to determine the RTC type (instead
263 * of reading the client->name we're given)
264 */
265 client = &ds1307->dev;
202 client->addr = address; 266 client->addr = address;
203 client->adapter = adapter; 267 client->adapter = adapter;
204 client->driver = &ds1307_driver; 268 client->driver = &ds1307_driver;
205 client->flags = 0;
206 269
270 /* HACK: "force" implies "needs ds1337-style-oscillator setup", and
271 * that's the only kind of chip setup we'll know about. Until the
272 * driver model conversion, here's where to add any board-specific
273 * code to say what kind of chip is present...
274 */
275 if (kind >= 0)
276 chip = find_chip("ds1337");
277 else
278 chip = find_chip("ds1307");
279 strlcpy(client->name, chip->name, I2C_NAME_SIZE);
280
281 ds1307->client = client;
207 i2c_set_clientdata(client, ds1307); 282 i2c_set_clientdata(client, ds1307);
208 283
209 ds1307->msg[0].addr = client->addr; 284 ds1307->msg[0].addr = client->addr;
@@ -216,14 +291,17 @@ ds1307_detect(struct i2c_adapter *adapter, int address, int kind)
216 ds1307->msg[1].len = sizeof(ds1307->regs); 291 ds1307->msg[1].len = sizeof(ds1307->regs);
217 ds1307->msg[1].buf = ds1307->regs; 292 ds1307->msg[1].buf = ds1307->regs;
218 293
219 /* HACK: "force" implies "needs ds1337-style-oscillator setup" */ 294 ds1307->type = chip->type;
220 if (kind >= 0) { 295
296 switch (ds1307->type) {
297 case ds_1337:
298 case ds_1339:
221 ds1307->type = ds_1337; 299 ds1307->type = ds_1337;
222 300
223 ds1307->reg_addr = DS1337_REG_CONTROL; 301 ds1307->reg_addr = DS1337_REG_CONTROL;
224 ds1307->msg[1].len = 2; 302 ds1307->msg[1].len = 2;
225 303
226 tmp = i2c_transfer(client->adapter, ds1307->msg, 2); 304 tmp = i2c_transfer(adapter, ds1307->msg, 2);
227 if (tmp != 2) { 305 if (tmp != 2) {
228 pr_debug("read error %d\n", tmp); 306 pr_debug("read error %d\n", tmp);
229 err = -EIO; 307 err = -EIO;
@@ -236,16 +314,20 @@ ds1307_detect(struct i2c_adapter *adapter, int address, int kind)
236 /* oscillator is off; need to turn it on */ 314 /* oscillator is off; need to turn it on */
237 if ((ds1307->regs[0] & DS1337_BIT_nEOSC) 315 if ((ds1307->regs[0] & DS1337_BIT_nEOSC)
238 || (ds1307->regs[1] & DS1337_BIT_OSF)) { 316 || (ds1307->regs[1] & DS1337_BIT_OSF)) {
239 printk(KERN_ERR "no ds1337 oscillator code\n"); 317no_osc_start:
318 printk(KERN_ERR "no %s oscillator code\n",
319 chip->name);
240 goto exit_free; 320 goto exit_free;
241 } 321 }
242 } else 322 break;
243 ds1307->type = ds_1307; 323 default:
324 break;
325 }
244 326
245read_rtc: 327read_rtc:
246 /* read RTC registers */ 328 /* read RTC registers */
247 329
248 tmp = i2c_transfer(client->adapter, ds1307->msg, 2); 330 tmp = i2c_transfer(adapter, ds1307->msg, 2);
249 if (tmp != 2) { 331 if (tmp != 2) {
250 pr_debug("read error %d\n", tmp); 332 pr_debug("read error %d\n", tmp);
251 err = -EIO; 333 err = -EIO;
@@ -257,20 +339,27 @@ read_rtc:
257 * still a few values that are clearly out-of-range. 339 * still a few values that are clearly out-of-range.
258 */ 340 */
259 tmp = ds1307->regs[DS1307_REG_SECS]; 341 tmp = ds1307->regs[DS1307_REG_SECS];
260 if (tmp & DS1307_BIT_CH) { 342 switch (ds1307->type) {
261 if (ds1307->type && ds1307->type != ds_1307) { 343 case ds_1307:
262 pr_debug("not a ds1307?\n"); 344 case ds_1338:
263 goto exit_free; 345 case m41t00:
346 if (tmp & DS1307_BIT_CH) {
347 i2c_smbus_write_byte_data(client, 0, 0);
348 dev_warn(&client->dev,
349 "oscillator started; SET TIME!\n");
350 goto read_rtc;
264 } 351 }
265 ds1307->type = ds_1307; 352 break;
266 353 case ds_1340:
267 /* this partial initialization should work for ds1307, 354 /* FIXME write code to start the oscillator */
268 * ds1338, ds1340, st m41t00, and more. 355 if (tmp & DS1307_BIT_CH)
269 */ 356 goto no_osc_start;
270 dev_warn(&client->dev, "oscillator started; SET TIME!\n"); 357 break;
271 i2c_smbus_write_byte_data(client, 0, 0); 358 default:
272 goto read_rtc; 359 break;
273 } 360 }
361
362 tmp = ds1307->regs[DS1307_REG_SECS];
274 tmp = BCD2BIN(tmp & 0x7f); 363 tmp = BCD2BIN(tmp & 0x7f);
275 if (tmp > 60) 364 if (tmp > 60)
276 goto exit_free; 365 goto exit_free;
@@ -288,6 +377,9 @@ read_rtc:
288 377
289 /* force into in 24 hour mode (most chips) or 378 /* force into in 24 hour mode (most chips) or
290 * disable century bit (ds1340) 379 * disable century bit (ds1340)
380 *
381 * REVISIT forcing 24 hour mode can prevent multi-master
382 * configs from sharing this RTC ... don't do this.
291 */ 383 */
292 tmp = ds1307->regs[DS1307_REG_HOUR]; 384 tmp = ds1307->regs[DS1307_REG_HOUR];
293 if (tmp & (1 << 6)) { 385 if (tmp & (1 << 6)) {
@@ -300,26 +392,6 @@ read_rtc:
300 BIN2BCD(tmp)); 392 BIN2BCD(tmp));
301 } 393 }
302 394
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 */ 395 /* Tell the I2C layer a new client has arrived */
324 if ((err = i2c_attach_client(client))) 396 if ((err = i2c_attach_client(client)))
325 goto exit_free; 397 goto exit_free;