]> git.sur5r.net Git - groeck-it87/commitdiff
Fix up support for IT8613E
authorGuenter Roeck <linux@roeck-us.net>
Wed, 19 Apr 2017 03:40:05 +0000 (20:40 -0700)
committerGuenter Roeck <linux@roeck-us.net>
Wed, 19 Apr 2017 03:40:05 +0000 (20:40 -0700)
Feature detection and pwm temperature mapping differs from other chips.
Also disable pwm1, fan1, vin3, and vin6.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
it87.c

diff --git a/it87.c b/it87.c
index 4e01fd0e97c507832a77ff6c50d93b436e267cf0..bde1e051fcc4e4c3c9b5813f78fd1c3515ec40f7 100644 (file)
--- a/it87.c
+++ b/it87.c
@@ -81,8 +81,8 @@
 
 enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
             it8771, it8772, it8781, it8782, it8783, it8786, it8790,
-            it8792, it8603, it8607, it8613, it8620, it8622, it8628, it8655, it8665,
-            it8686 };
+            it8792, it8603, it8607, it8613, it8620, it8622, it8628, it8655,
+            it8665, it8686 };
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
@@ -565,8 +565,8 @@ static const struct it87_devices it87_devices[] = {
                 .features = FEAT_NEWER_AUTOPWM | FEAT_11MV_ADC | FEAT_16BIT_FANS
                   | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
                   | FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
-                  | FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING,
-                .num_temp_limit = 3,
+                  | FEAT_AVCC3 | FEAT_SCALING,
+                .num_temp_limit = 6,
                 .peci_mask = 0x07,
         },
        [it8620] = {
@@ -900,7 +900,10 @@ static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
 {
        data->pwm_ctrl[nr] = it87_read_value(data, data->REG_PWM[nr]);
        if (has_newer_autopwm(data)) {
-               data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+               if (data->type == it8613)
+                       data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x38;
+               else
+                       data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
                data->pwm_duty[nr] = it87_read_value(data,
                                                     IT87_REG_PWM_DUTY[nr]);
        } else {
@@ -1751,10 +1754,16 @@ static ssize_t show_pwm_temp_map(struct device *dev,
        int map;
 
        map = data->pwm_temp_map[nr];
-       if (map >= 3)
-               map = 0;        /* Should never happen */
-       if (nr >= 3)            /* pwm channels 3..6 map to temp4..6 */
-               map += 3;
+       if (data->type == it8613) {
+               map >>= 3;
+               if (map >= 7)
+                       map = 0;        /* Should never happen */
+       } else {
+               if (map >= 3)
+                       map = 0;        /* Should never happen */
+               if (nr >= 3)            /* pwm channels 3..6 map to temp4..6 */
+                       map += 3;
+       }
 
        return sprintf(buf, "%d\n", (int)BIT(map));
 }
@@ -1772,7 +1781,7 @@ static ssize_t set_pwm_temp_map(struct device *dev,
        if (kstrtol(buf, 10, &val) < 0)
                return -EINVAL;
 
-       if (nr >= 3)
+       if (nr >= 3 && data->type != it8613)
                val -= 3;
 
        switch (val) {
@@ -1785,10 +1794,27 @@ static ssize_t set_pwm_temp_map(struct device *dev,
        case BIT(2):
                reg = 0x02;
                break;
+       case BIT(3):
+               reg = 0x03;
+               break;
+       case BIT(4):
+               reg = 0x04;
+               break;
+       case BIT(5):
+               reg = 0x05;
+               break;
+       case BIT(5) | BIT(6):
+               reg = 0x06;
+               break;
        default:
                return -EINVAL;
        }
 
+       if (data->type == it8613)
+               reg <<= 3;
+       else if (reg > 0x02)
+               return -EINVAL;
+
        mutex_lock(&data->update_lock);
        it87_update_pwm_ctrl(data, nr);
        data->pwm_temp_map[nr] = reg;
@@ -2965,6 +2991,43 @@ static int __init it87_find(int sioaddr, unsigned short *address,
                        sio_data->skip_in |= BIT(6); /* No VIN6 */
                }
 
+               sio_data->beep_pin = superio_inb(sioaddr,
+                                                IT87_SIO_BEEP_PIN_REG) & 0x3f;
+       } else if (sio_data->type == it8613) {
+               int reg27, reg29, reg2a;
+
+               superio_select(sioaddr, GPIO);
+
+               /* Check for pwm3, fan3, pwm5, fan5 */
+               reg27 = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
+               if (reg27 & BIT(1))
+                       sio_data->skip_fan |= BIT(4);
+               if (reg27 & BIT(3))
+                       sio_data->skip_pwm |= BIT(4);
+               if (reg27 & BIT(6))
+                       sio_data->skip_pwm |= BIT(2);
+               if (reg27 & BIT(7))
+                       sio_data->skip_fan |= BIT(2);
+
+               /* Check for pwm2, fan2 */
+               reg29 = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
+               if (reg29 & BIT(1))
+                       sio_data->skip_pwm |= BIT(1);
+               if (reg29 & BIT(2))
+                       sio_data->skip_fan |= BIT(1);
+
+               /* Check for pwm4, fan4 */
+               reg2a = superio_inb(sioaddr, IT87_SIO_PINX1_REG);
+               if (!(reg2a & BIT(0)) || (reg29 & BIT(7))) {
+                       sio_data->skip_fan |= BIT(3);
+                       sio_data->skip_pwm |= BIT(3);
+               }
+
+               sio_data->skip_pwm |= BIT(0); /* No pwm1 */
+               sio_data->skip_fan |= BIT(0); /* No fan1 */
+               sio_data->skip_in |= BIT(3);  /* No VIN3 */
+               sio_data->skip_in |= BIT(6);  /* No VIN6 */
+
                sio_data->beep_pin = superio_inb(sioaddr,
                                                 IT87_SIO_BEEP_PIN_REG) & 0x3f;
        } else if (sio_data->type == it8620 || sio_data->type == it8628 ||
@@ -3022,7 +3085,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
 
                sio_data->beep_pin = superio_inb(sioaddr,
                                                 IT87_SIO_BEEP_PIN_REG) & 0x3f;
-       } else if (sio_data->type == it8613 || sio_data->type == it8622) {
+       } else if (sio_data->type == it8622) {
                int reg;
 
                superio_select(sioaddr, GPIO);