aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/fschmd.c
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
commit40ac1994bf988dac05434f856c2a4fa24e22b2ea (patch)
tree88acc783bdb40d53df0cce86a67197391574e809 /drivers/hwmon/fschmd.c
parentc2df1591df3ea83b4a5890a1131dd821ca07e761 (diff)
hwmon: (fschmd) Convert to a new-style i2c driver
The new-style fschmd 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: Hans de Goede <j.w.r.degoede@hhs.nl>
Diffstat (limited to 'drivers/hwmon/fschmd.c')
-rw-r--r--drivers/hwmon/fschmd.c112
1 files changed, 57 insertions, 55 deletions
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index bd89d270a5ed..967170368933 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -171,20 +171,37 @@ static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
171 * Functions declarations 171 * Functions declarations
172 */ 172 */
173 173
174static int fschmd_attach_adapter(struct i2c_adapter *adapter); 174static int fschmd_probe(struct i2c_client *client,
175static int fschmd_detach_client(struct i2c_client *client); 175 const struct i2c_device_id *id);
176static int fschmd_detect(struct i2c_client *client, int kind,
177 struct i2c_board_info *info);
178static int fschmd_remove(struct i2c_client *client);
176static struct fschmd_data *fschmd_update_device(struct device *dev); 179static struct fschmd_data *fschmd_update_device(struct device *dev);
177 180
178/* 181/*
179 * Driver data (common to all clients) 182 * Driver data (common to all clients)
180 */ 183 */
181 184
185static const struct i2c_device_id fschmd_id[] = {
186 { "fscpos", fscpos },
187 { "fscher", fscher },
188 { "fscscy", fscscy },
189 { "fschrc", fschrc },
190 { "fschmd", fschmd },
191 { }
192};
193MODULE_DEVICE_TABLE(i2c, fschmd_id);
194
182static struct i2c_driver fschmd_driver = { 195static struct i2c_driver fschmd_driver = {
196 .class = I2C_CLASS_HWMON,
183 .driver = { 197 .driver = {
184 .name = FSCHMD_NAME, 198 .name = FSCHMD_NAME,
185 }, 199 },
186 .attach_adapter = fschmd_attach_adapter, 200 .probe = fschmd_probe,
187 .detach_client = fschmd_detach_client, 201 .remove = fschmd_remove,
202 .id_table = fschmd_id,
203 .detect = fschmd_detect,
204 .address_data = &addr_data,
188}; 205};
189 206
190/* 207/*
@@ -192,7 +209,6 @@ static struct i2c_driver fschmd_driver = {
192 */ 209 */
193 210
194struct fschmd_data { 211struct fschmd_data {
195 struct i2c_client client;
196 struct device *hwmon_dev; 212 struct device *hwmon_dev;
197 struct mutex update_lock; 213 struct mutex update_lock;
198 int kind; 214 int kind;
@@ -269,7 +285,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute
269 v = SENSORS_LIMIT(v, -128, 127) + 128; 285 v = SENSORS_LIMIT(v, -128, 127) + 128;
270 286
271 mutex_lock(&data->update_lock); 287 mutex_lock(&data->update_lock);
272 i2c_smbus_write_byte_data(&data->client, 288 i2c_smbus_write_byte_data(to_i2c_client(dev),
273 FSCHMD_REG_TEMP_LIMIT[data->kind][index], v); 289 FSCHMD_REG_TEMP_LIMIT[data->kind][index], v);
274 data->temp_max[index] = v; 290 data->temp_max[index] = v;
275 mutex_unlock(&data->update_lock); 291 mutex_unlock(&data->update_lock);
@@ -346,14 +362,14 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute
346 362
347 mutex_lock(&data->update_lock); 363 mutex_lock(&data->update_lock);
348 364
349 reg = i2c_smbus_read_byte_data(&data->client, 365 reg = i2c_smbus_read_byte_data(to_i2c_client(dev),
350 FSCHMD_REG_FAN_RIPPLE[data->kind][index]); 366 FSCHMD_REG_FAN_RIPPLE[data->kind][index]);
351 367
352 /* bits 2..7 reserved => mask with 0x03 */ 368 /* bits 2..7 reserved => mask with 0x03 */
353 reg &= ~0x03; 369 reg &= ~0x03;
354 reg |= v; 370 reg |= v;
355 371
356 i2c_smbus_write_byte_data(&data->client, 372 i2c_smbus_write_byte_data(to_i2c_client(dev),
357 FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg); 373 FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg);
358 374
359 data->fan_ripple[index] = reg; 375 data->fan_ripple[index] = reg;
@@ -416,7 +432,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
416 432
417 mutex_lock(&data->update_lock); 433 mutex_lock(&data->update_lock);
418 434
419 i2c_smbus_write_byte_data(&data->client, 435 i2c_smbus_write_byte_data(to_i2c_client(dev),
420 FSCHMD_REG_FAN_MIN[data->kind][index], v); 436 FSCHMD_REG_FAN_MIN[data->kind][index], v);
421 data->fan_min[index] = v; 437 data->fan_min[index] = v;
422 438
@@ -448,14 +464,14 @@ static ssize_t store_alert_led(struct device *dev,
448 464
449 mutex_lock(&data->update_lock); 465 mutex_lock(&data->update_lock);
450 466
451 reg = i2c_smbus_read_byte_data(&data->client, FSCHMD_REG_CONTROL); 467 reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL);
452 468
453 if (v) 469 if (v)
454 reg |= FSCHMD_CONTROL_ALERT_LED_MASK; 470 reg |= FSCHMD_CONTROL_ALERT_LED_MASK;
455 else 471 else
456 reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK; 472 reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK;
457 473
458 i2c_smbus_write_byte_data(&data->client, FSCHMD_REG_CONTROL, reg); 474 i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg);
459 475
460 data->global_control = reg; 476 data->global_control = reg;
461 477
@@ -600,32 +616,15 @@ static void fschmd_dmi_decode(const struct dmi_header *header)
600 } 616 }
601} 617}
602 618
603static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind) 619static int fschmd_detect(struct i2c_client *client, int kind,
620 struct i2c_board_info *info)
604{ 621{
605 struct i2c_client *client; 622 struct i2c_adapter *adapter = client->adapter;
606 struct fschmd_data *data;
607 u8 revision;
608 const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
609 "Heracles", "Heimdall" };
610 const char * const client_names[5] = { "fscpos", "fscher", "fscscy", 623 const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
611 "fschrc", "fschmd" }; 624 "fschrc", "fschmd" };
612 int i, err = 0;
613 625
614 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 626 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
615 return 0; 627 return -ENODEV;
616
617 /* OK. For now, we presume we have a valid client. We now create the
618 * client structure, even though we cannot fill it completely yet.
619 * But it allows us to access i2c_smbus_read_byte_data. */
620 if (!(data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL)))
621 return -ENOMEM;
622
623 client = &data->client;
624 i2c_set_clientdata(client, data);
625 client->addr = address;
626 client->adapter = adapter;
627 client->driver = &fschmd_driver;
628 mutex_init(&data->update_lock);
629 628
630 /* Detect & Identify the chip */ 629 /* Detect & Identify the chip */
631 if (kind <= 0) { 630 if (kind <= 0) {
@@ -650,9 +649,31 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
650 else if (!strcmp(id, "HMD")) 649 else if (!strcmp(id, "HMD"))
651 kind = fschmd; 650 kind = fschmd;
652 else 651 else
653 goto exit_free; 652 return -ENODEV;
654 } 653 }
655 654
655 strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE);
656
657 return 0;
658}
659
660static int fschmd_probe(struct i2c_client *client,
661 const struct i2c_device_id *id)
662{
663 struct fschmd_data *data;
664 u8 revision;
665 const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
666 "Heracles", "Heimdall" };
667 int i, err;
668 enum chips kind = id->driver_data;
669
670 data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL);
671 if (!data)
672 return -ENOMEM;
673
674 i2c_set_clientdata(client, data);
675 mutex_init(&data->update_lock);
676
656 if (kind == fscpos) { 677 if (kind == fscpos) {
657 /* The Poseidon has hardwired temp limits, fill these 678 /* The Poseidon has hardwired temp limits, fill these
658 in for the alarm resetting code */ 679 in for the alarm resetting code */
@@ -674,11 +695,6 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
674 695
675 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */ 696 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
676 data->kind = kind - 1; 697 data->kind = kind - 1;
677 strlcpy(client->name, client_names[data->kind], I2C_NAME_SIZE);
678
679 /* Tell the I2C layer a new client has arrived */
680 if ((err = i2c_attach_client(client)))
681 goto exit_free;
682 698
683 for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) { 699 for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
684 err = device_create_file(&client->dev, 700 err = device_create_file(&client->dev,
@@ -726,25 +742,14 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
726 return 0; 742 return 0;
727 743
728exit_detach: 744exit_detach:
729 fschmd_detach_client(client); /* will also free data for us */ 745 fschmd_remove(client); /* will also free data for us */
730 return err;
731
732exit_free:
733 kfree(data);
734 return err; 746 return err;
735} 747}
736 748
737static int fschmd_attach_adapter(struct i2c_adapter *adapter) 749static int fschmd_remove(struct i2c_client *client)
738{
739 if (!(adapter->class & I2C_CLASS_HWMON))
740 return 0;
741 return i2c_probe(adapter, &addr_data, fschmd_detect);
742}
743
744static int fschmd_detach_client(struct i2c_client *client)
745{ 750{
746 struct fschmd_data *data = i2c_get_clientdata(client); 751 struct fschmd_data *data = i2c_get_clientdata(client);
747 int i, err; 752 int i;
748 753
749 /* Check if registered in case we're called from fschmd_detect 754 /* Check if registered in case we're called from fschmd_detect
750 to cleanup after an error */ 755 to cleanup after an error */
@@ -760,9 +765,6 @@ static int fschmd_detach_client(struct i2c_client *client)
760 device_remove_file(&client->dev, 765 device_remove_file(&client->dev,
761 &fschmd_fan_attr[i].dev_attr); 766 &fschmd_fan_attr[i].dev_attr);
762 767
763 if ((err = i2c_detach_client(client)))
764 return err;
765
766 kfree(data); 768 kfree(data);
767 return 0; 769 return 0;
768} 770}