diff options
author | Guenter Roeck <linux@roeck-us.net> | 2017-05-17 21:09:41 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2017-06-11 20:08:19 -0400 |
commit | e5c85221103830a9b234ca0bb957910799a95d7e (patch) | |
tree | b72cf1a5395ccb7c31d33fbb1386a4a94eba31ca | |
parent | cc66b30382549aca35385c04f9a9911052c548ef (diff) |
hwmon: (nct6775) Improve fan detection
Recent chips support multiple pins for fan speed inputs and fan control
outputs. Examine all of them to determine supported fan controls.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/nct6775.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index 318e0c5a34c8..4667691ca6a8 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -105,6 +105,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal"); | |||
105 | #define NCT6775_LD_ACPI 0x0a | 105 | #define NCT6775_LD_ACPI 0x0a |
106 | #define NCT6775_LD_HWM 0x0b | 106 | #define NCT6775_LD_HWM 0x0b |
107 | #define NCT6775_LD_VID 0x0d | 107 | #define NCT6775_LD_VID 0x0d |
108 | #define NCT6775_LD_12 0x12 | ||
108 | 109 | ||
109 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | 110 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ |
110 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | 111 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ |
@@ -3392,6 +3393,8 @@ nct6775_check_fan_inputs(struct nct6775_data *data) | |||
3392 | pwm5pin = false; | 3393 | pwm5pin = false; |
3393 | pwm6pin = false; | 3394 | pwm6pin = false; |
3394 | } else { /* NCT6779D, NCT6791D, NCT6792D, or NCT6793D */ | 3395 | } else { /* NCT6779D, NCT6791D, NCT6792D, or NCT6793D */ |
3396 | int regval_1b, regval_2a, regval_eb; | ||
3397 | |||
3395 | regval = superio_inb(sioreg, 0x1c); | 3398 | regval = superio_inb(sioreg, 0x1c); |
3396 | 3399 | ||
3397 | fan3pin = !(regval & BIT(5)); | 3400 | fan3pin = !(regval & BIT(5)); |
@@ -3402,17 +3405,43 @@ nct6775_check_fan_inputs(struct nct6775_data *data) | |||
3402 | pwm4pin = !(regval & BIT(1)); | 3405 | pwm4pin = !(regval & BIT(1)); |
3403 | pwm5pin = !(regval & BIT(2)); | 3406 | pwm5pin = !(regval & BIT(2)); |
3404 | 3407 | ||
3405 | fan4min = fan4pin; | 3408 | regval = superio_inb(sioreg, 0x2d); |
3406 | 3409 | switch (data->kind) { | |
3407 | if (data->kind == nct6791 || data->kind == nct6792 || | 3410 | case nct6791: |
3408 | data->kind == nct6793) { | 3411 | case nct6792: |
3409 | regval = superio_inb(sioreg, 0x2d); | 3412 | fan6pin = regval & BIT(1); |
3410 | fan6pin = (regval & BIT(1)); | 3413 | pwm6pin = regval & BIT(0); |
3411 | pwm6pin = (regval & BIT(0)); | 3414 | break; |
3412 | } else { /* NCT6779D */ | 3415 | case nct6793: |
3416 | regval_1b = superio_inb(sioreg, 0x1b); | ||
3417 | regval_2a = superio_inb(sioreg, 0x2a); | ||
3418 | |||
3419 | if (!pwm5pin) | ||
3420 | pwm5pin = regval & BIT(7); | ||
3421 | fan6pin = regval & BIT(1); | ||
3422 | pwm6pin = regval & BIT(0); | ||
3423 | if (!fan5pin) | ||
3424 | fan5pin = regval_1b & BIT(5); | ||
3425 | |||
3426 | superio_select(sioreg, NCT6775_LD_12); | ||
3427 | regval_eb = superio_inb(sioreg, 0xeb); | ||
3428 | if (!fan5pin) | ||
3429 | fan5pin = regval_eb & BIT(5); | ||
3430 | if (!pwm5pin) | ||
3431 | pwm5pin = (regval_eb & BIT(4)) && | ||
3432 | !(regval_2a & BIT(0)); | ||
3433 | if (!fan6pin) | ||
3434 | fan6pin = regval_eb & BIT(3); | ||
3435 | if (!pwm6pin) | ||
3436 | pwm6pin = regval_eb & BIT(2); | ||
3437 | break; | ||
3438 | default: /* NCT6779D */ | ||
3413 | fan6pin = false; | 3439 | fan6pin = false; |
3414 | pwm6pin = false; | 3440 | pwm6pin = false; |
3441 | break; | ||
3415 | } | 3442 | } |
3443 | |||
3444 | fan4min = fan4pin; | ||
3416 | } | 3445 | } |
3417 | 3446 | ||
3418 | /* fan 1 and 2 (0x03) are always present */ | 3447 | /* fan 1 and 2 (0x03) are always present */ |