diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:15 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:15 -0400 |
commit | c6d3f6fa1b0b984991d6e2a261c7dd7f2685c7bd (patch) | |
tree | 6e734c4519f50cc14a96ad3b328a2791303709b6 /drivers/hwmon | |
parent | 70b724063f789a443aff1e1a6f0f04d971342116 (diff) |
hwmon: (max1619) Convert to a new-style i2c driver
The new-style max1619 driver implements the optional detect() callback
to cover the use cases of the legacy driver.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Alexey Fisher <fishor@mail.ru>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/max1619.c | 101 |
1 files changed, 44 insertions, 57 deletions
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 7e7267a04544..1ab1cacad598 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
@@ -79,23 +79,34 @@ I2C_CLIENT_INSMOD_1(max1619); | |||
79 | * Functions declaration | 79 | * Functions declaration |
80 | */ | 80 | */ |
81 | 81 | ||
82 | static int max1619_attach_adapter(struct i2c_adapter *adapter); | 82 | static int max1619_probe(struct i2c_client *client, |
83 | static int max1619_detect(struct i2c_adapter *adapter, int address, | 83 | const struct i2c_device_id *id); |
84 | int kind); | 84 | static int max1619_detect(struct i2c_client *client, int kind, |
85 | struct i2c_board_info *info); | ||
85 | static void max1619_init_client(struct i2c_client *client); | 86 | static void max1619_init_client(struct i2c_client *client); |
86 | static int max1619_detach_client(struct i2c_client *client); | 87 | static int max1619_remove(struct i2c_client *client); |
87 | static struct max1619_data *max1619_update_device(struct device *dev); | 88 | static struct max1619_data *max1619_update_device(struct device *dev); |
88 | 89 | ||
89 | /* | 90 | /* |
90 | * Driver data (common to all clients) | 91 | * Driver data (common to all clients) |
91 | */ | 92 | */ |
92 | 93 | ||
94 | static const struct i2c_device_id max1619_id[] = { | ||
95 | { "max1619", max1619 }, | ||
96 | { } | ||
97 | }; | ||
98 | MODULE_DEVICE_TABLE(i2c, max1619_id); | ||
99 | |||
93 | static struct i2c_driver max1619_driver = { | 100 | static struct i2c_driver max1619_driver = { |
101 | .class = I2C_CLASS_HWMON, | ||
94 | .driver = { | 102 | .driver = { |
95 | .name = "max1619", | 103 | .name = "max1619", |
96 | }, | 104 | }, |
97 | .attach_adapter = max1619_attach_adapter, | 105 | .probe = max1619_probe, |
98 | .detach_client = max1619_detach_client, | 106 | .remove = max1619_remove, |
107 | .id_table = max1619_id, | ||
108 | .detect = max1619_detect, | ||
109 | .address_data = &addr_data, | ||
99 | }; | 110 | }; |
100 | 111 | ||
101 | /* | 112 | /* |
@@ -103,7 +114,6 @@ static struct i2c_driver max1619_driver = { | |||
103 | */ | 114 | */ |
104 | 115 | ||
105 | struct max1619_data { | 116 | struct max1619_data { |
106 | struct i2c_client client; | ||
107 | struct device *hwmon_dev; | 117 | struct device *hwmon_dev; |
108 | struct mutex update_lock; | 118 | struct mutex update_lock; |
109 | char valid; /* zero until following fields are valid */ | 119 | char valid; /* zero until following fields are valid */ |
@@ -208,41 +218,15 @@ static const struct attribute_group max1619_group = { | |||
208 | * Real code | 218 | * Real code |
209 | */ | 219 | */ |
210 | 220 | ||
211 | static int max1619_attach_adapter(struct i2c_adapter *adapter) | 221 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
212 | { | 222 | static int max1619_detect(struct i2c_client *new_client, int kind, |
213 | if (!(adapter->class & I2C_CLASS_HWMON)) | 223 | struct i2c_board_info *info) |
214 | return 0; | ||
215 | return i2c_probe(adapter, &addr_data, max1619_detect); | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * The following function does more than just detection. If detection | ||
220 | * succeeds, it also registers the new chip. | ||
221 | */ | ||
222 | static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | ||
223 | { | 224 | { |
224 | struct i2c_client *new_client; | 225 | struct i2c_adapter *adapter = new_client->adapter; |
225 | struct max1619_data *data; | ||
226 | int err = 0; | ||
227 | const char *name = ""; | ||
228 | u8 reg_config=0, reg_convrate=0, reg_status=0; | 226 | u8 reg_config=0, reg_convrate=0, reg_status=0; |
229 | 227 | ||
230 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 228 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
231 | goto exit; | 229 | return -ENODEV; |
232 | |||
233 | if (!(data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL))) { | ||
234 | err = -ENOMEM; | ||
235 | goto exit; | ||
236 | } | ||
237 | |||
238 | /* The common I2C client data is placed right before the | ||
239 | MAX1619-specific data. */ | ||
240 | new_client = &data->client; | ||
241 | i2c_set_clientdata(new_client, data); | ||
242 | new_client->addr = address; | ||
243 | new_client->adapter = adapter; | ||
244 | new_client->driver = &max1619_driver; | ||
245 | new_client->flags = 0; | ||
246 | 230 | ||
247 | /* | 231 | /* |
248 | * Now we do the remaining detection. A negative kind means that | 232 | * Now we do the remaining detection. A negative kind means that |
@@ -265,8 +249,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | |||
265 | || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) { | 249 | || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) { |
266 | dev_dbg(&adapter->dev, | 250 | dev_dbg(&adapter->dev, |
267 | "MAX1619 detection failed at 0x%02x.\n", | 251 | "MAX1619 detection failed at 0x%02x.\n", |
268 | address); | 252 | new_client->addr); |
269 | goto exit_free; | 253 | return -ENODEV; |
270 | } | 254 | } |
271 | } | 255 | } |
272 | 256 | ||
@@ -285,28 +269,37 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | |||
285 | dev_info(&adapter->dev, | 269 | dev_info(&adapter->dev, |
286 | "Unsupported chip (man_id=0x%02X, " | 270 | "Unsupported chip (man_id=0x%02X, " |
287 | "chip_id=0x%02X).\n", man_id, chip_id); | 271 | "chip_id=0x%02X).\n", man_id, chip_id); |
288 | goto exit_free; | 272 | return -ENODEV; |
289 | } | 273 | } |
290 | } | 274 | } |
291 | 275 | ||
292 | if (kind == max1619) | 276 | strlcpy(info->type, "max1619", I2C_NAME_SIZE); |
293 | name = "max1619"; | 277 | |
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int max1619_probe(struct i2c_client *new_client, | ||
282 | const struct i2c_device_id *id) | ||
283 | { | ||
284 | struct max1619_data *data; | ||
285 | int err; | ||
286 | |||
287 | data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL); | ||
288 | if (!data) { | ||
289 | err = -ENOMEM; | ||
290 | goto exit; | ||
291 | } | ||
294 | 292 | ||
295 | /* We can fill in the remaining client fields */ | 293 | i2c_set_clientdata(new_client, data); |
296 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | ||
297 | data->valid = 0; | 294 | data->valid = 0; |
298 | mutex_init(&data->update_lock); | 295 | mutex_init(&data->update_lock); |
299 | 296 | ||
300 | /* Tell the I2C layer a new client has arrived */ | ||
301 | if ((err = i2c_attach_client(new_client))) | ||
302 | goto exit_free; | ||
303 | |||
304 | /* Initialize the MAX1619 chip */ | 297 | /* Initialize the MAX1619 chip */ |
305 | max1619_init_client(new_client); | 298 | max1619_init_client(new_client); |
306 | 299 | ||
307 | /* Register sysfs hooks */ | 300 | /* Register sysfs hooks */ |
308 | if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) | 301 | if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) |
309 | goto exit_detach; | 302 | goto exit_free; |
310 | 303 | ||
311 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 304 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
312 | if (IS_ERR(data->hwmon_dev)) { | 305 | if (IS_ERR(data->hwmon_dev)) { |
@@ -318,8 +311,6 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) | |||
318 | 311 | ||
319 | exit_remove_files: | 312 | exit_remove_files: |
320 | sysfs_remove_group(&new_client->dev.kobj, &max1619_group); | 313 | sysfs_remove_group(&new_client->dev.kobj, &max1619_group); |
321 | exit_detach: | ||
322 | i2c_detach_client(new_client); | ||
323 | exit_free: | 314 | exit_free: |
324 | kfree(data); | 315 | kfree(data); |
325 | exit: | 316 | exit: |
@@ -341,17 +332,13 @@ static void max1619_init_client(struct i2c_client *client) | |||
341 | config & 0xBF); /* run */ | 332 | config & 0xBF); /* run */ |
342 | } | 333 | } |
343 | 334 | ||
344 | static int max1619_detach_client(struct i2c_client *client) | 335 | static int max1619_remove(struct i2c_client *client) |
345 | { | 336 | { |
346 | struct max1619_data *data = i2c_get_clientdata(client); | 337 | struct max1619_data *data = i2c_get_clientdata(client); |
347 | int err; | ||
348 | 338 | ||
349 | hwmon_device_unregister(data->hwmon_dev); | 339 | hwmon_device_unregister(data->hwmon_dev); |
350 | sysfs_remove_group(&client->dev.kobj, &max1619_group); | 340 | sysfs_remove_group(&client->dev.kobj, &max1619_group); |
351 | 341 | ||
352 | if ((err = i2c_detach_client(client))) | ||
353 | return err; | ||
354 | |||
355 | kfree(data); | 342 | kfree(data); |
356 | return 0; | 343 | return 0; |
357 | } | 344 | } |