X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=it87.c;h=6f62ff6201bf451ed7f648e1829d3063e14b5d86;hb=96544e8ed5c9c97697d8e7b7c955a4910d66302a;hp=f54724106da14bf2e88e0a077f5e4a565f7da395;hpb=4f62f4d0fd86904853fd9e285b7dd7ebdbfcf244;p=groeck-it87 diff --git a/it87.c b/it87.c index f547241..6f62ff6 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 + * IT8655E 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 @@ -75,7 +77,8 @@ enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732, it8771, it8772, it8781, it8782, it8783, it8786, it8790, - it8792, it8603, it8607, it8620, it8622, it8628, it8686 }; + it8792, it8603, it8607, it8620, it8622, it8628, it8655, it8665, + it8686 }; static unsigned short force_id; module_param(force_id, ushort, 0); @@ -170,6 +173,8 @@ static inline void superio_exit(int ioreg) #define IT8622E_DEVID 0x8622 #define IT8623E_DEVID 0x8623 #define IT8628E_DEVID 0x8628 +#define IT8655E_DEVID 0x8655 +#define IT8665E_DEVID 0x8665 #define IT8686E_DEVID 0x8686 #define IT87_ACT_REG 0x30 #define IT87_BASE_REG 0x60 @@ -180,8 +185,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 */ @@ -237,16 +244,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 }; @@ -312,31 +330,35 @@ struct it87_devices { #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 */ +#define FEAT_FANCTL_ONOFF BIT(23) /* chip has FAN_CTL ON/OFF */ static const struct it87_devices it87_devices[] = { [it87] = { .name = "it87", .suffix = "F", - .features = FEAT_OLD_AUTOPWM, /* may need to overwrite */ + .features = FEAT_OLD_AUTOPWM | FEAT_FANCTL_ONOFF, + /* may need to overwrite */ }, [it8712] = { .name = "it8712", .suffix = "F", - .features = FEAT_OLD_AUTOPWM | FEAT_VID, + .features = FEAT_OLD_AUTOPWM | FEAT_VID | FEAT_FANCTL_ONOFF, /* may need to overwrite */ }, [it8716] = { .name = "it8716", .suffix = "F", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID - | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2, + | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2 + | FEAT_FANCTL_ONOFF, }, [it8718] = { .name = "it8718", .suffix = "F", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS - | FEAT_PWM_FREQ2, + | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF, .old_peci_mask = 0x4, }, [it8720] = { @@ -344,7 +366,7 @@ static const struct it87_devices it87_devices[] = { .suffix = "F", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS - | FEAT_PWM_FREQ2, + | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF, .old_peci_mask = 0x4, }, [it8721] = { @@ -353,7 +375,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 | FEAT_FANCTL_ONOFF, .peci_mask = 0x05, .old_peci_mask = 0x02, /* Actually reports PCH */ }, @@ -362,7 +384,8 @@ 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 + | FEAT_FANCTL_ONOFF, .peci_mask = 0x07, }, [it8732] = { @@ -371,7 +394,7 @@ static const struct it87_devices it87_devices[] = { .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_FOUR_FANS - | FEAT_FOUR_PWM, + | FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF, .peci_mask = 0x07, .old_peci_mask = 0x02, /* Actually reports PCH */ }, @@ -380,7 +403,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 | FEAT_FANCTL_ONOFF, /* PECI: guesswork */ /* 12mV ADC (OHM) */ /* 16 bit fans (OHM) */ @@ -392,7 +415,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 | FEAT_FANCTL_ONOFF, /* PECI (coreboot) */ /* 12mV ADC (HWSensors4, OHM) */ /* 16 bit fans (HWSensors4, OHM) */ @@ -403,21 +426,24 @@ static const struct it87_devices it87_devices[] = { .name = "it8781", .suffix = "F", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET - | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, + | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2 + | FEAT_FANCTL_ONOFF, .old_peci_mask = 0x4, }, [it8782] = { .name = "it8782", .suffix = "F", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET - | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, + | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2 + | FEAT_FANCTL_ONOFF, .old_peci_mask = 0x4, }, [it8783] = { .name = "it8783", .suffix = "E/F", .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET - | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2, + | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2 + | FEAT_FANCTL_ONOFF, .old_peci_mask = 0x4, }, [it8786] = { @@ -425,23 +451,23 @@ 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_FANCTL_ONOFF, .peci_mask = 0x07, }, [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 | FEAT_FANCTL_ONOFF, .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 | FEAT_FANCTL_ONOFF, .peci_mask = 0x07, }, [it8603] = { @@ -449,7 +475,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] = { @@ -457,7 +483,8 @@ 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 + | FEAT_FANCTL_ONOFF, .peci_mask = 0x07, }, [it8620] = { @@ -466,7 +493,8 @@ 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 + | FEAT_FANCTL_ONOFF, .peci_mask = 0x07, }, [it8622] = { @@ -475,7 +503,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] = { @@ -484,7 +512,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_SIX_TEMP | FEAT_SCALING | FEAT_AVCC3 + | FEAT_FANCTL_ONOFF, + .peci_mask = 0x07, + }, + [it8655] = { + .name = "it8655", + .suffix = "E", + .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS + | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_AVCC3 + | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL, + .peci_mask = 0x07, + }, + [it8665] = { + .name = "it8665", + .suffix = "E", + .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS + | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_AVCC3 + | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS + | FEAT_SIX_PWM | FEAT_BANK_SEL, .peci_mask = 0x07, }, [it8686] = { @@ -493,7 +539,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_BANK_SEL, + | FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING | FEAT_AVCC3, .peci_mask = 0x07, }, }; @@ -529,6 +575,8 @@ static const struct it87_devices it87_devices[] = { FEAT_FIVE_PWM \ | FEAT_SIX_PWM)) #define has_bank_sel(data) ((data)->features & FEAT_BANK_SEL) +#define has_scaling(data) ((data)->features & FEAT_SCALING) +#define has_fanctl_onoff(data) ((data)->features & FEAT_FANCTL_ONOFF) struct it87_sio_data { enum chips type; @@ -557,6 +605,13 @@ struct it87_data { 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; @@ -750,7 +805,7 @@ static void it87_write_value(struct it87_data *data, u16 reg, u8 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, @@ -838,15 +893,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++) { @@ -1159,11 +1214,12 @@ static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type, static int pwm_mode(const struct it87_data *data, int nr) { - if (data->type != it8603 && nr < 3 && !(data->fan_main_ctrl & BIT(nr))) + if (has_fanctl_onoff(data) && nr < 3 && + !(data->fan_main_ctrl & BIT(nr))) return 0; /* Full speed */ if (data->pwm_ctrl[nr] & 0x80) return 2; /* Automatic mode */ - if ((data->type == it8603 || nr >= 3) && + if ((!has_fanctl_onoff(data) || nr >= 3) && data->pwm_duty[nr] == pwm_to_reg(data, 0xff)) return 0; /* Full speed */ @@ -1254,9 +1310,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); @@ -1273,7 +1329,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]); } @@ -1320,7 +1376,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; @@ -1376,7 +1432,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); if (val == 0) { - if (nr < 3 && data->type != it8603) { + if (nr < 3 && has_fanctl_onoff(data)) { int tmp; /* make sure the fan is on when in on/off mode */ tmp = it87_read_value(data, IT87_REG_FAN_CTL); @@ -1400,7 +1456,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; @@ -1414,9 +1470,9 @@ 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) { + if (has_fanctl_onoff(data) && nr < 3) { /* set SmartGuardian mode */ data->fan_main_ctrl |= BIT(nr); it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, @@ -1461,7 +1517,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]); } } @@ -1562,7 +1618,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; @@ -2115,9 +2171,9 @@ static struct attribute *it87_attributes_in[] = { &sensor_dev_attr_in8_input.dev_attr.attr, /* 40 */ &sensor_dev_attr_in9_input.dev_attr.attr, /* 41 */ - &sensor_dev_attr_in10_input.dev_attr.attr, /* 41 */ - &sensor_dev_attr_in11_input.dev_attr.attr, /* 41 */ - &sensor_dev_attr_in12_input.dev_attr.attr, /* 41 */ + &sensor_dev_attr_in10_input.dev_attr.attr, /* 42 */ + &sensor_dev_attr_in11_input.dev_attr.attr, /* 43 */ + &sensor_dev_attr_in12_input.dev_attr.attr, /* 44 */ NULL }; @@ -2534,6 +2590,12 @@ static int __init it87_find(int sioaddr, unsigned short *address, case IT8628E_DEVID: sio_data->type = it8628; break; + case IT8655E_DEVID: + sio_data->type = it8655; + break; + case IT8665E_DEVID: + sio_data->type = it8665; + break; case IT8686E_DEVID: sio_data->type = it8686; break; @@ -2731,10 +2793,14 @@ static int __init it87_find(int sioaddr, unsigned short *address, /* Check if AVCC is on VIN3 */ reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG); - if (reg & BIT(0)) - sio_data->internal |= BIT(0); - else + if (reg & BIT(0)) { + /* For it8686, the bit just enables AVCC3 */ + if (sio_data->type != it8686) + sio_data->internal |= BIT(0); + } else { + sio_data->internal &= ~BIT(3); sio_data->skip_in |= BIT(9); + } sio_data->beep_pin = superio_inb(sioaddr, IT87_SIO_BEEP_PIN_REG) & 0x3f; @@ -2801,6 +2867,72 @@ 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 == it8655) { + 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); + + 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 { @@ -2939,6 +3071,32 @@ static void it87_init_device(struct platform_device *pdev) int tmp, i; u8 mask; + /* Initialize chip specific register pointers */ + switch (data->type) { + case it8655: + 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 @@ -3018,20 +3176,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 */ @@ -3063,7 +3240,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 @@ -3078,7 +3255,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; } @@ -3163,7 +3340,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))