diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hwmon/w83793.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/w83793.c')
-rw-r--r-- | drivers/hwmon/w83793.c | 483 |
1 files changed, 222 insertions, 261 deletions
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 99799fd1d91..854f9117f1a 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c | |||
@@ -1,34 +1,34 @@ | |||
1 | /* | 1 | /* |
2 | * w83793.c - Linux kernel driver for hardware monitoring | 2 | w83793.c - Linux kernel driver for hardware monitoring |
3 | * Copyright (C) 2006 Winbond Electronics Corp. | 3 | Copyright (C) 2006 Winbond Electronics Corp. |
4 | * Yuan Mu | 4 | Yuan Mu |
5 | * Rudolf Marek <r.marek@assembler.cz> | 5 | Rudolf Marek <r.marek@assembler.cz> |
6 | * Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG. | 6 | Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG. |
7 | * Watchdog driver part | 7 | Watchdog driver part |
8 | * (Based partially on fschmd driver, | 8 | (Based partially on fschmd driver, |
9 | * Copyright 2007-2008 by Hans de Goede) | 9 | Copyright 2007-2008 by Hans de Goede) |
10 | * | 10 | |
11 | * This program is free software; you can redistribute it and/or modify | 11 | This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 12 | it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation - version 2. | 13 | the Free Software Foundation - version 2. |
14 | * | 14 | |
15 | * This program is distributed in the hope that it will be useful, | 15 | This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | GNU General Public License for more details. |
19 | * | 19 | |
20 | * You should have received a copy of the GNU General Public License | 20 | You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 22 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
23 | * 02110-1301 USA. | 23 | 02110-1301 USA. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Supports following chips: | 27 | Supports following chips: |
28 | * | 28 | |
29 | * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | 29 | Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA |
30 | * w83793 10 12 8 6 0x7b 0x5ca3 yes no | 30 | w83793 10 12 8 6 0x7b 0x5ca3 yes no |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/kref.h> | 46 | #include <linux/kref.h> |
47 | #include <linux/notifier.h> | 47 | #include <linux/notifier.h> |
48 | #include <linux/reboot.h> | 48 | #include <linux/reboot.h> |
49 | #include <linux/jiffies.h> | ||
50 | 49 | ||
51 | /* Default values */ | 50 | /* Default values */ |
52 | #define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */ | 51 | #define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */ |
@@ -62,7 +61,7 @@ module_param_array(force_subclients, short, NULL, 0); | |||
62 | MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " | 61 | MODULE_PARM_DESC(force_subclients, "List of subclient addresses: " |
63 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 62 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); |
64 | 63 | ||
65 | static bool reset; | 64 | static int reset; |
66 | module_param(reset, bool, 0); | 65 | module_param(reset, bool, 0); |
67 | MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); | 66 | MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); |
68 | 67 | ||
@@ -72,16 +71,16 @@ MODULE_PARM_DESC(timeout, | |||
72 | "Watchdog timeout in minutes. 2<= timeout <=255 (default=" | 71 | "Watchdog timeout in minutes. 2<= timeout <=255 (default=" |
73 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); | 72 | __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); |
74 | 73 | ||
75 | static bool nowayout = WATCHDOG_NOWAYOUT; | 74 | static int nowayout = WATCHDOG_NOWAYOUT; |
76 | module_param(nowayout, bool, 0); | 75 | module_param(nowayout, int, 0); |
77 | MODULE_PARM_DESC(nowayout, | 76 | MODULE_PARM_DESC(nowayout, |
78 | "Watchdog cannot be stopped once started (default=" | 77 | "Watchdog cannot be stopped once started (default=" |
79 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 78 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
80 | 79 | ||
81 | /* | 80 | /* |
82 | * Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved | 81 | Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved |
83 | * as ID, Bank Select registers | 82 | as ID, Bank Select registers |
84 | */ | 83 | */ |
85 | #define W83793_REG_BANKSEL 0x00 | 84 | #define W83793_REG_BANKSEL 0x00 |
86 | #define W83793_REG_VENDORID 0x0d | 85 | #define W83793_REG_VENDORID 0x0d |
87 | #define W83793_REG_CHIPID 0x0e | 86 | #define W83793_REG_CHIPID 0x0e |
@@ -111,10 +110,8 @@ static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f }; | |||
111 | #define TEMP_CRIT_HYST 2 | 110 | #define TEMP_CRIT_HYST 2 |
112 | #define TEMP_WARN 3 | 111 | #define TEMP_WARN 3 |
113 | #define TEMP_WARN_HYST 4 | 112 | #define TEMP_WARN_HYST 4 |
114 | /* | 113 | /* only crit and crit_hyst affect real-time alarm status |
115 | * only crit and crit_hyst affect real-time alarm status | 114 | current crit crit_hyst warn warn_hyst */ |
116 | * current crit crit_hyst warn warn_hyst | ||
117 | */ | ||
118 | static u16 W83793_REG_TEMP[][5] = { | 115 | static u16 W83793_REG_TEMP[][5] = { |
119 | {0x1c, 0x78, 0x79, 0x7a, 0x7b}, | 116 | {0x1c, 0x78, 0x79, 0x7a, 0x7b}, |
120 | {0x1d, 0x7c, 0x7d, 0x7e, 0x7f}, | 117 | {0x1d, 0x7c, 0x7d, 0x7e, 0x7f}, |
@@ -184,7 +181,7 @@ static inline unsigned long FAN_FROM_REG(u16 val) | |||
184 | { | 181 | { |
185 | if ((val >= 0xfff) || (val == 0)) | 182 | if ((val >= 0xfff) || (val == 0)) |
186 | return 0; | 183 | return 0; |
187 | return 1350000UL / val; | 184 | return (1350000UL / val); |
188 | } | 185 | } |
189 | 186 | ||
190 | static inline u16 FAN_TO_REG(long rpm) | 187 | static inline u16 FAN_TO_REG(long rpm) |
@@ -196,7 +193,7 @@ static inline u16 FAN_TO_REG(long rpm) | |||
196 | 193 | ||
197 | static inline unsigned long TIME_FROM_REG(u8 reg) | 194 | static inline unsigned long TIME_FROM_REG(u8 reg) |
198 | { | 195 | { |
199 | return reg * 100; | 196 | return (reg * 100); |
200 | } | 197 | } |
201 | 198 | ||
202 | static inline u8 TIME_TO_REG(unsigned long val) | 199 | static inline u8 TIME_TO_REG(unsigned long val) |
@@ -206,7 +203,7 @@ static inline u8 TIME_TO_REG(unsigned long val) | |||
206 | 203 | ||
207 | static inline long TEMP_FROM_REG(s8 reg) | 204 | static inline long TEMP_FROM_REG(s8 reg) |
208 | { | 205 | { |
209 | return reg * 1000; | 206 | return (reg * 1000); |
210 | } | 207 | } |
211 | 208 | ||
212 | static inline s8 TEMP_TO_REG(long val, s8 min, s8 max) | 209 | static inline s8 TEMP_TO_REG(long val, s8 min, s8 max) |
@@ -221,8 +218,7 @@ struct w83793_data { | |||
221 | char valid; /* !=0 if following fields are valid */ | 218 | char valid; /* !=0 if following fields are valid */ |
222 | unsigned long last_updated; /* In jiffies */ | 219 | unsigned long last_updated; /* In jiffies */ |
223 | unsigned long last_nonvolatile; /* In jiffies, last time we update the | 220 | unsigned long last_nonvolatile; /* In jiffies, last time we update the |
224 | * nonvolatile registers | 221 | nonvolatile registers */ |
225 | */ | ||
226 | 222 | ||
227 | u8 bank; | 223 | u8 bank; |
228 | u8 vrm; | 224 | u8 vrm; |
@@ -237,8 +233,7 @@ struct w83793_data { | |||
237 | s8 temp[6][5]; /* current, crit, crit_hyst,warn, warn_hyst */ | 233 | s8 temp[6][5]; /* current, crit, crit_hyst,warn, warn_hyst */ |
238 | u8 temp_low_bits; /* Additional resolution TD1-TD4 */ | 234 | u8 temp_low_bits; /* Additional resolution TD1-TD4 */ |
239 | u8 temp_mode[2]; /* byte 0: Temp D1-D4 mode each has 2 bits | 235 | u8 temp_mode[2]; /* byte 0: Temp D1-D4 mode each has 2 bits |
240 | * byte 1: Temp R1,R2 mode, each has 1 bit | 236 | byte 1: Temp R1,R2 mode, each has 1 bit */ |
241 | */ | ||
242 | u8 temp_critical; /* If reached all fan will be at full speed */ | 237 | u8 temp_critical; /* If reached all fan will be at full speed */ |
243 | u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ | 238 | u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ |
244 | 239 | ||
@@ -273,21 +268,17 @@ struct w83793_data { | |||
273 | int watchdog_timeout; /* watchdog timeout in minutes */ | 268 | int watchdog_timeout; /* watchdog timeout in minutes */ |
274 | }; | 269 | }; |
275 | 270 | ||
276 | /* | 271 | /* Somewhat ugly :( global data pointer list with all devices, so that |
277 | * Somewhat ugly :( global data pointer list with all devices, so that | 272 | we can find our device data as when using misc_register. There is no |
278 | * we can find our device data as when using misc_register. There is no | 273 | other method to get to one's device data from the open file-op and |
279 | * other method to get to one's device data from the open file-op and | 274 | for usage in the reboot notifier callback. */ |
280 | * for usage in the reboot notifier callback. | ||
281 | */ | ||
282 | static LIST_HEAD(watchdog_data_list); | 275 | static LIST_HEAD(watchdog_data_list); |
283 | 276 | ||
284 | /* Note this lock not only protect list access, but also data.kref access */ | 277 | /* Note this lock not only protect list access, but also data.kref access */ |
285 | static DEFINE_MUTEX(watchdog_data_mutex); | 278 | static DEFINE_MUTEX(watchdog_data_mutex); |
286 | 279 | ||
287 | /* | 280 | /* Release our data struct when we're detached from the i2c client *and* all |
288 | * Release our data struct when we're detached from the i2c client *and* all | 281 | references to our watchdog device are released */ |
289 | * references to our watchdog device are released | ||
290 | */ | ||
291 | static void w83793_release_resources(struct kref *ref) | 282 | static void w83793_release_resources(struct kref *ref) |
292 | { | 283 | { |
293 | struct w83793_data *data = container_of(ref, struct w83793_data, kref); | 284 | struct w83793_data *data = container_of(ref, struct w83793_data, kref); |
@@ -346,14 +337,7 @@ store_vrm(struct device *dev, struct device_attribute *attr, | |||
346 | const char *buf, size_t count) | 337 | const char *buf, size_t count) |
347 | { | 338 | { |
348 | struct w83793_data *data = dev_get_drvdata(dev); | 339 | struct w83793_data *data = dev_get_drvdata(dev); |
349 | unsigned long val; | 340 | data->vrm = simple_strtoul(buf, NULL, 10); |
350 | int err; | ||
351 | |||
352 | err = kstrtoul(buf, 10, &val); | ||
353 | if (err) | ||
354 | return err; | ||
355 | |||
356 | data->vrm = val; | ||
357 | return count; | 341 | return count; |
358 | } | 342 | } |
359 | 343 | ||
@@ -370,7 +354,7 @@ show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf) | |||
370 | int bit = sensor_attr->index & 0x07; | 354 | int bit = sensor_attr->index & 0x07; |
371 | u8 val; | 355 | u8 val; |
372 | 356 | ||
373 | if (nr == ALARM_STATUS) { | 357 | if (ALARM_STATUS == nr) { |
374 | val = (data->alarms[index] >> (bit)) & 1; | 358 | val = (data->alarms[index] >> (bit)) & 1; |
375 | } else { /* BEEP_ENABLE */ | 359 | } else { /* BEEP_ENABLE */ |
376 | val = (data->beeps[index] >> (bit)) & 1; | 360 | val = (data->beeps[index] >> (bit)) & 1; |
@@ -390,14 +374,10 @@ store_beep(struct device *dev, struct device_attribute *attr, | |||
390 | int index = sensor_attr->index >> 3; | 374 | int index = sensor_attr->index >> 3; |
391 | int shift = sensor_attr->index & 0x07; | 375 | int shift = sensor_attr->index & 0x07; |
392 | u8 beep_bit = 1 << shift; | 376 | u8 beep_bit = 1 << shift; |
393 | unsigned long val; | 377 | u8 val; |
394 | int err; | ||
395 | |||
396 | err = kstrtoul(buf, 10, &val); | ||
397 | if (err) | ||
398 | return err; | ||
399 | 378 | ||
400 | if (val > 1) | 379 | val = simple_strtoul(buf, NULL, 10); |
380 | if (val != 0 && val != 1) | ||
401 | return -EINVAL; | 381 | return -EINVAL; |
402 | 382 | ||
403 | mutex_lock(&data->update_lock); | 383 | mutex_lock(&data->update_lock); |
@@ -423,14 +403,9 @@ store_beep_enable(struct device *dev, struct device_attribute *attr, | |||
423 | { | 403 | { |
424 | struct i2c_client *client = to_i2c_client(dev); | 404 | struct i2c_client *client = to_i2c_client(dev); |
425 | struct w83793_data *data = i2c_get_clientdata(client); | 405 | struct w83793_data *data = i2c_get_clientdata(client); |
426 | unsigned long val; | 406 | u8 val = simple_strtoul(buf, NULL, 10); |
427 | int err; | ||
428 | 407 | ||
429 | err = kstrtoul(buf, 10, &val); | 408 | if (val != 0 && val != 1) |
430 | if (err) | ||
431 | return err; | ||
432 | |||
433 | if (val > 1) | ||
434 | return -EINVAL; | 409 | return -EINVAL; |
435 | 410 | ||
436 | mutex_lock(&data->update_lock); | 411 | mutex_lock(&data->update_lock); |
@@ -443,6 +418,27 @@ store_beep_enable(struct device *dev, struct device_attribute *attr, | |||
443 | return count; | 418 | return count; |
444 | } | 419 | } |
445 | 420 | ||
421 | /* Write any value to clear chassis alarm */ | ||
422 | static ssize_t | ||
423 | store_chassis_clear_legacy(struct device *dev, | ||
424 | struct device_attribute *attr, const char *buf, | ||
425 | size_t count) | ||
426 | { | ||
427 | struct i2c_client *client = to_i2c_client(dev); | ||
428 | struct w83793_data *data = i2c_get_clientdata(client); | ||
429 | u8 val; | ||
430 | |||
431 | dev_warn(dev, "Attribute chassis is deprecated, " | ||
432 | "use intrusion0_alarm instead\n"); | ||
433 | |||
434 | mutex_lock(&data->update_lock); | ||
435 | val = w83793_read_value(client, W83793_REG_CLR_CHASSIS); | ||
436 | val |= 0x80; | ||
437 | w83793_write_value(client, W83793_REG_CLR_CHASSIS, val); | ||
438 | mutex_unlock(&data->update_lock); | ||
439 | return count; | ||
440 | } | ||
441 | |||
446 | /* Write 0 to clear chassis alarm */ | 442 | /* Write 0 to clear chassis alarm */ |
447 | static ssize_t | 443 | static ssize_t |
448 | store_chassis_clear(struct device *dev, | 444 | store_chassis_clear(struct device *dev, |
@@ -453,12 +449,8 @@ store_chassis_clear(struct device *dev, | |||
453 | struct w83793_data *data = i2c_get_clientdata(client); | 449 | struct w83793_data *data = i2c_get_clientdata(client); |
454 | unsigned long val; | 450 | unsigned long val; |
455 | u8 reg; | 451 | u8 reg; |
456 | int err; | ||
457 | 452 | ||
458 | err = kstrtoul(buf, 10, &val); | 453 | if (strict_strtoul(buf, 10, &val) || val != 0) |
459 | if (err) | ||
460 | return err; | ||
461 | if (val) | ||
462 | return -EINVAL; | 454 | return -EINVAL; |
463 | 455 | ||
464 | mutex_lock(&data->update_lock); | 456 | mutex_lock(&data->update_lock); |
@@ -481,10 +473,11 @@ show_fan(struct device *dev, struct device_attribute *attr, char *buf) | |||
481 | struct w83793_data *data = w83793_update_device(dev); | 473 | struct w83793_data *data = w83793_update_device(dev); |
482 | u16 val; | 474 | u16 val; |
483 | 475 | ||
484 | if (nr == FAN_INPUT) | 476 | if (FAN_INPUT == nr) { |
485 | val = data->fan[index] & 0x0fff; | 477 | val = data->fan[index] & 0x0fff; |
486 | else | 478 | } else { |
487 | val = data->fan_min[index] & 0x0fff; | 479 | val = data->fan_min[index] & 0x0fff; |
480 | } | ||
488 | 481 | ||
489 | return sprintf(buf, "%lu\n", FAN_FROM_REG(val)); | 482 | return sprintf(buf, "%lu\n", FAN_FROM_REG(val)); |
490 | } | 483 | } |
@@ -498,13 +491,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
498 | int index = sensor_attr->index; | 491 | int index = sensor_attr->index; |
499 | struct i2c_client *client = to_i2c_client(dev); | 492 | struct i2c_client *client = to_i2c_client(dev); |
500 | struct w83793_data *data = i2c_get_clientdata(client); | 493 | struct w83793_data *data = i2c_get_clientdata(client); |
501 | unsigned long val; | 494 | u16 val = FAN_TO_REG(simple_strtoul(buf, NULL, 10)); |
502 | int err; | ||
503 | |||
504 | err = kstrtoul(buf, 10, &val); | ||
505 | if (err) | ||
506 | return err; | ||
507 | val = FAN_TO_REG(val); | ||
508 | 495 | ||
509 | mutex_lock(&data->update_lock); | 496 | mutex_lock(&data->update_lock); |
510 | data->fan_min[index] = val; | 497 | data->fan_min[index] = val; |
@@ -526,7 +513,7 @@ show_pwm(struct device *dev, struct device_attribute *attr, char *buf) | |||
526 | int nr = sensor_attr->nr; | 513 | int nr = sensor_attr->nr; |
527 | int index = sensor_attr->index; | 514 | int index = sensor_attr->index; |
528 | 515 | ||
529 | if (nr == PWM_STOP_TIME) | 516 | if (PWM_STOP_TIME == nr) |
530 | val = TIME_FROM_REG(data->pwm_stop_time[index]); | 517 | val = TIME_FROM_REG(data->pwm_stop_time[index]); |
531 | else | 518 | else |
532 | val = (data->pwm[index][nr] & 0x3f) << 2; | 519 | val = (data->pwm[index][nr] & 0x3f) << 2; |
@@ -544,21 +531,17 @@ store_pwm(struct device *dev, struct device_attribute *attr, | |||
544 | to_sensor_dev_attr_2(attr); | 531 | to_sensor_dev_attr_2(attr); |
545 | int nr = sensor_attr->nr; | 532 | int nr = sensor_attr->nr; |
546 | int index = sensor_attr->index; | 533 | int index = sensor_attr->index; |
547 | unsigned long val; | 534 | u8 val; |
548 | int err; | ||
549 | |||
550 | err = kstrtoul(buf, 10, &val); | ||
551 | if (err) | ||
552 | return err; | ||
553 | 535 | ||
554 | mutex_lock(&data->update_lock); | 536 | mutex_lock(&data->update_lock); |
555 | if (nr == PWM_STOP_TIME) { | 537 | if (PWM_STOP_TIME == nr) { |
556 | val = TIME_TO_REG(val); | 538 | val = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); |
557 | data->pwm_stop_time[index] = val; | 539 | data->pwm_stop_time[index] = val; |
558 | w83793_write_value(client, W83793_REG_PWM_STOP_TIME(index), | 540 | w83793_write_value(client, W83793_REG_PWM_STOP_TIME(index), |
559 | val); | 541 | val); |
560 | } else { | 542 | } else { |
561 | val = SENSORS_LIMIT(val, 0, 0xff) >> 2; | 543 | val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) |
544 | >> 2; | ||
562 | data->pwm[index][nr] = | 545 | data->pwm[index][nr] = |
563 | w83793_read_value(client, W83793_REG_PWM(index, nr)) & 0xc0; | 546 | w83793_read_value(client, W83793_REG_PWM(index, nr)) & 0xc0; |
564 | data->pwm[index][nr] |= val; | 547 | data->pwm[index][nr] |= val; |
@@ -580,7 +563,7 @@ show_temp(struct device *dev, struct device_attribute *attr, char *buf) | |||
580 | struct w83793_data *data = w83793_update_device(dev); | 563 | struct w83793_data *data = w83793_update_device(dev); |
581 | long temp = TEMP_FROM_REG(data->temp[index][nr]); | 564 | long temp = TEMP_FROM_REG(data->temp[index][nr]); |
582 | 565 | ||
583 | if (nr == TEMP_READ && index < 4) { /* Only TD1-TD4 have low bits */ | 566 | if (TEMP_READ == nr && index < 4) { /* Only TD1-TD4 have low bits */ |
584 | int low = ((data->temp_low_bits >> (index * 2)) & 0x03) * 250; | 567 | int low = ((data->temp_low_bits >> (index * 2)) & 0x03) * 250; |
585 | temp += temp > 0 ? low : -low; | 568 | temp += temp > 0 ? low : -low; |
586 | } | 569 | } |
@@ -597,12 +580,7 @@ store_temp(struct device *dev, struct device_attribute *attr, | |||
597 | int index = sensor_attr->index; | 580 | int index = sensor_attr->index; |
598 | struct i2c_client *client = to_i2c_client(dev); | 581 | struct i2c_client *client = to_i2c_client(dev); |
599 | struct w83793_data *data = i2c_get_clientdata(client); | 582 | struct w83793_data *data = i2c_get_clientdata(client); |
600 | long tmp; | 583 | long tmp = simple_strtol(buf, NULL, 10); |
601 | int err; | ||
602 | |||
603 | err = kstrtol(buf, 10, &tmp); | ||
604 | if (err) | ||
605 | return err; | ||
606 | 584 | ||
607 | mutex_lock(&data->update_lock); | 585 | mutex_lock(&data->update_lock); |
608 | data->temp[index][nr] = TEMP_TO_REG(tmp, -128, 127); | 586 | data->temp[index][nr] = TEMP_TO_REG(tmp, -128, 127); |
@@ -613,18 +591,18 @@ store_temp(struct device *dev, struct device_attribute *attr, | |||
613 | } | 591 | } |
614 | 592 | ||
615 | /* | 593 | /* |
616 | * TD1-TD4 | 594 | TD1-TD4 |
617 | * each has 4 mode:(2 bits) | 595 | each has 4 mode:(2 bits) |
618 | * 0: Stop monitor | 596 | 0: Stop monitor |
619 | * 1: Use internal temp sensor(default) | 597 | 1: Use internal temp sensor(default) |
620 | * 2: Reserved | 598 | 2: Reserved |
621 | * 3: Use sensor in Intel CPU and get result by PECI | 599 | 3: Use sensor in Intel CPU and get result by PECI |
622 | * | 600 | |
623 | * TR1-TR2 | 601 | TR1-TR2 |
624 | * each has 2 mode:(1 bit) | 602 | each has 2 mode:(1 bit) |
625 | * 0: Disable temp sensor monitor | 603 | 0: Disable temp sensor monitor |
626 | * 1: To enable temp sensors monitor | 604 | 1: To enable temp sensors monitor |
627 | */ | 605 | */ |
628 | 606 | ||
629 | /* 0 disable, 6 PECI */ | 607 | /* 0 disable, 6 PECI */ |
630 | static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 }; | 608 | static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 }; |
@@ -644,10 +622,11 @@ show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) | |||
644 | tmp = (data->temp_mode[index] >> shift) & mask; | 622 | tmp = (data->temp_mode[index] >> shift) & mask; |
645 | 623 | ||
646 | /* for the internal sensor, found out if diode or thermistor */ | 624 | /* for the internal sensor, found out if diode or thermistor */ |
647 | if (tmp == 1) | 625 | if (tmp == 1) { |
648 | tmp = index == 0 ? 3 : 4; | 626 | tmp = index == 0 ? 3 : 4; |
649 | else | 627 | } else { |
650 | tmp = TO_TEMP_MODE[tmp]; | 628 | tmp = TO_TEMP_MODE[tmp]; |
629 | } | ||
651 | 630 | ||
652 | return sprintf(buf, "%d\n", tmp); | 631 | return sprintf(buf, "%d\n", tmp); |
653 | } | 632 | } |
@@ -663,12 +642,7 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, | |||
663 | int index = sensor_attr->index; | 642 | int index = sensor_attr->index; |
664 | u8 mask = (index < 4) ? 0x03 : 0x01; | 643 | u8 mask = (index < 4) ? 0x03 : 0x01; |
665 | u8 shift = (index < 4) ? (2 * index) : (index - 4); | 644 | u8 shift = (index < 4) ? (2 * index) : (index - 4); |
666 | unsigned long val; | 645 | u8 val = simple_strtoul(buf, NULL, 10); |
667 | int err; | ||
668 | |||
669 | err = kstrtoul(buf, 10, &val); | ||
670 | if (err) | ||
671 | return err; | ||
672 | 646 | ||
673 | /* transform the sysfs interface values into table above */ | 647 | /* transform the sysfs interface values into table above */ |
674 | if ((val == 6) && (index < 4)) { | 648 | if ((val == 6) && (index < 4)) { |
@@ -707,14 +681,15 @@ show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf) | |||
707 | struct w83793_data *data = w83793_update_device(dev); | 681 | struct w83793_data *data = w83793_update_device(dev); |
708 | u32 val = 0; | 682 | u32 val = 0; |
709 | 683 | ||
710 | if (nr == SETUP_PWM_DEFAULT) | 684 | if (SETUP_PWM_DEFAULT == nr) { |
711 | val = (data->pwm_default & 0x3f) << 2; | 685 | val = (data->pwm_default & 0x3f) << 2; |
712 | else if (nr == SETUP_PWM_UPTIME) | 686 | } else if (SETUP_PWM_UPTIME == nr) { |
713 | val = TIME_FROM_REG(data->pwm_uptime); | 687 | val = TIME_FROM_REG(data->pwm_uptime); |
714 | else if (nr == SETUP_PWM_DOWNTIME) | 688 | } else if (SETUP_PWM_DOWNTIME == nr) { |
715 | val = TIME_FROM_REG(data->pwm_downtime); | 689 | val = TIME_FROM_REG(data->pwm_downtime); |
716 | else if (nr == SETUP_TEMP_CRITICAL) | 690 | } else if (SETUP_TEMP_CRITICAL == nr) { |
717 | val = TEMP_FROM_REG(data->temp_critical & 0x7f); | 691 | val = TEMP_FROM_REG(data->temp_critical & 0x7f); |
692 | } | ||
718 | 693 | ||
719 | return sprintf(buf, "%d\n", val); | 694 | return sprintf(buf, "%d\n", val); |
720 | } | 695 | } |
@@ -728,34 +703,31 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
728 | int nr = sensor_attr->nr; | 703 | int nr = sensor_attr->nr; |
729 | struct i2c_client *client = to_i2c_client(dev); | 704 | struct i2c_client *client = to_i2c_client(dev); |
730 | struct w83793_data *data = i2c_get_clientdata(client); | 705 | struct w83793_data *data = i2c_get_clientdata(client); |
731 | long val; | ||
732 | int err; | ||
733 | |||
734 | err = kstrtol(buf, 10, &val); | ||
735 | if (err) | ||
736 | return err; | ||
737 | 706 | ||
738 | mutex_lock(&data->update_lock); | 707 | mutex_lock(&data->update_lock); |
739 | if (nr == SETUP_PWM_DEFAULT) { | 708 | if (SETUP_PWM_DEFAULT == nr) { |
740 | data->pwm_default = | 709 | data->pwm_default = |
741 | w83793_read_value(client, W83793_REG_PWM_DEFAULT) & 0xc0; | 710 | w83793_read_value(client, W83793_REG_PWM_DEFAULT) & 0xc0; |
742 | data->pwm_default |= SENSORS_LIMIT(val, 0, 0xff) >> 2; | 711 | data->pwm_default |= SENSORS_LIMIT(simple_strtoul(buf, NULL, |
712 | 10), | ||
713 | 0, 0xff) >> 2; | ||
743 | w83793_write_value(client, W83793_REG_PWM_DEFAULT, | 714 | w83793_write_value(client, W83793_REG_PWM_DEFAULT, |
744 | data->pwm_default); | 715 | data->pwm_default); |
745 | } else if (nr == SETUP_PWM_UPTIME) { | 716 | } else if (SETUP_PWM_UPTIME == nr) { |
746 | data->pwm_uptime = TIME_TO_REG(val); | 717 | data->pwm_uptime = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); |
747 | data->pwm_uptime += data->pwm_uptime == 0 ? 1 : 0; | 718 | data->pwm_uptime += data->pwm_uptime == 0 ? 1 : 0; |
748 | w83793_write_value(client, W83793_REG_PWM_UPTIME, | 719 | w83793_write_value(client, W83793_REG_PWM_UPTIME, |
749 | data->pwm_uptime); | 720 | data->pwm_uptime); |
750 | } else if (nr == SETUP_PWM_DOWNTIME) { | 721 | } else if (SETUP_PWM_DOWNTIME == nr) { |
751 | data->pwm_downtime = TIME_TO_REG(val); | 722 | data->pwm_downtime = TIME_TO_REG(simple_strtoul(buf, NULL, 10)); |
752 | data->pwm_downtime += data->pwm_downtime == 0 ? 1 : 0; | 723 | data->pwm_downtime += data->pwm_downtime == 0 ? 1 : 0; |
753 | w83793_write_value(client, W83793_REG_PWM_DOWNTIME, | 724 | w83793_write_value(client, W83793_REG_PWM_DOWNTIME, |
754 | data->pwm_downtime); | 725 | data->pwm_downtime); |
755 | } else { /* SETUP_TEMP_CRITICAL */ | 726 | } else { /* SETUP_TEMP_CRITICAL */ |
756 | data->temp_critical = | 727 | data->temp_critical = |
757 | w83793_read_value(client, W83793_REG_TEMP_CRITICAL) & 0x80; | 728 | w83793_read_value(client, W83793_REG_TEMP_CRITICAL) & 0x80; |
758 | data->temp_critical |= TEMP_TO_REG(val, 0, 0x7f); | 729 | data->temp_critical |= TEMP_TO_REG(simple_strtol(buf, NULL, 10), |
730 | 0, 0x7f); | ||
759 | w83793_write_value(client, W83793_REG_TEMP_CRITICAL, | 731 | w83793_write_value(client, W83793_REG_TEMP_CRITICAL, |
760 | data->temp_critical); | 732 | data->temp_critical); |
761 | } | 733 | } |
@@ -765,31 +737,31 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, | |||
765 | } | 737 | } |
766 | 738 | ||
767 | /* | 739 | /* |
768 | * Temp SmartFan control | 740 | Temp SmartFan control |
769 | * TEMP_FAN_MAP | 741 | TEMP_FAN_MAP |
770 | * Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1... | 742 | Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1... |
771 | * It's possible two or more temp channels control the same fan, w83793 | 743 | It's possible two or more temp channels control the same fan, w83793 |
772 | * always prefers to pick the most critical request and applies it to | 744 | always prefers to pick the most critical request and applies it to |
773 | * the related Fan. | 745 | the related Fan. |
774 | * It's possible one fan is not in any mapping of 6 temp channels, this | 746 | It's possible one fan is not in any mapping of 6 temp channels, this |
775 | * means the fan is manual mode | 747 | means the fan is manual mode |
776 | * | 748 | |
777 | * TEMP_PWM_ENABLE | 749 | TEMP_PWM_ENABLE |
778 | * Each temp channel has its own SmartFan mode, and temp channel | 750 | Each temp channel has its own SmartFan mode, and temp channel |
779 | * control fans that are set by TEMP_FAN_MAP | 751 | control fans that are set by TEMP_FAN_MAP |
780 | * 0: SmartFanII mode | 752 | 0: SmartFanII mode |
781 | * 1: Thermal Cruise Mode | 753 | 1: Thermal Cruise Mode |
782 | * | 754 | |
783 | * TEMP_CRUISE | 755 | TEMP_CRUISE |
784 | * Target temperature in thermal cruise mode, w83793 will try to turn | 756 | Target temperature in thermal cruise mode, w83793 will try to turn |
785 | * fan speed to keep the temperature of target device around this | 757 | fan speed to keep the temperature of target device around this |
786 | * temperature. | 758 | temperature. |
787 | * | 759 | |
788 | * TEMP_TOLERANCE | 760 | TEMP_TOLERANCE |
789 | * If Temp higher or lower than target with this tolerance, w83793 | 761 | If Temp higher or lower than target with this tolerance, w83793 |
790 | * will take actions to speed up or slow down the fan to keep the | 762 | will take actions to speed up or slow down the fan to keep the |
791 | * temperature within the tolerance range. | 763 | temperature within the tolerance range. |
792 | */ | 764 | */ |
793 | 765 | ||
794 | #define TEMP_FAN_MAP 0 | 766 | #define TEMP_FAN_MAP 0 |
795 | #define TEMP_PWM_ENABLE 1 | 767 | #define TEMP_PWM_ENABLE 1 |
@@ -805,12 +777,12 @@ show_sf_ctrl(struct device *dev, struct device_attribute *attr, char *buf) | |||
805 | struct w83793_data *data = w83793_update_device(dev); | 777 | struct w83793_data *data = w83793_update_device(dev); |
806 | u32 val; | 778 | u32 val; |
807 | 779 | ||
808 | if (nr == TEMP_FAN_MAP) { | 780 | if (TEMP_FAN_MAP == nr) { |
809 | val = data->temp_fan_map[index]; | 781 | val = data->temp_fan_map[index]; |
810 | } else if (nr == TEMP_PWM_ENABLE) { | 782 | } else if (TEMP_PWM_ENABLE == nr) { |
811 | /* +2 to transfrom into 2 and 3 to conform with sysfs intf */ | 783 | /* +2 to transfrom into 2 and 3 to conform with sysfs intf */ |
812 | val = ((data->pwm_enable >> index) & 0x01) + 2; | 784 | val = ((data->pwm_enable >> index) & 0x01) + 2; |
813 | } else if (nr == TEMP_CRUISE) { | 785 | } else if (TEMP_CRUISE == nr) { |
814 | val = TEMP_FROM_REG(data->temp_cruise[index] & 0x7f); | 786 | val = TEMP_FROM_REG(data->temp_cruise[index] & 0x7f); |
815 | } else { /* TEMP_TOLERANCE */ | 787 | } else { /* TEMP_TOLERANCE */ |
816 | val = data->tolerance[index >> 1] >> ((index & 0x01) ? 4 : 0); | 788 | val = data->tolerance[index >> 1] >> ((index & 0x01) ? 4 : 0); |
@@ -829,20 +801,16 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr, | |||
829 | int index = sensor_attr->index; | 801 | int index = sensor_attr->index; |
830 | struct i2c_client *client = to_i2c_client(dev); | 802 | struct i2c_client *client = to_i2c_client(dev); |
831 | struct w83793_data *data = i2c_get_clientdata(client); | 803 | struct w83793_data *data = i2c_get_clientdata(client); |
832 | long val; | 804 | u32 val; |
833 | int err; | ||
834 | |||
835 | err = kstrtol(buf, 10, &val); | ||
836 | if (err) | ||
837 | return err; | ||
838 | 805 | ||
839 | mutex_lock(&data->update_lock); | 806 | mutex_lock(&data->update_lock); |
840 | if (nr == TEMP_FAN_MAP) { | 807 | if (TEMP_FAN_MAP == nr) { |
841 | val = SENSORS_LIMIT(val, 0, 255); | 808 | val = simple_strtoul(buf, NULL, 10) & 0xff; |
842 | w83793_write_value(client, W83793_REG_TEMP_FAN_MAP(index), val); | 809 | w83793_write_value(client, W83793_REG_TEMP_FAN_MAP(index), val); |
843 | data->temp_fan_map[index] = val; | 810 | data->temp_fan_map[index] = val; |
844 | } else if (nr == TEMP_PWM_ENABLE) { | 811 | } else if (TEMP_PWM_ENABLE == nr) { |
845 | if (val == 2 || val == 3) { | 812 | val = simple_strtoul(buf, NULL, 10); |
813 | if (2 == val || 3 == val) { | ||
846 | data->pwm_enable = | 814 | data->pwm_enable = |
847 | w83793_read_value(client, W83793_REG_PWM_ENABLE); | 815 | w83793_read_value(client, W83793_REG_PWM_ENABLE); |
848 | if (val - 2) | 816 | if (val - 2) |
@@ -855,11 +823,12 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr, | |||
855 | mutex_unlock(&data->update_lock); | 823 | mutex_unlock(&data->update_lock); |
856 | return -EINVAL; | 824 | return -EINVAL; |
857 | } | 825 | } |
858 | } else if (nr == TEMP_CRUISE) { | 826 | } else if (TEMP_CRUISE == nr) { |
859 | data->temp_cruise[index] = | 827 | data->temp_cruise[index] = |
860 | w83793_read_value(client, W83793_REG_TEMP_CRUISE(index)); | 828 | w83793_read_value(client, W83793_REG_TEMP_CRUISE(index)); |
829 | val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f); | ||
861 | data->temp_cruise[index] &= 0x80; | 830 | data->temp_cruise[index] &= 0x80; |
862 | data->temp_cruise[index] |= TEMP_TO_REG(val, 0, 0x7f); | 831 | data->temp_cruise[index] |= val; |
863 | 832 | ||
864 | w83793_write_value(client, W83793_REG_TEMP_CRUISE(index), | 833 | w83793_write_value(client, W83793_REG_TEMP_CRUISE(index), |
865 | data->temp_cruise[index]); | 834 | data->temp_cruise[index]); |
@@ -869,8 +838,9 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr, | |||
869 | data->tolerance[i] = | 838 | data->tolerance[i] = |
870 | w83793_read_value(client, W83793_REG_TEMP_TOL(i)); | 839 | w83793_read_value(client, W83793_REG_TEMP_TOL(i)); |
871 | 840 | ||
841 | val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x0f); | ||
872 | data->tolerance[i] &= ~(0x0f << shift); | 842 | data->tolerance[i] &= ~(0x0f << shift); |
873 | data->tolerance[i] |= TEMP_TO_REG(val, 0, 0x0f) << shift; | 843 | data->tolerance[i] |= val << shift; |
874 | w83793_write_value(client, W83793_REG_TEMP_TOL(i), | 844 | w83793_write_value(client, W83793_REG_TEMP_TOL(i), |
875 | data->tolerance[i]); | 845 | data->tolerance[i]); |
876 | } | 846 | } |
@@ -901,13 +871,7 @@ store_sf2_pwm(struct device *dev, struct device_attribute *attr, | |||
901 | to_sensor_dev_attr_2(attr); | 871 | to_sensor_dev_attr_2(attr); |
902 | int nr = sensor_attr->nr; | 872 | int nr = sensor_attr->nr; |
903 | int index = sensor_attr->index; | 873 | int index = sensor_attr->index; |
904 | unsigned long val; | 874 | u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) >> 2; |
905 | int err; | ||
906 | |||
907 | err = kstrtoul(buf, 10, &val); | ||
908 | if (err) | ||
909 | return err; | ||
910 | val = SENSORS_LIMIT(val, 0, 0xff) >> 2; | ||
911 | 875 | ||
912 | mutex_lock(&data->update_lock); | 876 | mutex_lock(&data->update_lock); |
913 | data->sf2_pwm[index][nr] = | 877 | data->sf2_pwm[index][nr] = |
@@ -942,13 +906,7 @@ store_sf2_temp(struct device *dev, struct device_attribute *attr, | |||
942 | to_sensor_dev_attr_2(attr); | 906 | to_sensor_dev_attr_2(attr); |
943 | int nr = sensor_attr->nr; | 907 | int nr = sensor_attr->nr; |
944 | int index = sensor_attr->index; | 908 | int index = sensor_attr->index; |
945 | long val; | 909 | u8 val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f); |
946 | int err; | ||
947 | |||
948 | err = kstrtol(buf, 10, &val); | ||
949 | if (err) | ||
950 | return err; | ||
951 | val = TEMP_TO_REG(val, 0, 0x7f); | ||
952 | 910 | ||
953 | mutex_lock(&data->update_lock); | 911 | mutex_lock(&data->update_lock); |
954 | data->sf2_temp[index][nr] = | 912 | data->sf2_temp[index][nr] = |
@@ -990,19 +948,17 @@ store_in(struct device *dev, struct device_attribute *attr, | |||
990 | int index = sensor_attr->index; | 948 | int index = sensor_attr->index; |
991 | struct i2c_client *client = to_i2c_client(dev); | 949 | struct i2c_client *client = to_i2c_client(dev); |
992 | struct w83793_data *data = i2c_get_clientdata(client); | 950 | struct w83793_data *data = i2c_get_clientdata(client); |
993 | unsigned long val; | 951 | u32 val; |
994 | int err; | ||
995 | |||
996 | err = kstrtoul(buf, 10, &val); | ||
997 | if (err) | ||
998 | return err; | ||
999 | val = (val + scale_in[index] / 2) / scale_in[index]; | ||
1000 | 952 | ||
953 | val = | ||
954 | (simple_strtoul(buf, NULL, 10) + | ||
955 | scale_in[index] / 2) / scale_in[index]; | ||
1001 | mutex_lock(&data->update_lock); | 956 | mutex_lock(&data->update_lock); |
1002 | if (index > 2) { | 957 | if (index > 2) { |
1003 | /* fix the limit values of 5VDD and 5VSB to ALARM mechanism */ | 958 | /* fix the limit values of 5VDD and 5VSB to ALARM mechanism */ |
1004 | if (nr == 1 || nr == 2) | 959 | if (1 == nr || 2 == nr) { |
1005 | val -= scale_in_add[index] / scale_in[index]; | 960 | val -= scale_in_add[index] / scale_in[index]; |
961 | } | ||
1006 | val = SENSORS_LIMIT(val, 0, 255); | 962 | val = SENSORS_LIMIT(val, 0, 255); |
1007 | } else { | 963 | } else { |
1008 | val = SENSORS_LIMIT(val, 0, 0x3FF); | 964 | val = SENSORS_LIMIT(val, 0, 0x3FF); |
@@ -1169,6 +1125,8 @@ static struct sensor_device_attribute_2 w83793_vid[] = { | |||
1169 | static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm); | 1125 | static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm); |
1170 | 1126 | ||
1171 | static struct sensor_device_attribute_2 sda_single_files[] = { | 1127 | static struct sensor_device_attribute_2 sda_single_files[] = { |
1128 | SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, | ||
1129 | store_chassis_clear_legacy, ALARM_STATUS, 30), | ||
1172 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, | 1130 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, |
1173 | store_chassis_clear, ALARM_STATUS, 30), | 1131 | store_chassis_clear, ALARM_STATUS, 30), |
1174 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable, | 1132 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable, |
@@ -1185,8 +1143,9 @@ static struct sensor_device_attribute_2 sda_single_files[] = { | |||
1185 | 1143 | ||
1186 | static void w83793_init_client(struct i2c_client *client) | 1144 | static void w83793_init_client(struct i2c_client *client) |
1187 | { | 1145 | { |
1188 | if (reset) | 1146 | if (reset) { |
1189 | w83793_write_value(client, W83793_REG_CONFIG, 0x80); | 1147 | w83793_write_value(client, W83793_REG_CONFIG, 0x80); |
1148 | } | ||
1190 | 1149 | ||
1191 | /* Start monitoring */ | 1150 | /* Start monitoring */ |
1192 | w83793_write_value(client, W83793_REG_CONFIG, | 1151 | w83793_write_value(client, W83793_REG_CONFIG, |
@@ -1300,12 +1259,10 @@ static int watchdog_open(struct inode *inode, struct file *filp) | |||
1300 | struct w83793_data *pos, *data = NULL; | 1259 | struct w83793_data *pos, *data = NULL; |
1301 | int watchdog_is_open; | 1260 | int watchdog_is_open; |
1302 | 1261 | ||
1303 | /* | 1262 | /* We get called from drivers/char/misc.c with misc_mtx hold, and we |
1304 | * We get called from drivers/char/misc.c with misc_mtx hold, and we | 1263 | call misc_register() from w83793_probe() with watchdog_data_mutex |
1305 | * call misc_register() from w83793_probe() with watchdog_data_mutex | 1264 | hold, as misc_register() takes the misc_mtx lock, this is a possible |
1306 | * hold, as misc_register() takes the misc_mtx lock, this is a possible | 1265 | deadlock, so we use mutex_trylock here. */ |
1307 | * deadlock, so we use mutex_trylock here. | ||
1308 | */ | ||
1309 | if (!mutex_trylock(&watchdog_data_mutex)) | 1266 | if (!mutex_trylock(&watchdog_data_mutex)) |
1310 | return -ERESTARTSYS; | 1267 | return -ERESTARTSYS; |
1311 | list_for_each_entry(pos, &watchdog_data_list, list) { | 1268 | list_for_each_entry(pos, &watchdog_data_list, list) { |
@@ -1318,10 +1275,8 @@ static int watchdog_open(struct inode *inode, struct file *filp) | |||
1318 | /* Check, if device is already open */ | 1275 | /* Check, if device is already open */ |
1319 | watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open); | 1276 | watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open); |
1320 | 1277 | ||
1321 | /* | 1278 | /* Increase data reference counter (if not already done). |
1322 | * Increase data reference counter (if not already done). | 1279 | Note we can never not have found data, so we don't check for this */ |
1323 | * Note we can never not have found data, so we don't check for this | ||
1324 | */ | ||
1325 | if (!watchdog_is_open) | 1280 | if (!watchdog_is_open) |
1326 | kref_get(&data->kref); | 1281 | kref_get(&data->kref); |
1327 | 1282 | ||
@@ -1601,8 +1556,9 @@ w83793_detect_subclients(struct i2c_client *client) | |||
1601 | } | 1556 | } |
1602 | 1557 | ||
1603 | tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR); | 1558 | tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR); |
1604 | if (!(tmp & 0x08)) | 1559 | if (!(tmp & 0x08)) { |
1605 | data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (tmp & 0x7)); | 1560 | data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (tmp & 0x7)); |
1561 | } | ||
1606 | if (!(tmp & 0x80)) { | 1562 | if (!(tmp & 0x80)) { |
1607 | if ((data->lm75[0] != NULL) | 1563 | if ((data->lm75[0] != NULL) |
1608 | && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) { | 1564 | && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) { |
@@ -1635,8 +1591,9 @@ static int w83793_detect(struct i2c_client *client, | |||
1635 | struct i2c_adapter *adapter = client->adapter; | 1591 | struct i2c_adapter *adapter = client->adapter; |
1636 | unsigned short address = client->addr; | 1592 | unsigned short address = client->addr; |
1637 | 1593 | ||
1638 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1594 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
1639 | return -ENODEV; | 1595 | return -ENODEV; |
1596 | } | ||
1640 | 1597 | ||
1641 | bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); | 1598 | bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); |
1642 | 1599 | ||
@@ -1647,10 +1604,8 @@ static int w83793_detect(struct i2c_client *client, | |||
1647 | return -ENODEV; | 1604 | return -ENODEV; |
1648 | } | 1605 | } |
1649 | 1606 | ||
1650 | /* | 1607 | /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR |
1651 | * If Winbond chip, address of chip and W83793_REG_I2C_ADDR | 1608 | should match */ |
1652 | * should match | ||
1653 | */ | ||
1654 | if ((bank & 0x07) == 0 | 1609 | if ((bank & 0x07) == 0 |
1655 | && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) != | 1610 | && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) != |
1656 | (address << 1)) { | 1611 | (address << 1)) { |
@@ -1692,11 +1647,9 @@ static int w83793_probe(struct i2c_client *client, | |||
1692 | INIT_LIST_HEAD(&data->list); | 1647 | INIT_LIST_HEAD(&data->list); |
1693 | kref_init(&data->kref); | 1648 | kref_init(&data->kref); |
1694 | 1649 | ||
1695 | /* | 1650 | /* Store client pointer in our data struct for watchdog usage |
1696 | * Store client pointer in our data struct for watchdog usage | 1651 | (where the client is found through a data ptr instead of the |
1697 | * (where the client is found through a data ptr instead of the | 1652 | otherway around) */ |
1698 | * otherway around) | ||
1699 | */ | ||
1700 | data->client = client; | 1653 | data->client = client; |
1701 | 1654 | ||
1702 | err = w83793_detect_subclients(client); | 1655 | err = w83793_detect_subclients(client); |
@@ -1707,8 +1660,8 @@ static int w83793_probe(struct i2c_client *client, | |||
1707 | w83793_init_client(client); | 1660 | w83793_init_client(client); |
1708 | 1661 | ||
1709 | /* | 1662 | /* |
1710 | * Only fan 1-5 has their own input pins, | 1663 | Only fan 1-5 has their own input pins, |
1711 | * Pwm 1-3 has their own pins | 1664 | Pwm 1-3 has their own pins |
1712 | */ | 1665 | */ |
1713 | data->has_fan = 0x1f; | 1666 | data->has_fan = 0x1f; |
1714 | data->has_pwm = 0x07; | 1667 | data->has_pwm = 0x07; |
@@ -1770,7 +1723,7 @@ static int w83793_probe(struct i2c_client *client, | |||
1770 | } | 1723 | } |
1771 | 1724 | ||
1772 | /* check the temp1-6 mode, ignore former AMDSI selected inputs */ | 1725 | /* check the temp1-6 mode, ignore former AMDSI selected inputs */ |
1773 | tmp = w83793_read_value(client, W83793_REG_TEMP_MODE[0]); | 1726 | tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]); |
1774 | if (tmp & 0x01) | 1727 | if (tmp & 0x01) |
1775 | data->has_temp |= 0x01; | 1728 | data->has_temp |= 0x01; |
1776 | if (tmp & 0x04) | 1729 | if (tmp & 0x04) |
@@ -1780,7 +1733,7 @@ static int w83793_probe(struct i2c_client *client, | |||
1780 | if (tmp & 0x40) | 1733 | if (tmp & 0x40) |
1781 | data->has_temp |= 0x08; | 1734 | data->has_temp |= 0x08; |
1782 | 1735 | ||
1783 | tmp = w83793_read_value(client, W83793_REG_TEMP_MODE[1]); | 1736 | tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]); |
1784 | if (tmp & 0x01) | 1737 | if (tmp & 0x01) |
1785 | data->has_temp |= 0x10; | 1738 | data->has_temp |= 0x10; |
1786 | if (tmp & 0x02) | 1739 | if (tmp & 0x02) |
@@ -1870,11 +1823,9 @@ static int w83793_probe(struct i2c_client *client, | |||
1870 | goto exit_devunreg; | 1823 | goto exit_devunreg; |
1871 | } | 1824 | } |
1872 | 1825 | ||
1873 | /* | 1826 | /* Enable Watchdog registers. |
1874 | * Enable Watchdog registers. | 1827 | Set Configuration Register to Enable Watch Dog Registers |
1875 | * Set Configuration Register to Enable Watch Dog Registers | 1828 | (Bit 2) = XXXX, X1XX. */ |
1876 | * (Bit 2) = XXXX, X1XX. | ||
1877 | */ | ||
1878 | tmp = w83793_read_value(client, W83793_REG_CONFIG); | 1829 | tmp = w83793_read_value(client, W83793_REG_CONFIG); |
1879 | w83793_write_value(client, W83793_REG_CONFIG, tmp | 0x04); | 1830 | w83793_write_value(client, W83793_REG_CONFIG, tmp | 0x04); |
1880 | 1831 | ||
@@ -1888,11 +1839,9 @@ static int w83793_probe(struct i2c_client *client, | |||
1888 | /* Disable Soft Watchdog during initialiation */ | 1839 | /* Disable Soft Watchdog during initialiation */ |
1889 | watchdog_disable(data); | 1840 | watchdog_disable(data); |
1890 | 1841 | ||
1891 | /* | 1842 | /* We take the data_mutex lock early so that watchdog_open() cannot |
1892 | * We take the data_mutex lock early so that watchdog_open() cannot | 1843 | run when misc_register() has completed, but we've not yet added |
1893 | * run when misc_register() has completed, but we've not yet added | 1844 | our data to the watchdog_data_list (and set the default timeout) */ |
1894 | * our data to the watchdog_data_list (and set the default timeout) | ||
1895 | */ | ||
1896 | mutex_lock(&watchdog_data_mutex); | 1845 | mutex_lock(&watchdog_data_mutex); |
1897 | for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) { | 1846 | for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) { |
1898 | /* Register our watchdog part */ | 1847 | /* Register our watchdog part */ |
@@ -1972,9 +1921,9 @@ static void w83793_update_nonvolatile(struct device *dev) | |||
1972 | struct w83793_data *data = i2c_get_clientdata(client); | 1921 | struct w83793_data *data = i2c_get_clientdata(client); |
1973 | int i, j; | 1922 | int i, j; |
1974 | /* | 1923 | /* |
1975 | * They are somewhat "stable" registers, and to update them every time | 1924 | They are somewhat "stable" registers, and to update them every time |
1976 | * takes so much time, it's just not worthy. Update them in a long | 1925 | takes so much time, it's just not worthy. Update them in a long |
1977 | * interval to avoid exception. | 1926 | interval to avoid exception. |
1978 | */ | 1927 | */ |
1979 | if (!(time_after(jiffies, data->last_nonvolatile + HZ * 300) | 1928 | if (!(time_after(jiffies, data->last_nonvolatile + HZ * 300) |
1980 | || !data->valid)) | 1929 | || !data->valid)) |
@@ -1991,8 +1940,9 @@ static void w83793_update_nonvolatile(struct device *dev) | |||
1991 | 1940 | ||
1992 | for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { | 1941 | for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { |
1993 | /* Update the Fan measured value and limits */ | 1942 | /* Update the Fan measured value and limits */ |
1994 | if (!(data->has_fan & (1 << i))) | 1943 | if (!(data->has_fan & (1 << i))) { |
1995 | continue; | 1944 | continue; |
1945 | } | ||
1996 | data->fan_min[i] = | 1946 | data->fan_min[i] = |
1997 | w83793_read_value(client, W83793_REG_FAN_MIN(i)) << 8; | 1947 | w83793_read_value(client, W83793_REG_FAN_MIN(i)) << 8; |
1998 | data->fan_min[i] |= | 1948 | data->fan_min[i] |= |
@@ -2047,8 +1997,9 @@ static void w83793_update_nonvolatile(struct device *dev) | |||
2047 | w83793_read_value(client, W83793_REG_TEMP_CRITICAL); | 1997 | w83793_read_value(client, W83793_REG_TEMP_CRITICAL); |
2048 | data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP); | 1998 | data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP); |
2049 | 1999 | ||
2050 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) | 2000 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) { |
2051 | data->beeps[i] = w83793_read_value(client, W83793_REG_BEEP(i)); | 2001 | data->beeps[i] = w83793_read_value(client, W83793_REG_BEEP(i)); |
2002 | } | ||
2052 | 2003 | ||
2053 | data->last_nonvolatile = jiffies; | 2004 | data->last_nonvolatile = jiffies; |
2054 | } | 2005 | } |
@@ -2074,8 +2025,9 @@ static struct w83793_data *w83793_update_device(struct device *dev) | |||
2074 | w83793_read_value(client, W83793_REG_IN_LOW_BITS[IN_READ]); | 2025 | w83793_read_value(client, W83793_REG_IN_LOW_BITS[IN_READ]); |
2075 | 2026 | ||
2076 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { | 2027 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { |
2077 | if (!(data->has_fan & (1 << i))) | 2028 | if (!(data->has_fan & (1 << i))) { |
2078 | continue; | 2029 | continue; |
2030 | } | ||
2079 | data->fan[i] = | 2031 | data->fan[i] = |
2080 | w83793_read_value(client, W83793_REG_FAN(i)) << 8; | 2032 | w83793_read_value(client, W83793_REG_FAN(i)) << 8; |
2081 | data->fan[i] |= | 2033 | data->fan[i] |= |
@@ -2115,10 +2067,8 @@ END: | |||
2115 | return data; | 2067 | return data; |
2116 | } | 2068 | } |
2117 | 2069 | ||
2118 | /* | 2070 | /* Ignore the possibility that somebody change bank outside the driver |
2119 | * Ignore the possibility that somebody change bank outside the driver | 2071 | Must be called with data->update_lock held, except during initialization */ |
2120 | * Must be called with data->update_lock held, except during initialization | ||
2121 | */ | ||
2122 | static u8 w83793_read_value(struct i2c_client *client, u16 reg) | 2072 | static u8 w83793_read_value(struct i2c_client *client, u16 reg) |
2123 | { | 2073 | { |
2124 | struct w83793_data *data = i2c_get_clientdata(client); | 2074 | struct w83793_data *data = i2c_get_clientdata(client); |
@@ -2153,16 +2103,16 @@ static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value) | |||
2153 | 2103 | ||
2154 | new_bank |= data->bank & 0xfc; | 2104 | new_bank |= data->bank & 0xfc; |
2155 | if (data->bank != new_bank) { | 2105 | if (data->bank != new_bank) { |
2156 | res = i2c_smbus_write_byte_data(client, W83793_REG_BANKSEL, | 2106 | if ((res = i2c_smbus_write_byte_data |
2157 | new_bank); | 2107 | (client, W83793_REG_BANKSEL, new_bank)) >= 0) |
2158 | if (res < 0) { | 2108 | data->bank = new_bank; |
2109 | else { | ||
2159 | dev_err(&client->dev, | 2110 | dev_err(&client->dev, |
2160 | "set bank to %d failed, fall back " | 2111 | "set bank to %d failed, fall back " |
2161 | "to bank %d, write reg 0x%x error\n", | 2112 | "to bank %d, write reg 0x%x error\n", |
2162 | new_bank, data->bank, reg); | 2113 | new_bank, data->bank, reg); |
2163 | goto END; | 2114 | goto END; |
2164 | } | 2115 | } |
2165 | data->bank = new_bank; | ||
2166 | } | 2116 | } |
2167 | 2117 | ||
2168 | res = i2c_smbus_write_byte_data(client, reg & 0xff, value); | 2118 | res = i2c_smbus_write_byte_data(client, reg & 0xff, value); |
@@ -2170,8 +2120,19 @@ END: | |||
2170 | return res; | 2120 | return res; |
2171 | } | 2121 | } |
2172 | 2122 | ||
2173 | module_i2c_driver(w83793_driver); | 2123 | static int __init sensors_w83793_init(void) |
2124 | { | ||
2125 | return i2c_add_driver(&w83793_driver); | ||
2126 | } | ||
2127 | |||
2128 | static void __exit sensors_w83793_exit(void) | ||
2129 | { | ||
2130 | i2c_del_driver(&w83793_driver); | ||
2131 | } | ||
2174 | 2132 | ||
2175 | MODULE_AUTHOR("Yuan Mu, Sven Anders"); | 2133 | MODULE_AUTHOR("Yuan Mu, Sven Anders"); |
2176 | MODULE_DESCRIPTION("w83793 driver"); | 2134 | MODULE_DESCRIPTION("w83793 driver"); |
2177 | MODULE_LICENSE("GPL"); | 2135 | MODULE_LICENSE("GPL"); |
2136 | |||
2137 | module_init(sensors_w83793_init); | ||
2138 | module_exit(sensors_w83793_exit); | ||