aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2017-05-17 21:09:41 -0400
committerGuenter Roeck <linux@roeck-us.net>2017-06-11 20:08:19 -0400
commite5c85221103830a9b234ca0bb957910799a95d7e (patch)
treeb72cf1a5395ccb7c31d33fbb1386a4a94eba31ca
parentcc66b30382549aca35385c04f9a9911052c548ef (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.c45
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 */