diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/hwmon/max6650.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/hwmon/max6650.c')
-rw-r--r-- | drivers/hwmon/max6650.c | 80 |
1 files changed, 29 insertions, 51 deletions
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index a0160ee5caef..ece3aafa54b3 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * max6650.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | * max6650.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | * monitoring. | 3 | * monitoring. |
4 | * | 4 | * |
5 | * (C) 2007 by Hans J. Koch <hjk@linutronix.de> | 5 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> |
6 | * | 6 | * |
7 | * based on code written by John Morris <john.morris@spirentcom.com> | 7 | * based on code written by John Morris <john.morris@spirentcom.com> |
8 | * Copyright (c) 2003 Spirent Communications | 8 | * Copyright (c) 2003 Spirent Communications |
@@ -41,13 +41,6 @@ | |||
41 | #include <linux/err.h> | 41 | #include <linux/err.h> |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Addresses to scan. There are four disjoint possibilities, by pin config. | ||
45 | */ | ||
46 | |||
47 | static const unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, | ||
48 | I2C_CLIENT_END}; | ||
49 | |||
50 | /* | ||
51 | * Insmod parameters | 44 | * Insmod parameters |
52 | */ | 45 | */ |
53 | 46 | ||
@@ -114,8 +107,6 @@ module_param(clock, int, S_IRUGO); | |||
114 | 107 | ||
115 | static int max6650_probe(struct i2c_client *client, | 108 | static int max6650_probe(struct i2c_client *client, |
116 | const struct i2c_device_id *id); | 109 | const struct i2c_device_id *id); |
117 | static int max6650_detect(struct i2c_client *client, | ||
118 | struct i2c_board_info *info); | ||
119 | static int max6650_init_client(struct i2c_client *client); | 110 | static int max6650_init_client(struct i2c_client *client); |
120 | static int max6650_remove(struct i2c_client *client); | 111 | static int max6650_remove(struct i2c_client *client); |
121 | static struct max6650_data *max6650_update_device(struct device *dev); | 112 | static struct max6650_data *max6650_update_device(struct device *dev); |
@@ -125,21 +116,19 @@ static struct max6650_data *max6650_update_device(struct device *dev); | |||
125 | */ | 116 | */ |
126 | 117 | ||
127 | static const struct i2c_device_id max6650_id[] = { | 118 | static const struct i2c_device_id max6650_id[] = { |
128 | { "max6650", 0 }, | 119 | { "max6650", 1 }, |
120 | { "max6651", 4 }, | ||
129 | { } | 121 | { } |
130 | }; | 122 | }; |
131 | MODULE_DEVICE_TABLE(i2c, max6650_id); | 123 | MODULE_DEVICE_TABLE(i2c, max6650_id); |
132 | 124 | ||
133 | static struct i2c_driver max6650_driver = { | 125 | static struct i2c_driver max6650_driver = { |
134 | .class = I2C_CLASS_HWMON, | ||
135 | .driver = { | 126 | .driver = { |
136 | .name = "max6650", | 127 | .name = "max6650", |
137 | }, | 128 | }, |
138 | .probe = max6650_probe, | 129 | .probe = max6650_probe, |
139 | .remove = max6650_remove, | 130 | .remove = max6650_remove, |
140 | .id_table = max6650_id, | 131 | .id_table = max6650_id, |
141 | .detect = max6650_detect, | ||
142 | .address_list = normal_i2c, | ||
143 | }; | 132 | }; |
144 | 133 | ||
145 | /* | 134 | /* |
@@ -150,6 +139,7 @@ struct max6650_data | |||
150 | { | 139 | { |
151 | struct device *hwmon_dev; | 140 | struct device *hwmon_dev; |
152 | struct mutex update_lock; | 141 | struct mutex update_lock; |
142 | int nr_fans; | ||
153 | char valid; /* zero until following fields are valid */ | 143 | char valid; /* zero until following fields are valid */ |
154 | unsigned long last_updated; /* in jiffies */ | 144 | unsigned long last_updated; /* in jiffies */ |
155 | 145 | ||
@@ -501,9 +491,6 @@ static mode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a, | |||
501 | 491 | ||
502 | static struct attribute *max6650_attrs[] = { | 492 | static struct attribute *max6650_attrs[] = { |
503 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 493 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
504 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
505 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
506 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
507 | &dev_attr_fan1_target.attr, | 494 | &dev_attr_fan1_target.attr, |
508 | &dev_attr_fan1_div.attr, | 495 | &dev_attr_fan1_div.attr, |
509 | &dev_attr_pwm1_enable.attr, | 496 | &dev_attr_pwm1_enable.attr, |
@@ -521,42 +508,21 @@ static struct attribute_group max6650_attr_grp = { | |||
521 | .is_visible = max6650_attrs_visible, | 508 | .is_visible = max6650_attrs_visible, |
522 | }; | 509 | }; |
523 | 510 | ||
511 | static struct attribute *max6651_attrs[] = { | ||
512 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
513 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
514 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
515 | NULL | ||
516 | }; | ||
517 | |||
518 | static const struct attribute_group max6651_attr_grp = { | ||
519 | .attrs = max6651_attrs, | ||
520 | }; | ||
521 | |||
524 | /* | 522 | /* |
525 | * Real code | 523 | * Real code |
526 | */ | 524 | */ |
527 | 525 | ||
528 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
529 | static int max6650_detect(struct i2c_client *client, | ||
530 | struct i2c_board_info *info) | ||
531 | { | ||
532 | struct i2c_adapter *adapter = client->adapter; | ||
533 | int address = client->addr; | ||
534 | |||
535 | dev_dbg(&adapter->dev, "max6650_detect called\n"); | ||
536 | |||
537 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
538 | dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support " | ||
539 | "byte read mode, skipping.\n"); | ||
540 | return -ENODEV; | ||
541 | } | ||
542 | |||
543 | if (((i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0) | ||
544 | ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0) | ||
545 | ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0) | ||
546 | ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0) | ||
547 | ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) { | ||
548 | dev_dbg(&adapter->dev, | ||
549 | "max6650: detection failed at 0x%02x.\n", address); | ||
550 | return -ENODEV; | ||
551 | } | ||
552 | |||
553 | dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address); | ||
554 | |||
555 | strlcpy(info->type, "max6650", I2C_NAME_SIZE); | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | static int max6650_probe(struct i2c_client *client, | 526 | static int max6650_probe(struct i2c_client *client, |
561 | const struct i2c_device_id *id) | 527 | const struct i2c_device_id *id) |
562 | { | 528 | { |
@@ -570,6 +536,7 @@ static int max6650_probe(struct i2c_client *client, | |||
570 | 536 | ||
571 | i2c_set_clientdata(client, data); | 537 | i2c_set_clientdata(client, data); |
572 | mutex_init(&data->update_lock); | 538 | mutex_init(&data->update_lock); |
539 | data->nr_fans = id->driver_data; | ||
573 | 540 | ||
574 | /* | 541 | /* |
575 | * Initialize the max6650 chip | 542 | * Initialize the max6650 chip |
@@ -581,6 +548,12 @@ static int max6650_probe(struct i2c_client *client, | |||
581 | err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); | 548 | err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); |
582 | if (err) | 549 | if (err) |
583 | goto err_free; | 550 | goto err_free; |
551 | /* 3 additional fan inputs for the MAX6651 */ | ||
552 | if (data->nr_fans == 4) { | ||
553 | err = sysfs_create_group(&client->dev.kobj, &max6651_attr_grp); | ||
554 | if (err) | ||
555 | goto err_remove; | ||
556 | } | ||
584 | 557 | ||
585 | data->hwmon_dev = hwmon_device_register(&client->dev); | 558 | data->hwmon_dev = hwmon_device_register(&client->dev); |
586 | if (!IS_ERR(data->hwmon_dev)) | 559 | if (!IS_ERR(data->hwmon_dev)) |
@@ -588,6 +561,9 @@ static int max6650_probe(struct i2c_client *client, | |||
588 | 561 | ||
589 | err = PTR_ERR(data->hwmon_dev); | 562 | err = PTR_ERR(data->hwmon_dev); |
590 | dev_err(&client->dev, "error registering hwmon device.\n"); | 563 | dev_err(&client->dev, "error registering hwmon device.\n"); |
564 | if (data->nr_fans == 4) | ||
565 | sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp); | ||
566 | err_remove: | ||
591 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | 567 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); |
592 | err_free: | 568 | err_free: |
593 | kfree(data); | 569 | kfree(data); |
@@ -598,8 +574,10 @@ static int max6650_remove(struct i2c_client *client) | |||
598 | { | 574 | { |
599 | struct max6650_data *data = i2c_get_clientdata(client); | 575 | struct max6650_data *data = i2c_get_clientdata(client); |
600 | 576 | ||
601 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | ||
602 | hwmon_device_unregister(data->hwmon_dev); | 577 | hwmon_device_unregister(data->hwmon_dev); |
578 | if (data->nr_fans == 4) | ||
579 | sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp); | ||
580 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | ||
603 | kfree(data); | 581 | kfree(data); |
604 | return 0; | 582 | return 0; |
605 | } | 583 | } |
@@ -712,7 +690,7 @@ static struct max6650_data *max6650_update_device(struct device *dev) | |||
712 | MAX6650_REG_SPEED); | 690 | MAX6650_REG_SPEED); |
713 | data->config = i2c_smbus_read_byte_data(client, | 691 | data->config = i2c_smbus_read_byte_data(client, |
714 | MAX6650_REG_CONFIG); | 692 | MAX6650_REG_CONFIG); |
715 | for (i = 0; i < 4; i++) { | 693 | for (i = 0; i < data->nr_fans; i++) { |
716 | data->tach[i] = i2c_smbus_read_byte_data(client, | 694 | data->tach[i] = i2c_smbus_read_byte_data(client, |
717 | tach_reg[i]); | 695 | tach_reg[i]); |
718 | } | 696 | } |