diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:12 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:12 -0400 |
commit | c2df1591df3ea83b4a5890a1131dd821ca07e761 (patch) | |
tree | f22157913224afdb26afbc51745405edaad30bea | |
parent | 935ada8c4481f9591caa1b88c83127c5931a8855 (diff) |
hwmon: (fscher) Convert to a new-style i2c driver
The new-style fscher 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: Reinhard Nissl <rnissl@gmx.de>
-rw-r--r-- | drivers/hwmon/fscher.c | 93 |
1 files changed, 42 insertions, 51 deletions
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index ed26b66e0831..12c70e402cb2 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c | |||
@@ -106,9 +106,11 @@ I2C_CLIENT_INSMOD_1(fscher); | |||
106 | * Functions declaration | 106 | * Functions declaration |
107 | */ | 107 | */ |
108 | 108 | ||
109 | static int fscher_attach_adapter(struct i2c_adapter *adapter); | 109 | static int fscher_probe(struct i2c_client *client, |
110 | static int fscher_detect(struct i2c_adapter *adapter, int address, int kind); | 110 | const struct i2c_device_id *id); |
111 | static int fscher_detach_client(struct i2c_client *client); | 111 | static int fscher_detect(struct i2c_client *client, int kind, |
112 | struct i2c_board_info *info); | ||
113 | static int fscher_remove(struct i2c_client *client); | ||
112 | static struct fscher_data *fscher_update_device(struct device *dev); | 114 | static struct fscher_data *fscher_update_device(struct device *dev); |
113 | static void fscher_init_client(struct i2c_client *client); | 115 | static void fscher_init_client(struct i2c_client *client); |
114 | 116 | ||
@@ -119,12 +121,21 @@ static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value); | |||
119 | * Driver data (common to all clients) | 121 | * Driver data (common to all clients) |
120 | */ | 122 | */ |
121 | 123 | ||
124 | static const struct i2c_device_id fscher_id[] = { | ||
125 | { "fscher", fscher }, | ||
126 | { } | ||
127 | }; | ||
128 | |||
122 | static struct i2c_driver fscher_driver = { | 129 | static struct i2c_driver fscher_driver = { |
130 | .class = I2C_CLASS_HWMON, | ||
123 | .driver = { | 131 | .driver = { |
124 | .name = "fscher", | 132 | .name = "fscher", |
125 | }, | 133 | }, |
126 | .attach_adapter = fscher_attach_adapter, | 134 | .probe = fscher_probe, |
127 | .detach_client = fscher_detach_client, | 135 | .remove = fscher_remove, |
136 | .id_table = fscher_id, | ||
137 | .detect = fscher_detect, | ||
138 | .address_data = &addr_data, | ||
128 | }; | 139 | }; |
129 | 140 | ||
130 | /* | 141 | /* |
@@ -132,7 +143,6 @@ static struct i2c_driver fscher_driver = { | |||
132 | */ | 143 | */ |
133 | 144 | ||
134 | struct fscher_data { | 145 | struct fscher_data { |
135 | struct i2c_client client; | ||
136 | struct device *hwmon_dev; | 146 | struct device *hwmon_dev; |
137 | struct mutex update_lock; | 147 | struct mutex update_lock; |
138 | char valid; /* zero until following fields are valid */ | 148 | char valid; /* zero until following fields are valid */ |
@@ -283,38 +293,14 @@ static const struct attribute_group fscher_group = { | |||
283 | * Real code | 293 | * Real code |
284 | */ | 294 | */ |
285 | 295 | ||
286 | static int fscher_attach_adapter(struct i2c_adapter *adapter) | 296 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
287 | { | 297 | static int fscher_detect(struct i2c_client *new_client, int kind, |
288 | if (!(adapter->class & I2C_CLASS_HWMON)) | 298 | struct i2c_board_info *info) |
289 | return 0; | ||
290 | return i2c_probe(adapter, &addr_data, fscher_detect); | ||
291 | } | ||
292 | |||
293 | static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) | ||
294 | { | 299 | { |
295 | struct i2c_client *new_client; | 300 | struct i2c_adapter *adapter = new_client->adapter; |
296 | struct fscher_data *data; | ||
297 | int err = 0; | ||
298 | 301 | ||
299 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 302 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
300 | goto exit; | 303 | return -ENODEV; |
301 | |||
302 | /* OK. For now, we presume we have a valid client. We now create the | ||
303 | * client structure, even though we cannot fill it completely yet. | ||
304 | * But it allows us to access i2c_smbus_read_byte_data. */ | ||
305 | if (!(data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL))) { | ||
306 | err = -ENOMEM; | ||
307 | goto exit; | ||
308 | } | ||
309 | |||
310 | /* The common I2C client data is placed right before the | ||
311 | * Hermes-specific data. */ | ||
312 | new_client = &data->client; | ||
313 | i2c_set_clientdata(new_client, data); | ||
314 | new_client->addr = address; | ||
315 | new_client->adapter = adapter; | ||
316 | new_client->driver = &fscher_driver; | ||
317 | new_client->flags = 0; | ||
318 | 304 | ||
319 | /* Do the remaining detection unless force or force_fscher parameter */ | 305 | /* Do the remaining detection unless force or force_fscher parameter */ |
320 | if (kind < 0) { | 306 | if (kind < 0) { |
@@ -324,24 +310,35 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) | |||
324 | FSCHER_REG_IDENT_1) != 0x45) /* 'E' */ | 310 | FSCHER_REG_IDENT_1) != 0x45) /* 'E' */ |
325 | || (i2c_smbus_read_byte_data(new_client, | 311 | || (i2c_smbus_read_byte_data(new_client, |
326 | FSCHER_REG_IDENT_2) != 0x52)) /* 'R' */ | 312 | FSCHER_REG_IDENT_2) != 0x52)) /* 'R' */ |
327 | goto exit_free; | 313 | return -ENODEV; |
314 | } | ||
315 | |||
316 | strlcpy(info->type, "fscher", I2C_NAME_SIZE); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int fscher_probe(struct i2c_client *new_client, | ||
322 | const struct i2c_device_id *id) | ||
323 | { | ||
324 | struct fscher_data *data; | ||
325 | int err; | ||
326 | |||
327 | data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL); | ||
328 | if (!data) { | ||
329 | err = -ENOMEM; | ||
330 | goto exit; | ||
328 | } | 331 | } |
329 | 332 | ||
330 | /* Fill in the remaining client fields and put it into the | 333 | i2c_set_clientdata(new_client, data); |
331 | * global list */ | ||
332 | strlcpy(new_client->name, "fscher", I2C_NAME_SIZE); | ||
333 | data->valid = 0; | 334 | data->valid = 0; |
334 | mutex_init(&data->update_lock); | 335 | mutex_init(&data->update_lock); |
335 | 336 | ||
336 | /* Tell the I2C layer a new client has arrived */ | ||
337 | if ((err = i2c_attach_client(new_client))) | ||
338 | goto exit_free; | ||
339 | |||
340 | fscher_init_client(new_client); | 337 | fscher_init_client(new_client); |
341 | 338 | ||
342 | /* Register sysfs hooks */ | 339 | /* Register sysfs hooks */ |
343 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) | 340 | if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) |
344 | goto exit_detach; | 341 | goto exit_free; |
345 | 342 | ||
346 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | 343 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
347 | if (IS_ERR(data->hwmon_dev)) { | 344 | if (IS_ERR(data->hwmon_dev)) { |
@@ -353,25 +350,19 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) | |||
353 | 350 | ||
354 | exit_remove_files: | 351 | exit_remove_files: |
355 | sysfs_remove_group(&new_client->dev.kobj, &fscher_group); | 352 | sysfs_remove_group(&new_client->dev.kobj, &fscher_group); |
356 | exit_detach: | ||
357 | i2c_detach_client(new_client); | ||
358 | exit_free: | 353 | exit_free: |
359 | kfree(data); | 354 | kfree(data); |
360 | exit: | 355 | exit: |
361 | return err; | 356 | return err; |
362 | } | 357 | } |
363 | 358 | ||
364 | static int fscher_detach_client(struct i2c_client *client) | 359 | static int fscher_remove(struct i2c_client *client) |
365 | { | 360 | { |
366 | struct fscher_data *data = i2c_get_clientdata(client); | 361 | struct fscher_data *data = i2c_get_clientdata(client); |
367 | int err; | ||
368 | 362 | ||
369 | hwmon_device_unregister(data->hwmon_dev); | 363 | hwmon_device_unregister(data->hwmon_dev); |
370 | sysfs_remove_group(&client->dev.kobj, &fscher_group); | 364 | sysfs_remove_group(&client->dev.kobj, &fscher_group); |
371 | 365 | ||
372 | if ((err = i2c_detach_client(client))) | ||
373 | return err; | ||
374 | |||
375 | kfree(data); | 366 | kfree(data); |
376 | return 0; | 367 | return 0; |
377 | } | 368 | } |