diff options
| author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:14 -0400 |
|---|---|---|
| committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:14 -0400 |
| commit | b6aacdcefac8ed60e77930b6e74129da6478e20e (patch) | |
| tree | 128508b4bd43f77ec7ae91535ee3f13e4a7a6683 | |
| parent | 8c8bacc883610b672d3f08dc6ebf1f17e495f5b9 (diff) | |
hwmon: (lm83) Convert to a new-style i2c driver
The new-style lm83 driver implements the optional detect() callback
to cover the use cases of the legacy driver.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
| -rw-r--r-- | drivers/hwmon/lm83.c | 104 |
1 files changed, 49 insertions, 55 deletions
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 6a8642fa25fb..e59e2d1f080c 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * lm83.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | * lm83.c - Part of lm_sensors, Linux kernel modules for hardware |
| 3 | * monitoring | 3 | * monitoring |
| 4 | * Copyright (C) 2003-2006 Jean Delvare <khali@linux-fr.org> | 4 | * Copyright (C) 2003-2008 Jean Delvare <khali@linux-fr.org> |
| 5 | * | 5 | * |
| 6 | * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is | 6 | * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is |
| 7 | * a sensor chip made by National Semiconductor. It reports up to four | 7 | * a sensor chip made by National Semiconductor. It reports up to four |
| @@ -118,21 +118,34 @@ static const u8 LM83_REG_W_HIGH[] = { | |||
| 118 | * Functions declaration | 118 | * Functions declaration |
| 119 | */ | 119 | */ |
| 120 | 120 | ||
| 121 | static int lm83_attach_adapter(struct i2c_adapter *adapter); | 121 | static int lm83_detect(struct i2c_client *new_client, int kind, |
| 122 | static int lm83_detect(struct i2c_adapter *adapter, int address, int kind); | 122 | struct i2c_board_info *info); |
| 123 | static int lm83_detach_client(struct i2c_client *client); | 123 | static int lm83_probe(struct i2c_client *client, |
| 124 | const struct i2c_device_id *id); | ||
| 125 | static int lm83_remove(struct i2c_client *client); | ||
| 124 | static struct lm83_data *lm83_update_device(struct device *dev); | 126 | static struct lm83_data *lm83_update_device(struct device *dev); |
| 125 | 127 | ||
| 126 | /* | 128 | /* |
| 127 | * Driver data (common to all clients) | 129 | * Driver data (common to all clients) |
| 128 | */ | 130 | */ |
| 129 | 131 | ||
| 132 | static const struct i2c_device_id lm83_id[] = { | ||
| 133 | { "lm83", lm83 }, | ||
| 134 | { "lm82", lm82 }, | ||
| 135 | { } | ||
| 136 | }; | ||
| 137 | MODULE_DEVICE_TABLE(i2c, lm83_id); | ||
| 138 | |||
| 130 | static struct i2c_driver lm83_driver = { | 139 | static struct i2c_driver lm83_driver = { |
| 140 | .class = I2C_CLASS_HWMON, | ||
| 131 | .driver = { | 141 | .driver = { |
| 132 | .name = "lm83", | 142 | .name = "lm83", |
| 133 | }, | 143 | }, |
| 134 | .attach_adapter = lm83_attach_adapter, | 144 | .probe = lm83_probe, |
| 135 | .detach_client = lm83_detach_client, | 145 | .remove = lm83_remove, |
| 146 | .id_table = lm83_id, | ||
| 147 | .detect = lm83_detect, | ||
| 148 | .address_data = &addr_data, | ||
| 136 | }; | 149 | }; |
| 137 | 150 | ||
| 138 | /* | 151 | /* |
| @@ -140,7 +153,6 @@ static struct i2c_driver lm83_driver = { | |||
| 140 | */ | 153 | */ |
| 141 | 154 | ||
| 142 | struct lm83_data { | 155 | struct lm83_data { |
| 143 | struct i2c_client client; | ||
| 144 | struct device *hwmon_dev; | 156 | struct device *hwmon_dev; |
| 145 | struct mutex update_lock; | 157 | struct mutex update_lock; |
| 146 | char valid; /* zero until following fields are valid */ | 158 | char valid; /* zero until following fields are valid */ |
| @@ -278,40 +290,15 @@ static const struct attribute_group lm83_group_opt = { | |||
| 278 | * Real code | 290 | * Real code |
| 279 | */ | 291 | */ |
| 280 | 292 | ||
| 281 | static int lm83_attach_adapter(struct i2c_adapter *adapter) | 293 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
| 294 | static int lm83_detect(struct i2c_client *new_client, int kind, | ||
| 295 | struct i2c_board_info *info) | ||
| 282 | { | 296 | { |
| 283 | if (!(adapter->class & I2C_CLASS_HWMON)) | 297 | struct i2c_adapter *adapter = new_client->adapter; |
| 284 | return 0; | ||
| 285 | return i2c_probe(adapter, &addr_data, lm83_detect); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* | ||
| 289 | * The following function does more than just detection. If detection | ||
| 290 | * succeeds, it also registers the new chip. | ||
| 291 | */ | ||
| 292 | static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) | ||
| 293 | { | ||
| 294 | struct i2c_client *new_client; | ||
| 295 | struct lm83_data *data; | ||
| 296 | int err = 0; | ||
| 297 | const char *name = ""; | 298 | const char *name = ""; |
| 298 | 299 | ||
| 299 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 300 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
| 300 | goto exit; | 301 | return -ENODEV; |
| 301 | |||
| 302 | if (!(data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL))) { | ||
| 303 | err = -ENOMEM; | ||
| 304 | goto exit; | ||
| 305 | } | ||
| 306 | |||
| 307 | /* The common I2C client data is placed right after the | ||
| 308 | * LM83-specific data. */ | ||
| 309 | new_client = &data->client; | ||
| 310 | i2c_set_clientdata(new_client, data); | ||
| 311 | new_client->addr = address; | ||
| 312 | new_client->adapter = adapter; | ||
| 313 | new_client->driver = &lm83_driver; | ||
| 314 | new_client->flags = 0; | ||
| 315 | 302 | ||
| 316 | /* Now we do the detection and identification. A negative kind | 303 | /* Now we do the detection and identification. A negative kind |
| 317 | * means that the driver was loaded with no force parameter | 304 | * means that the driver was loaded with no force parameter |
| @@ -335,8 +322,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 335 | ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG) | 322 | ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG) |
| 336 | & 0x41) != 0x00)) { | 323 | & 0x41) != 0x00)) { |
| 337 | dev_dbg(&adapter->dev, | 324 | dev_dbg(&adapter->dev, |
| 338 | "LM83 detection failed at 0x%02x.\n", address); | 325 | "LM83 detection failed at 0x%02x.\n", |
| 339 | goto exit_free; | 326 | new_client->addr); |
| 327 | return -ENODEV; | ||
| 340 | } | 328 | } |
| 341 | } | 329 | } |
| 342 | 330 | ||
| @@ -361,7 +349,7 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 361 | dev_info(&adapter->dev, | 349 | dev_info(&adapter->dev, |
| 362 | "Unsupported chip (man_id=0x%02X, " | 350 | "Unsupported chip (man_id=0x%02X, " |
| 363 | "chip_id=0x%02X).\n", man_id, chip_id); | 351 | "chip_id=0x%02X).\n", man_id, chip_id); |
| 364 | goto exit_free; | 352 | return -ENODEV; |
| 365 | } | 353 | } |
| 366 | } | 354 | } |
| 367 | 355 | ||
| @@ -372,15 +360,27 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 372 | name = "lm82"; | 360 | name = "lm82"; |
| 373 | } | 361 | } |
| 374 | 362 | ||
| 375 | /* We can fill in the remaining client fields */ | 363 | strlcpy(info->type, name, I2C_NAME_SIZE); |
| 376 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | 364 | |
| 365 | return 0; | ||
| 366 | } | ||
| 367 | |||
| 368 | static int lm83_probe(struct i2c_client *new_client, | ||
| 369 | const struct i2c_device_id *id) | ||
| 370 | { | ||
| 371 | struct lm83_data *data; | ||
| 372 | int err; | ||
| 373 | |||
| 374 | data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL); | ||
| 375 | if (!data) { | ||
| 376 | err = -ENOMEM; | ||
| 377 | goto exit; | ||
| 378 | } | ||
| 379 | |||
| 380 | i2c_set_clientdata(new_client, data); | ||
| 377 | data->valid = 0; | 381 | data->valid = 0; |
| 378 | mutex_init(&data->update_lock); | 382 | mutex_init(&data->update_lock); |
| 379 | 383 | ||
| 380 | /* Tell the I2C layer a new client has arrived */ | ||
| 381 | if ((err = i2c_attach_client(new_client))) | ||
| 382 | goto exit_free; | ||
| 383 | |||
| 384 | /* | 384 | /* |
| 385 | * Register sysfs hooks | 385 | * Register sysfs hooks |
| 386 | * The LM82 can only monitor one external diode which is | 386 | * The LM82 can only monitor one external diode which is |
| @@ -389,9 +389,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 389 | */ | 389 | */ |
| 390 | 390 | ||
| 391 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group))) | 391 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group))) |
| 392 | goto exit_detach; | 392 | goto exit_free; |
| 393 | 393 | ||
| 394 | if (kind == lm83) { | 394 | if (id->driver_data == lm83) { |
| 395 | if ((err = sysfs_create_group(&new_client->dev.kobj, | 395 | if ((err = sysfs_create_group(&new_client->dev.kobj, |
| 396 | &lm83_group_opt))) | 396 | &lm83_group_opt))) |
| 397 | goto exit_remove_files; | 397 | goto exit_remove_files; |
| @@ -408,26 +408,20 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 408 | exit_remove_files: | 408 | exit_remove_files: |
| 409 | sysfs_remove_group(&new_client->dev.kobj, &lm83_group); | 409 | sysfs_remove_group(&new_client->dev.kobj, &lm83_group); |
| 410 | sysfs_remove_group(&new_client->dev.kobj, &lm83_group_opt); | 410 | sysfs_remove_group(&new_client->dev.kobj, &lm83_group_opt); |
| 411 | exit_detach: | ||
| 412 | i2c_detach_client(new_client); | ||
| 413 | exit_free: | 411 | exit_free: |
| 414 | kfree(data); | 412 | kfree(data); |
| 415 | exit: | 413 | exit: |
| 416 | return err; | 414 | return err; |
| 417 | } | 415 | } |
| 418 | 416 | ||
| 419 | static int lm83_detach_client(struct i2c_client *client) | 417 | static int lm83_remove(struct i2c_client *client) |
| 420 | { | 418 | { |
| 421 | struct lm83_data *data = i2c_get_clientdata(client); | 419 | struct lm83_data *data = i2c_get_clientdata(client); |
| 422 | int err; | ||
| 423 | 420 | ||
| 424 | hwmon_device_unregister(data->hwmon_dev); | 421 | hwmon_device_unregister(data->hwmon_dev); |
| 425 | sysfs_remove_group(&client->dev.kobj, &lm83_group); | 422 | sysfs_remove_group(&client->dev.kobj, &lm83_group); |
| 426 | sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); | 423 | sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); |
| 427 | 424 | ||
| 428 | if ((err = i2c_detach_client(client))) | ||
| 429 | return err; | ||
| 430 | |||
| 431 | kfree(data); | 425 | kfree(data); |
| 432 | return 0; | 426 | return 0; |
| 433 | } | 427 | } |
