diff options
author | Axel Lin <axel.lin@ingics.com> | 2014-06-28 22:32:36 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2014-08-04 10:01:35 -0400 |
commit | 28e6274d8fa67ecb468eaa219c45595384e3bda8 (patch) | |
tree | d04300d509080db44552bc0b5030ec9931459b43 | |
parent | 4fd5233f82278df58b523b20f1f21967fe7a6c29 (diff) |
hwmon: (amc6821) Avoid forward declaration
Reorder functions to avoid forward declaration.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/amc6821.c | 360 |
1 files changed, 154 insertions, 206 deletions
diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index 8a67ec6279a4..29c17fcc487b 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c | |||
@@ -21,7 +21,6 @@ | |||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | |||
25 | #include <linux/kernel.h> /* Needed for KERN_INFO */ | 24 | #include <linux/kernel.h> /* Needed for KERN_INFO */ |
26 | #include <linux/module.h> | 25 | #include <linux/module.h> |
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -33,7 +32,6 @@ | |||
33 | #include <linux/err.h> | 32 | #include <linux/err.h> |
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
35 | 34 | ||
36 | |||
37 | /* | 35 | /* |
38 | * Addresses to scan. | 36 | * Addresses to scan. |
39 | */ | 37 | */ |
@@ -41,8 +39,6 @@ | |||
41 | static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e, | 39 | static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e, |
42 | 0x4c, 0x4d, 0x4e, I2C_CLIENT_END}; | 40 | 0x4c, 0x4d, 0x4e, I2C_CLIENT_END}; |
43 | 41 | ||
44 | |||
45 | |||
46 | /* | 42 | /* |
47 | * Insmod parameters | 43 | * Insmod parameters |
48 | */ | 44 | */ |
@@ -53,7 +49,6 @@ module_param(pwminv, int, S_IRUGO); | |||
53 | static int init = 1; /*Power-on initialization.*/ | 49 | static int init = 1; /*Power-on initialization.*/ |
54 | module_param(init, int, S_IRUGO); | 50 | module_param(init, int, S_IRUGO); |
55 | 51 | ||
56 | |||
57 | enum chips { amc6821 }; | 52 | enum chips { amc6821 }; |
58 | 53 | ||
59 | #define AMC6821_REG_DEV_ID 0x3D | 54 | #define AMC6821_REG_DEV_ID 0x3D |
@@ -152,40 +147,6 @@ static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI, | |||
152 | AMC6821_REG_TACH_LLIMITH, | 147 | AMC6821_REG_TACH_LLIMITH, |
153 | AMC6821_REG_TACH_HLIMITH, }; | 148 | AMC6821_REG_TACH_HLIMITH, }; |
154 | 149 | ||
155 | static int amc6821_probe( | ||
156 | struct i2c_client *client, | ||
157 | const struct i2c_device_id *id); | ||
158 | static int amc6821_detect( | ||
159 | struct i2c_client *client, | ||
160 | struct i2c_board_info *info); | ||
161 | static int amc6821_init_client(struct i2c_client *client); | ||
162 | static int amc6821_remove(struct i2c_client *client); | ||
163 | static struct amc6821_data *amc6821_update_device(struct device *dev); | ||
164 | |||
165 | /* | ||
166 | * Driver data (common to all clients) | ||
167 | */ | ||
168 | |||
169 | static const struct i2c_device_id amc6821_id[] = { | ||
170 | { "amc6821", amc6821 }, | ||
171 | { } | ||
172 | }; | ||
173 | |||
174 | MODULE_DEVICE_TABLE(i2c, amc6821_id); | ||
175 | |||
176 | static struct i2c_driver amc6821_driver = { | ||
177 | .class = I2C_CLASS_HWMON, | ||
178 | .driver = { | ||
179 | .name = "amc6821", | ||
180 | }, | ||
181 | .probe = amc6821_probe, | ||
182 | .remove = amc6821_remove, | ||
183 | .id_table = amc6821_id, | ||
184 | .detect = amc6821_detect, | ||
185 | .address_list = normal_i2c, | ||
186 | }; | ||
187 | |||
188 | |||
189 | /* | 150 | /* |
190 | * Client data (each client gets its own) | 151 | * Client data (each client gets its own) |
191 | */ | 152 | */ |
@@ -213,6 +174,108 @@ struct amc6821_data { | |||
213 | u8 stat2; | 174 | u8 stat2; |
214 | }; | 175 | }; |
215 | 176 | ||
177 | static struct amc6821_data *amc6821_update_device(struct device *dev) | ||
178 | { | ||
179 | struct i2c_client *client = to_i2c_client(dev); | ||
180 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
181 | int timeout = HZ; | ||
182 | u8 reg; | ||
183 | int i; | ||
184 | |||
185 | mutex_lock(&data->update_lock); | ||
186 | |||
187 | if (time_after(jiffies, data->last_updated + timeout) || | ||
188 | !data->valid) { | ||
189 | |||
190 | for (i = 0; i < TEMP_IDX_LEN; i++) | ||
191 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
192 | temp_reg[i]); | ||
193 | |||
194 | data->stat1 = i2c_smbus_read_byte_data(client, | ||
195 | AMC6821_REG_STAT1); | ||
196 | data->stat2 = i2c_smbus_read_byte_data(client, | ||
197 | AMC6821_REG_STAT2); | ||
198 | |||
199 | data->pwm1 = i2c_smbus_read_byte_data(client, | ||
200 | AMC6821_REG_DCY); | ||
201 | for (i = 0; i < FAN1_IDX_LEN; i++) { | ||
202 | data->fan[i] = i2c_smbus_read_byte_data( | ||
203 | client, | ||
204 | fan_reg_low[i]); | ||
205 | data->fan[i] += i2c_smbus_read_byte_data( | ||
206 | client, | ||
207 | fan_reg_hi[i]) << 8; | ||
208 | } | ||
209 | data->fan1_div = i2c_smbus_read_byte_data(client, | ||
210 | AMC6821_REG_CONF4); | ||
211 | data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2; | ||
212 | |||
213 | data->pwm1_auto_point_pwm[0] = 0; | ||
214 | data->pwm1_auto_point_pwm[2] = 255; | ||
215 | data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client, | ||
216 | AMC6821_REG_DCY_LOW_TEMP); | ||
217 | |||
218 | data->temp1_auto_point_temp[0] = | ||
219 | i2c_smbus_read_byte_data(client, | ||
220 | AMC6821_REG_PSV_TEMP); | ||
221 | data->temp2_auto_point_temp[0] = | ||
222 | data->temp1_auto_point_temp[0]; | ||
223 | reg = i2c_smbus_read_byte_data(client, | ||
224 | AMC6821_REG_LTEMP_FAN_CTRL); | ||
225 | data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1; | ||
226 | reg &= 0x07; | ||
227 | reg = 0x20 >> reg; | ||
228 | if (reg > 0) | ||
229 | data->temp1_auto_point_temp[2] = | ||
230 | data->temp1_auto_point_temp[1] + | ||
231 | (data->pwm1_auto_point_pwm[2] - | ||
232 | data->pwm1_auto_point_pwm[1]) / reg; | ||
233 | else | ||
234 | data->temp1_auto_point_temp[2] = 255; | ||
235 | |||
236 | reg = i2c_smbus_read_byte_data(client, | ||
237 | AMC6821_REG_RTEMP_FAN_CTRL); | ||
238 | data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1; | ||
239 | reg &= 0x07; | ||
240 | reg = 0x20 >> reg; | ||
241 | if (reg > 0) | ||
242 | data->temp2_auto_point_temp[2] = | ||
243 | data->temp2_auto_point_temp[1] + | ||
244 | (data->pwm1_auto_point_pwm[2] - | ||
245 | data->pwm1_auto_point_pwm[1]) / reg; | ||
246 | else | ||
247 | data->temp2_auto_point_temp[2] = 255; | ||
248 | |||
249 | reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); | ||
250 | reg = (reg >> 5) & 0x3; | ||
251 | switch (reg) { | ||
252 | case 0: /*open loop: software sets pwm1*/ | ||
253 | data->pwm1_auto_channels_temp = 0; | ||
254 | data->pwm1_enable = 1; | ||
255 | break; | ||
256 | case 2: /*closed loop: remote T (temp2)*/ | ||
257 | data->pwm1_auto_channels_temp = 2; | ||
258 | data->pwm1_enable = 2; | ||
259 | break; | ||
260 | case 3: /*closed loop: local and remote T (temp2)*/ | ||
261 | data->pwm1_auto_channels_temp = 3; | ||
262 | data->pwm1_enable = 3; | ||
263 | break; | ||
264 | case 1: /* | ||
265 | * semi-open loop: software sets rpm, chip controls | ||
266 | * pwm1, currently not implemented | ||
267 | */ | ||
268 | data->pwm1_auto_channels_temp = 0; | ||
269 | data->pwm1_enable = 0; | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | data->last_updated = jiffies; | ||
274 | data->valid = 1; | ||
275 | } | ||
276 | mutex_unlock(&data->update_lock); | ||
277 | return data; | ||
278 | } | ||
216 | 279 | ||
217 | static ssize_t get_temp( | 280 | static ssize_t get_temp( |
218 | struct device *dev, | 281 | struct device *dev, |
@@ -225,8 +288,6 @@ static ssize_t get_temp( | |||
225 | return sprintf(buf, "%d\n", data->temp[ix] * 1000); | 288 | return sprintf(buf, "%d\n", data->temp[ix] * 1000); |
226 | } | 289 | } |
227 | 290 | ||
228 | |||
229 | |||
230 | static ssize_t set_temp( | 291 | static ssize_t set_temp( |
231 | struct device *dev, | 292 | struct device *dev, |
232 | struct device_attribute *attr, | 293 | struct device_attribute *attr, |
@@ -253,9 +314,6 @@ static ssize_t set_temp( | |||
253 | return count; | 314 | return count; |
254 | } | 315 | } |
255 | 316 | ||
256 | |||
257 | |||
258 | |||
259 | static ssize_t get_temp_alarm( | 317 | static ssize_t get_temp_alarm( |
260 | struct device *dev, | 318 | struct device *dev, |
261 | struct device_attribute *devattr, | 319 | struct device_attribute *devattr, |
@@ -294,9 +352,6 @@ static ssize_t get_temp_alarm( | |||
294 | return sprintf(buf, "0"); | 352 | return sprintf(buf, "0"); |
295 | } | 353 | } |
296 | 354 | ||
297 | |||
298 | |||
299 | |||
300 | static ssize_t get_temp2_fault( | 355 | static ssize_t get_temp2_fault( |
301 | struct device *dev, | 356 | struct device *dev, |
302 | struct device_attribute *devattr, | 357 | struct device_attribute *devattr, |
@@ -396,7 +451,6 @@ unlock: | |||
396 | return count; | 451 | return count; |
397 | } | 452 | } |
398 | 453 | ||
399 | |||
400 | static ssize_t get_pwm1_auto_channels_temp( | 454 | static ssize_t get_pwm1_auto_channels_temp( |
401 | struct device *dev, | 455 | struct device *dev, |
402 | struct device_attribute *devattr, | 456 | struct device_attribute *devattr, |
@@ -406,7 +460,6 @@ static ssize_t get_pwm1_auto_channels_temp( | |||
406 | return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp); | 460 | return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp); |
407 | } | 461 | } |
408 | 462 | ||
409 | |||
410 | static ssize_t get_temp_auto_point_temp( | 463 | static ssize_t get_temp_auto_point_temp( |
411 | struct device *dev, | 464 | struct device *dev, |
412 | struct device_attribute *devattr, | 465 | struct device_attribute *devattr, |
@@ -428,7 +481,6 @@ static ssize_t get_temp_auto_point_temp( | |||
428 | } | 481 | } |
429 | } | 482 | } |
430 | 483 | ||
431 | |||
432 | static ssize_t get_pwm1_auto_point_pwm( | 484 | static ssize_t get_pwm1_auto_point_pwm( |
433 | struct device *dev, | 485 | struct device *dev, |
434 | struct device_attribute *devattr, | 486 | struct device_attribute *devattr, |
@@ -439,7 +491,6 @@ static ssize_t get_pwm1_auto_point_pwm( | |||
439 | return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]); | 491 | return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]); |
440 | } | 492 | } |
441 | 493 | ||
442 | |||
443 | static inline ssize_t set_slope_register(struct i2c_client *client, | 494 | static inline ssize_t set_slope_register(struct i2c_client *client, |
444 | u8 reg, | 495 | u8 reg, |
445 | u8 dpwm, | 496 | u8 dpwm, |
@@ -462,8 +513,6 @@ static inline ssize_t set_slope_register(struct i2c_client *client, | |||
462 | return 0; | 513 | return 0; |
463 | } | 514 | } |
464 | 515 | ||
465 | |||
466 | |||
467 | static ssize_t set_temp_auto_point_temp( | 516 | static ssize_t set_temp_auto_point_temp( |
468 | struct device *dev, | 517 | struct device *dev, |
469 | struct device_attribute *attr, | 518 | struct device_attribute *attr, |
@@ -537,8 +586,6 @@ EXIT: | |||
537 | return count; | 586 | return count; |
538 | } | 587 | } |
539 | 588 | ||
540 | |||
541 | |||
542 | static ssize_t set_pwm1_auto_point_pwm( | 589 | static ssize_t set_pwm1_auto_point_pwm( |
543 | struct device *dev, | 590 | struct device *dev, |
544 | struct device_attribute *attr, | 591 | struct device_attribute *attr, |
@@ -591,8 +638,6 @@ static ssize_t get_fan( | |||
591 | return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix])); | 638 | return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix])); |
592 | } | 639 | } |
593 | 640 | ||
594 | |||
595 | |||
596 | static ssize_t get_fan1_fault( | 641 | static ssize_t get_fan1_fault( |
597 | struct device *dev, | 642 | struct device *dev, |
598 | struct device_attribute *devattr, | 643 | struct device_attribute *devattr, |
@@ -605,8 +650,6 @@ static ssize_t get_fan1_fault( | |||
605 | return sprintf(buf, "0"); | 650 | return sprintf(buf, "0"); |
606 | } | 651 | } |
607 | 652 | ||
608 | |||
609 | |||
610 | static ssize_t set_fan( | 653 | static ssize_t set_fan( |
611 | struct device *dev, | 654 | struct device *dev, |
612 | struct device_attribute *attr, | 655 | struct device_attribute *attr, |
@@ -639,8 +682,6 @@ EXIT: | |||
639 | return count; | 682 | return count; |
640 | } | 683 | } |
641 | 684 | ||
642 | |||
643 | |||
644 | static ssize_t get_fan1_div( | 685 | static ssize_t get_fan1_div( |
645 | struct device *dev, | 686 | struct device *dev, |
646 | struct device_attribute *devattr, | 687 | struct device_attribute *devattr, |
@@ -693,8 +734,6 @@ EXIT: | |||
693 | return count; | 734 | return count; |
694 | } | 735 | } |
695 | 736 | ||
696 | |||
697 | |||
698 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | 737 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, |
699 | get_temp, NULL, IDX_TEMP1_INPUT); | 738 | get_temp, NULL, IDX_TEMP1_INPUT); |
700 | static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp, | 739 | static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp, |
@@ -759,8 +798,6 @@ static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, | |||
759 | static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO, | 798 | static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO, |
760 | get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2); | 799 | get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2); |
761 | 800 | ||
762 | |||
763 | |||
764 | static struct attribute *amc6821_attrs[] = { | 801 | static struct attribute *amc6821_attrs[] = { |
765 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 802 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
766 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 803 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
@@ -801,8 +838,6 @@ static struct attribute_group amc6821_attr_grp = { | |||
801 | .attrs = amc6821_attrs, | 838 | .attrs = amc6821_attrs, |
802 | }; | 839 | }; |
803 | 840 | ||
804 | |||
805 | |||
806 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 841 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
807 | static int amc6821_detect( | 842 | static int amc6821_detect( |
808 | struct i2c_client *client, | 843 | struct i2c_client *client, |
@@ -849,53 +884,6 @@ static int amc6821_detect( | |||
849 | return 0; | 884 | return 0; |
850 | } | 885 | } |
851 | 886 | ||
852 | static int amc6821_probe( | ||
853 | struct i2c_client *client, | ||
854 | const struct i2c_device_id *id) | ||
855 | { | ||
856 | struct amc6821_data *data; | ||
857 | int err; | ||
858 | |||
859 | data = devm_kzalloc(&client->dev, sizeof(struct amc6821_data), | ||
860 | GFP_KERNEL); | ||
861 | if (!data) | ||
862 | return -ENOMEM; | ||
863 | |||
864 | i2c_set_clientdata(client, data); | ||
865 | mutex_init(&data->update_lock); | ||
866 | |||
867 | /* | ||
868 | * Initialize the amc6821 chip | ||
869 | */ | ||
870 | err = amc6821_init_client(client); | ||
871 | if (err) | ||
872 | return err; | ||
873 | |||
874 | err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp); | ||
875 | if (err) | ||
876 | return err; | ||
877 | |||
878 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
879 | if (!IS_ERR(data->hwmon_dev)) | ||
880 | return 0; | ||
881 | |||
882 | err = PTR_ERR(data->hwmon_dev); | ||
883 | dev_err(&client->dev, "error registering hwmon device.\n"); | ||
884 | sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); | ||
885 | return err; | ||
886 | } | ||
887 | |||
888 | static int amc6821_remove(struct i2c_client *client) | ||
889 | { | ||
890 | struct amc6821_data *data = i2c_get_clientdata(client); | ||
891 | |||
892 | hwmon_device_unregister(data->hwmon_dev); | ||
893 | sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); | ||
894 | |||
895 | return 0; | ||
896 | } | ||
897 | |||
898 | |||
899 | static int amc6821_init_client(struct i2c_client *client) | 887 | static int amc6821_init_client(struct i2c_client *client) |
900 | { | 888 | { |
901 | int config; | 889 | int config; |
@@ -982,110 +970,70 @@ static int amc6821_init_client(struct i2c_client *client) | |||
982 | return 0; | 970 | return 0; |
983 | } | 971 | } |
984 | 972 | ||
985 | 973 | static int amc6821_probe(struct i2c_client *client, | |
986 | static struct amc6821_data *amc6821_update_device(struct device *dev) | 974 | const struct i2c_device_id *id) |
987 | { | 975 | { |
988 | struct i2c_client *client = to_i2c_client(dev); | 976 | struct amc6821_data *data; |
989 | struct amc6821_data *data = i2c_get_clientdata(client); | 977 | int err; |
990 | int timeout = HZ; | ||
991 | u8 reg; | ||
992 | int i; | ||
993 | |||
994 | mutex_lock(&data->update_lock); | ||
995 | 978 | ||
996 | if (time_after(jiffies, data->last_updated + timeout) || | 979 | data = devm_kzalloc(&client->dev, sizeof(struct amc6821_data), |
997 | !data->valid) { | 980 | GFP_KERNEL); |
981 | if (!data) | ||
982 | return -ENOMEM; | ||
998 | 983 | ||
999 | for (i = 0; i < TEMP_IDX_LEN; i++) | 984 | i2c_set_clientdata(client, data); |
1000 | data->temp[i] = i2c_smbus_read_byte_data(client, | 985 | mutex_init(&data->update_lock); |
1001 | temp_reg[i]); | ||
1002 | 986 | ||
1003 | data->stat1 = i2c_smbus_read_byte_data(client, | 987 | /* |
1004 | AMC6821_REG_STAT1); | 988 | * Initialize the amc6821 chip |
1005 | data->stat2 = i2c_smbus_read_byte_data(client, | 989 | */ |
1006 | AMC6821_REG_STAT2); | 990 | err = amc6821_init_client(client); |
991 | if (err) | ||
992 | return err; | ||
1007 | 993 | ||
1008 | data->pwm1 = i2c_smbus_read_byte_data(client, | 994 | err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp); |
1009 | AMC6821_REG_DCY); | 995 | if (err) |
1010 | for (i = 0; i < FAN1_IDX_LEN; i++) { | 996 | return err; |
1011 | data->fan[i] = i2c_smbus_read_byte_data( | ||
1012 | client, | ||
1013 | fan_reg_low[i]); | ||
1014 | data->fan[i] += i2c_smbus_read_byte_data( | ||
1015 | client, | ||
1016 | fan_reg_hi[i]) << 8; | ||
1017 | } | ||
1018 | data->fan1_div = i2c_smbus_read_byte_data(client, | ||
1019 | AMC6821_REG_CONF4); | ||
1020 | data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2; | ||
1021 | 997 | ||
1022 | data->pwm1_auto_point_pwm[0] = 0; | 998 | data->hwmon_dev = hwmon_device_register(&client->dev); |
1023 | data->pwm1_auto_point_pwm[2] = 255; | 999 | if (!IS_ERR(data->hwmon_dev)) |
1024 | data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client, | 1000 | return 0; |
1025 | AMC6821_REG_DCY_LOW_TEMP); | ||
1026 | 1001 | ||
1027 | data->temp1_auto_point_temp[0] = | 1002 | err = PTR_ERR(data->hwmon_dev); |
1028 | i2c_smbus_read_byte_data(client, | 1003 | dev_err(&client->dev, "error registering hwmon device.\n"); |
1029 | AMC6821_REG_PSV_TEMP); | 1004 | sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); |
1030 | data->temp2_auto_point_temp[0] = | 1005 | return err; |
1031 | data->temp1_auto_point_temp[0]; | 1006 | } |
1032 | reg = i2c_smbus_read_byte_data(client, | ||
1033 | AMC6821_REG_LTEMP_FAN_CTRL); | ||
1034 | data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1; | ||
1035 | reg &= 0x07; | ||
1036 | reg = 0x20 >> reg; | ||
1037 | if (reg > 0) | ||
1038 | data->temp1_auto_point_temp[2] = | ||
1039 | data->temp1_auto_point_temp[1] + | ||
1040 | (data->pwm1_auto_point_pwm[2] - | ||
1041 | data->pwm1_auto_point_pwm[1]) / reg; | ||
1042 | else | ||
1043 | data->temp1_auto_point_temp[2] = 255; | ||
1044 | 1007 | ||
1045 | reg = i2c_smbus_read_byte_data(client, | 1008 | static int amc6821_remove(struct i2c_client *client) |
1046 | AMC6821_REG_RTEMP_FAN_CTRL); | 1009 | { |
1047 | data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1; | 1010 | struct amc6821_data *data = i2c_get_clientdata(client); |
1048 | reg &= 0x07; | ||
1049 | reg = 0x20 >> reg; | ||
1050 | if (reg > 0) | ||
1051 | data->temp2_auto_point_temp[2] = | ||
1052 | data->temp2_auto_point_temp[1] + | ||
1053 | (data->pwm1_auto_point_pwm[2] - | ||
1054 | data->pwm1_auto_point_pwm[1]) / reg; | ||
1055 | else | ||
1056 | data->temp2_auto_point_temp[2] = 255; | ||
1057 | 1011 | ||
1058 | reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); | 1012 | hwmon_device_unregister(data->hwmon_dev); |
1059 | reg = (reg >> 5) & 0x3; | 1013 | sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp); |
1060 | switch (reg) { | ||
1061 | case 0: /*open loop: software sets pwm1*/ | ||
1062 | data->pwm1_auto_channels_temp = 0; | ||
1063 | data->pwm1_enable = 1; | ||
1064 | break; | ||
1065 | case 2: /*closed loop: remote T (temp2)*/ | ||
1066 | data->pwm1_auto_channels_temp = 2; | ||
1067 | data->pwm1_enable = 2; | ||
1068 | break; | ||
1069 | case 3: /*closed loop: local and remote T (temp2)*/ | ||
1070 | data->pwm1_auto_channels_temp = 3; | ||
1071 | data->pwm1_enable = 3; | ||
1072 | break; | ||
1073 | case 1: /* | ||
1074 | * semi-open loop: software sets rpm, chip controls | ||
1075 | * pwm1, currently not implemented | ||
1076 | */ | ||
1077 | data->pwm1_auto_channels_temp = 0; | ||
1078 | data->pwm1_enable = 0; | ||
1079 | break; | ||
1080 | } | ||
1081 | 1014 | ||
1082 | data->last_updated = jiffies; | 1015 | return 0; |
1083 | data->valid = 1; | ||
1084 | } | ||
1085 | mutex_unlock(&data->update_lock); | ||
1086 | return data; | ||
1087 | } | 1016 | } |
1088 | 1017 | ||
1018 | static const struct i2c_device_id amc6821_id[] = { | ||
1019 | { "amc6821", amc6821 }, | ||
1020 | { } | ||
1021 | }; | ||
1022 | |||
1023 | MODULE_DEVICE_TABLE(i2c, amc6821_id); | ||
1024 | |||
1025 | static struct i2c_driver amc6821_driver = { | ||
1026 | .class = I2C_CLASS_HWMON, | ||
1027 | .driver = { | ||
1028 | .name = "amc6821", | ||
1029 | }, | ||
1030 | .probe = amc6821_probe, | ||
1031 | .remove = amc6821_remove, | ||
1032 | .id_table = amc6821_id, | ||
1033 | .detect = amc6821_detect, | ||
1034 | .address_list = normal_i2c, | ||
1035 | }; | ||
1036 | |||
1089 | module_i2c_driver(amc6821_driver); | 1037 | module_i2c_driver(amc6821_driver); |
1090 | 1038 | ||
1091 | MODULE_LICENSE("GPL"); | 1039 | MODULE_LICENSE("GPL"); |