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:
85
it87.c
85
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);
|
||||
|
Reference in New Issue
Block a user