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 /drivers/hwmon/lm83.c | |
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>
Diffstat (limited to 'drivers/hwmon/lm83.c')
-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 | } |