diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-16 18:07:46 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-16 18:07:46 -0500 |
| commit | adfeb6e9f46ded31b46fe406ad0dd6a9b4e0f7fe (patch) | |
| tree | 244eeecd2f0ecce8b84ab1301824168f1651d632 | |
| parent | 97740400bc76b64781d01f8cdfbcf750582006ef (diff) | |
| parent | 5f8b1f877e0212bfde8cb950725391f4a50c9396 (diff) | |
Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
hwmon: (sysfs-interface) Update tempX_type attribute to be more generic
hwmon: (adm1031) Fix coding style issues
hwmon: (it87) Add IT8728F support
hwmon: (coretemp) Add missing section annotations
hwmon: (lm90) Add range check to set_update_interval
hwmon: (lm63) Support extended lookup table of LM96163
hwmon: (lm63) Expose automatic fan speed control lookup table
hwmon: (lm63) Fix incorrect comment about I2C address
hwmon: (lm63) LM64 has a dedicated pin for tachometer
hwmon: (lm63) Add sensor type attribute for external sensor on LM96163
hwmon: (lm63) Add support for update_interval sysfs attribute
hwmon: (lm63) Add support for writing the external critical temperature
hwmon: (lm63) Add support for unsigned upper temperature limits
hwmon: (lm63) Add support for LM96163
hwmon: (lm63) Add support for external temperature offset register
hwmon: (lm63) Fix checkpatch errors
hwmon: (max1111) Change sysfs interface to in[0-3]_input in millivolts
| -rw-r--r-- | Documentation/hwmon/it87 | 13 | ||||
| -rw-r--r-- | Documentation/hwmon/lm63 | 21 | ||||
| -rw-r--r-- | Documentation/hwmon/sysfs-interface | 2 | ||||
| -rw-r--r-- | drivers/hwmon/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/hwmon/adm1031.c | 153 | ||||
| -rw-r--r-- | drivers/hwmon/coretemp.c | 26 | ||||
| -rw-r--r-- | drivers/hwmon/it87.c | 61 | ||||
| -rw-r--r-- | drivers/hwmon/lm63.c | 592 | ||||
| -rw-r--r-- | drivers/hwmon/lm90.c | 2 | ||||
| -rw-r--r-- | drivers/hwmon/max1111.c | 15 |
10 files changed, 735 insertions, 158 deletions
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 6f496a586732..23b7def21ba8 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
| @@ -26,6 +26,10 @@ Supported chips: | |||
| 26 | Prefix: 'it8721' | 26 | Prefix: 'it8721' |
| 27 | Addresses scanned: from Super I/O config space (8 I/O ports) | 27 | Addresses scanned: from Super I/O config space (8 I/O ports) |
| 28 | Datasheet: Not publicly available | 28 | Datasheet: Not publicly available |
| 29 | * IT8728F | ||
| 30 | Prefix: 'it8728' | ||
| 31 | Addresses scanned: from Super I/O config space (8 I/O ports) | ||
| 32 | Datasheet: Not publicly available | ||
| 29 | * SiS950 [clone of IT8705F] | 33 | * SiS950 [clone of IT8705F] |
| 30 | Prefix: 'it87' | 34 | Prefix: 'it87' |
| 31 | Addresses scanned: from Super I/O config space (8 I/O ports) | 35 | Addresses scanned: from Super I/O config space (8 I/O ports) |
| @@ -71,7 +75,7 @@ Description | |||
| 71 | ----------- | 75 | ----------- |
| 72 | 76 | ||
| 73 | This driver implements support for the IT8705F, IT8712F, IT8716F, | 77 | This driver implements support for the IT8705F, IT8712F, IT8716F, |
| 74 | IT8718F, IT8720F, IT8721F, IT8726F, IT8758E and SiS950 chips. | 78 | IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E and SiS950 chips. |
| 75 | 79 | ||
| 76 | These chips are 'Super I/O chips', supporting floppy disks, infrared ports, | 80 | These chips are 'Super I/O chips', supporting floppy disks, infrared ports, |
| 77 | joysticks and other miscellaneous stuff. For hardware monitoring, they | 81 | joysticks and other miscellaneous stuff. For hardware monitoring, they |
| @@ -105,6 +109,9 @@ The IT8726F is just bit enhanced IT8716F with additional hardware | |||
| 105 | for AMD power sequencing. Therefore the chip will appear as IT8716F | 109 | for AMD power sequencing. Therefore the chip will appear as IT8716F |
| 106 | to userspace applications. | 110 | to userspace applications. |
| 107 | 111 | ||
| 112 | The IT8728F is considered compatible with the IT8721F, until a datasheet | ||
| 113 | becomes available (hopefully.) | ||
| 114 | |||
| 108 | Temperatures are measured in degrees Celsius. An alarm is triggered once | 115 | Temperatures are measured in degrees Celsius. An alarm is triggered once |
| 109 | when the Overtemperature Shutdown limit is crossed. | 116 | when the Overtemperature Shutdown limit is crossed. |
| 110 | 117 | ||
| @@ -121,8 +128,8 @@ alarm is triggered if the voltage has crossed a programmable minimum or | |||
| 121 | maximum limit. Note that minimum in this case always means 'closest to | 128 | maximum limit. Note that minimum in this case always means 'closest to |
| 122 | zero'; this is important for negative voltage measurements. All voltage | 129 | zero'; this is important for negative voltage measurements. All voltage |
| 123 | inputs can measure voltages between 0 and 4.08 volts, with a resolution of | 130 | inputs can measure voltages between 0 and 4.08 volts, with a resolution of |
| 124 | 0.016 volt (except IT8721F/IT8758E: 0.012 volt.) The battery voltage in8 does | 131 | 0.016 volt (except IT8721F/IT8758E and IT8728F: 0.012 volt.) The battery |
| 125 | not have limit registers. | 132 | voltage in8 does not have limit registers. |
| 126 | 133 | ||
| 127 | On the IT8721F/IT8758E, some voltage inputs are internal and scaled inside | 134 | On the IT8721F/IT8758E, some voltage inputs are internal and scaled inside |
| 128 | the chip (in7, in8 and optionally in3). The driver handles this transparently | 135 | the chip (in7, in8 and optionally in3). The driver handles this transparently |
diff --git a/Documentation/hwmon/lm63 b/Documentation/hwmon/lm63 index b9843eab1afb..4d30d209881a 100644 --- a/Documentation/hwmon/lm63 +++ b/Documentation/hwmon/lm63 | |||
| @@ -12,6 +12,11 @@ Supported chips: | |||
| 12 | Addresses scanned: I2C 0x18 and 0x4e | 12 | Addresses scanned: I2C 0x18 and 0x4e |
| 13 | Datasheet: Publicly available at the National Semiconductor website | 13 | Datasheet: Publicly available at the National Semiconductor website |
| 14 | http://www.national.com/pf/LM/LM64.html | 14 | http://www.national.com/pf/LM/LM64.html |
| 15 | * National Semiconductor LM96163 | ||
| 16 | Prefix: 'lm96163' | ||
| 17 | Addresses scanned: I2C 0x4c | ||
| 18 | Datasheet: Publicly available at the National Semiconductor website | ||
| 19 | http://www.national.com/pf/LM/LM96163.html | ||
| 15 | 20 | ||
| 16 | Author: Jean Delvare <khali@linux-fr.org> | 21 | Author: Jean Delvare <khali@linux-fr.org> |
| 17 | 22 | ||
| @@ -49,16 +54,24 @@ value for measuring the speed of the fan. It can measure fan speeds down to | |||
| 49 | Note that the pin used for fan monitoring is shared with an alert out | 54 | Note that the pin used for fan monitoring is shared with an alert out |
| 50 | function. Depending on how the board designer wanted to use the chip, fan | 55 | function. Depending on how the board designer wanted to use the chip, fan |
| 51 | speed monitoring will or will not be possible. The proper chip configuration | 56 | speed monitoring will or will not be possible. The proper chip configuration |
| 52 | is left to the BIOS, and the driver will blindly trust it. | 57 | is left to the BIOS, and the driver will blindly trust it. Only the original |
| 58 | LM63 suffers from this limitation, the LM64 and LM96163 have separate pins | ||
| 59 | for fan monitoring and alert out. On the LM64, monitoring is always enabled; | ||
| 60 | on the LM96163 it can be disabled. | ||
| 53 | 61 | ||
| 54 | A PWM output can be used to control the speed of the fan. The LM63 has two | 62 | A PWM output can be used to control the speed of the fan. The LM63 has two |
| 55 | PWM modes: manual and automatic. Automatic mode is not fully implemented yet | 63 | PWM modes: manual and automatic. Automatic mode is not fully implemented yet |
| 56 | (you cannot define your custom PWM/temperature curve), and mode change isn't | 64 | (you cannot define your custom PWM/temperature curve), and mode change isn't |
| 57 | supported either. | 65 | supported either. |
| 58 | 66 | ||
| 59 | The lm63 driver will not update its values more frequently than every | 67 | The lm63 driver will not update its values more frequently than configured with |
| 60 | second; reading them more often will do no harm, but will return 'old' | 68 | the update_interval sysfs attribute; reading them more often will do no harm, |
| 61 | values. | 69 | but will return 'old' values. Values in the automatic fan control lookup table |
| 70 | (attributes pwm1_auto_*) have their own independent lifetime of 5 seconds. | ||
| 62 | 71 | ||
| 63 | The LM64 is effectively an LM63 with GPIO lines. The driver does not | 72 | The LM64 is effectively an LM63 with GPIO lines. The driver does not |
| 64 | support these GPIO lines at present. | 73 | support these GPIO lines at present. |
| 74 | |||
| 75 | The LM96163 is an enhanced version of LM63 with improved temperature accuracy | ||
| 76 | and better PWM resolution. For LM96163, the external temperature sensor type is | ||
| 77 | configurable as CPU embedded diode(1) or 3904 transistor(2). | ||
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index a4aa8f600e09..1f4dd855a299 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
| @@ -304,7 +304,7 @@ value (fastest fan speed) wins. | |||
| 304 | temp[1-*]_type Sensor type selection. | 304 | temp[1-*]_type Sensor type selection. |
| 305 | Integers 1 to 6 | 305 | Integers 1 to 6 |
| 306 | RW | 306 | RW |
| 307 | 1: PII/Celeron Diode | 307 | 1: CPU embedded diode |
| 308 | 2: 3904 transistor | 308 | 2: 3904 transistor |
| 309 | 3: thermal diode | 309 | 3: thermal diode |
| 310 | 4: thermistor | 310 | 4: thermistor |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index cb351d358387..02260406b9e4 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -474,8 +474,8 @@ config SENSORS_IT87 | |||
| 474 | select HWMON_VID | 474 | select HWMON_VID |
| 475 | help | 475 | help |
| 476 | If you say yes here you get support for ITE IT8705F, IT8712F, | 476 | If you say yes here you get support for ITE IT8705F, IT8712F, |
| 477 | IT8716F, IT8718F, IT8720F, IT8721F, IT8726F and IT8758E sensor | 477 | IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F and IT8758E |
| 478 | chips, and the SiS960 clone. | 478 | sensor chips, and the SiS960 clone. |
| 479 | 479 | ||
| 480 | This driver can also be built as a module. If so, the module | 480 | This driver can also be built as a module. If so, the module |
| 481 | will be called it87. | 481 | will be called it87. |
| @@ -515,11 +515,11 @@ config SENSORS_LINEAGE | |||
| 515 | will be called lineage-pem. | 515 | will be called lineage-pem. |
| 516 | 516 | ||
| 517 | config SENSORS_LM63 | 517 | config SENSORS_LM63 |
| 518 | tristate "National Semiconductor LM63 and LM64" | 518 | tristate "National Semiconductor LM63 and compatibles" |
| 519 | depends on I2C | 519 | depends on I2C |
| 520 | help | 520 | help |
| 521 | If you say yes here you get support for the National | 521 | If you say yes here you get support for the National |
| 522 | Semiconductor LM63 and LM64 remote diode digital temperature | 522 | Semiconductor LM63, LM64, and LM96163 remote diode digital temperature |
| 523 | sensors with integrated fan control. Such chips are found | 523 | sensors with integrated fan control. Such chips are found |
| 524 | on the Tyan S4882 (Thunder K8QS Pro) motherboard, among | 524 | on the Tyan S4882 (Thunder K8QS Pro) motherboard, among |
| 525 | others. | 525 | others. |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index e6291dafa4ca..97e2cfb0bc93 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
| @@ -155,7 +155,8 @@ adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value) | |||
| 155 | #define TEMP_OFFSET_FROM_REG(val) TEMP_FROM_REG((val) < 0 ? \ | 155 | #define TEMP_OFFSET_FROM_REG(val) TEMP_FROM_REG((val) < 0 ? \ |
| 156 | (val) | 0x70 : (val)) | 156 | (val) | 0x70 : (val)) |
| 157 | 157 | ||
| 158 | #define FAN_FROM_REG(reg, div) ((reg) ? (11250 * 60) / ((reg) * (div)) : 0) | 158 | #define FAN_FROM_REG(reg, div) ((reg) ? \ |
| 159 | (11250 * 60) / ((reg) * (div)) : 0) | ||
| 159 | 160 | ||
| 160 | static int FAN_TO_REG(int reg, int div) | 161 | static int FAN_TO_REG(int reg, int div) |
| 161 | { | 162 | { |
| @@ -174,8 +175,8 @@ static int FAN_TO_REG(int reg, int div) | |||
| 174 | (((reg) & 0x1F) | (((val) << 5) & 0xe0)) | 175 | (((reg) & 0x1F) | (((val) << 5) & 0xe0)) |
| 175 | 176 | ||
| 176 | #define AUTO_TEMP_MIN_TO_REG(val, reg) \ | 177 | #define AUTO_TEMP_MIN_TO_REG(val, reg) \ |
| 177 | ((((val)/500) & 0xf8)|((reg) & 0x7)) | 178 | ((((val) / 500) & 0xf8) | ((reg) & 0x7)) |
| 178 | #define AUTO_TEMP_RANGE_FROM_REG(reg) (5000 * (1<< ((reg)&0x7))) | 179 | #define AUTO_TEMP_RANGE_FROM_REG(reg) (5000 * (1 << ((reg) & 0x7))) |
| 179 | #define AUTO_TEMP_MIN_FROM_REG(reg) (1000 * ((((reg) >> 3) & 0x1f) << 2)) | 180 | #define AUTO_TEMP_MIN_FROM_REG(reg) (1000 * ((((reg) >> 3) & 0x1f) << 2)) |
| 180 | 181 | ||
| 181 | #define AUTO_TEMP_MIN_FROM_REG_DEG(reg) ((((reg) >> 3) & 0x1f) << 2) | 182 | #define AUTO_TEMP_MIN_FROM_REG_DEG(reg) ((((reg) >> 3) & 0x1f) << 2) |
| @@ -202,7 +203,7 @@ static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm) | |||
| 202 | 203 | ||
| 203 | /* FAN auto control */ | 204 | /* FAN auto control */ |
| 204 | #define GET_FAN_AUTO_BITFIELD(data, idx) \ | 205 | #define GET_FAN_AUTO_BITFIELD(data, idx) \ |
| 205 | (*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx%2] | 206 | (*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx % 2] |
| 206 | 207 | ||
| 207 | /* The tables below contains the possible values for the auto fan | 208 | /* The tables below contains the possible values for the auto fan |
| 208 | * control bitfields. the index in the table is the register value. | 209 | * control bitfields. the index in the table is the register value. |
| @@ -230,7 +231,7 @@ static const auto_chan_table_t auto_channel_select_table_adm1030 = { | |||
| 230 | */ | 231 | */ |
| 231 | static int | 232 | static int |
| 232 | get_fan_auto_nearest(struct adm1031_data *data, | 233 | get_fan_auto_nearest(struct adm1031_data *data, |
| 233 | int chan, u8 val, u8 reg, u8 * new_reg) | 234 | int chan, u8 val, u8 reg, u8 *new_reg) |
| 234 | { | 235 | { |
| 235 | int i; | 236 | int i; |
| 236 | int first_match = -1, exact_match = -1; | 237 | int first_match = -1, exact_match = -1; |
| @@ -258,13 +259,13 @@ get_fan_auto_nearest(struct adm1031_data *data, | |||
| 258 | } | 259 | } |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | if (exact_match >= 0) { | 262 | if (exact_match >= 0) |
| 262 | *new_reg = exact_match; | 263 | *new_reg = exact_match; |
| 263 | } else if (first_match >= 0) { | 264 | else if (first_match >= 0) |
| 264 | *new_reg = first_match; | 265 | *new_reg = first_match; |
| 265 | } else { | 266 | else |
| 266 | return -EINVAL; | 267 | return -EINVAL; |
| 267 | } | 268 | |
| 268 | return 0; | 269 | return 0; |
| 269 | } | 270 | } |
| 270 | 271 | ||
| @@ -283,23 +284,28 @@ set_fan_auto_channel(struct device *dev, struct device_attribute *attr, | |||
| 283 | struct i2c_client *client = to_i2c_client(dev); | 284 | struct i2c_client *client = to_i2c_client(dev); |
| 284 | struct adm1031_data *data = i2c_get_clientdata(client); | 285 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 285 | int nr = to_sensor_dev_attr(attr)->index; | 286 | int nr = to_sensor_dev_attr(attr)->index; |
| 286 | int val = simple_strtol(buf, NULL, 10); | 287 | long val; |
| 287 | u8 reg; | 288 | u8 reg; |
| 288 | int ret; | 289 | int ret; |
| 289 | u8 old_fan_mode; | 290 | u8 old_fan_mode; |
| 290 | 291 | ||
| 292 | ret = kstrtol(buf, 10, &val); | ||
| 293 | if (ret) | ||
| 294 | return ret; | ||
| 295 | |||
| 291 | old_fan_mode = data->conf1; | 296 | old_fan_mode = data->conf1; |
| 292 | 297 | ||
| 293 | mutex_lock(&data->update_lock); | 298 | mutex_lock(&data->update_lock); |
| 294 | 299 | ||
| 295 | if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, ®))) { | 300 | ret = get_fan_auto_nearest(data, nr, val, data->conf1, ®); |
| 301 | if (ret) { | ||
| 296 | mutex_unlock(&data->update_lock); | 302 | mutex_unlock(&data->update_lock); |
| 297 | return ret; | 303 | return ret; |
| 298 | } | 304 | } |
| 299 | data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1); | 305 | data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1); |
| 300 | if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^ | 306 | if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^ |
| 301 | (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) { | 307 | (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) { |
| 302 | if (data->conf1 & ADM1031_CONF1_AUTO_MODE){ | 308 | if (data->conf1 & ADM1031_CONF1_AUTO_MODE) { |
| 303 | /* Switch to Auto Fan Mode | 309 | /* Switch to Auto Fan Mode |
| 304 | * Save PWM registers | 310 | * Save PWM registers |
| 305 | * Set PWM registers to 33% Both */ | 311 | * Set PWM registers to 33% Both */ |
| @@ -350,7 +356,12 @@ set_auto_temp_min(struct device *dev, struct device_attribute *attr, | |||
| 350 | struct i2c_client *client = to_i2c_client(dev); | 356 | struct i2c_client *client = to_i2c_client(dev); |
| 351 | struct adm1031_data *data = i2c_get_clientdata(client); | 357 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 352 | int nr = to_sensor_dev_attr(attr)->index; | 358 | int nr = to_sensor_dev_attr(attr)->index; |
| 353 | int val = simple_strtol(buf, NULL, 10); | 359 | long val; |
| 360 | int ret; | ||
| 361 | |||
| 362 | ret = kstrtol(buf, 10, &val); | ||
| 363 | if (ret) | ||
| 364 | return ret; | ||
| 354 | 365 | ||
| 355 | mutex_lock(&data->update_lock); | 366 | mutex_lock(&data->update_lock); |
| 356 | data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]); | 367 | data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]); |
| @@ -374,10 +385,16 @@ set_auto_temp_max(struct device *dev, struct device_attribute *attr, | |||
| 374 | struct i2c_client *client = to_i2c_client(dev); | 385 | struct i2c_client *client = to_i2c_client(dev); |
| 375 | struct adm1031_data *data = i2c_get_clientdata(client); | 386 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 376 | int nr = to_sensor_dev_attr(attr)->index; | 387 | int nr = to_sensor_dev_attr(attr)->index; |
| 377 | int val = simple_strtol(buf, NULL, 10); | 388 | long val; |
| 389 | int ret; | ||
| 390 | |||
| 391 | ret = kstrtol(buf, 10, &val); | ||
| 392 | if (ret) | ||
| 393 | return ret; | ||
| 378 | 394 | ||
| 379 | mutex_lock(&data->update_lock); | 395 | mutex_lock(&data->update_lock); |
| 380 | data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]); | 396 | data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], |
| 397 | data->pwm[nr]); | ||
| 381 | adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), | 398 | adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), |
| 382 | data->temp_max[nr]); | 399 | data->temp_max[nr]); |
| 383 | mutex_unlock(&data->update_lock); | 400 | mutex_unlock(&data->update_lock); |
| @@ -410,8 +427,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
| 410 | struct i2c_client *client = to_i2c_client(dev); | 427 | struct i2c_client *client = to_i2c_client(dev); |
| 411 | struct adm1031_data *data = i2c_get_clientdata(client); | 428 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 412 | int nr = to_sensor_dev_attr(attr)->index; | 429 | int nr = to_sensor_dev_attr(attr)->index; |
| 413 | int val = simple_strtol(buf, NULL, 10); | 430 | long val; |
| 414 | int reg; | 431 | int ret, reg; |
| 432 | |||
| 433 | ret = kstrtol(buf, 10, &val); | ||
| 434 | if (ret) | ||
| 435 | return ret; | ||
| 415 | 436 | ||
| 416 | mutex_lock(&data->update_lock); | 437 | mutex_lock(&data->update_lock); |
| 417 | if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) && | 438 | if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) && |
| @@ -449,9 +470,13 @@ static int trust_fan_readings(struct adm1031_data *data, int chan) | |||
| 449 | 470 | ||
| 450 | if (data->conf1 & ADM1031_CONF1_AUTO_MODE) { | 471 | if (data->conf1 & ADM1031_CONF1_AUTO_MODE) { |
| 451 | switch (data->conf1 & 0x60) { | 472 | switch (data->conf1 & 0x60) { |
| 452 | case 0x00: /* remote temp1 controls fan1 remote temp2 controls fan2 */ | 473 | case 0x00: |
| 474 | /* | ||
| 475 | * remote temp1 controls fan1, | ||
| 476 | * remote temp2 controls fan2 | ||
| 477 | */ | ||
| 453 | res = data->temp[chan+1] >= | 478 | res = data->temp[chan+1] >= |
| 454 | AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]); | 479 | AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]); |
| 455 | break; | 480 | break; |
| 456 | case 0x20: /* remote temp1 controls both fans */ | 481 | case 0x20: /* remote temp1 controls both fans */ |
| 457 | res = | 482 | res = |
| @@ -515,7 +540,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
| 515 | struct i2c_client *client = to_i2c_client(dev); | 540 | struct i2c_client *client = to_i2c_client(dev); |
| 516 | struct adm1031_data *data = i2c_get_clientdata(client); | 541 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 517 | int nr = to_sensor_dev_attr(attr)->index; | 542 | int nr = to_sensor_dev_attr(attr)->index; |
| 518 | int val = simple_strtol(buf, NULL, 10); | 543 | long val; |
| 544 | int ret; | ||
| 545 | |||
| 546 | ret = kstrtol(buf, 10, &val); | ||
| 547 | if (ret) | ||
| 548 | return ret; | ||
| 519 | 549 | ||
| 520 | mutex_lock(&data->update_lock); | 550 | mutex_lock(&data->update_lock); |
| 521 | if (val) { | 551 | if (val) { |
| @@ -534,10 +564,15 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
| 534 | struct i2c_client *client = to_i2c_client(dev); | 564 | struct i2c_client *client = to_i2c_client(dev); |
| 535 | struct adm1031_data *data = i2c_get_clientdata(client); | 565 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 536 | int nr = to_sensor_dev_attr(attr)->index; | 566 | int nr = to_sensor_dev_attr(attr)->index; |
| 537 | int val = simple_strtol(buf, NULL, 10); | 567 | long val; |
| 538 | u8 tmp; | 568 | u8 tmp; |
| 539 | int old_div; | 569 | int old_div; |
| 540 | int new_min; | 570 | int new_min; |
| 571 | int ret; | ||
| 572 | |||
| 573 | ret = kstrtol(buf, 10, &val); | ||
| 574 | if (ret) | ||
| 575 | return ret; | ||
| 541 | 576 | ||
| 542 | tmp = val == 8 ? 0xc0 : | 577 | tmp = val == 8 ? 0xc0 : |
| 543 | val == 4 ? 0x80 : | 578 | val == 4 ? 0x80 : |
| @@ -631,9 +666,13 @@ static ssize_t set_temp_offset(struct device *dev, | |||
| 631 | struct i2c_client *client = to_i2c_client(dev); | 666 | struct i2c_client *client = to_i2c_client(dev); |
| 632 | struct adm1031_data *data = i2c_get_clientdata(client); | 667 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 633 | int nr = to_sensor_dev_attr(attr)->index; | 668 | int nr = to_sensor_dev_attr(attr)->index; |
| 634 | int val; | 669 | long val; |
| 670 | int ret; | ||
| 671 | |||
| 672 | ret = kstrtol(buf, 10, &val); | ||
| 673 | if (ret) | ||
| 674 | return ret; | ||
| 635 | 675 | ||
| 636 | val = simple_strtol(buf, NULL, 10); | ||
| 637 | val = SENSORS_LIMIT(val, -15000, 15000); | 676 | val = SENSORS_LIMIT(val, -15000, 15000); |
| 638 | mutex_lock(&data->update_lock); | 677 | mutex_lock(&data->update_lock); |
| 639 | data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val); | 678 | data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val); |
| @@ -648,9 +687,13 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
| 648 | struct i2c_client *client = to_i2c_client(dev); | 687 | struct i2c_client *client = to_i2c_client(dev); |
| 649 | struct adm1031_data *data = i2c_get_clientdata(client); | 688 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 650 | int nr = to_sensor_dev_attr(attr)->index; | 689 | int nr = to_sensor_dev_attr(attr)->index; |
| 651 | int val; | 690 | long val; |
| 691 | int ret; | ||
| 692 | |||
| 693 | ret = kstrtol(buf, 10, &val); | ||
| 694 | if (ret) | ||
| 695 | return ret; | ||
| 652 | 696 | ||
| 653 | val = simple_strtol(buf, NULL, 10); | ||
| 654 | val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); | 697 | val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); |
| 655 | mutex_lock(&data->update_lock); | 698 | mutex_lock(&data->update_lock); |
| 656 | data->temp_min[nr] = TEMP_TO_REG(val); | 699 | data->temp_min[nr] = TEMP_TO_REG(val); |
| @@ -665,9 +708,13 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
| 665 | struct i2c_client *client = to_i2c_client(dev); | 708 | struct i2c_client *client = to_i2c_client(dev); |
| 666 | struct adm1031_data *data = i2c_get_clientdata(client); | 709 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 667 | int nr = to_sensor_dev_attr(attr)->index; | 710 | int nr = to_sensor_dev_attr(attr)->index; |
| 668 | int val; | 711 | long val; |
| 712 | int ret; | ||
| 713 | |||
| 714 | ret = kstrtol(buf, 10, &val); | ||
| 715 | if (ret) | ||
| 716 | return ret; | ||
| 669 | 717 | ||
| 670 | val = simple_strtol(buf, NULL, 10); | ||
| 671 | val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); | 718 | val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); |
| 672 | mutex_lock(&data->update_lock); | 719 | mutex_lock(&data->update_lock); |
| 673 | data->temp_max[nr] = TEMP_TO_REG(val); | 720 | data->temp_max[nr] = TEMP_TO_REG(val); |
| @@ -682,9 +729,13 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, | |||
| 682 | struct i2c_client *client = to_i2c_client(dev); | 729 | struct i2c_client *client = to_i2c_client(dev); |
| 683 | struct adm1031_data *data = i2c_get_clientdata(client); | 730 | struct adm1031_data *data = i2c_get_clientdata(client); |
| 684 | int nr = to_sensor_dev_attr(attr)->index; | 731 | int nr = to_sensor_dev_attr(attr)->index; |
| 685 | int val; | 732 | long val; |
| 733 | int ret; | ||
| 734 | |||
| 735 | ret = kstrtol(buf, 10, &val); | ||
| 736 | if (ret) | ||
| 737 | return ret; | ||
| 686 | 738 | ||
| 687 | val = simple_strtol(buf, NULL, 10); | ||
| 688 | val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); | 739 | val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); |
| 689 | mutex_lock(&data->update_lock); | 740 | mutex_lock(&data->update_lock); |
| 690 | data->temp_crit[nr] = TEMP_TO_REG(val); | 741 | data->temp_crit[nr] = TEMP_TO_REG(val); |
| @@ -711,7 +762,8 @@ temp_reg(2); | |||
| 711 | temp_reg(3); | 762 | temp_reg(3); |
| 712 | 763 | ||
| 713 | /* Alarms */ | 764 | /* Alarms */ |
| 714 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) | 765 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, |
| 766 | char *buf) | ||
| 715 | { | 767 | { |
| 716 | struct adm1031_data *data = adm1031_update_device(dev); | 768 | struct adm1031_data *data = adm1031_update_device(dev); |
| 717 | return sprintf(buf, "%d\n", data->alarm); | 769 | return sprintf(buf, "%d\n", data->alarm); |
| @@ -919,12 +971,13 @@ static int adm1031_probe(struct i2c_client *client, | |||
| 919 | adm1031_init_client(client); | 971 | adm1031_init_client(client); |
| 920 | 972 | ||
| 921 | /* Register sysfs hooks */ | 973 | /* Register sysfs hooks */ |
| 922 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1031_group))) | 974 | err = sysfs_create_group(&client->dev.kobj, &adm1031_group); |
| 975 | if (err) | ||
| 923 | goto exit_free; | 976 | goto exit_free; |
| 924 | 977 | ||
| 925 | if (data->chip_type == adm1031) { | 978 | if (data->chip_type == adm1031) { |
| 926 | if ((err = sysfs_create_group(&client->dev.kobj, | 979 | err = sysfs_create_group(&client->dev.kobj, &adm1031_group_opt); |
| 927 | &adm1031_group_opt))) | 980 | if (err) |
| 928 | goto exit_remove; | 981 | goto exit_remove; |
| 929 | } | 982 | } |
| 930 | 983 | ||
| @@ -970,14 +1023,13 @@ static void adm1031_init_client(struct i2c_client *client) | |||
| 970 | } | 1023 | } |
| 971 | /* Initialize the ADM1031 chip (enables fan speed reading ) */ | 1024 | /* Initialize the ADM1031 chip (enables fan speed reading ) */ |
| 972 | read_val = adm1031_read_value(client, ADM1031_REG_CONF2); | 1025 | read_val = adm1031_read_value(client, ADM1031_REG_CONF2); |
| 973 | if ((read_val | mask) != read_val) { | 1026 | if ((read_val | mask) != read_val) |
| 974 | adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask); | 1027 | adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask); |
| 975 | } | ||
| 976 | 1028 | ||
| 977 | read_val = adm1031_read_value(client, ADM1031_REG_CONF1); | 1029 | read_val = adm1031_read_value(client, ADM1031_REG_CONF1); |
| 978 | if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) { | 1030 | if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) { |
| 979 | adm1031_write_value(client, ADM1031_REG_CONF1, read_val | | 1031 | adm1031_write_value(client, ADM1031_REG_CONF1, |
| 980 | ADM1031_CONF1_MONITOR_ENABLE); | 1032 | read_val | ADM1031_CONF1_MONITOR_ENABLE); |
| 981 | } | 1033 | } |
| 982 | 1034 | ||
| 983 | /* Read the chip's update rate */ | 1035 | /* Read the chip's update rate */ |
| @@ -1024,8 +1076,7 @@ static struct adm1031_data *adm1031_update_device(struct device *dev) | |||
| 1024 | /* oldh is actually newer */ | 1076 | /* oldh is actually newer */ |
| 1025 | if (newh != oldh) | 1077 | if (newh != oldh) |
| 1026 | dev_warn(&client->dev, | 1078 | dev_warn(&client->dev, |
| 1027 | "Remote temperature may be " | 1079 | "Remote temperature may be wrong.\n"); |
| 1028 | "wrong.\n"); | ||
| 1029 | #endif | 1080 | #endif |
| 1030 | } | 1081 | } |
| 1031 | data->temp[chan] = newh; | 1082 | data->temp[chan] = newh; |
| @@ -1052,22 +1103,24 @@ static struct adm1031_data *adm1031_update_device(struct device *dev) | |||
| 1052 | data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2); | 1103 | data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2); |
| 1053 | 1104 | ||
| 1054 | data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0)) | 1105 | data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0)) |
| 1055 | | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) | 1106 | | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8); |
| 1056 | << 8); | 1107 | if (data->chip_type == adm1030) |
| 1057 | if (data->chip_type == adm1030) { | ||
| 1058 | data->alarm &= 0xc0ff; | 1108 | data->alarm &= 0xc0ff; |
| 1059 | } | ||
| 1060 | 1109 | ||
| 1061 | for (chan=0; chan<(data->chip_type == adm1030 ? 1 : 2); chan++) { | 1110 | for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2); |
| 1111 | chan++) { | ||
| 1062 | data->fan_div[chan] = | 1112 | data->fan_div[chan] = |
| 1063 | adm1031_read_value(client, ADM1031_REG_FAN_DIV(chan)); | 1113 | adm1031_read_value(client, |
| 1114 | ADM1031_REG_FAN_DIV(chan)); | ||
| 1064 | data->fan_min[chan] = | 1115 | data->fan_min[chan] = |
| 1065 | adm1031_read_value(client, ADM1031_REG_FAN_MIN(chan)); | 1116 | adm1031_read_value(client, |
| 1117 | ADM1031_REG_FAN_MIN(chan)); | ||
| 1066 | data->fan[chan] = | 1118 | data->fan[chan] = |
| 1067 | adm1031_read_value(client, ADM1031_REG_FAN_SPEED(chan)); | 1119 | adm1031_read_value(client, |
| 1120 | ADM1031_REG_FAN_SPEED(chan)); | ||
| 1068 | data->pwm[chan] = | 1121 | data->pwm[chan] = |
| 1069 | 0xf & (adm1031_read_value(client, ADM1031_REG_PWM) >> | 1122 | (adm1031_read_value(client, |
| 1070 | (4*chan)); | 1123 | ADM1031_REG_PWM) >> (4 * chan)) & 0x0f; |
| 1071 | } | 1124 | } |
| 1072 | data->last_updated = jiffies; | 1125 | data->last_updated = jiffies; |
| 1073 | data->valid = 1; | 1126 | data->valid = 1; |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 1fdef885341c..a6c6ec36615e 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
| @@ -190,7 +190,8 @@ static ssize_t show_temp(struct device *dev, | |||
| 190 | return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; | 190 | return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | 193 | static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, |
| 194 | struct device *dev) | ||
| 194 | { | 195 | { |
| 195 | /* The 100C is default for both mobile and non mobile CPUs */ | 196 | /* The 100C is default for both mobile and non mobile CPUs */ |
| 196 | 197 | ||
| @@ -284,7 +285,8 @@ static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | |||
| 284 | return tjmax; | 285 | return tjmax; |
| 285 | } | 286 | } |
| 286 | 287 | ||
| 287 | static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | 288 | static int __cpuinit get_tjmax(struct cpuinfo_x86 *c, u32 id, |
| 289 | struct device *dev) | ||
| 288 | { | 290 | { |
| 289 | int err; | 291 | int err; |
| 290 | u32 eax, edx; | 292 | u32 eax, edx; |
| @@ -323,7 +325,8 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | |||
| 323 | return adjust_tjmax(c, id, dev); | 325 | return adjust_tjmax(c, id, dev); |
| 324 | } | 326 | } |
| 325 | 327 | ||
| 326 | static int create_name_attr(struct platform_data *pdata, struct device *dev) | 328 | static int __devinit create_name_attr(struct platform_data *pdata, |
| 329 | struct device *dev) | ||
| 327 | { | 330 | { |
| 328 | sysfs_attr_init(&pdata->name_attr.attr); | 331 | sysfs_attr_init(&pdata->name_attr.attr); |
| 329 | pdata->name_attr.attr.name = "name"; | 332 | pdata->name_attr.attr.name = "name"; |
| @@ -332,8 +335,8 @@ static int create_name_attr(struct platform_data *pdata, struct device *dev) | |||
| 332 | return device_create_file(dev, &pdata->name_attr); | 335 | return device_create_file(dev, &pdata->name_attr); |
| 333 | } | 336 | } |
| 334 | 337 | ||
| 335 | static int create_core_attrs(struct temp_data *tdata, struct device *dev, | 338 | static int __cpuinit create_core_attrs(struct temp_data *tdata, |
| 336 | int attr_no) | 339 | struct device *dev, int attr_no) |
| 337 | { | 340 | { |
| 338 | int err, i; | 341 | int err, i; |
| 339 | static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev, | 342 | static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev, |
| @@ -383,7 +386,7 @@ static int __cpuinit chk_ucode_version(unsigned int cpu) | |||
| 383 | return 0; | 386 | return 0; |
| 384 | } | 387 | } |
| 385 | 388 | ||
| 386 | static struct platform_device *coretemp_get_pdev(unsigned int cpu) | 389 | static struct platform_device __cpuinit *coretemp_get_pdev(unsigned int cpu) |
| 387 | { | 390 | { |
| 388 | u16 phys_proc_id = TO_PHYS_ID(cpu); | 391 | u16 phys_proc_id = TO_PHYS_ID(cpu); |
| 389 | struct pdev_entry *p; | 392 | struct pdev_entry *p; |
| @@ -400,7 +403,8 @@ static struct platform_device *coretemp_get_pdev(unsigned int cpu) | |||
| 400 | return NULL; | 403 | return NULL; |
| 401 | } | 404 | } |
| 402 | 405 | ||
| 403 | static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag) | 406 | static struct temp_data __cpuinit *init_temp_data(unsigned int cpu, |
| 407 | int pkg_flag) | ||
| 404 | { | 408 | { |
| 405 | struct temp_data *tdata; | 409 | struct temp_data *tdata; |
| 406 | 410 | ||
| @@ -418,7 +422,7 @@ static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag) | |||
| 418 | return tdata; | 422 | return tdata; |
| 419 | } | 423 | } |
| 420 | 424 | ||
| 421 | static int create_core_data(struct platform_device *pdev, | 425 | static int __cpuinit create_core_data(struct platform_device *pdev, |
| 422 | unsigned int cpu, int pkg_flag) | 426 | unsigned int cpu, int pkg_flag) |
| 423 | { | 427 | { |
| 424 | struct temp_data *tdata; | 428 | struct temp_data *tdata; |
| @@ -489,7 +493,7 @@ exit_free: | |||
| 489 | return err; | 493 | return err; |
| 490 | } | 494 | } |
| 491 | 495 | ||
| 492 | static void coretemp_add_core(unsigned int cpu, int pkg_flag) | 496 | static void __cpuinit coretemp_add_core(unsigned int cpu, int pkg_flag) |
| 493 | { | 497 | { |
| 494 | struct platform_device *pdev = coretemp_get_pdev(cpu); | 498 | struct platform_device *pdev = coretemp_get_pdev(cpu); |
| 495 | int err; | 499 | int err; |
| @@ -618,7 +622,7 @@ exit: | |||
| 618 | return err; | 622 | return err; |
| 619 | } | 623 | } |
| 620 | 624 | ||
| 621 | static void coretemp_device_remove(unsigned int cpu) | 625 | static void __cpuinit coretemp_device_remove(unsigned int cpu) |
| 622 | { | 626 | { |
| 623 | struct pdev_entry *p, *n; | 627 | struct pdev_entry *p, *n; |
| 624 | u16 phys_proc_id = TO_PHYS_ID(cpu); | 628 | u16 phys_proc_id = TO_PHYS_ID(cpu); |
| @@ -634,7 +638,7 @@ static void coretemp_device_remove(unsigned int cpu) | |||
| 634 | mutex_unlock(&pdev_list_mutex); | 638 | mutex_unlock(&pdev_list_mutex); |
| 635 | } | 639 | } |
| 636 | 640 | ||
| 637 | static bool is_any_core_online(struct platform_data *pdata) | 641 | static bool __cpuinit is_any_core_online(struct platform_data *pdata) |
| 638 | { | 642 | { |
| 639 | int i; | 643 | int i; |
| 640 | 644 | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 603ef2af2707..0054d6f9cec9 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * IT8720F Super I/O chip w/LPC interface | 17 | * IT8720F Super I/O chip w/LPC interface |
| 18 | * IT8721F Super I/O chip w/LPC interface | 18 | * IT8721F Super I/O chip w/LPC interface |
| 19 | * IT8726F Super I/O chip w/LPC interface | 19 | * IT8726F Super I/O chip w/LPC interface |
| 20 | * IT8728F Super I/O chip w/LPC interface | ||
| 20 | * IT8758E Super I/O chip w/LPC interface | 21 | * IT8758E Super I/O chip w/LPC interface |
| 21 | * Sis950 A clone of the IT8705F | 22 | * Sis950 A clone of the IT8705F |
| 22 | * | 23 | * |
| @@ -58,7 +59,7 @@ | |||
| 58 | 59 | ||
| 59 | #define DRVNAME "it87" | 60 | #define DRVNAME "it87" |
| 60 | 61 | ||
| 61 | enum chips { it87, it8712, it8716, it8718, it8720, it8721 }; | 62 | enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728 }; |
| 62 | 63 | ||
| 63 | static unsigned short force_id; | 64 | static unsigned short force_id; |
| 64 | module_param(force_id, ushort, 0); | 65 | module_param(force_id, ushort, 0); |
| @@ -135,6 +136,7 @@ static inline void superio_exit(void) | |||
| 135 | #define IT8720F_DEVID 0x8720 | 136 | #define IT8720F_DEVID 0x8720 |
| 136 | #define IT8721F_DEVID 0x8721 | 137 | #define IT8721F_DEVID 0x8721 |
| 137 | #define IT8726F_DEVID 0x8726 | 138 | #define IT8726F_DEVID 0x8726 |
| 139 | #define IT8728F_DEVID 0x8728 | ||
| 138 | #define IT87_ACT_REG 0x30 | 140 | #define IT87_ACT_REG 0x30 |
| 139 | #define IT87_BASE_REG 0x60 | 141 | #define IT87_BASE_REG 0x60 |
| 140 | 142 | ||
| @@ -274,11 +276,31 @@ struct it87_data { | |||
| 274 | s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ | 276 | s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ |
| 275 | }; | 277 | }; |
| 276 | 278 | ||
| 279 | static inline int has_12mv_adc(const struct it87_data *data) | ||
| 280 | { | ||
| 281 | /* | ||
| 282 | * IT8721F and later have a 12 mV ADC, also with internal scaling | ||
| 283 | * on selected inputs. | ||
| 284 | */ | ||
| 285 | return data->type == it8721 | ||
| 286 | || data->type == it8728; | ||
| 287 | } | ||
| 288 | |||
| 289 | static inline int has_newer_autopwm(const struct it87_data *data) | ||
| 290 | { | ||
| 291 | /* | ||
| 292 | * IT8721F and later have separate registers for the temperature | ||
| 293 | * mapping and the manual duty cycle. | ||
| 294 | */ | ||
| 295 | return data->type == it8721 | ||
| 296 | || data->type == it8728; | ||
| 297 | } | ||
| 298 | |||
| 277 | static u8 in_to_reg(const struct it87_data *data, int nr, long val) | 299 | static u8 in_to_reg(const struct it87_data *data, int nr, long val) |
| 278 | { | 300 | { |
| 279 | long lsb; | 301 | long lsb; |
| 280 | 302 | ||
| 281 | if (data->type == it8721) { | 303 | if (has_12mv_adc(data)) { |
| 282 | if (data->in_scaled & (1 << nr)) | 304 | if (data->in_scaled & (1 << nr)) |
| 283 | lsb = 24; | 305 | lsb = 24; |
| 284 | else | 306 | else |
| @@ -292,7 +314,7 @@ static u8 in_to_reg(const struct it87_data *data, int nr, long val) | |||
| 292 | 314 | ||
| 293 | static int in_from_reg(const struct it87_data *data, int nr, int val) | 315 | static int in_from_reg(const struct it87_data *data, int nr, int val) |
| 294 | { | 316 | { |
| 295 | if (data->type == it8721) { | 317 | if (has_12mv_adc(data)) { |
| 296 | if (data->in_scaled & (1 << nr)) | 318 | if (data->in_scaled & (1 << nr)) |
| 297 | return val * 24; | 319 | return val * 24; |
| 298 | else | 320 | else |
| @@ -329,7 +351,7 @@ static inline u16 FAN16_TO_REG(long rpm) | |||
| 329 | 351 | ||
| 330 | static u8 pwm_to_reg(const struct it87_data *data, long val) | 352 | static u8 pwm_to_reg(const struct it87_data *data, long val) |
| 331 | { | 353 | { |
| 332 | if (data->type == it8721) | 354 | if (has_newer_autopwm(data)) |
| 333 | return val; | 355 | return val; |
| 334 | else | 356 | else |
| 335 | return val >> 1; | 357 | return val >> 1; |
| @@ -337,7 +359,7 @@ static u8 pwm_to_reg(const struct it87_data *data, long val) | |||
| 337 | 359 | ||
| 338 | static int pwm_from_reg(const struct it87_data *data, u8 reg) | 360 | static int pwm_from_reg(const struct it87_data *data, u8 reg) |
| 339 | { | 361 | { |
| 340 | if (data->type == it8721) | 362 | if (has_newer_autopwm(data)) |
| 341 | return reg; | 363 | return reg; |
| 342 | else | 364 | else |
| 343 | return (reg & 0x7f) << 1; | 365 | return (reg & 0x7f) << 1; |
| @@ -374,7 +396,8 @@ static inline int has_16bit_fans(const struct it87_data *data) | |||
| 374 | || data->type == it8716 | 396 | || data->type == it8716 |
| 375 | || data->type == it8718 | 397 | || data->type == it8718 |
| 376 | || data->type == it8720 | 398 | || data->type == it8720 |
| 377 | || data->type == it8721; | 399 | || data->type == it8721 |
| 400 | || data->type == it8728; | ||
| 378 | } | 401 | } |
| 379 | 402 | ||
| 380 | static inline int has_old_autopwm(const struct it87_data *data) | 403 | static inline int has_old_autopwm(const struct it87_data *data) |
| @@ -842,7 +865,7 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
| 842 | data->fan_main_ctrl); | 865 | data->fan_main_ctrl); |
| 843 | } else { | 866 | } else { |
| 844 | if (val == 1) /* Manual mode */ | 867 | if (val == 1) /* Manual mode */ |
| 845 | data->pwm_ctrl[nr] = data->type == it8721 ? | 868 | data->pwm_ctrl[nr] = has_newer_autopwm(data) ? |
| 846 | data->pwm_temp_map[nr] : | 869 | data->pwm_temp_map[nr] : |
| 847 | data->pwm_duty[nr]; | 870 | data->pwm_duty[nr]; |
| 848 | else /* Automatic mode */ | 871 | else /* Automatic mode */ |
| @@ -870,7 +893,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
| 870 | return -EINVAL; | 893 | return -EINVAL; |
| 871 | 894 | ||
| 872 | mutex_lock(&data->update_lock); | 895 | mutex_lock(&data->update_lock); |
| 873 | if (data->type == it8721) { | 896 | if (has_newer_autopwm(data)) { |
| 874 | /* If we are in automatic mode, the PWM duty cycle register | 897 | /* If we are in automatic mode, the PWM duty cycle register |
| 875 | * is read-only so we can't write the value */ | 898 | * is read-only so we can't write the value */ |
| 876 | if (data->pwm_ctrl[nr] & 0x80) { | 899 | if (data->pwm_ctrl[nr] & 0x80) { |
| @@ -1311,8 +1334,8 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr, | |||
| 1311 | struct it87_data *data = dev_get_drvdata(dev); | 1334 | struct it87_data *data = dev_get_drvdata(dev); |
| 1312 | int nr = to_sensor_dev_attr(attr)->index; | 1335 | int nr = to_sensor_dev_attr(attr)->index; |
| 1313 | 1336 | ||
| 1314 | return sprintf(buf, "%s\n", data->type == it8721 ? labels_it8721[nr] | 1337 | return sprintf(buf, "%s\n", has_12mv_adc(data) ? labels_it8721[nr] |
| 1315 | : labels[nr]); | 1338 | : labels[nr]); |
| 1316 | } | 1339 | } |
| 1317 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0); | 1340 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0); |
| 1318 | static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1); | 1341 | static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1); |
| @@ -1605,6 +1628,9 @@ static int __init it87_find(unsigned short *address, | |||
| 1605 | case IT8721F_DEVID: | 1628 | case IT8721F_DEVID: |
| 1606 | sio_data->type = it8721; | 1629 | sio_data->type = it8721; |
| 1607 | break; | 1630 | break; |
| 1631 | case IT8728F_DEVID: | ||
| 1632 | sio_data->type = it8728; | ||
| 1633 | break; | ||
| 1608 | case 0xffff: /* No device at all */ | 1634 | case 0xffff: /* No device at all */ |
| 1609 | goto exit; | 1635 | goto exit; |
| 1610 | default: | 1636 | default: |
| @@ -1646,8 +1672,11 @@ static int __init it87_find(unsigned short *address, | |||
| 1646 | superio_select(GPIO); | 1672 | superio_select(GPIO); |
| 1647 | 1673 | ||
| 1648 | reg = superio_inb(IT87_SIO_GPIO3_REG); | 1674 | reg = superio_inb(IT87_SIO_GPIO3_REG); |
| 1649 | if (sio_data->type == it8721) { | 1675 | if (sio_data->type == it8721 || sio_data->type == it8728) { |
| 1650 | /* The IT8721F/IT8758E doesn't have VID pins at all */ | 1676 | /* |
| 1677 | * The IT8721F/IT8758E doesn't have VID pins at all, | ||
| 1678 | * not sure about the IT8728F. | ||
| 1679 | */ | ||
| 1651 | sio_data->skip_vid = 1; | 1680 | sio_data->skip_vid = 1; |
| 1652 | } else { | 1681 | } else { |
| 1653 | /* We need at least 4 VID pins */ | 1682 | /* We need at least 4 VID pins */ |
| @@ -1692,7 +1721,8 @@ static int __init it87_find(unsigned short *address, | |||
| 1692 | } | 1721 | } |
| 1693 | if (reg & (1 << 0)) | 1722 | if (reg & (1 << 0)) |
| 1694 | sio_data->internal |= (1 << 0); | 1723 | sio_data->internal |= (1 << 0); |
| 1695 | if ((reg & (1 << 1)) || sio_data->type == it8721) | 1724 | if ((reg & (1 << 1)) || sio_data->type == it8721 || |
| 1725 | sio_data->type == it8728) | ||
| 1696 | sio_data->internal |= (1 << 1); | 1726 | sio_data->internal |= (1 << 1); |
| 1697 | 1727 | ||
| 1698 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; | 1728 | sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; |
| @@ -1770,6 +1800,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
| 1770 | "it8718", | 1800 | "it8718", |
| 1771 | "it8720", | 1801 | "it8720", |
| 1772 | "it8721", | 1802 | "it8721", |
| 1803 | "it8728", | ||
| 1773 | }; | 1804 | }; |
| 1774 | 1805 | ||
| 1775 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1806 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| @@ -1807,7 +1838,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
| 1807 | enable_pwm_interface = it87_check_pwm(dev); | 1838 | enable_pwm_interface = it87_check_pwm(dev); |
| 1808 | 1839 | ||
| 1809 | /* Starting with IT8721F, we handle scaling of internal voltages */ | 1840 | /* Starting with IT8721F, we handle scaling of internal voltages */ |
| 1810 | if (data->type == it8721) { | 1841 | if (has_12mv_adc(data)) { |
| 1811 | if (sio_data->internal & (1 << 0)) | 1842 | if (sio_data->internal & (1 << 0)) |
| 1812 | data->in_scaled |= (1 << 3); /* in3 is AVCC */ | 1843 | data->in_scaled |= (1 << 3); /* in3 is AVCC */ |
| 1813 | if (sio_data->internal & (1 << 1)) | 1844 | if (sio_data->internal & (1 << 1)) |
| @@ -2093,7 +2124,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
| 2093 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) | 2124 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) |
| 2094 | { | 2125 | { |
| 2095 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); | 2126 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); |
| 2096 | if (data->type == it8721) { | 2127 | if (has_newer_autopwm(data)) { |
| 2097 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | 2128 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; |
| 2098 | data->pwm_duty[nr] = it87_read_value(data, | 2129 | data->pwm_duty[nr] = it87_read_value(data, |
| 2099 | IT87_REG_PWM_DUTY(nr)); | 2130 | IT87_REG_PWM_DUTY(nr)); |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 508cb291f71b..5e6457a6644d 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
| @@ -47,10 +47,14 @@ | |||
| 47 | #include <linux/err.h> | 47 | #include <linux/err.h> |
| 48 | #include <linux/mutex.h> | 48 | #include <linux/mutex.h> |
| 49 | #include <linux/sysfs.h> | 49 | #include <linux/sysfs.h> |
| 50 | #include <linux/types.h> | ||
| 50 | 51 | ||
| 51 | /* | 52 | /* |
| 52 | * Addresses to scan | 53 | * Addresses to scan |
| 53 | * Address is fully defined internally and cannot be changed. | 54 | * Address is fully defined internally and cannot be changed except for |
| 55 | * LM64 which has one pin dedicated to address selection. | ||
| 56 | * LM63 and LM96163 have address 0x4c. | ||
| 57 | * LM64 can have address 0x18 or 0x4e. | ||
| 54 | */ | 58 | */ |
| 55 | 59 | ||
| 56 | static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; | 60 | static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; |
| @@ -60,6 +64,7 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; | |||
| 60 | */ | 64 | */ |
| 61 | 65 | ||
| 62 | #define LM63_REG_CONFIG1 0x03 | 66 | #define LM63_REG_CONFIG1 0x03 |
| 67 | #define LM63_REG_CONVRATE 0x04 | ||
| 63 | #define LM63_REG_CONFIG2 0xBF | 68 | #define LM63_REG_CONFIG2 0xBF |
| 64 | #define LM63_REG_CONFIG_FAN 0x4A | 69 | #define LM63_REG_CONFIG_FAN 0x4A |
| 65 | 70 | ||
| @@ -70,6 +75,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; | |||
| 70 | 75 | ||
| 71 | #define LM63_REG_PWM_VALUE 0x4C | 76 | #define LM63_REG_PWM_VALUE 0x4C |
| 72 | #define LM63_REG_PWM_FREQ 0x4D | 77 | #define LM63_REG_PWM_FREQ 0x4D |
| 78 | #define LM63_REG_LUT_TEMP_HYST 0x4F | ||
| 79 | #define LM63_REG_LUT_TEMP(nr) (0x50 + 2 * (nr)) | ||
| 80 | #define LM63_REG_LUT_PWM(nr) (0x51 + 2 * (nr)) | ||
| 73 | 81 | ||
| 74 | #define LM63_REG_LOCAL_TEMP 0x00 | 82 | #define LM63_REG_LOCAL_TEMP 0x00 |
| 75 | #define LM63_REG_LOCAL_HIGH 0x05 | 83 | #define LM63_REG_LOCAL_HIGH 0x05 |
| @@ -91,6 +99,16 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; | |||
| 91 | #define LM63_REG_MAN_ID 0xFE | 99 | #define LM63_REG_MAN_ID 0xFE |
| 92 | #define LM63_REG_CHIP_ID 0xFF | 100 | #define LM63_REG_CHIP_ID 0xFF |
| 93 | 101 | ||
| 102 | #define LM96163_REG_TRUTHERM 0x30 | ||
| 103 | #define LM96163_REG_REMOTE_TEMP_U_MSB 0x31 | ||
| 104 | #define LM96163_REG_REMOTE_TEMP_U_LSB 0x32 | ||
| 105 | #define LM96163_REG_CONFIG_ENHANCED 0x45 | ||
| 106 | |||
| 107 | #define LM63_MAX_CONVRATE 9 | ||
| 108 | |||
| 109 | #define LM63_MAX_CONVRATE_HZ 32 | ||
| 110 | #define LM96163_MAX_CONVRATE_HZ 26 | ||
| 111 | |||
| 94 | /* | 112 | /* |
| 95 | * Conversions and various macros | 113 | * Conversions and various macros |
| 96 | * For tachometer counts, the LM63 uses 16-bit values. | 114 | * For tachometer counts, the LM63 uses 16-bit values. |
| @@ -112,15 +130,24 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; | |||
| 112 | (val) >= 127000 ? 127 : \ | 130 | (val) >= 127000 ? 127 : \ |
| 113 | (val) < 0 ? ((val) - 500) / 1000 : \ | 131 | (val) < 0 ? ((val) - 500) / 1000 : \ |
| 114 | ((val) + 500) / 1000) | 132 | ((val) + 500) / 1000) |
| 133 | #define TEMP8U_TO_REG(val) ((val) <= 0 ? 0 : \ | ||
| 134 | (val) >= 255000 ? 255 : \ | ||
| 135 | ((val) + 500) / 1000) | ||
| 115 | #define TEMP11_FROM_REG(reg) ((reg) / 32 * 125) | 136 | #define TEMP11_FROM_REG(reg) ((reg) / 32 * 125) |
| 116 | #define TEMP11_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ | 137 | #define TEMP11_TO_REG(val) ((val) <= -128000 ? 0x8000 : \ |
| 117 | (val) >= 127875 ? 0x7FE0 : \ | 138 | (val) >= 127875 ? 0x7FE0 : \ |
| 118 | (val) < 0 ? ((val) - 62) / 125 * 32 : \ | 139 | (val) < 0 ? ((val) - 62) / 125 * 32 : \ |
| 119 | ((val) + 62) / 125 * 32) | 140 | ((val) + 62) / 125 * 32) |
| 141 | #define TEMP11U_TO_REG(val) ((val) <= 0 ? 0 : \ | ||
| 142 | (val) >= 255875 ? 0xFFE0 : \ | ||
| 143 | ((val) + 62) / 125 * 32) | ||
| 120 | #define HYST_TO_REG(val) ((val) <= 0 ? 0 : \ | 144 | #define HYST_TO_REG(val) ((val) <= 0 ? 0 : \ |
| 121 | (val) >= 127000 ? 127 : \ | 145 | (val) >= 127000 ? 127 : \ |
| 122 | ((val) + 500) / 1000) | 146 | ((val) + 500) / 1000) |
| 123 | 147 | ||
| 148 | #define UPDATE_INTERVAL(max, rate) \ | ||
| 149 | ((1000 << (LM63_MAX_CONVRATE - (rate))) / (max)) | ||
| 150 | |||
| 124 | /* | 151 | /* |
| 125 | * Functions declaration | 152 | * Functions declaration |
| 126 | */ | 153 | */ |
| @@ -134,7 +161,7 @@ static struct lm63_data *lm63_update_device(struct device *dev); | |||
| 134 | static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); | 161 | static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); |
| 135 | static void lm63_init_client(struct i2c_client *client); | 162 | static void lm63_init_client(struct i2c_client *client); |
| 136 | 163 | ||
| 137 | enum chips { lm63, lm64 }; | 164 | enum chips { lm63, lm64, lm96163 }; |
| 138 | 165 | ||
| 139 | /* | 166 | /* |
| 140 | * Driver data (common to all clients) | 167 | * Driver data (common to all clients) |
| @@ -143,6 +170,7 @@ enum chips { lm63, lm64 }; | |||
| 143 | static const struct i2c_device_id lm63_id[] = { | 170 | static const struct i2c_device_id lm63_id[] = { |
| 144 | { "lm63", lm63 }, | 171 | { "lm63", lm63 }, |
| 145 | { "lm64", lm64 }, | 172 | { "lm64", lm64 }, |
| 173 | { "lm96163", lm96163 }, | ||
| 146 | { } | 174 | { } |
| 147 | }; | 175 | }; |
| 148 | MODULE_DEVICE_TABLE(i2c, lm63_id); | 176 | MODULE_DEVICE_TABLE(i2c, lm63_id); |
| @@ -167,26 +195,53 @@ struct lm63_data { | |||
| 167 | struct device *hwmon_dev; | 195 | struct device *hwmon_dev; |
| 168 | struct mutex update_lock; | 196 | struct mutex update_lock; |
| 169 | char valid; /* zero until following fields are valid */ | 197 | char valid; /* zero until following fields are valid */ |
| 198 | char lut_valid; /* zero until lut fields are valid */ | ||
| 170 | unsigned long last_updated; /* in jiffies */ | 199 | unsigned long last_updated; /* in jiffies */ |
| 171 | int kind; | 200 | unsigned long lut_last_updated; /* in jiffies */ |
| 201 | enum chips kind; | ||
| 172 | int temp2_offset; | 202 | int temp2_offset; |
| 173 | 203 | ||
| 204 | int update_interval; /* in milliseconds */ | ||
| 205 | int max_convrate_hz; | ||
| 206 | int lut_size; /* 8 or 12 */ | ||
| 207 | |||
| 174 | /* registers values */ | 208 | /* registers values */ |
| 175 | u8 config, config_fan; | 209 | u8 config, config_fan; |
| 176 | u16 fan[2]; /* 0: input | 210 | u16 fan[2]; /* 0: input |
| 177 | 1: low limit */ | 211 | 1: low limit */ |
| 178 | u8 pwm1_freq; | 212 | u8 pwm1_freq; |
| 179 | u8 pwm1_value; | 213 | u8 pwm1[13]; /* 0: current output |
| 180 | s8 temp8[3]; /* 0: local input | 214 | 1-12: lookup table */ |
| 215 | s8 temp8[15]; /* 0: local input | ||
| 181 | 1: local high limit | 216 | 1: local high limit |
| 182 | 2: remote critical limit */ | 217 | 2: remote critical limit |
| 183 | s16 temp11[3]; /* 0: remote input | 218 | 3-14: lookup table */ |
| 219 | s16 temp11[4]; /* 0: remote input | ||
| 184 | 1: remote low limit | 220 | 1: remote low limit |
| 185 | 2: remote high limit */ | 221 | 2: remote high limit |
| 222 | 3: remote offset */ | ||
| 223 | u16 temp11u; /* remote input (unsigned) */ | ||
| 186 | u8 temp2_crit_hyst; | 224 | u8 temp2_crit_hyst; |
| 225 | u8 lut_temp_hyst; | ||
| 187 | u8 alarms; | 226 | u8 alarms; |
| 227 | bool pwm_highres; | ||
| 228 | bool lut_temp_highres; | ||
| 229 | bool remote_unsigned; /* true if unsigned remote upper limits */ | ||
| 230 | bool trutherm; | ||
| 188 | }; | 231 | }; |
| 189 | 232 | ||
| 233 | static inline int temp8_from_reg(struct lm63_data *data, int nr) | ||
| 234 | { | ||
| 235 | if (data->remote_unsigned) | ||
| 236 | return TEMP8_FROM_REG((u8)data->temp8[nr]); | ||
| 237 | return TEMP8_FROM_REG(data->temp8[nr]); | ||
| 238 | } | ||
| 239 | |||
| 240 | static inline int lut_temp_from_reg(struct lm63_data *data, int nr) | ||
| 241 | { | ||
| 242 | return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000); | ||
| 243 | } | ||
| 244 | |||
| 190 | /* | 245 | /* |
| 191 | * Sysfs callback functions and files | 246 | * Sysfs callback functions and files |
| 192 | */ | 247 | */ |
| @@ -204,7 +259,12 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *dummy, | |||
| 204 | { | 259 | { |
| 205 | struct i2c_client *client = to_i2c_client(dev); | 260 | struct i2c_client *client = to_i2c_client(dev); |
| 206 | struct lm63_data *data = i2c_get_clientdata(client); | 261 | struct lm63_data *data = i2c_get_clientdata(client); |
| 207 | unsigned long val = simple_strtoul(buf, NULL, 10); | 262 | unsigned long val; |
| 263 | int err; | ||
| 264 | |||
| 265 | err = kstrtoul(buf, 10, &val); | ||
| 266 | if (err) | ||
| 267 | return err; | ||
| 208 | 268 | ||
| 209 | mutex_lock(&data->update_lock); | 269 | mutex_lock(&data->update_lock); |
| 210 | data->fan[1] = FAN_TO_REG(val); | 270 | data->fan[1] = FAN_TO_REG(val); |
| @@ -216,13 +276,22 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *dummy, | |||
| 216 | return count; | 276 | return count; |
| 217 | } | 277 | } |
| 218 | 278 | ||
| 219 | static ssize_t show_pwm1(struct device *dev, struct device_attribute *dummy, | 279 | static ssize_t show_pwm1(struct device *dev, struct device_attribute *devattr, |
| 220 | char *buf) | 280 | char *buf) |
| 221 | { | 281 | { |
| 282 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 222 | struct lm63_data *data = lm63_update_device(dev); | 283 | struct lm63_data *data = lm63_update_device(dev); |
| 223 | return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ? | 284 | int nr = attr->index; |
| 224 | 255 : (data->pwm1_value * 255 + data->pwm1_freq) / | 285 | int pwm; |
| 225 | (2 * data->pwm1_freq)); | 286 | |
| 287 | if (data->pwm_highres) | ||
| 288 | pwm = data->pwm1[nr]; | ||
| 289 | else | ||
| 290 | pwm = data->pwm1[nr] >= 2 * data->pwm1_freq ? | ||
| 291 | 255 : (data->pwm1[nr] * 255 + data->pwm1_freq) / | ||
| 292 | (2 * data->pwm1_freq); | ||
| 293 | |||
| 294 | return sprintf(buf, "%d\n", pwm); | ||
| 226 | } | 295 | } |
| 227 | 296 | ||
| 228 | static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, | 297 | static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, |
| @@ -231,22 +300,26 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy, | |||
| 231 | struct i2c_client *client = to_i2c_client(dev); | 300 | struct i2c_client *client = to_i2c_client(dev); |
| 232 | struct lm63_data *data = i2c_get_clientdata(client); | 301 | struct lm63_data *data = i2c_get_clientdata(client); |
| 233 | unsigned long val; | 302 | unsigned long val; |
| 234 | 303 | int err; | |
| 304 | |||
| 235 | if (!(data->config_fan & 0x20)) /* register is read-only */ | 305 | if (!(data->config_fan & 0x20)) /* register is read-only */ |
| 236 | return -EPERM; | 306 | return -EPERM; |
| 237 | 307 | ||
| 238 | val = simple_strtoul(buf, NULL, 10); | 308 | err = kstrtoul(buf, 10, &val); |
| 309 | if (err) | ||
| 310 | return err; | ||
| 311 | |||
| 312 | val = SENSORS_LIMIT(val, 0, 255); | ||
| 239 | mutex_lock(&data->update_lock); | 313 | mutex_lock(&data->update_lock); |
| 240 | data->pwm1_value = val <= 0 ? 0 : | 314 | data->pwm1[0] = data->pwm_highres ? val : |
| 241 | val >= 255 ? 2 * data->pwm1_freq : | 315 | (val * data->pwm1_freq * 2 + 127) / 255; |
| 242 | (val * data->pwm1_freq * 2 + 127) / 255; | 316 | i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1[0]); |
| 243 | i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value); | ||
| 244 | mutex_unlock(&data->update_lock); | 317 | mutex_unlock(&data->update_lock); |
| 245 | return count; | 318 | return count; |
| 246 | } | 319 | } |
| 247 | 320 | ||
| 248 | static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dummy, | 321 | static ssize_t show_pwm1_enable(struct device *dev, |
| 249 | char *buf) | 322 | struct device_attribute *dummy, char *buf) |
| 250 | { | 323 | { |
| 251 | struct lm63_data *data = lm63_update_device(dev); | 324 | struct lm63_data *data = lm63_update_device(dev); |
| 252 | return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); | 325 | return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); |
| @@ -273,21 +346,47 @@ static ssize_t show_remote_temp8(struct device *dev, | |||
| 273 | { | 346 | { |
| 274 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 347 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 275 | struct lm63_data *data = lm63_update_device(dev); | 348 | struct lm63_data *data = lm63_update_device(dev); |
| 276 | return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]) | 349 | return sprintf(buf, "%d\n", temp8_from_reg(data, attr->index) |
| 350 | + data->temp2_offset); | ||
| 351 | } | ||
| 352 | |||
| 353 | static ssize_t show_lut_temp(struct device *dev, | ||
| 354 | struct device_attribute *devattr, | ||
| 355 | char *buf) | ||
| 356 | { | ||
| 357 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 358 | struct lm63_data *data = lm63_update_device(dev); | ||
| 359 | return sprintf(buf, "%d\n", lut_temp_from_reg(data, attr->index) | ||
| 277 | + data->temp2_offset); | 360 | + data->temp2_offset); |
| 278 | } | 361 | } |
| 279 | 362 | ||
| 280 | static ssize_t set_local_temp8(struct device *dev, | 363 | static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr, |
| 281 | struct device_attribute *dummy, | 364 | const char *buf, size_t count) |
| 282 | const char *buf, size_t count) | ||
| 283 | { | 365 | { |
| 366 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 284 | struct i2c_client *client = to_i2c_client(dev); | 367 | struct i2c_client *client = to_i2c_client(dev); |
| 285 | struct lm63_data *data = i2c_get_clientdata(client); | 368 | struct lm63_data *data = i2c_get_clientdata(client); |
| 286 | long val = simple_strtol(buf, NULL, 10); | 369 | int nr = attr->index; |
| 370 | int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH; | ||
| 371 | long val; | ||
| 372 | int err; | ||
| 373 | int temp; | ||
| 374 | |||
| 375 | err = kstrtol(buf, 10, &val); | ||
| 376 | if (err) | ||
| 377 | return err; | ||
| 287 | 378 | ||
| 288 | mutex_lock(&data->update_lock); | 379 | mutex_lock(&data->update_lock); |
| 289 | data->temp8[1] = TEMP8_TO_REG(val); | 380 | if (nr == 2) { |
| 290 | i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]); | 381 | if (data->remote_unsigned) |
| 382 | temp = TEMP8U_TO_REG(val - data->temp2_offset); | ||
| 383 | else | ||
| 384 | temp = TEMP8_TO_REG(val - data->temp2_offset); | ||
| 385 | } else { | ||
| 386 | temp = TEMP8_TO_REG(val); | ||
| 387 | } | ||
| 388 | data->temp8[nr] = temp; | ||
| 389 | i2c_smbus_write_byte_data(client, reg, temp); | ||
| 291 | mutex_unlock(&data->update_lock); | 390 | mutex_unlock(&data->update_lock); |
| 292 | return count; | 391 | return count; |
| 293 | } | 392 | } |
| @@ -297,28 +396,56 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr, | |||
| 297 | { | 396 | { |
| 298 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 397 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 299 | struct lm63_data *data = lm63_update_device(dev); | 398 | struct lm63_data *data = lm63_update_device(dev); |
| 300 | return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]) | 399 | int nr = attr->index; |
| 301 | + data->temp2_offset); | 400 | int temp; |
| 401 | |||
| 402 | if (!nr) { | ||
| 403 | /* | ||
| 404 | * Use unsigned temperature unless its value is zero. | ||
| 405 | * If it is zero, use signed temperature. | ||
| 406 | */ | ||
| 407 | if (data->temp11u) | ||
| 408 | temp = TEMP11_FROM_REG(data->temp11u); | ||
| 409 | else | ||
| 410 | temp = TEMP11_FROM_REG(data->temp11[nr]); | ||
| 411 | } else { | ||
| 412 | if (data->remote_unsigned && nr == 2) | ||
| 413 | temp = TEMP11_FROM_REG((u16)data->temp11[nr]); | ||
| 414 | else | ||
| 415 | temp = TEMP11_FROM_REG(data->temp11[nr]); | ||
| 416 | } | ||
| 417 | return sprintf(buf, "%d\n", temp + data->temp2_offset); | ||
| 302 | } | 418 | } |
| 303 | 419 | ||
| 304 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | 420 | static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, |
| 305 | const char *buf, size_t count) | 421 | const char *buf, size_t count) |
| 306 | { | 422 | { |
| 307 | static const u8 reg[4] = { | 423 | static const u8 reg[6] = { |
| 308 | LM63_REG_REMOTE_LOW_MSB, | 424 | LM63_REG_REMOTE_LOW_MSB, |
| 309 | LM63_REG_REMOTE_LOW_LSB, | 425 | LM63_REG_REMOTE_LOW_LSB, |
| 310 | LM63_REG_REMOTE_HIGH_MSB, | 426 | LM63_REG_REMOTE_HIGH_MSB, |
| 311 | LM63_REG_REMOTE_HIGH_LSB, | 427 | LM63_REG_REMOTE_HIGH_LSB, |
| 428 | LM63_REG_REMOTE_OFFSET_MSB, | ||
| 429 | LM63_REG_REMOTE_OFFSET_LSB, | ||
| 312 | }; | 430 | }; |
| 313 | 431 | ||
| 314 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 432 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 315 | struct i2c_client *client = to_i2c_client(dev); | 433 | struct i2c_client *client = to_i2c_client(dev); |
| 316 | struct lm63_data *data = i2c_get_clientdata(client); | 434 | struct lm63_data *data = i2c_get_clientdata(client); |
| 317 | long val = simple_strtol(buf, NULL, 10); | 435 | long val; |
| 436 | int err; | ||
| 318 | int nr = attr->index; | 437 | int nr = attr->index; |
| 319 | 438 | ||
| 439 | err = kstrtol(buf, 10, &val); | ||
| 440 | if (err) | ||
| 441 | return err; | ||
| 442 | |||
| 320 | mutex_lock(&data->update_lock); | 443 | mutex_lock(&data->update_lock); |
| 321 | data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset); | 444 | if (data->remote_unsigned && nr == 2) |
| 445 | data->temp11[nr] = TEMP11U_TO_REG(val - data->temp2_offset); | ||
| 446 | else | ||
| 447 | data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset); | ||
| 448 | |||
| 322 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], | 449 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], |
| 323 | data->temp11[nr] >> 8); | 450 | data->temp11[nr] >> 8); |
| 324 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], | 451 | i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], |
| @@ -327,35 +454,143 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr, | |||
| 327 | return count; | 454 | return count; |
| 328 | } | 455 | } |
| 329 | 456 | ||
| 330 | /* Hysteresis register holds a relative value, while we want to present | 457 | /* |
| 331 | an absolute to user-space */ | 458 | * Hysteresis register holds a relative value, while we want to present |
| 332 | static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy, | 459 | * an absolute to user-space |
| 333 | char *buf) | 460 | */ |
| 461 | static ssize_t show_temp2_crit_hyst(struct device *dev, | ||
| 462 | struct device_attribute *dummy, char *buf) | ||
| 334 | { | 463 | { |
| 335 | struct lm63_data *data = lm63_update_device(dev); | 464 | struct lm63_data *data = lm63_update_device(dev); |
| 336 | return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2]) | 465 | return sprintf(buf, "%d\n", temp8_from_reg(data, 2) |
| 337 | + data->temp2_offset | 466 | + data->temp2_offset |
| 338 | - TEMP8_FROM_REG(data->temp2_crit_hyst)); | 467 | - TEMP8_FROM_REG(data->temp2_crit_hyst)); |
| 339 | } | 468 | } |
| 340 | 469 | ||
| 341 | /* And now the other way around, user-space provides an absolute | 470 | static ssize_t show_lut_temp_hyst(struct device *dev, |
| 342 | hysteresis value and we have to store a relative one */ | 471 | struct device_attribute *devattr, char *buf) |
| 343 | static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy, | 472 | { |
| 473 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 474 | struct lm63_data *data = lm63_update_device(dev); | ||
| 475 | |||
| 476 | return sprintf(buf, "%d\n", lut_temp_from_reg(data, attr->index) | ||
| 477 | + data->temp2_offset | ||
| 478 | - TEMP8_FROM_REG(data->lut_temp_hyst)); | ||
| 479 | } | ||
| 480 | |||
| 481 | /* | ||
| 482 | * And now the other way around, user-space provides an absolute | ||
| 483 | * hysteresis value and we have to store a relative one | ||
| 484 | */ | ||
| 485 | static ssize_t set_temp2_crit_hyst(struct device *dev, | ||
| 486 | struct device_attribute *dummy, | ||
| 344 | const char *buf, size_t count) | 487 | const char *buf, size_t count) |
| 345 | { | 488 | { |
| 346 | struct i2c_client *client = to_i2c_client(dev); | 489 | struct i2c_client *client = to_i2c_client(dev); |
| 347 | struct lm63_data *data = i2c_get_clientdata(client); | 490 | struct lm63_data *data = i2c_get_clientdata(client); |
| 348 | long val = simple_strtol(buf, NULL, 10); | 491 | long val; |
| 492 | int err; | ||
| 349 | long hyst; | 493 | long hyst; |
| 350 | 494 | ||
| 495 | err = kstrtol(buf, 10, &val); | ||
| 496 | if (err) | ||
| 497 | return err; | ||
| 498 | |||
| 351 | mutex_lock(&data->update_lock); | 499 | mutex_lock(&data->update_lock); |
| 352 | hyst = TEMP8_FROM_REG(data->temp8[2]) + data->temp2_offset - val; | 500 | hyst = temp8_from_reg(data, 2) + data->temp2_offset - val; |
| 353 | i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST, | 501 | i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST, |
| 354 | HYST_TO_REG(hyst)); | 502 | HYST_TO_REG(hyst)); |
| 355 | mutex_unlock(&data->update_lock); | 503 | mutex_unlock(&data->update_lock); |
| 356 | return count; | 504 | return count; |
| 357 | } | 505 | } |
| 358 | 506 | ||
| 507 | /* | ||
| 508 | * Set conversion rate. | ||
| 509 | * client->update_lock must be held when calling this function. | ||
| 510 | */ | ||
| 511 | static void lm63_set_convrate(struct i2c_client *client, struct lm63_data *data, | ||
| 512 | unsigned int interval) | ||
| 513 | { | ||
| 514 | int i; | ||
| 515 | unsigned int update_interval; | ||
| 516 | |||
| 517 | /* Shift calculations to avoid rounding errors */ | ||
| 518 | interval <<= 6; | ||
| 519 | |||
| 520 | /* find the nearest update rate */ | ||
| 521 | update_interval = (1 << (LM63_MAX_CONVRATE + 6)) * 1000 | ||
| 522 | / data->max_convrate_hz; | ||
| 523 | for (i = 0; i < LM63_MAX_CONVRATE; i++, update_interval >>= 1) | ||
| 524 | if (interval >= update_interval * 3 / 4) | ||
| 525 | break; | ||
| 526 | |||
| 527 | i2c_smbus_write_byte_data(client, LM63_REG_CONVRATE, i); | ||
| 528 | data->update_interval = UPDATE_INTERVAL(data->max_convrate_hz, i); | ||
| 529 | } | ||
| 530 | |||
| 531 | static ssize_t show_update_interval(struct device *dev, | ||
| 532 | struct device_attribute *attr, char *buf) | ||
| 533 | { | ||
| 534 | struct lm63_data *data = dev_get_drvdata(dev); | ||
| 535 | |||
| 536 | return sprintf(buf, "%u\n", data->update_interval); | ||
| 537 | } | ||
| 538 | |||
| 539 | static ssize_t set_update_interval(struct device *dev, | ||
| 540 | struct device_attribute *attr, | ||
| 541 | const char *buf, size_t count) | ||
| 542 | { | ||
| 543 | struct i2c_client *client = to_i2c_client(dev); | ||
| 544 | struct lm63_data *data = i2c_get_clientdata(client); | ||
| 545 | unsigned long val; | ||
| 546 | int err; | ||
| 547 | |||
| 548 | err = kstrtoul(buf, 10, &val); | ||
| 549 | if (err) | ||
| 550 | return err; | ||
| 551 | |||
| 552 | mutex_lock(&data->update_lock); | ||
| 553 | lm63_set_convrate(client, data, SENSORS_LIMIT(val, 0, 100000)); | ||
| 554 | mutex_unlock(&data->update_lock); | ||
| 555 | |||
| 556 | return count; | ||
| 557 | } | ||
| 558 | |||
| 559 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, | ||
| 560 | char *buf) | ||
| 561 | { | ||
| 562 | struct i2c_client *client = to_i2c_client(dev); | ||
| 563 | struct lm63_data *data = i2c_get_clientdata(client); | ||
| 564 | |||
| 565 | return sprintf(buf, data->trutherm ? "1\n" : "2\n"); | ||
| 566 | } | ||
| 567 | |||
| 568 | static ssize_t set_type(struct device *dev, struct device_attribute *attr, | ||
| 569 | const char *buf, size_t count) | ||
| 570 | { | ||
| 571 | struct i2c_client *client = to_i2c_client(dev); | ||
| 572 | struct lm63_data *data = i2c_get_clientdata(client); | ||
| 573 | unsigned long val; | ||
| 574 | int ret; | ||
| 575 | u8 reg; | ||
| 576 | |||
| 577 | ret = kstrtoul(buf, 10, &val); | ||
| 578 | if (ret < 0) | ||
| 579 | return ret; | ||
| 580 | if (val != 1 && val != 2) | ||
| 581 | return -EINVAL; | ||
| 582 | |||
| 583 | mutex_lock(&data->update_lock); | ||
| 584 | data->trutherm = val == 1; | ||
| 585 | reg = i2c_smbus_read_byte_data(client, LM96163_REG_TRUTHERM) & ~0x02; | ||
| 586 | i2c_smbus_write_byte_data(client, LM96163_REG_TRUTHERM, | ||
| 587 | reg | (data->trutherm ? 0x02 : 0x00)); | ||
| 588 | data->valid = 0; | ||
| 589 | mutex_unlock(&data->update_lock); | ||
| 590 | |||
| 591 | return count; | ||
| 592 | } | ||
| 593 | |||
| 359 | static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, | 594 | static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, |
| 360 | char *buf) | 595 | char *buf) |
| 361 | { | 596 | { |
| @@ -377,27 +612,87 @@ static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | |||
| 377 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, | 612 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, |
| 378 | set_fan, 1); | 613 | set_fan, 1); |
| 379 | 614 | ||
| 380 | static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1); | 615 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0); |
| 381 | static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); | 616 | static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); |
| 617 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, show_pwm1, NULL, 1); | ||
| 618 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IRUGO, | ||
| 619 | show_lut_temp, NULL, 3); | ||
| 620 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO, | ||
| 621 | show_lut_temp_hyst, NULL, 3); | ||
| 622 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO, show_pwm1, NULL, 2); | ||
| 623 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO, | ||
| 624 | show_lut_temp, NULL, 4); | ||
| 625 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO, | ||
| 626 | show_lut_temp_hyst, NULL, 4); | ||
| 627 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, show_pwm1, NULL, 3); | ||
| 628 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IRUGO, | ||
| 629 | show_lut_temp, NULL, 5); | ||
| 630 | static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO, | ||
| 631 | show_lut_temp_hyst, NULL, 5); | ||
| 632 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO, show_pwm1, NULL, 4); | ||
| 633 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IRUGO, | ||
| 634 | show_lut_temp, NULL, 6); | ||
| 635 | static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO, | ||
| 636 | show_lut_temp_hyst, NULL, 6); | ||
| 637 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm1, NULL, 5); | ||
| 638 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IRUGO, | ||
| 639 | show_lut_temp, NULL, 7); | ||
| 640 | static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO, | ||
| 641 | show_lut_temp_hyst, NULL, 7); | ||
| 642 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IRUGO, show_pwm1, NULL, 6); | ||
| 643 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IRUGO, | ||
| 644 | show_lut_temp, NULL, 8); | ||
| 645 | static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO, | ||
| 646 | show_lut_temp_hyst, NULL, 8); | ||
| 647 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IRUGO, show_pwm1, NULL, 7); | ||
| 648 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IRUGO, | ||
| 649 | show_lut_temp, NULL, 9); | ||
| 650 | static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO, | ||
| 651 | show_lut_temp_hyst, NULL, 9); | ||
| 652 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IRUGO, show_pwm1, NULL, 8); | ||
| 653 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO, | ||
| 654 | show_lut_temp, NULL, 10); | ||
| 655 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, | ||
| 656 | show_lut_temp_hyst, NULL, 10); | ||
| 657 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9); | ||
| 658 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO, | ||
| 659 | show_lut_temp, NULL, 11); | ||
| 660 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO, | ||
| 661 | show_lut_temp_hyst, NULL, 11); | ||
| 662 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10); | ||
| 663 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO, | ||
| 664 | show_lut_temp, NULL, 12); | ||
| 665 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO, | ||
| 666 | show_lut_temp_hyst, NULL, 12); | ||
| 667 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11); | ||
| 668 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO, | ||
| 669 | show_lut_temp, NULL, 13); | ||
| 670 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO, | ||
| 671 | show_lut_temp_hyst, NULL, 13); | ||
| 672 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12); | ||
| 673 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO, | ||
| 674 | show_lut_temp, NULL, 14); | ||
| 675 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO, | ||
| 676 | show_lut_temp_hyst, NULL, 14); | ||
| 382 | 677 | ||
| 383 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); | 678 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); |
| 384 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, | 679 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, |
| 385 | set_local_temp8, 1); | 680 | set_temp8, 1); |
| 386 | 681 | ||
| 387 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); | 682 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); |
| 388 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, | 683 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11, |
| 389 | set_temp11, 1); | 684 | set_temp11, 1); |
| 390 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, | 685 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11, |
| 391 | set_temp11, 2); | 686 | set_temp11, 2); |
| 392 | /* | 687 | static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11, |
| 393 | * On LM63, temp2_crit can be set only once, which should be job | 688 | set_temp11, 3); |
| 394 | * of the bootloader. | ||
| 395 | */ | ||
| 396 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8, | 689 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_remote_temp8, |
| 397 | NULL, 2); | 690 | set_temp8, 2); |
| 398 | static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, | 691 | static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, |
| 399 | set_temp2_crit_hyst); | 692 | set_temp2_crit_hyst); |
| 400 | 693 | ||
| 694 | static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type); | ||
| 695 | |||
| 401 | /* Individual alarm files */ | 696 | /* Individual alarm files */ |
| 402 | static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); | 697 | static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); |
| 403 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); | 698 | static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); |
| @@ -408,14 +703,43 @@ static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | |||
| 408 | /* Raw alarm file for compatibility */ | 703 | /* Raw alarm file for compatibility */ |
| 409 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 704 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
| 410 | 705 | ||
| 706 | static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, | ||
| 707 | set_update_interval); | ||
| 708 | |||
| 411 | static struct attribute *lm63_attributes[] = { | 709 | static struct attribute *lm63_attributes[] = { |
| 412 | &dev_attr_pwm1.attr, | 710 | &sensor_dev_attr_pwm1.dev_attr.attr, |
| 413 | &dev_attr_pwm1_enable.attr, | 711 | &dev_attr_pwm1_enable.attr, |
| 712 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | ||
| 713 | &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, | ||
| 714 | &sensor_dev_attr_pwm1_auto_point1_temp_hyst.dev_attr.attr, | ||
| 715 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | ||
| 716 | &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, | ||
| 717 | &sensor_dev_attr_pwm1_auto_point2_temp_hyst.dev_attr.attr, | ||
| 718 | &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, | ||
| 719 | &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, | ||
| 720 | &sensor_dev_attr_pwm1_auto_point3_temp_hyst.dev_attr.attr, | ||
| 721 | &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr, | ||
| 722 | &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, | ||
| 723 | &sensor_dev_attr_pwm1_auto_point4_temp_hyst.dev_attr.attr, | ||
| 724 | &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr, | ||
| 725 | &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr, | ||
| 726 | &sensor_dev_attr_pwm1_auto_point5_temp_hyst.dev_attr.attr, | ||
| 727 | &sensor_dev_attr_pwm1_auto_point6_pwm.dev_attr.attr, | ||
| 728 | &sensor_dev_attr_pwm1_auto_point6_temp.dev_attr.attr, | ||
| 729 | &sensor_dev_attr_pwm1_auto_point6_temp_hyst.dev_attr.attr, | ||
| 730 | &sensor_dev_attr_pwm1_auto_point7_pwm.dev_attr.attr, | ||
| 731 | &sensor_dev_attr_pwm1_auto_point7_temp.dev_attr.attr, | ||
| 732 | &sensor_dev_attr_pwm1_auto_point7_temp_hyst.dev_attr.attr, | ||
| 733 | &sensor_dev_attr_pwm1_auto_point8_pwm.dev_attr.attr, | ||
| 734 | &sensor_dev_attr_pwm1_auto_point8_temp.dev_attr.attr, | ||
| 735 | &sensor_dev_attr_pwm1_auto_point8_temp_hyst.dev_attr.attr, | ||
| 736 | |||
| 414 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 737 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
| 415 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 738 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
| 416 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 739 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
| 417 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 740 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
| 418 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 741 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
| 742 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
| 419 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | 743 | &sensor_dev_attr_temp2_crit.dev_attr.attr, |
| 420 | &dev_attr_temp2_crit_hyst.attr, | 744 | &dev_attr_temp2_crit_hyst.attr, |
| 421 | 745 | ||
| @@ -425,10 +749,54 @@ static struct attribute *lm63_attributes[] = { | |||
| 425 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 749 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
| 426 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 750 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
| 427 | &dev_attr_alarms.attr, | 751 | &dev_attr_alarms.attr, |
| 752 | &dev_attr_update_interval.attr, | ||
| 428 | NULL | 753 | NULL |
| 429 | }; | 754 | }; |
| 430 | 755 | ||
| 756 | static struct attribute *lm63_attributes_extra_lut[] = { | ||
| 757 | &sensor_dev_attr_pwm1_auto_point9_pwm.dev_attr.attr, | ||
| 758 | &sensor_dev_attr_pwm1_auto_point9_temp.dev_attr.attr, | ||
| 759 | &sensor_dev_attr_pwm1_auto_point9_temp_hyst.dev_attr.attr, | ||
| 760 | &sensor_dev_attr_pwm1_auto_point10_pwm.dev_attr.attr, | ||
| 761 | &sensor_dev_attr_pwm1_auto_point10_temp.dev_attr.attr, | ||
| 762 | &sensor_dev_attr_pwm1_auto_point10_temp_hyst.dev_attr.attr, | ||
| 763 | &sensor_dev_attr_pwm1_auto_point11_pwm.dev_attr.attr, | ||
| 764 | &sensor_dev_attr_pwm1_auto_point11_temp.dev_attr.attr, | ||
| 765 | &sensor_dev_attr_pwm1_auto_point11_temp_hyst.dev_attr.attr, | ||
| 766 | &sensor_dev_attr_pwm1_auto_point12_pwm.dev_attr.attr, | ||
| 767 | &sensor_dev_attr_pwm1_auto_point12_temp.dev_attr.attr, | ||
| 768 | &sensor_dev_attr_pwm1_auto_point12_temp_hyst.dev_attr.attr, | ||
| 769 | NULL | ||
| 770 | }; | ||
| 771 | |||
| 772 | static const struct attribute_group lm63_group_extra_lut = { | ||
| 773 | .attrs = lm63_attributes_extra_lut, | ||
| 774 | }; | ||
| 775 | |||
| 776 | /* | ||
| 777 | * On LM63, temp2_crit can be set only once, which should be job | ||
| 778 | * of the bootloader. | ||
| 779 | * On LM64, temp2_crit can always be set. | ||
| 780 | * On LM96163, temp2_crit can be set if bit 1 of the configuration | ||
| 781 | * register is true. | ||
| 782 | */ | ||
| 783 | static umode_t lm63_attribute_mode(struct kobject *kobj, | ||
| 784 | struct attribute *attr, int index) | ||
| 785 | { | ||
| 786 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 787 | struct i2c_client *client = to_i2c_client(dev); | ||
| 788 | struct lm63_data *data = i2c_get_clientdata(client); | ||
| 789 | |||
| 790 | if (attr == &sensor_dev_attr_temp2_crit.dev_attr.attr | ||
| 791 | && (data->kind == lm64 || | ||
| 792 | (data->kind == lm96163 && (data->config & 0x02)))) | ||
| 793 | return attr->mode | S_IWUSR; | ||
| 794 | |||
| 795 | return attr->mode; | ||
| 796 | } | ||
| 797 | |||
| 431 | static const struct attribute_group lm63_group = { | 798 | static const struct attribute_group lm63_group = { |
| 799 | .is_visible = lm63_attribute_mode, | ||
| 432 | .attrs = lm63_attributes, | 800 | .attrs = lm63_attributes, |
| 433 | }; | 801 | }; |
| 434 | 802 | ||
| @@ -487,6 +855,8 @@ static int lm63_detect(struct i2c_client *new_client, | |||
| 487 | strlcpy(info->type, "lm63", I2C_NAME_SIZE); | 855 | strlcpy(info->type, "lm63", I2C_NAME_SIZE); |
| 488 | else if (chip_id == 0x51 && (address == 0x18 || address == 0x4e)) | 856 | else if (chip_id == 0x51 && (address == 0x18 || address == 0x4e)) |
| 489 | strlcpy(info->type, "lm64", I2C_NAME_SIZE); | 857 | strlcpy(info->type, "lm64", I2C_NAME_SIZE); |
| 858 | else if (chip_id == 0x49 && address == 0x4c) | ||
| 859 | strlcpy(info->type, "lm96163", I2C_NAME_SIZE); | ||
| 490 | else | 860 | else |
| 491 | return -ENODEV; | 861 | return -ENODEV; |
| 492 | 862 | ||
| @@ -518,12 +888,24 @@ static int lm63_probe(struct i2c_client *new_client, | |||
| 518 | lm63_init_client(new_client); | 888 | lm63_init_client(new_client); |
| 519 | 889 | ||
| 520 | /* Register sysfs hooks */ | 890 | /* Register sysfs hooks */ |
| 521 | if ((err = sysfs_create_group(&new_client->dev.kobj, | 891 | err = sysfs_create_group(&new_client->dev.kobj, &lm63_group); |
| 522 | &lm63_group))) | 892 | if (err) |
| 523 | goto exit_free; | 893 | goto exit_free; |
| 524 | if (data->config & 0x04) { /* tachometer enabled */ | 894 | if (data->config & 0x04) { /* tachometer enabled */ |
| 525 | if ((err = sysfs_create_group(&new_client->dev.kobj, | 895 | err = sysfs_create_group(&new_client->dev.kobj, |
| 526 | &lm63_group_fan1))) | 896 | &lm63_group_fan1); |
| 897 | if (err) | ||
| 898 | goto exit_remove_files; | ||
| 899 | } | ||
| 900 | if (data->kind == lm96163) { | ||
| 901 | err = device_create_file(&new_client->dev, | ||
| 902 | &dev_attr_temp2_type); | ||
| 903 | if (err) | ||
| 904 | goto exit_remove_files; | ||
| 905 | |||
| 906 | err = sysfs_create_group(&new_client->dev.kobj, | ||
| 907 | &lm63_group_extra_lut); | ||
| 908 | if (err) | ||
| 527 | goto exit_remove_files; | 909 | goto exit_remove_files; |
| 528 | } | 910 | } |
| 529 | 911 | ||
| @@ -538,17 +920,25 @@ static int lm63_probe(struct i2c_client *new_client, | |||
| 538 | exit_remove_files: | 920 | exit_remove_files: |
| 539 | sysfs_remove_group(&new_client->dev.kobj, &lm63_group); | 921 | sysfs_remove_group(&new_client->dev.kobj, &lm63_group); |
| 540 | sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); | 922 | sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); |
| 923 | if (data->kind == lm96163) { | ||
| 924 | device_remove_file(&new_client->dev, &dev_attr_temp2_type); | ||
| 925 | sysfs_remove_group(&new_client->dev.kobj, | ||
| 926 | &lm63_group_extra_lut); | ||
| 927 | } | ||
| 541 | exit_free: | 928 | exit_free: |
| 542 | kfree(data); | 929 | kfree(data); |
| 543 | exit: | 930 | exit: |
| 544 | return err; | 931 | return err; |
| 545 | } | 932 | } |
| 546 | 933 | ||
| 547 | /* Idealy we shouldn't have to initialize anything, since the BIOS | 934 | /* |
| 548 | should have taken care of everything */ | 935 | * Ideally we shouldn't have to initialize anything, since the BIOS |
| 936 | * should have taken care of everything | ||
| 937 | */ | ||
| 549 | static void lm63_init_client(struct i2c_client *client) | 938 | static void lm63_init_client(struct i2c_client *client) |
| 550 | { | 939 | { |
| 551 | struct lm63_data *data = i2c_get_clientdata(client); | 940 | struct lm63_data *data = i2c_get_clientdata(client); |
| 941 | u8 convrate; | ||
| 552 | 942 | ||
| 553 | data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); | 943 | data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); |
| 554 | data->config_fan = i2c_smbus_read_byte_data(client, | 944 | data->config_fan = i2c_smbus_read_byte_data(client, |
| @@ -561,16 +951,57 @@ static void lm63_init_client(struct i2c_client *client) | |||
| 561 | i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, | 951 | i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, |
| 562 | data->config); | 952 | data->config); |
| 563 | } | 953 | } |
| 954 | /* Tachometer is always enabled on LM64 */ | ||
| 955 | if (data->kind == lm64) | ||
| 956 | data->config |= 0x04; | ||
| 564 | 957 | ||
| 565 | /* We may need pwm1_freq before ever updating the client data */ | 958 | /* We may need pwm1_freq before ever updating the client data */ |
| 566 | data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ); | 959 | data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ); |
| 567 | if (data->pwm1_freq == 0) | 960 | if (data->pwm1_freq == 0) |
| 568 | data->pwm1_freq = 1; | 961 | data->pwm1_freq = 1; |
| 569 | 962 | ||
| 963 | switch (data->kind) { | ||
| 964 | case lm63: | ||
| 965 | case lm64: | ||
| 966 | data->max_convrate_hz = LM63_MAX_CONVRATE_HZ; | ||
| 967 | data->lut_size = 8; | ||
| 968 | break; | ||
| 969 | case lm96163: | ||
| 970 | data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ; | ||
| 971 | data->lut_size = 12; | ||
| 972 | data->trutherm | ||
| 973 | = i2c_smbus_read_byte_data(client, | ||
| 974 | LM96163_REG_TRUTHERM) & 0x02; | ||
| 975 | break; | ||
| 976 | } | ||
| 977 | convrate = i2c_smbus_read_byte_data(client, LM63_REG_CONVRATE); | ||
| 978 | if (unlikely(convrate > LM63_MAX_CONVRATE)) | ||
| 979 | convrate = LM63_MAX_CONVRATE; | ||
| 980 | data->update_interval = UPDATE_INTERVAL(data->max_convrate_hz, | ||
| 981 | convrate); | ||
| 982 | |||
| 983 | /* | ||
| 984 | * For LM96163, check if high resolution PWM | ||
| 985 | * and unsigned temperature format is enabled. | ||
| 986 | */ | ||
| 987 | if (data->kind == lm96163) { | ||
| 988 | u8 config_enhanced | ||
| 989 | = i2c_smbus_read_byte_data(client, | ||
| 990 | LM96163_REG_CONFIG_ENHANCED); | ||
| 991 | if (config_enhanced & 0x20) | ||
| 992 | data->lut_temp_highres = true; | ||
| 993 | if ((config_enhanced & 0x10) | ||
| 994 | && !(data->config_fan & 0x08) && data->pwm1_freq == 8) | ||
| 995 | data->pwm_highres = true; | ||
| 996 | if (config_enhanced & 0x08) | ||
| 997 | data->remote_unsigned = true; | ||
| 998 | } | ||
| 999 | |||
| 570 | /* Show some debug info about the LM63 configuration */ | 1000 | /* Show some debug info about the LM63 configuration */ |
| 571 | dev_dbg(&client->dev, "Alert/tach pin configured for %s\n", | 1001 | if (data->kind == lm63) |
| 572 | (data->config & 0x04) ? "tachometer input" : | 1002 | dev_dbg(&client->dev, "Alert/tach pin configured for %s\n", |
| 573 | "alert output"); | 1003 | (data->config & 0x04) ? "tachometer input" : |
| 1004 | "alert output"); | ||
| 574 | dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n", | 1005 | dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n", |
| 575 | (data->config_fan & 0x08) ? "1.4" : "360", | 1006 | (data->config_fan & 0x08) ? "1.4" : "360", |
| 576 | ((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq); | 1007 | ((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq); |
| @@ -586,6 +1017,10 @@ static int lm63_remove(struct i2c_client *client) | |||
| 586 | hwmon_device_unregister(data->hwmon_dev); | 1017 | hwmon_device_unregister(data->hwmon_dev); |
| 587 | sysfs_remove_group(&client->dev.kobj, &lm63_group); | 1018 | sysfs_remove_group(&client->dev.kobj, &lm63_group); |
| 588 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); | 1019 | sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); |
| 1020 | if (data->kind == lm96163) { | ||
| 1021 | device_remove_file(&client->dev, &dev_attr_temp2_type); | ||
| 1022 | sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); | ||
| 1023 | } | ||
| 589 | 1024 | ||
| 590 | kfree(data); | 1025 | kfree(data); |
| 591 | return 0; | 1026 | return 0; |
| @@ -595,10 +1030,15 @@ static struct lm63_data *lm63_update_device(struct device *dev) | |||
| 595 | { | 1030 | { |
| 596 | struct i2c_client *client = to_i2c_client(dev); | 1031 | struct i2c_client *client = to_i2c_client(dev); |
| 597 | struct lm63_data *data = i2c_get_clientdata(client); | 1032 | struct lm63_data *data = i2c_get_clientdata(client); |
| 1033 | unsigned long next_update; | ||
| 1034 | int i; | ||
| 598 | 1035 | ||
| 599 | mutex_lock(&data->update_lock); | 1036 | mutex_lock(&data->update_lock); |
| 600 | 1037 | ||
| 601 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 1038 | next_update = data->last_updated |
| 1039 | + msecs_to_jiffies(data->update_interval) + 1; | ||
| 1040 | |||
| 1041 | if (time_after(jiffies, next_update) || !data->valid) { | ||
| 602 | if (data->config & 0x04) { /* tachometer enabled */ | 1042 | if (data->config & 0x04) { /* tachometer enabled */ |
| 603 | /* order matters for fan1_input */ | 1043 | /* order matters for fan1_input */ |
| 604 | data->fan[0] = i2c_smbus_read_byte_data(client, | 1044 | data->fan[0] = i2c_smbus_read_byte_data(client, |
| @@ -615,8 +1055,8 @@ static struct lm63_data *lm63_update_device(struct device *dev) | |||
| 615 | LM63_REG_PWM_FREQ); | 1055 | LM63_REG_PWM_FREQ); |
| 616 | if (data->pwm1_freq == 0) | 1056 | if (data->pwm1_freq == 0) |
| 617 | data->pwm1_freq = 1; | 1057 | data->pwm1_freq = 1; |
| 618 | data->pwm1_value = i2c_smbus_read_byte_data(client, | 1058 | data->pwm1[0] = i2c_smbus_read_byte_data(client, |
| 619 | LM63_REG_PWM_VALUE); | 1059 | LM63_REG_PWM_VALUE); |
| 620 | 1060 | ||
| 621 | data->temp8[0] = i2c_smbus_read_byte_data(client, | 1061 | data->temp8[0] = i2c_smbus_read_byte_data(client, |
| 622 | LM63_REG_LOCAL_TEMP); | 1062 | LM63_REG_LOCAL_TEMP); |
| @@ -636,6 +1076,17 @@ static struct lm63_data *lm63_update_device(struct device *dev) | |||
| 636 | LM63_REG_REMOTE_HIGH_MSB) << 8) | 1076 | LM63_REG_REMOTE_HIGH_MSB) << 8) |
| 637 | | i2c_smbus_read_byte_data(client, | 1077 | | i2c_smbus_read_byte_data(client, |
| 638 | LM63_REG_REMOTE_HIGH_LSB); | 1078 | LM63_REG_REMOTE_HIGH_LSB); |
| 1079 | data->temp11[3] = (i2c_smbus_read_byte_data(client, | ||
| 1080 | LM63_REG_REMOTE_OFFSET_MSB) << 8) | ||
| 1081 | | i2c_smbus_read_byte_data(client, | ||
| 1082 | LM63_REG_REMOTE_OFFSET_LSB); | ||
| 1083 | |||
| 1084 | if (data->kind == lm96163) | ||
| 1085 | data->temp11u = (i2c_smbus_read_byte_data(client, | ||
| 1086 | LM96163_REG_REMOTE_TEMP_U_MSB) << 8) | ||
| 1087 | | i2c_smbus_read_byte_data(client, | ||
| 1088 | LM96163_REG_REMOTE_TEMP_U_LSB); | ||
| 1089 | |||
| 639 | data->temp8[2] = i2c_smbus_read_byte_data(client, | 1090 | data->temp8[2] = i2c_smbus_read_byte_data(client, |
| 640 | LM63_REG_REMOTE_TCRIT); | 1091 | LM63_REG_REMOTE_TCRIT); |
| 641 | data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, | 1092 | data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, |
| @@ -648,6 +1099,21 @@ static struct lm63_data *lm63_update_device(struct device *dev) | |||
| 648 | data->valid = 1; | 1099 | data->valid = 1; |
| 649 | } | 1100 | } |
| 650 | 1101 | ||
| 1102 | if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || | ||
| 1103 | !data->lut_valid) { | ||
| 1104 | for (i = 0; i < data->lut_size; i++) { | ||
| 1105 | data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, | ||
| 1106 | LM63_REG_LUT_PWM(i)); | ||
| 1107 | data->temp8[3 + i] = i2c_smbus_read_byte_data(client, | ||
| 1108 | LM63_REG_LUT_TEMP(i)); | ||
| 1109 | } | ||
| 1110 | data->lut_temp_hyst = i2c_smbus_read_byte_data(client, | ||
| 1111 | LM63_REG_LUT_TEMP_HYST); | ||
| 1112 | |||
| 1113 | data->lut_last_updated = jiffies; | ||
| 1114 | data->lut_valid = 1; | ||
| 1115 | } | ||
| 1116 | |||
| 651 | mutex_unlock(&data->update_lock); | 1117 | mutex_unlock(&data->update_lock); |
| 652 | 1118 | ||
| 653 | return data; | 1119 | return data; |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index bdfd675488ae..d2dd5f90496d 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
| @@ -917,7 +917,7 @@ static ssize_t set_update_interval(struct device *dev, | |||
| 917 | return err; | 917 | return err; |
| 918 | 918 | ||
| 919 | mutex_lock(&data->update_lock); | 919 | mutex_lock(&data->update_lock); |
| 920 | lm90_set_convrate(client, data, val); | 920 | lm90_set_convrate(client, data, SENSORS_LIMIT(val, 0, 100000)); |
| 921 | mutex_unlock(&data->update_lock); | 921 | mutex_unlock(&data->update_lock); |
| 922 | 922 | ||
| 923 | return count; | 923 | return count; |
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index 84ef3a898707..482ca901db30 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c | |||
| @@ -106,11 +106,14 @@ static ssize_t show_adc(struct device *dev, | |||
| 106 | if (ret < 0) | 106 | if (ret < 0) |
| 107 | return ret; | 107 | return ret; |
| 108 | 108 | ||
| 109 | return sprintf(buf, "%d\n", ret); | 109 | /* assume the reference voltage to be 2.048V, with an 8-bit sample, |
| 110 | * the LSB weight is 8mV | ||
| 111 | */ | ||
| 112 | return sprintf(buf, "%d\n", ret * 8); | ||
| 110 | } | 113 | } |
| 111 | 114 | ||
| 112 | #define MAX1111_ADC_ATTR(_id) \ | 115 | #define MAX1111_ADC_ATTR(_id) \ |
| 113 | SENSOR_DEVICE_ATTR(adc##_id##_in, S_IRUGO, show_adc, NULL, _id) | 116 | SENSOR_DEVICE_ATTR(in##_id##_input, S_IRUGO, show_adc, NULL, _id) |
| 114 | 117 | ||
| 115 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 118 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
| 116 | static MAX1111_ADC_ATTR(0); | 119 | static MAX1111_ADC_ATTR(0); |
| @@ -120,10 +123,10 @@ static MAX1111_ADC_ATTR(3); | |||
| 120 | 123 | ||
| 121 | static struct attribute *max1111_attributes[] = { | 124 | static struct attribute *max1111_attributes[] = { |
| 122 | &dev_attr_name.attr, | 125 | &dev_attr_name.attr, |
| 123 | &sensor_dev_attr_adc0_in.dev_attr.attr, | 126 | &sensor_dev_attr_in0_input.dev_attr.attr, |
| 124 | &sensor_dev_attr_adc1_in.dev_attr.attr, | 127 | &sensor_dev_attr_in1_input.dev_attr.attr, |
| 125 | &sensor_dev_attr_adc2_in.dev_attr.attr, | 128 | &sensor_dev_attr_in2_input.dev_attr.attr, |
| 126 | &sensor_dev_attr_adc3_in.dev_attr.attr, | 129 | &sensor_dev_attr_in3_input.dev_attr.attr, |
| 127 | NULL, | 130 | NULL, |
| 128 | }; | 131 | }; |
| 129 | 132 | ||
