diff options
author | Igor Mammedov <niallain@gmail.com> | 2008-04-28 19:08:21 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-04-28 19:08:21 -0400 |
commit | e9f20d6f03e8df393b001dab6dc5226c2a5daf57 (patch) | |
tree | 73e94fa5e4f83576c97e36187b809c5aad2ade30 /drivers/rtc/rtc-x1205.c | |
parent | bf62fd887cab230f5952b611bde25e8e15acb454 (diff) | |
parent | e31a94ed371c70855eb30b77c490d6d85dd4da26 (diff) |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/rtc/rtc-x1205.c')
-rw-r--r-- | drivers/rtc/rtc-x1205.c | 170 |
1 files changed, 63 insertions, 107 deletions
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index b90fb1866ce9..095282f63523 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -22,20 +22,7 @@ | |||
22 | #include <linux/rtc.h> | 22 | #include <linux/rtc.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | 24 | ||
25 | #define DRV_VERSION "1.0.7" | 25 | #define DRV_VERSION "1.0.8" |
26 | |||
27 | /* Addresses to scan: none. This chip is located at | ||
28 | * 0x6f and uses a two bytes register addressing. | ||
29 | * Two bytes need to be written to read a single register, | ||
30 | * while most other chips just require one and take the second | ||
31 | * one as the data to be written. To prevent corrupting | ||
32 | * unknown chips, the user must explicitly set the probe parameter. | ||
33 | */ | ||
34 | |||
35 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
36 | |||
37 | /* Insmod parameters */ | ||
38 | I2C_CLIENT_INSMOD; | ||
39 | 26 | ||
40 | /* offsets into CCR area */ | 27 | /* offsets into CCR area */ |
41 | 28 | ||
@@ -91,19 +78,7 @@ I2C_CLIENT_INSMOD; | |||
91 | 78 | ||
92 | #define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */ | 79 | #define X1205_HR_MIL 0x80 /* Set in ccr.hour for 24 hr mode */ |
93 | 80 | ||
94 | /* Prototypes */ | 81 | static struct i2c_driver x1205_driver; |
95 | static int x1205_attach(struct i2c_adapter *adapter); | ||
96 | static int x1205_detach(struct i2c_client *client); | ||
97 | static int x1205_probe(struct i2c_adapter *adapter, int address, int kind); | ||
98 | |||
99 | static struct i2c_driver x1205_driver = { | ||
100 | .driver = { | ||
101 | .name = "x1205", | ||
102 | }, | ||
103 | .id = I2C_DRIVERID_X1205, | ||
104 | .attach_adapter = &x1205_attach, | ||
105 | .detach_client = &x1205_detach, | ||
106 | }; | ||
107 | 82 | ||
108 | /* | 83 | /* |
109 | * In the routines that deal directly with the x1205 hardware, we use | 84 | * In the routines that deal directly with the x1205 hardware, we use |
@@ -124,14 +99,14 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
124 | 99 | ||
125 | /* read date registers */ | 100 | /* read date registers */ |
126 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 101 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
127 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 102 | dev_err(&client->dev, "%s: read error\n", __func__); |
128 | return -EIO; | 103 | return -EIO; |
129 | } | 104 | } |
130 | 105 | ||
131 | dev_dbg(&client->dev, | 106 | dev_dbg(&client->dev, |
132 | "%s: raw read data - sec=%02x, min=%02x, hr=%02x, " | 107 | "%s: raw read data - sec=%02x, min=%02x, hr=%02x, " |
133 | "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n", | 108 | "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n", |
134 | __FUNCTION__, | 109 | __func__, |
135 | buf[0], buf[1], buf[2], buf[3], | 110 | buf[0], buf[1], buf[2], buf[3], |
136 | buf[4], buf[5], buf[6], buf[7]); | 111 | buf[4], buf[5], buf[6], buf[7]); |
137 | 112 | ||
@@ -146,7 +121,7 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
146 | 121 | ||
147 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 122 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
148 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 123 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
149 | __FUNCTION__, | 124 | __func__, |
150 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 125 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
151 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 126 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
152 | 127 | ||
@@ -164,7 +139,7 @@ static int x1205_get_status(struct i2c_client *client, unsigned char *sr) | |||
164 | 139 | ||
165 | /* read status register */ | 140 | /* read status register */ |
166 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 141 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
167 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 142 | dev_err(&client->dev, "%s: read error\n", __func__); |
168 | return -EIO; | 143 | return -EIO; |
169 | } | 144 | } |
170 | 145 | ||
@@ -187,7 +162,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
187 | 162 | ||
188 | dev_dbg(&client->dev, | 163 | dev_dbg(&client->dev, |
189 | "%s: secs=%d, mins=%d, hours=%d\n", | 164 | "%s: secs=%d, mins=%d, hours=%d\n", |
190 | __FUNCTION__, | 165 | __func__, |
191 | tm->tm_sec, tm->tm_min, tm->tm_hour); | 166 | tm->tm_sec, tm->tm_min, tm->tm_hour); |
192 | 167 | ||
193 | buf[CCR_SEC] = BIN2BCD(tm->tm_sec); | 168 | buf[CCR_SEC] = BIN2BCD(tm->tm_sec); |
@@ -200,7 +175,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
200 | if (datetoo) { | 175 | if (datetoo) { |
201 | dev_dbg(&client->dev, | 176 | dev_dbg(&client->dev, |
202 | "%s: mday=%d, mon=%d, year=%d, wday=%d\n", | 177 | "%s: mday=%d, mon=%d, year=%d, wday=%d\n", |
203 | __FUNCTION__, | 178 | __func__, |
204 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 179 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
205 | 180 | ||
206 | buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); | 181 | buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); |
@@ -216,12 +191,12 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
216 | 191 | ||
217 | /* this sequence is required to unlock the chip */ | 192 | /* this sequence is required to unlock the chip */ |
218 | if ((xfer = i2c_master_send(client, wel, 3)) != 3) { | 193 | if ((xfer = i2c_master_send(client, wel, 3)) != 3) { |
219 | dev_err(&client->dev, "%s: wel - %d\n", __FUNCTION__, xfer); | 194 | dev_err(&client->dev, "%s: wel - %d\n", __func__, xfer); |
220 | return -EIO; | 195 | return -EIO; |
221 | } | 196 | } |
222 | 197 | ||
223 | if ((xfer = i2c_master_send(client, rwel, 3)) != 3) { | 198 | if ((xfer = i2c_master_send(client, rwel, 3)) != 3) { |
224 | dev_err(&client->dev, "%s: rwel - %d\n", __FUNCTION__, xfer); | 199 | dev_err(&client->dev, "%s: rwel - %d\n", __func__, xfer); |
225 | return -EIO; | 200 | return -EIO; |
226 | } | 201 | } |
227 | 202 | ||
@@ -233,7 +208,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
233 | if (xfer != 3) { | 208 | if (xfer != 3) { |
234 | dev_err(&client->dev, | 209 | dev_err(&client->dev, |
235 | "%s: xfer=%d addr=%02x, data=%02x\n", | 210 | "%s: xfer=%d addr=%02x, data=%02x\n", |
236 | __FUNCTION__, | 211 | __func__, |
237 | xfer, rdata[1], rdata[2]); | 212 | xfer, rdata[1], rdata[2]); |
238 | return -EIO; | 213 | return -EIO; |
239 | } | 214 | } |
@@ -241,7 +216,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
241 | 216 | ||
242 | /* disable further writes */ | 217 | /* disable further writes */ |
243 | if ((xfer = i2c_master_send(client, diswe, 3)) != 3) { | 218 | if ((xfer = i2c_master_send(client, diswe, 3)) != 3) { |
244 | dev_err(&client->dev, "%s: diswe - %d\n", __FUNCTION__, xfer); | 219 | dev_err(&client->dev, "%s: diswe - %d\n", __func__, xfer); |
245 | return -EIO; | 220 | return -EIO; |
246 | } | 221 | } |
247 | 222 | ||
@@ -274,11 +249,11 @@ static int x1205_get_dtrim(struct i2c_client *client, int *trim) | |||
274 | 249 | ||
275 | /* read dtr register */ | 250 | /* read dtr register */ |
276 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 251 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
277 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 252 | dev_err(&client->dev, "%s: read error\n", __func__); |
278 | return -EIO; | 253 | return -EIO; |
279 | } | 254 | } |
280 | 255 | ||
281 | dev_dbg(&client->dev, "%s: raw dtr=%x\n", __FUNCTION__, dtr); | 256 | dev_dbg(&client->dev, "%s: raw dtr=%x\n", __func__, dtr); |
282 | 257 | ||
283 | *trim = 0; | 258 | *trim = 0; |
284 | 259 | ||
@@ -306,11 +281,11 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) | |||
306 | 281 | ||
307 | /* read atr register */ | 282 | /* read atr register */ |
308 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { | 283 | if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { |
309 | dev_err(&client->dev, "%s: read error\n", __FUNCTION__); | 284 | dev_err(&client->dev, "%s: read error\n", __func__); |
310 | return -EIO; | 285 | return -EIO; |
311 | } | 286 | } |
312 | 287 | ||
313 | dev_dbg(&client->dev, "%s: raw atr=%x\n", __FUNCTION__, atr); | 288 | dev_dbg(&client->dev, "%s: raw atr=%x\n", __func__, atr); |
314 | 289 | ||
315 | /* atr is a two's complement value on 6 bits, | 290 | /* atr is a two's complement value on 6 bits, |
316 | * perform sign extension. The formula is | 291 | * perform sign extension. The formula is |
@@ -319,11 +294,11 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) | |||
319 | if (atr & 0x20) | 294 | if (atr & 0x20) |
320 | atr |= 0xC0; | 295 | atr |= 0xC0; |
321 | 296 | ||
322 | dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __FUNCTION__, atr, atr); | 297 | dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __func__, atr, atr); |
323 | 298 | ||
324 | *trim = (atr * 250) + 11000; | 299 | *trim = (atr * 250) + 11000; |
325 | 300 | ||
326 | dev_dbg(&client->dev, "%s: real=%d\n", __FUNCTION__, *trim); | 301 | dev_dbg(&client->dev, "%s: real=%d\n", __func__, *trim); |
327 | 302 | ||
328 | return 0; | 303 | return 0; |
329 | } | 304 | } |
@@ -377,7 +352,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
377 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { | 352 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { |
378 | dev_err(&client->dev, | 353 | dev_err(&client->dev, |
379 | "%s: could not read register %x\n", | 354 | "%s: could not read register %x\n", |
380 | __FUNCTION__, probe_zero_pattern[i]); | 355 | __func__, probe_zero_pattern[i]); |
381 | 356 | ||
382 | return -EIO; | 357 | return -EIO; |
383 | } | 358 | } |
@@ -385,7 +360,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
385 | if ((buf & probe_zero_pattern[i+1]) != 0) { | 360 | if ((buf & probe_zero_pattern[i+1]) != 0) { |
386 | dev_err(&client->dev, | 361 | dev_err(&client->dev, |
387 | "%s: register=%02x, zero pattern=%d, value=%x\n", | 362 | "%s: register=%02x, zero pattern=%d, value=%x\n", |
388 | __FUNCTION__, probe_zero_pattern[i], i, buf); | 363 | __func__, probe_zero_pattern[i], i, buf); |
389 | 364 | ||
390 | return -ENODEV; | 365 | return -ENODEV; |
391 | } | 366 | } |
@@ -405,7 +380,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
405 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { | 380 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { |
406 | dev_err(&client->dev, | 381 | dev_err(&client->dev, |
407 | "%s: could not read register %x\n", | 382 | "%s: could not read register %x\n", |
408 | __FUNCTION__, probe_limits_pattern[i].reg); | 383 | __func__, probe_limits_pattern[i].reg); |
409 | 384 | ||
410 | return -EIO; | 385 | return -EIO; |
411 | } | 386 | } |
@@ -416,7 +391,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
416 | value < probe_limits_pattern[i].min) { | 391 | value < probe_limits_pattern[i].min) { |
417 | dev_dbg(&client->dev, | 392 | dev_dbg(&client->dev, |
418 | "%s: register=%x, lim pattern=%d, value=%d\n", | 393 | "%s: register=%x, lim pattern=%d, value=%d\n", |
419 | __FUNCTION__, probe_limits_pattern[i].reg, | 394 | __func__, probe_limits_pattern[i].reg, |
420 | i, value); | 395 | i, value); |
421 | 396 | ||
422 | return -ENODEV; | 397 | return -ENODEV; |
@@ -497,58 +472,49 @@ static ssize_t x1205_sysfs_show_dtrim(struct device *dev, | |||
497 | } | 472 | } |
498 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); | 473 | static DEVICE_ATTR(dtrim, S_IRUGO, x1205_sysfs_show_dtrim, NULL); |
499 | 474 | ||
500 | static int x1205_attach(struct i2c_adapter *adapter) | 475 | static int x1205_sysfs_register(struct device *dev) |
476 | { | ||
477 | int err; | ||
478 | |||
479 | err = device_create_file(dev, &dev_attr_atrim); | ||
480 | if (err) | ||
481 | return err; | ||
482 | |||
483 | err = device_create_file(dev, &dev_attr_dtrim); | ||
484 | if (err) | ||
485 | device_remove_file(dev, &dev_attr_atrim); | ||
486 | |||
487 | return err; | ||
488 | } | ||
489 | |||
490 | static void x1205_sysfs_unregister(struct device *dev) | ||
501 | { | 491 | { |
502 | return i2c_probe(adapter, &addr_data, x1205_probe); | 492 | device_remove_file(dev, &dev_attr_atrim); |
493 | device_remove_file(dev, &dev_attr_dtrim); | ||
503 | } | 494 | } |
504 | 495 | ||
505 | static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) | 496 | |
497 | static int x1205_probe(struct i2c_client *client) | ||
506 | { | 498 | { |
507 | int err = 0; | 499 | int err = 0; |
508 | unsigned char sr; | 500 | unsigned char sr; |
509 | struct i2c_client *client; | ||
510 | struct rtc_device *rtc; | 501 | struct rtc_device *rtc; |
511 | 502 | ||
512 | dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); | 503 | dev_dbg(&client->dev, "%s\n", __func__); |
513 | |||
514 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { | ||
515 | err = -ENODEV; | ||
516 | goto exit; | ||
517 | } | ||
518 | |||
519 | if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { | ||
520 | err = -ENOMEM; | ||
521 | goto exit; | ||
522 | } | ||
523 | |||
524 | /* I2C client */ | ||
525 | client->addr = address; | ||
526 | client->driver = &x1205_driver; | ||
527 | client->adapter = adapter; | ||
528 | 504 | ||
529 | strlcpy(client->name, x1205_driver.driver.name, I2C_NAME_SIZE); | 505 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
530 | 506 | return -ENODEV; | |
531 | /* Verify the chip is really an X1205 */ | ||
532 | if (kind < 0) { | ||
533 | if (x1205_validate_client(client) < 0) { | ||
534 | err = -ENODEV; | ||
535 | goto exit_kfree; | ||
536 | } | ||
537 | } | ||
538 | 507 | ||
539 | /* Inform the i2c layer */ | 508 | if (x1205_validate_client(client) < 0) |
540 | if ((err = i2c_attach_client(client))) | 509 | return -ENODEV; |
541 | goto exit_kfree; | ||
542 | 510 | ||
543 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); | 511 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); |
544 | 512 | ||
545 | rtc = rtc_device_register(x1205_driver.driver.name, &client->dev, | 513 | rtc = rtc_device_register(x1205_driver.driver.name, &client->dev, |
546 | &x1205_rtc_ops, THIS_MODULE); | 514 | &x1205_rtc_ops, THIS_MODULE); |
547 | 515 | ||
548 | if (IS_ERR(rtc)) { | 516 | if (IS_ERR(rtc)) |
549 | err = PTR_ERR(rtc); | 517 | return PTR_ERR(rtc); |
550 | goto exit_detach; | ||
551 | } | ||
552 | 518 | ||
553 | i2c_set_clientdata(client, rtc); | 519 | i2c_set_clientdata(client, rtc); |
554 | 520 | ||
@@ -565,45 +531,35 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind) | |||
565 | else | 531 | else |
566 | dev_err(&client->dev, "couldn't read status\n"); | 532 | dev_err(&client->dev, "couldn't read status\n"); |
567 | 533 | ||
568 | err = device_create_file(&client->dev, &dev_attr_atrim); | 534 | err = x1205_sysfs_register(&client->dev); |
569 | if (err) goto exit_devreg; | 535 | if (err) |
570 | err = device_create_file(&client->dev, &dev_attr_dtrim); | 536 | goto exit_devreg; |
571 | if (err) goto exit_atrim; | ||
572 | 537 | ||
573 | return 0; | 538 | return 0; |
574 | 539 | ||
575 | exit_atrim: | ||
576 | device_remove_file(&client->dev, &dev_attr_atrim); | ||
577 | |||
578 | exit_devreg: | 540 | exit_devreg: |
579 | rtc_device_unregister(rtc); | 541 | rtc_device_unregister(rtc); |
580 | 542 | ||
581 | exit_detach: | ||
582 | i2c_detach_client(client); | ||
583 | |||
584 | exit_kfree: | ||
585 | kfree(client); | ||
586 | |||
587 | exit: | ||
588 | return err; | 543 | return err; |
589 | } | 544 | } |
590 | 545 | ||
591 | static int x1205_detach(struct i2c_client *client) | 546 | static int x1205_remove(struct i2c_client *client) |
592 | { | 547 | { |
593 | int err; | ||
594 | struct rtc_device *rtc = i2c_get_clientdata(client); | 548 | struct rtc_device *rtc = i2c_get_clientdata(client); |
595 | 549 | ||
596 | if (rtc) | 550 | rtc_device_unregister(rtc); |
597 | rtc_device_unregister(rtc); | 551 | x1205_sysfs_unregister(&client->dev); |
598 | |||
599 | if ((err = i2c_detach_client(client))) | ||
600 | return err; | ||
601 | |||
602 | kfree(client); | ||
603 | |||
604 | return 0; | 552 | return 0; |
605 | } | 553 | } |
606 | 554 | ||
555 | static struct i2c_driver x1205_driver = { | ||
556 | .driver = { | ||
557 | .name = "rtc-x1205", | ||
558 | }, | ||
559 | .probe = x1205_probe, | ||
560 | .remove = x1205_remove, | ||
561 | }; | ||
562 | |||
607 | static int __init x1205_init(void) | 563 | static int __init x1205_init(void) |
608 | { | 564 | { |
609 | return i2c_add_driver(&x1205_driver); | 565 | return i2c_add_driver(&x1205_driver); |