diff options
Diffstat (limited to 'drivers/rtc/rtc-pcf8583.c')
| -rw-r--r-- | drivers/rtc/rtc-pcf8583.c | 129 |
1 files changed, 39 insertions, 90 deletions
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 3d09d8f0b1f0..d388c662bf4b 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * drivers/rtc/rtc-pcf8583.c | 2 | * drivers/rtc/rtc-pcf8583.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2000 Russell King | 4 | * Copyright (C) 2000 Russell King |
| 5 | * Copyright (C) 2008 Wolfram Sang & Juergen Beisert, Pengutronix | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -14,7 +15,6 @@ | |||
| 14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 15 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
| 16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 17 | #include <linux/string.h> | ||
| 18 | #include <linux/rtc.h> | 18 | #include <linux/rtc.h> |
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
| @@ -27,7 +27,6 @@ struct rtc_mem { | |||
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | struct pcf8583 { | 29 | struct pcf8583 { |
| 30 | struct i2c_client client; | ||
| 31 | struct rtc_device *rtc; | 30 | struct rtc_device *rtc; |
| 32 | unsigned char ctrl; | 31 | unsigned char ctrl; |
| 33 | }; | 32 | }; |
| @@ -40,10 +39,6 @@ struct pcf8583 { | |||
| 40 | #define CTRL_ALARM 0x02 | 39 | #define CTRL_ALARM 0x02 |
| 41 | #define CTRL_TIMER 0x01 | 40 | #define CTRL_TIMER 0x01 |
| 42 | 41 | ||
| 43 | static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; | ||
| 44 | |||
| 45 | /* Module parameters */ | ||
| 46 | I2C_CLIENT_INSMOD; | ||
| 47 | 42 | ||
| 48 | static struct i2c_driver pcf8583_driver; | 43 | static struct i2c_driver pcf8583_driver; |
| 49 | 44 | ||
| @@ -269,106 +264,60 @@ static const struct rtc_class_ops pcf8583_rtc_ops = { | |||
| 269 | .set_time = pcf8583_rtc_set_time, | 264 | .set_time = pcf8583_rtc_set_time, |
| 270 | }; | 265 | }; |
| 271 | 266 | ||
| 272 | static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind); | 267 | static int pcf8583_probe(struct i2c_client *client, |
| 273 | 268 | const struct i2c_device_id *id) | |
| 274 | static int pcf8583_attach(struct i2c_adapter *adap) | ||
| 275 | { | ||
| 276 | return i2c_probe(adap, &addr_data, pcf8583_probe); | ||
| 277 | } | ||
| 278 | |||
| 279 | static int pcf8583_detach(struct i2c_client *client) | ||
| 280 | { | ||
| 281 | int err; | ||
| 282 | struct pcf8583 *pcf = i2c_get_clientdata(client); | ||
| 283 | struct rtc_device *rtc = pcf->rtc; | ||
| 284 | |||
| 285 | if (rtc) | ||
| 286 | rtc_device_unregister(rtc); | ||
| 287 | |||
| 288 | if ((err = i2c_detach_client(client))) | ||
| 289 | return err; | ||
| 290 | |||
| 291 | kfree(pcf); | ||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 295 | static struct i2c_driver pcf8583_driver = { | ||
| 296 | .driver = { | ||
| 297 | .name = "pcf8583", | ||
| 298 | }, | ||
| 299 | .id = I2C_DRIVERID_PCF8583, | ||
| 300 | .attach_adapter = pcf8583_attach, | ||
| 301 | .detach_client = pcf8583_detach, | ||
| 302 | }; | ||
| 303 | |||
| 304 | static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind) | ||
| 305 | { | 269 | { |
| 306 | struct pcf8583 *pcf; | 270 | struct pcf8583 *pcf8583; |
| 307 | struct i2c_client *client; | ||
| 308 | struct rtc_device *rtc; | ||
| 309 | unsigned char buf[1], ad[1] = { 0 }; | ||
| 310 | int err; | 271 | int err; |
| 311 | struct i2c_msg msgs[2] = { | ||
| 312 | { | ||
| 313 | .addr = addr, | ||
| 314 | .flags = 0, | ||
| 315 | .len = 1, | ||
| 316 | .buf = ad, | ||
| 317 | }, { | ||
| 318 | .addr = addr, | ||
| 319 | .flags = I2C_M_RD, | ||
| 320 | .len = 1, | ||
| 321 | .buf = buf, | ||
| 322 | } | ||
| 323 | }; | ||
| 324 | 272 | ||
| 325 | if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) | 273 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
| 326 | return 0; | 274 | return -ENODEV; |
| 327 | 275 | ||
| 328 | pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); | 276 | pcf8583 = kzalloc(sizeof(struct pcf8583), GFP_KERNEL); |
| 329 | if (!pcf) | 277 | if (!pcf8583) |
| 330 | return -ENOMEM; | 278 | return -ENOMEM; |
| 331 | 279 | ||
| 332 | client = &pcf->client; | 280 | pcf8583->rtc = rtc_device_register(pcf8583_driver.driver.name, |
| 281 | &client->dev, &pcf8583_rtc_ops, THIS_MODULE); | ||
| 333 | 282 | ||
| 334 | client->addr = addr; | 283 | if (IS_ERR(pcf8583->rtc)) { |
| 335 | client->adapter = adap; | 284 | err = PTR_ERR(pcf8583->rtc); |
| 336 | client->driver = &pcf8583_driver; | ||
| 337 | |||
| 338 | strlcpy(client->name, pcf8583_driver.driver.name, I2C_NAME_SIZE); | ||
| 339 | |||
| 340 | if (i2c_transfer(client->adapter, msgs, 2) != 2) { | ||
| 341 | err = -EIO; | ||
| 342 | goto exit_kfree; | 285 | goto exit_kfree; |
| 343 | } | 286 | } |
| 344 | 287 | ||
| 345 | err = i2c_attach_client(client); | 288 | i2c_set_clientdata(client, pcf8583); |
| 346 | 289 | return 0; | |
| 347 | if (err) | ||
| 348 | goto exit_kfree; | ||
| 349 | |||
| 350 | rtc = rtc_device_register(pcf8583_driver.driver.name, &client->dev, | ||
| 351 | &pcf8583_rtc_ops, THIS_MODULE); | ||
| 352 | 290 | ||
| 353 | if (IS_ERR(rtc)) { | 291 | exit_kfree: |
| 354 | err = PTR_ERR(rtc); | 292 | kfree(pcf8583); |
| 355 | goto exit_detach; | 293 | return err; |
| 356 | } | 294 | } |
| 357 | 295 | ||
| 358 | pcf->rtc = rtc; | 296 | static int __devexit pcf8583_remove(struct i2c_client *client) |
| 359 | i2c_set_clientdata(client, pcf); | 297 | { |
| 360 | set_ctrl(client, buf[0]); | 298 | struct pcf8583 *pcf8583 = i2c_get_clientdata(client); |
| 361 | 299 | ||
| 300 | if (pcf8583->rtc) | ||
| 301 | rtc_device_unregister(pcf8583->rtc); | ||
| 302 | kfree(pcf8583); | ||
| 362 | return 0; | 303 | return 0; |
| 304 | } | ||
| 363 | 305 | ||
| 364 | exit_detach: | 306 | static const struct i2c_device_id pcf8583_id[] = { |
| 365 | i2c_detach_client(client); | 307 | { "pcf8583", 0 }, |
| 366 | 308 | { } | |
| 367 | exit_kfree: | 309 | }; |
| 368 | kfree(pcf); | 310 | MODULE_DEVICE_TABLE(i2c, pcf8583_id); |
| 369 | 311 | ||
| 370 | return err; | 312 | static struct i2c_driver pcf8583_driver = { |
| 371 | } | 313 | .driver = { |
| 314 | .name = "pcf8583", | ||
| 315 | .owner = THIS_MODULE, | ||
| 316 | }, | ||
| 317 | .probe = pcf8583_probe, | ||
| 318 | .remove = __devexit_p(pcf8583_remove), | ||
| 319 | .id_table = pcf8583_id, | ||
| 320 | }; | ||
| 372 | 321 | ||
| 373 | static __init int pcf8583_init(void) | 322 | static __init int pcf8583_init(void) |
| 374 | { | 323 | { |
