aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-07-16 13:30:12 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-07-16 13:30:12 -0400
commitb9e39b1b1b79d3e074ca79b63f548ac48c85ca98 (patch)
tree713c5562a7f253a3a06a84d56b6deb8600438151 /drivers/hwmon
parent40ac1994bf988dac05434f856c2a4fa24e22b2ea (diff)
hwmon: (fscpos) Convert to a new-style i2c driver
The new-style fscpos 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')
-rw-r--r--drivers/hwmon/fscpos.c94
1 files changed, 41 insertions, 53 deletions
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
index 00f48484e54b..8a7bcf500b4e 100644
--- a/drivers/hwmon/fscpos.c
+++ b/drivers/hwmon/fscpos.c
@@ -87,9 +87,11 @@ static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 };
87/* 87/*
88 * Functions declaration 88 * Functions declaration
89 */ 89 */
90static int fscpos_attach_adapter(struct i2c_adapter *adapter); 90static int fscpos_probe(struct i2c_client *client,
91static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind); 91 const struct i2c_device_id *id);
92static int fscpos_detach_client(struct i2c_client *client); 92static int fscpos_detect(struct i2c_client *client, int kind,
93 struct i2c_board_info *info);
94static int fscpos_remove(struct i2c_client *client);
93 95
94static int fscpos_read_value(struct i2c_client *client, u8 reg); 96static int fscpos_read_value(struct i2c_client *client, u8 reg);
95static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value); 97static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value);
@@ -101,19 +103,27 @@ static void reset_fan_alarm(struct i2c_client *client, int nr);
101/* 103/*
102 * Driver data (common to all clients) 104 * Driver data (common to all clients)
103 */ 105 */
106static const struct i2c_device_id fscpos_id[] = {
107 { "fscpos", fscpos },
108 { }
109};
110
104static struct i2c_driver fscpos_driver = { 111static struct i2c_driver fscpos_driver = {
112 .class = I2C_CLASS_HWMON,
105 .driver = { 113 .driver = {
106 .name = "fscpos", 114 .name = "fscpos",
107 }, 115 },
108 .attach_adapter = fscpos_attach_adapter, 116 .probe = fscpos_probe,
109 .detach_client = fscpos_detach_client, 117 .remove = fscpos_remove,
118 .id_table = fscpos_id,
119 .detect = fscpos_detect,
120 .address_data = &addr_data,
110}; 121};
111 122
112/* 123/*
113 * Client data (each client gets its own) 124 * Client data (each client gets its own)
114 */ 125 */
115struct fscpos_data { 126struct fscpos_data {
116 struct i2c_client client;
117 struct device *hwmon_dev; 127 struct device *hwmon_dev;
118 struct mutex update_lock; 128 struct mutex update_lock;
119 char valid; /* 0 until following fields are valid */ 129 char valid; /* 0 until following fields are valid */
@@ -470,39 +480,14 @@ static const struct attribute_group fscpos_group = {
470 .attrs = fscpos_attributes, 480 .attrs = fscpos_attributes,
471}; 481};
472 482
473static int fscpos_attach_adapter(struct i2c_adapter *adapter) 483/* Return 0 if detection is successful, -ENODEV otherwise */
474{ 484static int fscpos_detect(struct i2c_client *new_client, int kind,
475 if (!(adapter->class & I2C_CLASS_HWMON)) 485 struct i2c_board_info *info)
476 return 0;
477 return i2c_probe(adapter, &addr_data, fscpos_detect);
478}
479
480static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
481{ 486{
482 struct i2c_client *new_client; 487 struct i2c_adapter *adapter = new_client->adapter;
483 struct fscpos_data *data;
484 int err = 0;
485 488
486 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 489 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
487 goto exit; 490 return -ENODEV;
488
489 /*
490 * OK. For now, we presume we have a valid client. We now create the
491 * client structure, even though we cannot fill it completely yet.
492 * But it allows us to access fscpos_{read,write}_value.
493 */
494
495 if (!(data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
496 err = -ENOMEM;
497 goto exit;
498 }
499
500 new_client = &data->client;
501 i2c_set_clientdata(new_client, data);
502 new_client->addr = address;
503 new_client->adapter = adapter;
504 new_client->driver = &fscpos_driver;
505 new_client->flags = 0;
506 491
507 /* Do the remaining detection unless force or force_fscpos parameter */ 492 /* Do the remaining detection unless force or force_fscpos parameter */
508 if (kind < 0) { 493 if (kind < 0) {
@@ -512,22 +497,30 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
512 != 0x45) /* 'E' */ 497 != 0x45) /* 'E' */
513 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2) 498 || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2)
514 != 0x47))/* 'G' */ 499 != 0x47))/* 'G' */
515 { 500 return -ENODEV;
516 dev_dbg(&new_client->dev, "fscpos detection failed\n");
517 goto exit_free;
518 }
519 } 501 }
520 502
521 /* Fill in the remaining client fields and put it in the global list */ 503 strlcpy(info->type, "fscpos", I2C_NAME_SIZE);
522 strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE);
523 504
505 return 0;
506}
507
508static int fscpos_probe(struct i2c_client *new_client,
509 const struct i2c_device_id *id)
510{
511 struct fscpos_data *data;
512 int err;
513
514 data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL);
515 if (!data) {
516 err = -ENOMEM;
517 goto exit;
518 }
519
520 i2c_set_clientdata(new_client, data);
524 data->valid = 0; 521 data->valid = 0;
525 mutex_init(&data->update_lock); 522 mutex_init(&data->update_lock);
526 523
527 /* Tell the I2C layer a new client has arrived */
528 if ((err = i2c_attach_client(new_client)))
529 goto exit_free;
530
531 /* Inizialize the fscpos chip */ 524 /* Inizialize the fscpos chip */
532 fscpos_init_client(new_client); 525 fscpos_init_client(new_client);
533 526
@@ -536,7 +529,7 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
536 529
537 /* Register sysfs hooks */ 530 /* Register sysfs hooks */
538 if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) 531 if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group)))
539 goto exit_detach; 532 goto exit_free;
540 533
541 data->hwmon_dev = hwmon_device_register(&new_client->dev); 534 data->hwmon_dev = hwmon_device_register(&new_client->dev);
542 if (IS_ERR(data->hwmon_dev)) { 535 if (IS_ERR(data->hwmon_dev)) {
@@ -548,24 +541,19 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
548 541
549exit_remove_files: 542exit_remove_files:
550 sysfs_remove_group(&new_client->dev.kobj, &fscpos_group); 543 sysfs_remove_group(&new_client->dev.kobj, &fscpos_group);
551exit_detach:
552 i2c_detach_client(new_client);
553exit_free: 544exit_free:
554 kfree(data); 545 kfree(data);
555exit: 546exit:
556 return err; 547 return err;
557} 548}
558 549
559static int fscpos_detach_client(struct i2c_client *client) 550static int fscpos_remove(struct i2c_client *client)
560{ 551{
561 struct fscpos_data *data = i2c_get_clientdata(client); 552 struct fscpos_data *data = i2c_get_clientdata(client);
562 int err;
563 553
564 hwmon_device_unregister(data->hwmon_dev); 554 hwmon_device_unregister(data->hwmon_dev);
565 sysfs_remove_group(&client->dev.kobj, &fscpos_group); 555 sysfs_remove_group(&client->dev.kobj, &fscpos_group);
566 556
567 if ((err = i2c_detach_client(client)))
568 return err;
569 kfree(data); 557 kfree(data);
570 return 0; 558 return 0;
571} 559}