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 <linux@roeck-us.net>
This commit is contained in:
Guenter Roeck
2017-04-18 20:40:05 -07:00
parent 13a3394e95
commit 577e315aef

85
it87.c
View File

@@ -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);