X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=it87.c;h=3f3558bc1da159c040de5f3881b625583f9e85a9;hb=3be51e20cb5458c8975d7980404dd962b021b616;hp=5a96c5c879ba2ad54954970859f86ac153914cb1;hpb=93d58d34ac5d5907624ac1033d0da67d36823269;p=groeck-it87 diff --git a/it87.c b/it87.c index 5a96c5c..3f3558b 100644 --- a/it87.c +++ b/it87.c @@ -16,6 +16,8 @@ * IT8622E Super I/O chip w/LPC interface * IT8623E Super I/O chip w/LPC interface * IT8628E Super I/O chip w/LPC interface + * IT8665E Super I/O chip w/LPC interface + * IT8686E Super I/O chip w/LPC interface * IT8705F Super I/O chip w/LPC interface * IT8712F Super I/O chip w/LPC interface * IT8716F Super I/O chip w/LPC interface @@ -74,7 +76,8 @@ enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732, it8771, it8772, it8781, it8782, it8783, it8786, it8790, - it8792, it8603, it8607, it8620, it8622, it8628 }; + it8792, it8603, it8607, it8620, it8622, it8628, it8665, + it8686 }; static unsigned short force_id; module_param(force_id, ushort, 0); @@ -169,6 +172,8 @@ static inline void superio_exit(int ioreg) #define IT8622E_DEVID 0x8622 #define IT8623E_DEVID 0x8623 #define IT8628E_DEVID 0x8628 +#define IT8665E_DEVID 0x8665 +#define IT8686E_DEVID 0x8686 #define IT87_ACT_REG 0x30 #define IT87_BASE_REG 0x60 @@ -178,8 +183,10 @@ static inline void superio_exit(int ioreg) #define IT87_SIO_GPIO3_REG 0x27 #define IT87_SIO_GPIO4_REG 0x28 #define IT87_SIO_GPIO5_REG 0x29 +#define IT87_SIO_GPIO9_REG 0xd3 #define IT87_SIO_PINX1_REG 0x2a /* Pin selection */ #define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ +#define IT87_SIO_PINX4_REG 0x2d /* Pin selection */ #define IT87_SIO_SPI_REG 0xef /* SPI function pin select */ #define IT87_SIO_VID_REG 0xfc /* VID value */ #define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */ @@ -213,6 +220,8 @@ static bool fix_pwm_polarity; #define IT87_REG_ALARM2 0x02 #define IT87_REG_ALARM3 0x03 +#define IT87_REG_BANK 0x06 + /* * The IT8718F and IT8720F have the VID value in a different register, in * Super-I/O configuration space. @@ -233,16 +242,27 @@ static bool fix_pwm_polarity; * - up to 6 fan (1 to 6) */ -static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c }; -static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e }; -static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x4d }; -static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0x4f }; +static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c }; +static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e }; +static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x4d }; +static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0x4f }; + +static const u8 IT87_REG_FAN_8665[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x93 }; +static const u8 IT87_REG_FAN_MIN_8665[] = + { 0x10, 0x11, 0x12, 0x84, 0x86, 0xb2 }; +static const u8 IT87_REG_FANX_8665[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x94 }; +static const u8 IT87_REG_FANX_MIN_8665[] = + { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0xb3 }; + static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; #define IT87_REG_FAN_MAIN_CTRL 0x13 #define IT87_REG_FAN_CTL 0x14 -static const u8 IT87_REG_PWM[] = { 0x15, 0x16, 0x17, 0x7f, 0xa7, 0xaf }; -static const u8 IT87_REG_PWM_DUTY[] = { 0x63, 0x6b, 0x73, 0x7b, 0xa3, 0xab }; + +static const u8 IT87_REG_PWM[] = { 0x15, 0x16, 0x17, 0x7f, 0xa7, 0xaf }; +static const u8 IT87_REG_PWM_8665[] = { 0x15, 0x16, 0x17, 0x1e, 0x1f, 0x92 }; + +static const u8 IT87_REG_PWM_DUTY[] = { 0x63, 0x6b, 0x73, 0x7b, 0xa3, 0xab }; static const u8 IT87_REG_VIN[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x2f, 0x2c, 0x2d, 0x2e }; @@ -307,6 +327,8 @@ struct it87_devices { #define FEAT_VIN3_5V BIT(18) /* VIN3 connected to +5V */ #define FEAT_FOUR_FANS BIT(19) /* Supports four fans */ #define FEAT_FOUR_PWM BIT(20) /* Supports four fan controls */ +#define FEAT_BANK_SEL BIT(21) /* Chip has multi-bank support */ +#define FEAT_SCALING BIT(22) /* Internal voltage scaling */ static const struct it87_devices it87_devices[] = { [it87] = { @@ -348,7 +370,7 @@ static const struct it87_devices it87_devices[] = { .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL - | FEAT_PWM_FREQ2, + | FEAT_PWM_FREQ2 | FEAT_SCALING, .peci_mask = 0x05, .old_peci_mask = 0x02, /* Actually reports PCH */ }, @@ -357,7 +379,7 @@ static const struct it87_devices it87_devices[] = { .suffix = "F", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS - | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2, + | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING, .peci_mask = 0x07, }, [it8732] = { @@ -375,7 +397,7 @@ static const struct it87_devices it87_devices[] = { .suffix = "E", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL - | FEAT_PWM_FREQ2, + | FEAT_PWM_FREQ2 | FEAT_SCALING, /* PECI: guesswork */ /* 12mV ADC (OHM) */ /* 16 bit fans (OHM) */ @@ -387,7 +409,7 @@ static const struct it87_devices it87_devices[] = { .suffix = "E", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL - | FEAT_PWM_FREQ2, + | FEAT_PWM_FREQ2 | FEAT_SCALING, /* PECI (coreboot) */ /* 12mV ADC (HWSensors4, OHM) */ /* 16 bit fans (HWSensors4, OHM) */ @@ -426,17 +448,17 @@ static const struct it87_devices it87_devices[] = { [it8790] = { .name = "it8790", .suffix = "E", - .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS - | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL - | FEAT_PWM_FREQ2, + .features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING + | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI + | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2, .peci_mask = 0x07, }, [it8792] = { .name = "it8792", .suffix = "E", - .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS - | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL - | FEAT_PWM_FREQ2, + .features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING + | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI + | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2, .peci_mask = 0x07, }, [it8603] = { @@ -444,7 +466,7 @@ static const struct it87_devices it87_devices[] = { .suffix = "E", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL - | FEAT_AVCC3 | FEAT_PWM_FREQ2, + | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING, .peci_mask = 0x07, }, [it8607] = { @@ -452,7 +474,7 @@ static const struct it87_devices it87_devices[] = { .suffix = "E", .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL - | FEAT_AVCC3 | FEAT_PWM_FREQ2, + | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING, .peci_mask = 0x07, }, [it8620] = { @@ -461,7 +483,7 @@ static const struct it87_devices it87_devices[] = { .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2 - | FEAT_SIX_TEMP | FEAT_VIN3_5V, + | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING, .peci_mask = 0x07, }, [it8622] = { @@ -470,7 +492,7 @@ static const struct it87_devices it87_devices[] = { .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_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_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING, .peci_mask = 0x07, }, [it8628] = { @@ -479,7 +501,25 @@ static const struct it87_devices it87_devices[] = { .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2 - | FEAT_SIX_TEMP | FEAT_VIN3_5V, + | FEAT_SIX_TEMP | FEAT_SCALING, + .peci_mask = 0x07, + }, + [it8665] = { + .name = "it8665", + .suffix = "E", + .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS + | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI + | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS + | FEAT_SIX_PWM | FEAT_BANK_SEL, + .peci_mask = 0x07, + }, + [it8686] = { + .name = "it8686", + .suffix = "E", + .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS + | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS + | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2 + | FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING, .peci_mask = 0x07, }, }; @@ -514,6 +554,8 @@ static const struct it87_devices it87_devices[] = { #define has_four_pwm(data) ((data)->features & (FEAT_FOUR_PWM | \ FEAT_FIVE_PWM \ | FEAT_SIX_PWM)) +#define has_bank_sel(data) ((data)->features & FEAT_BANK_SEL) +#define has_scaling(data) ((data)->features & FEAT_SCALING) struct it87_sio_data { enum chips type; @@ -538,9 +580,17 @@ struct it87_data { const struct attribute_group *groups[7]; enum chips type; u32 features; + u8 bank; u8 peci_mask; u8 old_peci_mask; + const u8 *REG_FAN; + const u8 *REG_FANX; + const u8 *REG_FAN_MIN; + const u8 *REG_FANX_MIN; + + const u8 *REG_PWM; + unsigned short addr; const char *name; struct mutex update_lock; @@ -686,15 +736,39 @@ static const unsigned int pwm_freq[8] = { 750000, }; +static int _it87_read_value(struct it87_data *data, u8 reg) +{ + outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); + return inb_p(data->addr + IT87_DATA_REG_OFFSET); +} + +static void _it87_write_value(struct it87_data *data, u8 reg, u8 value) +{ + outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); + outb_p(value, data->addr + IT87_DATA_REG_OFFSET); +} + +static void it87_set_bank(struct it87_data *data, u8 bank) +{ + if (has_bank_sel(data) && bank != data->bank) { + u8 breg = _it87_read_value(data, IT87_REG_BANK); + + breg &= 0x1f; + breg |= (bank << 5); + data->bank = bank; + _it87_write_value(data, IT87_REG_BANK, breg); + } +} + /* * Must be called with data->update_lock held, except during initialization. * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, * would slow down the IT87 access and should not be necessary. */ -static int it87_read_value(struct it87_data *data, u8 reg) +static int it87_read_value(struct it87_data *data, u16 reg) { - outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); - return inb_p(data->addr + IT87_DATA_REG_OFFSET); + it87_set_bank(data, reg >> 8); + return _it87_read_value(data, reg & 0xff); } /* @@ -702,15 +776,15 @@ static int it87_read_value(struct it87_data *data, u8 reg) * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, * would slow down the IT87 access and should not be necessary. */ -static void it87_write_value(struct it87_data *data, u8 reg, u8 value) +static void it87_write_value(struct it87_data *data, u16 reg, u8 value) { - outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET); - outb_p(value, data->addr + IT87_DATA_REG_OFFSET); + it87_set_bank(data, reg >> 8); + _it87_write_value(data, reg & 0xff, value); } static void it87_update_pwm_ctrl(struct it87_data *data, int nr) { - data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM[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; data->pwm_duty[nr] = it87_read_value(data, @@ -798,15 +872,15 @@ static struct it87_data *it87_update_device(struct device *dev) continue; data->fan[i][1] = - it87_read_value(data, IT87_REG_FAN_MIN[i]); + it87_read_value(data, data->REG_FAN_MIN[i]); data->fan[i][0] = it87_read_value(data, - IT87_REG_FAN[i]); + data->REG_FAN[i]); /* Add high byte if in 16-bit mode */ if (has_16bit_fans(data)) { data->fan[i][0] |= it87_read_value(data, - IT87_REG_FANX[i]) << 8; + data->REG_FANX[i]) << 8; data->fan[i][1] |= it87_read_value(data, - IT87_REG_FANX_MIN[i]) << 8; + data->REG_FANX_MIN[i]) << 8; } } for (i = 0; i < NUM_TEMP; i++) { @@ -1214,9 +1288,9 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, if (has_16bit_fans(data)) { data->fan[nr][index] = FAN16_TO_REG(val); - it87_write_value(data, IT87_REG_FAN_MIN[nr], + it87_write_value(data, data->REG_FAN_MIN[nr], data->fan[nr][index] & 0xff); - it87_write_value(data, IT87_REG_FANX_MIN[nr], + it87_write_value(data, data->REG_FANX_MIN[nr], data->fan[nr][index] >> 8); } else { reg = it87_read_value(data, IT87_REG_FAN_DIV); @@ -1233,7 +1307,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr, } data->fan[nr][index] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); - it87_write_value(data, IT87_REG_FAN_MIN[nr], + it87_write_value(data, data->REG_FAN_MIN[nr], data->fan[nr][index]); } @@ -1280,7 +1354,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, /* Restore fan min limit */ data->fan[nr][1] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); - it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan[nr][1]); + it87_write_value(data, data->REG_FAN_MIN[nr], data->fan[nr][1]); mutex_unlock(&data->update_lock); return count; @@ -1360,7 +1434,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, ctrl = data->pwm_duty[nr]; } data->pwm_ctrl[nr] = ctrl; - it87_write_value(data, IT87_REG_PWM[nr], ctrl); + it87_write_value(data, data->REG_PWM[nr], ctrl); } } else { u8 ctrl; @@ -1374,7 +1448,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80); } data->pwm_ctrl[nr] = ctrl; - it87_write_value(data, IT87_REG_PWM[nr], ctrl); + it87_write_value(data, data->REG_PWM[nr], ctrl); if (data->type != it8603 && nr < 3) { /* set SmartGuardian mode */ @@ -1421,7 +1495,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, */ if (!(data->pwm_ctrl[nr] & 0x80)) { data->pwm_ctrl[nr] = data->pwm_duty[nr]; - it87_write_value(data, IT87_REG_PWM[nr], + it87_write_value(data, data->REG_PWM[nr], data->pwm_ctrl[nr]); } } @@ -1522,7 +1596,7 @@ static ssize_t set_pwm_temp_map(struct device *dev, if (data->pwm_ctrl[nr] & 0x80) { data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & 0xfc) | data->pwm_temp_map[nr]; - it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]); + it87_write_value(data, data->REG_PWM[nr], data->pwm_ctrl[nr]); } mutex_unlock(&data->update_lock); return count; @@ -2494,6 +2568,12 @@ static int __init it87_find(int sioaddr, unsigned short *address, case IT8628E_DEVID: sio_data->type = it8628; break; + case IT8665E_DEVID: + sio_data->type = it8665; + break; + case IT8686E_DEVID: + sio_data->type = it8686; + break; case 0xffff: /* No device at all */ goto exit; default: @@ -2644,7 +2724,8 @@ 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 == it8620 || sio_data->type == it8628) { + } else if (sio_data->type == it8620 || sio_data->type == it8628 || + sio_data->type == it8686) { int reg; superio_select(sioaddr, GPIO); @@ -2757,6 +2838,48 @@ static int __init it87_find(int sioaddr, unsigned short *address, if (reg & BIT(0)) sio_data->internal |= BIT(0); + sio_data->beep_pin = superio_inb(sioaddr, + IT87_SIO_BEEP_PIN_REG) & 0x3f; + } else if (sio_data->type == it8665) { + int reg; + + superio_select(sioaddr, GPIO); + + /* Check for pwm2 */ + reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG); + if (reg & BIT(1)) + sio_data->skip_pwm |= BIT(1); + + /* Check for fan2 */ + reg = superio_inb(sioaddr, IT87_SIO_PINX4_REG); + if (reg & BIT(4)) + sio_data->skip_fan |= BIT(1); + + /* Check for pwm3, fan3 */ + reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG); + if (reg & BIT(6)) + sio_data->skip_pwm |= BIT(2); + if (reg & BIT(7)) + sio_data->skip_fan |= BIT(2); + + /* Check for pwm5, fan5 */ + reg = superio_inb(sioaddr, IT87_SIO_GPIO2_REG); + if (reg & BIT(5)) + sio_data->skip_pwm |= BIT(4); + if (!(reg & BIT(4))) + sio_data->skip_fan |= BIT(4); + + /* Check for pwm4, fan4, pwm6, fan6 */ + reg = superio_inb(sioaddr, IT87_SIO_GPIO9_REG); + if (reg & BIT(2)) + sio_data->skip_pwm |= BIT(3); + if (reg & BIT(3)) + sio_data->skip_fan |= BIT(3); + if (reg & BIT(0)) + sio_data->skip_pwm |= BIT(5); + if (reg & BIT(1)) + sio_data->skip_fan |= BIT(5); + sio_data->beep_pin = superio_inb(sioaddr, IT87_SIO_BEEP_PIN_REG) & 0x3f; } else { @@ -2895,6 +3018,31 @@ static void it87_init_device(struct platform_device *pdev) int tmp, i; u8 mask; + /* Initialize chip specific register pointers */ + switch (data->type) { + case it8665: + data->REG_FAN = IT87_REG_FAN_8665; + data->REG_FANX = IT87_REG_FANX_8665; + data->REG_FAN_MIN = IT87_REG_FAN_MIN_8665; + data->REG_FANX_MIN = IT87_REG_FANX_MIN_8665; + data->REG_PWM = IT87_REG_PWM_8665; + break; + case it8622: + data->REG_FAN = IT87_REG_FAN; + data->REG_FANX = IT87_REG_FANX; + data->REG_FAN_MIN = IT87_REG_FAN_MIN; + data->REG_FANX_MIN = IT87_REG_FANX_MIN; + data->REG_PWM = IT87_REG_PWM_8665; + break; + default: + data->REG_FAN = IT87_REG_FAN; + data->REG_FANX = IT87_REG_FANX; + data->REG_FAN_MIN = IT87_REG_FAN_MIN; + data->REG_FANX_MIN = IT87_REG_FANX_MIN; + data->REG_PWM = IT87_REG_PWM; + break; + } + /* * For each PWM channel: * - If it is in automatic mode, setting to manual mode should set @@ -2974,20 +3122,39 @@ static void it87_init_device(struct platform_device *pdev) data->has_fan |= BIT(3); /* fan4 enabled */ if (has_five_fans(data) && (tmp & BIT(5))) data->has_fan |= BIT(4); /* fan5 enabled */ - if (!has_fan16_config(data) && has_six_fans(data) && (tmp & BIT(2))) - data->has_fan |= BIT(5); /* fan6 enabled */ + if (has_six_fans(data)) { + switch (data->type) { + case it8620: + case it8628: + case it8686: + if (tmp & BIT(2)) + data->has_fan |= BIT(5); /* fan6 enabled */ + break; + case it8665: + tmp = it87_read_value(data, IT87_REG_FAN_DIV); + if (tmp & BIT(3)) + data->has_fan |= BIT(5); /* fan6 enabled */ + break; + default: + break; + } + } /* Fan input pins may be used for alternative functions */ data->has_fan &= ~sio_data->skip_fan; - /* Check if pwm5, pwm6 are enabled */ + /* Check if pwm6 is enabled */ if (has_six_pwm(data)) { - /* The following code may be IT8620E specific */ - tmp = it87_read_value(data, IT87_REG_FAN_DIV); - if ((tmp & 0xc0) == 0xc0) - sio_data->skip_pwm |= BIT(4); - if (!(tmp & BIT(3))) - sio_data->skip_pwm |= BIT(5); + switch (data->type) { + case it8620: + case it8686: + tmp = it87_read_value(data, IT87_REG_FAN_DIV); + if (!(tmp & BIT(3))) + sio_data->skip_pwm |= BIT(5); + break; + default: + break; + } } /* Start monitoring */ @@ -3019,7 +3186,7 @@ static int it87_check_pwm(struct device *dev) for (i = 0; i < ARRAY_SIZE(pwm); i++) pwm[i] = it87_read_value(data, - IT87_REG_PWM[i]); + data->REG_PWM[i]); /* * If any fan is in automatic pwm mode, the polarity @@ -3034,7 +3201,7 @@ static int it87_check_pwm(struct device *dev) tmp | 0x87); for (i = 0; i < 3; i++) it87_write_value(data, - IT87_REG_PWM[i], + data->REG_PWM[i], 0x7f & ~pwm[i]); return 1; } @@ -3081,6 +3248,8 @@ static int it87_probe(struct platform_device *pdev) data->features = it87_devices[sio_data->type].features; data->peci_mask = it87_devices[sio_data->type].peci_mask; data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask; + data->bank = 0xff; + /* * IT8705F Datasheet 0.4.1, 3h == Version G. * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. @@ -3117,7 +3286,7 @@ static int it87_probe(struct platform_device *pdev) enable_pwm_interface = it87_check_pwm(dev); /* Starting with IT8721F, we handle scaling of internal voltages */ - if (has_12mv_adc(data)) { + if (has_scaling(data)) { if (sio_data->internal & BIT(0)) data->in_scaled |= BIT(3); /* in3 is AVCC */ if (sio_data->internal & BIT(1))