aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm77.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-07-16 13:30:13 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-07-16 13:30:13 -0400
commita189dd62d328db7bf8ba68de6a948fdbc93dca25 (patch)
tree00a53527cbec8ce5aaef2eb5d4c6b698514554af /drivers/hwmon/lm77.c
parentd5957be2f1535b1a6c77eabba0781ec7245c5dea (diff)
hwmon: (lm77) Convert to a new-style i2c driver
The new-style lm77 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: Andras Bali <drewie@freemail.hu>
Diffstat (limited to 'drivers/hwmon/lm77.c')
-rw-r--r--drivers/hwmon/lm77.c102
1 files changed, 45 insertions, 57 deletions
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 36d5a8c3ad8c..866b401ab6e8 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -52,7 +52,6 @@ I2C_CLIENT_INSMOD_1(lm77);
52 52
53/* Each client has this additional data */ 53/* Each client has this additional data */
54struct lm77_data { 54struct lm77_data {
55 struct i2c_client client;
56 struct device *hwmon_dev; 55 struct device *hwmon_dev;
57 struct mutex update_lock; 56 struct mutex update_lock;
58 char valid; 57 char valid;
@@ -65,23 +64,35 @@ struct lm77_data {
65 u8 alarms; 64 u8 alarms;
66}; 65};
67 66
68static int lm77_attach_adapter(struct i2c_adapter *adapter); 67static int lm77_probe(struct i2c_client *client,
69static int lm77_detect(struct i2c_adapter *adapter, int address, int kind); 68 const struct i2c_device_id *id);
69static int lm77_detect(struct i2c_client *client, int kind,
70 struct i2c_board_info *info);
70static void lm77_init_client(struct i2c_client *client); 71static void lm77_init_client(struct i2c_client *client);
71static int lm77_detach_client(struct i2c_client *client); 72static int lm77_remove(struct i2c_client *client);
72static u16 lm77_read_value(struct i2c_client *client, u8 reg); 73static u16 lm77_read_value(struct i2c_client *client, u8 reg);
73static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value); 74static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value);
74 75
75static struct lm77_data *lm77_update_device(struct device *dev); 76static struct lm77_data *lm77_update_device(struct device *dev);
76 77
77 78
79static const struct i2c_device_id lm77_id[] = {
80 { "lm77", lm77 },
81 { }
82};
83MODULE_DEVICE_TABLE(i2c, lm77_id);
84
78/* This is the driver that will be inserted */ 85/* This is the driver that will be inserted */
79static struct i2c_driver lm77_driver = { 86static struct i2c_driver lm77_driver = {
87 .class = I2C_CLASS_HWMON,
80 .driver = { 88 .driver = {
81 .name = "lm77", 89 .name = "lm77",
82 }, 90 },
83 .attach_adapter = lm77_attach_adapter, 91 .probe = lm77_probe,
84 .detach_client = lm77_detach_client, 92 .remove = lm77_remove,
93 .id_table = lm77_id,
94 .detect = lm77_detect,
95 .address_data = &addr_data,
85}; 96};
86 97
87/* straight from the datasheet */ 98/* straight from the datasheet */
@@ -215,13 +226,6 @@ static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2);
215static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0); 226static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0);
216static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); 227static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1);
217 228
218static int lm77_attach_adapter(struct i2c_adapter *adapter)
219{
220 if (!(adapter->class & I2C_CLASS_HWMON))
221 return 0;
222 return i2c_probe(adapter, &addr_data, lm77_detect);
223}
224
225static struct attribute *lm77_attributes[] = { 229static struct attribute *lm77_attributes[] = {
226 &dev_attr_temp1_input.attr, 230 &dev_attr_temp1_input.attr,
227 &dev_attr_temp1_crit.attr, 231 &dev_attr_temp1_crit.attr,
@@ -240,32 +244,15 @@ static const struct attribute_group lm77_group = {
240 .attrs = lm77_attributes, 244 .attrs = lm77_attributes,
241}; 245};
242 246
243/* This function is called by i2c_probe */ 247/* Return 0 if detection is successful, -ENODEV otherwise */
244static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) 248static int lm77_detect(struct i2c_client *new_client, int kind,
249 struct i2c_board_info *info)
245{ 250{
246 struct i2c_client *new_client; 251 struct i2c_adapter *adapter = new_client->adapter;
247 struct lm77_data *data;
248 int err = 0;
249 const char *name = "";
250 252
251 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 253 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
252 I2C_FUNC_SMBUS_WORD_DATA)) 254 I2C_FUNC_SMBUS_WORD_DATA))
253 goto exit; 255 return -ENODEV;
254
255 /* OK. For now, we presume we have a valid client. We now create the
256 client structure, even though we cannot fill it completely yet.
257 But it allows us to access lm77_{read,write}_value. */
258 if (!(data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL))) {
259 err = -ENOMEM;
260 goto exit;
261 }
262
263 new_client = &data->client;
264 i2c_set_clientdata(new_client, data);
265 new_client->addr = address;
266 new_client->adapter = adapter;
267 new_client->driver = &lm77_driver;
268 new_client->flags = 0;
269 256
270 /* Here comes the remaining detection. Since the LM77 has no 257 /* Here comes the remaining detection. Since the LM77 has no
271 register dedicated to identification, we have to rely on the 258 register dedicated to identification, we have to rely on the
@@ -294,7 +281,7 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
294 || i2c_smbus_read_word_data(new_client, i + 3) != crit 281 || i2c_smbus_read_word_data(new_client, i + 3) != crit
295 || i2c_smbus_read_word_data(new_client, i + 4) != min 282 || i2c_smbus_read_word_data(new_client, i + 4) != min
296 || i2c_smbus_read_word_data(new_client, i + 5) != max) 283 || i2c_smbus_read_word_data(new_client, i + 5) != max)
297 goto exit_free; 284 return -ENODEV;
298 285
299 /* sign bits */ 286 /* sign bits */
300 if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0) 287 if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0)
@@ -302,51 +289,55 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
302 || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0) 289 || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0)
303 || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0) 290 || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0)
304 || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0)) 291 || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0))
305 goto exit_free; 292 return -ENODEV;
306 293
307 /* unused bits */ 294 /* unused bits */
308 if (conf & 0xe0) 295 if (conf & 0xe0)
309 goto exit_free; 296 return -ENODEV;
310 297
311 /* 0x06 and 0x07 return the last read value */ 298 /* 0x06 and 0x07 return the last read value */
312 cur = i2c_smbus_read_word_data(new_client, 0); 299 cur = i2c_smbus_read_word_data(new_client, 0);
313 if (i2c_smbus_read_word_data(new_client, 6) != cur 300 if (i2c_smbus_read_word_data(new_client, 6) != cur
314 || i2c_smbus_read_word_data(new_client, 7) != cur) 301 || i2c_smbus_read_word_data(new_client, 7) != cur)
315 goto exit_free; 302 return -ENODEV;
316 hyst = i2c_smbus_read_word_data(new_client, 2); 303 hyst = i2c_smbus_read_word_data(new_client, 2);
317 if (i2c_smbus_read_word_data(new_client, 6) != hyst 304 if (i2c_smbus_read_word_data(new_client, 6) != hyst
318 || i2c_smbus_read_word_data(new_client, 7) != hyst) 305 || i2c_smbus_read_word_data(new_client, 7) != hyst)
319 goto exit_free; 306 return -ENODEV;
320 min = i2c_smbus_read_word_data(new_client, 4); 307 min = i2c_smbus_read_word_data(new_client, 4);
321 if (i2c_smbus_read_word_data(new_client, 6) != min 308 if (i2c_smbus_read_word_data(new_client, 6) != min
322 || i2c_smbus_read_word_data(new_client, 7) != min) 309 || i2c_smbus_read_word_data(new_client, 7) != min)
323 goto exit_free; 310 return -ENODEV;
324 311
325 } 312 }
326 313
327 /* Determine the chip type - only one kind supported! */ 314 strlcpy(info->type, "lm77", I2C_NAME_SIZE);
328 if (kind <= 0)
329 kind = lm77;
330 315
331 if (kind == lm77) { 316 return 0;
332 name = "lm77"; 317}
318
319static int lm77_probe(struct i2c_client *new_client,
320 const struct i2c_device_id *id)
321{
322 struct lm77_data *data;
323 int err;
324
325 data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL);
326 if (!data) {
327 err = -ENOMEM;
328 goto exit;
333 } 329 }
334 330
335 /* Fill in the remaining client fields and put it into the global list */ 331 i2c_set_clientdata(new_client, data);
336 strlcpy(new_client->name, name, I2C_NAME_SIZE);
337 data->valid = 0; 332 data->valid = 0;
338 mutex_init(&data->update_lock); 333 mutex_init(&data->update_lock);
339 334
340 /* Tell the I2C layer a new client has arrived */
341 if ((err = i2c_attach_client(new_client)))
342 goto exit_free;
343
344 /* Initialize the LM77 chip */ 335 /* Initialize the LM77 chip */
345 lm77_init_client(new_client); 336 lm77_init_client(new_client);
346 337
347 /* Register sysfs hooks */ 338 /* Register sysfs hooks */
348 if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group))) 339 if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group)))
349 goto exit_detach; 340 goto exit_free;
350 341
351 data->hwmon_dev = hwmon_device_register(&new_client->dev); 342 data->hwmon_dev = hwmon_device_register(&new_client->dev);
352 if (IS_ERR(data->hwmon_dev)) { 343 if (IS_ERR(data->hwmon_dev)) {
@@ -358,20 +349,17 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
358 349
359exit_remove: 350exit_remove:
360 sysfs_remove_group(&new_client->dev.kobj, &lm77_group); 351 sysfs_remove_group(&new_client->dev.kobj, &lm77_group);
361exit_detach:
362 i2c_detach_client(new_client);
363exit_free: 352exit_free:
364 kfree(data); 353 kfree(data);
365exit: 354exit:
366 return err; 355 return err;
367} 356}
368 357
369static int lm77_detach_client(struct i2c_client *client) 358static int lm77_remove(struct i2c_client *client)
370{ 359{
371 struct lm77_data *data = i2c_get_clientdata(client); 360 struct lm77_data *data = i2c_get_clientdata(client);
372 hwmon_device_unregister(data->hwmon_dev); 361 hwmon_device_unregister(data->hwmon_dev);
373 sysfs_remove_group(&client->dev.kobj, &lm77_group); 362 sysfs_remove_group(&client->dev.kobj, &lm77_group);
374 i2c_detach_client(client);
375 kfree(data); 363 kfree(data);
376 return 0; 364 return 0;
377} 365}