From 577e315aef0f75116f6d4cbecc5b0d77845e26a2 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 18 Apr 2017 20:40:05 -0700 Subject: [PATCH] Fix up support for IT8613E Feature detection and pwm temperature mapping differs from other chips. Also disable pwm1, fan1, vin3, and vin6. Signed-off-by: Guenter Roeck --- it87.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/it87.c b/it87.c index 4e01fd0..bde1e05 100644 --- 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); -- 2.39.5