// SPDX-License-Identifier: GPL-2.0-or-later /* * it87.c - Part of lm_sensors, Linux kernel modules for hardware * monitoring. * * The IT8705F is an LPC-based Super I/O part that contains UARTs, a * parallel port, an IR port, a MIDI port, a floppy controller, etc., in * addition to an Environment Controller (Enhanced Hardware Monitor and * Fan Controller) * * This driver supports only the Environment Controller in the IT8705F and * similar parts. The other devices are supported by different drivers. * * Supports: IT8603E Super I/O chip w/LPC interface * IT8620E Super I/O chip w/LPC interface * IT8622E Super I/O chip w/LPC interface * IT8623E Super I/O chip w/LPC interface * IT8628E 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 * IT8718F Super I/O chip w/LPC interface * IT8720F Super I/O chip w/LPC interface * IT8721F Super I/O chip w/LPC interface * IT8726F Super I/O chip w/LPC interface * IT8728F Super I/O chip w/LPC interface * IT8732F Super I/O chip w/LPC interface * IT8758E Super I/O chip w/LPC interface * IT8771E Super I/O chip w/LPC interface * IT8772E Super I/O chip w/LPC interface * IT8781F Super I/O chip w/LPC interface * IT8782F Super I/O chip w/LPC interface * IT8783E/F Super I/O chip w/LPC interface * IT8786E Super I/O chip w/LPC interface * IT8790E Super I/O chip w/LPC interface * IT8792E Super I/O chip w/LPC interface * IT87952E Super I/O chip w/LPC interface * Sis950 A clone of the IT8705F * * Copyright (C) 2001 Chris Gauthron * Copyright (C) 2005-2010 Jean Delvare <jdelvare@suse.de>
*/
/* * The IT8718F and IT8720F have the VID value in a different register, in * Super-I/O configuration space.
*/ #define IT87_REG_VID 0x0a
/* Interface Selection register on other chips */ #define IT87_REG_IFSEL 0x0a
/* * The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b * for fan divisors. Later IT8712F revisions must use 16-bit tachometer * mode.
*/ #define IT87_REG_FAN_DIV 0x0b #define IT87_REG_FAN_16BIT 0x0c
/* * Monitors: * - up to 13 voltage (0 to 7, battery, avcc, 10 to 12) * - up to 6 temp (1 to 6) * - up to 6 fan (1 to 6)
*/
struct it87_sio_data { int sioaddr; enum chips type; /* Values read from Super-I/O config space */
u8 revision;
u8 vid_value;
u8 beep_pin;
u8 internal; /* Internal sensors can be labeled */ bool need_in7_reroute; /* Features skipped based on config or DMI */
u16 skip_in;
u8 skip_vid;
u8 skip_fan;
u8 skip_pwm;
u8 skip_temp;
u8 smbus_bitmap;
u8 ec_special_config;
};
/* * For each registered chip, we need to keep some data in memory. * The structure is dynamically allocated.
*/ struct it87_data { conststruct attribute_group *groups[7]; int sioaddr; enum chips type;
u32 features;
u8 peci_mask;
u8 old_peci_mask;
u8 smbus_bitmap; /* !=0 if SMBus needs to be disabled */
u8 ec_special_config; /* EC special config register restore value */
unsignedshort addr; constchar *name; struct mutex update_lock; bool valid; /* true if following fields are valid */ unsignedlong last_updated; /* In jiffies */
/* * The following 3 arrays correspond to the same registers up to * the IT8720F. The meaning of bits 6-0 depends on the value of bit * 7, and we want to preserve settings on mode changes, so we have * to track all values separately. * Starting with the IT8721F, the manual PWM duty cycles are stored * in separate registers (8-bit values), so the separate tracking * is no longer needed, but it is still done to keep the driver * simple.
*/
u8 has_pwm; /* Bitfield, pwm control enabled */
u8 pwm_ctrl[NUM_PWM]; /* Register value */
u8 pwm_duty[NUM_PWM]; /* Manual PWM value set by user */
u8 pwm_temp_map[NUM_PWM];/* PWM to temp. chan. mapping (bits 1-0) */
/* Automatic fan speed control registers */
u8 auto_pwm[NUM_AUTO_PWM][4]; /* [nr][3] is hard-coded */
s8 auto_temp[NUM_AUTO_PWM][5]; /* [nr][0] is point1_temp_hyst */
};
/* Board specific settings from DMI matching */ struct it87_dmi_data {
u8 skip_pwm; /* pwm channels to skip for this board */
};
/* Global for results from DMI matching, if needed */ staticstruct it87_dmi_data *dmi_data;
staticint adc_lsb(conststruct it87_data *data, int nr)
{ int lsb;
/* * PWM base frequencies. The frequency has to be divided by either 128 or 256, * depending on the chip type, to calculate the actual PWM frequency. * * Some of the chip datasheets suggest a base frequency of 51 kHz instead * of 750 kHz for the slowest base frequency, resulting in a PWM frequency * of 200 Hz. Sometimes both PWM frequency select registers are affected, * sometimes just one. It is unknown if this is a datasheet error or real, * so this is ignored for now.
*/ staticconstunsignedint pwm_freq[8] = {
48000000,
24000000,
12000000,
8000000,
6000000,
3000000,
1500000,
750000,
};
staticint smbus_disable(struct it87_data *data)
{ int err;
/* * Must be called with data->update_lock held, except during initialization. * Must be called with SMBus accesses disabled. * 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.
*/ staticint 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);
}
/* * Must be called with data->update_lock held, except during initialization. * Must be called with SMBus accesses disabled. * 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.
*/ staticvoid 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);
}
for (i = 0; i < 5 ; i++)
data->auto_temp[nr][i] = it87_read_value(data,
IT87_REG_AUTO_TEMP(nr, i)); for (i = 0; i < 3 ; i++)
data->auto_pwm[nr][i] = it87_read_value(data,
IT87_REG_AUTO_PWM(nr, i));
} elseif (has_newer_autopwm(data)) { int i;
/* * 0: temperature hysteresis (base + 5) * 1: fan off temperature (base + 0) * 2: fan start temperature (base + 1) * 3: fan max temperature (base + 2)
*/
data->auto_temp[nr][0] =
it87_read_value(data, IT87_REG_AUTO_TEMP(nr, 5));
staticstruct it87_data *it87_update_device(struct device *dev)
{ struct it87_data *data = dev_get_drvdata(dev); struct it87_data *ret = data; int err; int i;
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
!data->valid) {
err = smbus_disable(data); if (err) {
ret = ERR_PTR(err); goto unlock;
} if (update_vbat) { /* * Cleared after each update, so reenable. Value * returned by this read will be previous value
*/
it87_write_value(data, IT87_REG_CONFIG,
it87_read_value(data, IT87_REG_CONFIG) | 0x40);
} for (i = 0; i < NUM_VIN; i++) { if (!(data->has_in & BIT(i))) continue;
data->fan_main_ctrl = it87_read_value(data,
IT87_REG_FAN_MAIN_CTRL);
data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); for (i = 0; i < NUM_PWM; i++) { if (!(data->has_pwm & BIT(i))) continue;
it87_update_pwm_ctrl(data, i);
}
data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA); /* * The IT8705F does not have VID capability. * The IT8718F and later don't use IT87_REG_VID for the * same purpose.
*/ if (data->type == it8712 || data->type == it8716) {
data->vid = it87_read_value(data, IT87_REG_VID); /* * The older IT8712F revisions had only 5 VID pins, * but we assume it is always safe to read 6 bits.
*/
data->vid &= 0x3f;
}
data->last_updated = jiffies;
data->valid = true;
smbus_enable(data);
}
unlock:
mutex_unlock(&data->update_lock); return ret;
}
static ssize_t show_in(struct device *dev, struct device_attribute *attr, char *buf)
{ struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); struct it87_data *data = it87_update_device(dev); int index = sattr->index; int nr = sattr->nr;
/* Save fan min limit */
min = FAN_FROM_REG(data->fan[nr][1], DIV_FROM_REG(data->fan_div[nr]));
switch (nr) { case 0: case 1:
data->fan_div[nr] = DIV_TO_REG(val); break; case 2: if (val < 8)
data->fan_div[nr] = 1; else
data->fan_div[nr] = 3;
}
val = old & 0x80;
val |= (data->fan_div[0] & 0x07);
val |= (data->fan_div[1] & 0x07) << 3; if (data->fan_div[2] == 3)
val |= 0x1 << 6;
it87_write_value(data, IT87_REG_FAN_DIV, val);
/* 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_unlock(data); return count;
}
/* Returns 0 if OK, -EINVAL otherwise */ staticint check_trip_points(struct device *dev, int nr)
{ conststruct it87_data *data = dev_get_drvdata(dev); int i, err = 0;
if (has_old_autopwm(data)) { for (i = 0; i < 3; i++) { if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
err = -EINVAL;
} for (i = 0; i < 2; i++) { if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
err = -EINVAL;
}
} elseif (has_newer_autopwm(data)) { for (i = 1; i < 3; i++) { if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
err = -EINVAL;
}
}
if (err) {
dev_err(dev, "Inconsistent trip points, not switching to automatic mode\n");
dev_err(dev, "Adjust the trip points and try again\n");
} return err;
}
static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, constchar *buf, size_t count)
{ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); struct it87_data *data = dev_get_drvdata(dev); int nr = sensor_attr->index; long val; int err;
if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 2) return -EINVAL;
/* Check trip points before switching to automatic mode */ if (val == 2) { if (check_trip_points(dev, nr) < 0) return -EINVAL;
}
err = it87_lock(data); if (err) return err;
if (val == 0) { 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);
it87_write_value(data, IT87_REG_FAN_CTL, tmp | BIT(nr)); /* set on/off mode */
data->fan_main_ctrl &= ~BIT(nr);
it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
data->fan_main_ctrl);
} else {
u8 ctrl;
/* No on/off mode, set maximum pwm value */
data->pwm_duty[nr] = pwm_to_reg(data, 0xff);
it87_write_value(data, IT87_REG_PWM_DUTY[nr],
data->pwm_duty[nr]); /* and set manual mode */ if (has_newer_autopwm(data)) {
ctrl = (data->pwm_ctrl[nr] & 0x7c) |
data->pwm_temp_map[nr];
} else {
ctrl = data->pwm_duty[nr];
}
data->pwm_ctrl[nr] = ctrl;
it87_write_value(data, IT87_REG_PWM[nr], ctrl);
}
} else {
u8 ctrl;
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,
data->fan_main_ctrl);
}
}
it87_unlock(data); return count;
}
static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, constchar *buf, size_t count)
{ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); struct it87_data *data = dev_get_drvdata(dev); int nr = sensor_attr->index; long val; int err;
if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255) return -EINVAL;
err = it87_lock(data); if (err) return err;
it87_update_pwm_ctrl(data, nr); if (has_newer_autopwm(data)) { /* * If we are in automatic mode, the PWM duty cycle register * is read-only so we can't write the value.
*/ if (data->pwm_ctrl[nr] & 0x80) {
count = -EBUSY; goto unlock;
}
data->pwm_duty[nr] = pwm_to_reg(data, val);
it87_write_value(data, IT87_REG_PWM_DUTY[nr],
data->pwm_duty[nr]);
} else {
data->pwm_duty[nr] = pwm_to_reg(data, val); /* * If we are in manual mode, write the duty cycle immediately; * otherwise, just store it for later use.
*/ if (!(data->pwm_ctrl[nr] & 0x80)) {
data->pwm_ctrl[nr] = data->pwm_duty[nr];
it87_write_value(data, IT87_REG_PWM[nr],
data->pwm_ctrl[nr]);
}
}
unlock:
it87_unlock(data); return count;
}
static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr, constchar *buf, size_t count)
{ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); struct it87_data *data = dev_get_drvdata(dev); int nr = sensor_attr->index; unsignedlong val; int err; int i;
if (kstrtoul(buf, 10, &val) < 0) return -EINVAL;
val = clamp_val(val, 0, 1000000);
val *= has_newer_autopwm(data) ? 256 : 128;
/* Search for the nearest available frequency */ for (i = 0; i < 7; i++) { if (val > (pwm_freq[i] + pwm_freq[i + 1]) / 2) break;
}
static ssize_t show_pwm_temp_map(struct device *dev, struct device_attribute *attr, char *buf)
{ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); struct it87_data *data = it87_update_device(dev); int nr = sensor_attr->index; int map;
if (IS_ERR(data)) return PTR_ERR(data);
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;
return sprintf(buf, "%d\n", (int)BIT(map));
}
static ssize_t set_pwm_temp_map(struct device *dev, struct device_attribute *attr, constchar *buf,
size_t count)
{ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); struct it87_data *data = dev_get_drvdata(dev); int nr = sensor_attr->index; long val; int err;
u8 reg;
if (kstrtol(buf, 10, &val) < 0) return -EINVAL;
if (nr >= 3)
val -= 3;
switch (val) { case BIT(0):
reg = 0x00; break; case BIT(1):
reg = 0x01; break; case BIT(2):
reg = 0x02; break; default: return -EINVAL;
}
err = it87_lock(data); if (err) return err;
it87_update_pwm_ctrl(data, nr);
data->pwm_temp_map[nr] = reg; /* * If we are in automatic mode, write the temp mapping immediately; * otherwise, just store it for later use.
*/ 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_unlock(data); return count;
}
static ssize_t show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
{ struct it87_data *data = it87_update_device(dev); struct sensor_device_attribute_2 *sensor_attr =
to_sensor_dev_attr_2(attr); int nr = sensor_attr->nr; int point = sensor_attr->index;
static umode_t it87_in_is_visible(struct kobject *kobj, struct attribute *attr, int index)
{ struct device *dev = kobj_to_dev(kobj); struct it87_data *data = dev_get_drvdata(dev); int i = index / 5; /* voltage index */ int a = index % 5; /* attribute index */
if (index >= 40) { /* in8 and higher only have input attributes */
i = index - 40 + 8;
a = 0;
}
static umode_t it87_temp_is_visible(struct kobject *kobj, struct attribute *attr, int index)
{ struct device *dev = kobj_to_dev(kobj); struct it87_data *data = dev_get_drvdata(dev); int i = index / 7; /* temperature index */ int a = index % 7; /* attribute index */
if (index >= 21) {
i = index - 21 + 3;
a = 0;
}
if (!(data->has_temp & BIT(i))) return 0;
if (a == 3) { if (get_temp_type(data, i) == 0) return 0; return attr->mode;
}
static umode_t it87_fan_is_visible(struct kobject *kobj, struct attribute *attr, int index)
{ struct device *dev = kobj_to_dev(kobj); struct it87_data *data = dev_get_drvdata(dev); int i = index / 5; /* fan index */ int a = index % 5; /* attribute index */
if (index >= 15) { /* fan 4..6 don't have divisor attributes */
i = (index - 15) / 4 + 3;
a = (index - 15) % 4;
}
if (!(data->has_fan & BIT(i))) return 0;
if (a == 3) { /* beep */ if (!data->has_beep) return 0; /* first fan beep attribute is writable */ if (i == __ffs(data->has_fan)) return attr->mode | S_IWUSR;
}
if (a == 4 && has_16bit_fans(data)) /* divisor */ return 0;
static umode_t it87_pwm_is_visible(struct kobject *kobj, struct attribute *attr, int index)
{ struct device *dev = kobj_to_dev(kobj); struct it87_data *data = dev_get_drvdata(dev); int i = index / 4; /* pwm index */ int a = index % 4; /* attribute index */
if (!(data->has_pwm & BIT(i))) return 0;
/* pwmX_auto_channels_temp is only writable if auto pwm is supported */ if (a == 3 && (has_old_autopwm(data) || has_newer_autopwm(data))) return attr->mode | S_IWUSR;
/* pwm2_freq is writable if there are two pwm frequency selects */ if (has_pwm_freq2(data) && i == 1 && a == 2) return attr->mode | S_IWUSR;
static umode_t it87_auto_pwm_is_visible(struct kobject *kobj, struct attribute *attr, int index)
{ struct device *dev = kobj_to_dev(kobj); struct it87_data *data = dev_get_drvdata(dev); int i = index / 11; /* pwm index */ int a = index % 11; /* attribute index */
if (index >= 33) { /* pwm 4..6 */
i = (index - 33) / 6 + 3;
a = (index - 33) % 6 + 4;
}
if (!(data->has_pwm & BIT(i))) return 0;
if (has_newer_autopwm(data)) { if (a < 4) /* no auto point pwm */ return 0; if (a == 8) /* no auto_point4 */ return 0;
} if (has_old_autopwm(data)) { if (a >= 9) /* no pwm_auto_start, pwm_auto_slope */ return 0;
}
/* * Original explanation: * On various Gigabyte AM4 boards (AB350, AX370), the second Super-IO chip * (IT8792E) needs to be in configuration mode before accessing the first * due to a bug in IT8792E which otherwise results in LPC bus access errors. * This needs to be done before accessing the first Super-IO chip since * the second chip may have been accessed prior to loading this driver. * * The problem is also reported to affect IT8795E, which is used on X299 boards * and has the same chip ID as IT8792E (0x8733). It also appears to affect * systems with IT8790E, which is used on some Z97X-Gaming boards as well as * Z87X-OC. * * From other information supplied: * ChipIDs 0x8733, 0x8695 (early ID for IT87952E) and 0x8790 are initialized * and left in configuration mode, and entering and/or exiting configuration * mode is what causes the crash. * * The recommendation is to look up the chipID before doing any mode swap * and then act accordingly.
*/ /* SuperIO detection - will change isa_address if a chip is found */ staticint __init it87_find(int sioaddr, unsignedshort *address, struct it87_sio_data *sio_data, int chip_cnt)
{ int err;
u16 chip_type; conststruct it87_devices *config = NULL; bool enabled = false;
/* First step, lock memory but don't enter configuration mode */
err = superio_enter(sioaddr, true); if (err) return err;
err = -ENODEV;
chip_type = superio_inw(sioaddr, DEVID); /* Check for a valid chip before forcing chip id */ if (chip_type == 0xffff) { /* Enter configuration mode */
__superio_enter(sioaddr);
enabled = true; /* and then try again */
chip_type = superio_inw(sioaddr, DEVID); if (chip_type == 0xffff) gotoexit;
}
if (force_id_cnt == 1) { /* If only one value given use for all chips */ if (force_id[0])
chip_type = force_id[0];
} elseif (force_id[chip_cnt])
chip_type = force_id[chip_cnt];
switch (chip_type) { case IT8705F_DEVID:
sio_data->type = it87; break; case IT8712F_DEVID:
sio_data->type = it8712; break; case IT8716F_DEVID: case IT8726F_DEVID:
sio_data->type = it8716; break; case IT8718F_DEVID:
sio_data->type = it8718; break; case IT8720F_DEVID:
sio_data->type = it8720; break; case IT8721F_DEVID:
sio_data->type = it8721; break; case IT8728F_DEVID:
sio_data->type = it8728; break; case IT8732F_DEVID:
sio_data->type = it8732; break; case IT8792E_DEVID:
sio_data->type = it8792; break; case IT8771E_DEVID:
sio_data->type = it8771; break; case IT8772E_DEVID:
sio_data->type = it8772; break; case IT8781F_DEVID:
sio_data->type = it8781; break; case IT8782F_DEVID:
sio_data->type = it8782; break; case IT8783E_DEVID:
sio_data->type = it8783; break; case IT8786E_DEVID:
sio_data->type = it8786; break; case IT8790E_DEVID:
sio_data->type = it8790; break; case IT8603E_DEVID: case IT8623E_DEVID:
sio_data->type = it8603; break; case IT8620E_DEVID:
sio_data->type = it8620; break; case IT8622E_DEVID:
sio_data->type = it8622; break; case IT8628E_DEVID:
sio_data->type = it8628; break; case IT87952E_DEVID:
sio_data->type = it87952; break; case 0xffff: /* No device at all */ gotoexit; default:
pr_debug("Unsupported chip (DEVID=0x%x)\n", chip_type); gotoexit;
}
config = &it87_devices[sio_data->type];
/* * If previously we didn't enter configuration mode and it isn't a * chip we know is initialised in configuration mode, then enter * configuration mode. * * I don't know if any such chips can exist but be defensive.
*/ if (!enabled && !has_noconf(config)) {
__superio_enter(sioaddr);
enabled = true;
}
superio_select(sioaddr, PME); if (!(superio_inb(sioaddr, IT87_ACT_REG) & 0x01)) {
pr_info("Device (chip %s ioreg 0x%x) not activated, skipping\n",
config->model, sioaddr); gotoexit;
}
*address = superio_inw(sioaddr, IT87_BASE_REG) & ~(IT87_EXTENT - 1); if (*address == 0) {
pr_info("Base address not set (chip %s ioreg 0x%x), skipping\n",
config->model, sioaddr); gotoexit;
}
/* Read GPIO config and VID value from LDN 7 (GPIO) */ if (sio_data->type == it87) { /* The IT8705F has a different LD number for GPIO */
superio_select(sioaddr, 5);
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
} elseif (sio_data->type == it8783) { int reg25, reg27, reg2a, reg2c, regef;
/* Check if fan3 is there or not */ if ((reg27 & BIT(0)) || !(reg2c & BIT(2)))
sio_data->skip_fan |= BIT(2); if ((reg25 & BIT(4)) ||
(!(reg2a & BIT(1)) && (regef & BIT(0))))
sio_data->skip_pwm |= BIT(2);
/* Check if fan2 is there or not */ if (reg27 & BIT(7))
sio_data->skip_fan |= BIT(1); if (reg27 & BIT(3))
sio_data->skip_pwm |= BIT(1);
/* VIN5 */ if ((reg27 & BIT(0)) || (reg2c & BIT(2)))
sio_data->skip_in |= BIT(5); /* No VIN5 */
/* VIN6 */ if (reg27 & BIT(1))
sio_data->skip_in |= BIT(6); /* No VIN6 */
/* * VIN7 * Does not depend on bit 2 of Reg2C, contrary to datasheet.
*/ if (reg27 & BIT(2)) { /* * The data sheet is a bit unclear regarding the * internal voltage divider for VCCH5V. It says * "This bit enables and switches VIN7 (pin 91) to the * internal voltage divider for VCCH5V". * This is different to other chips, where the internal * voltage divider would connect VIN7 to an internal * voltage source. Maybe that is the case here as well. * * Since we don't know for sure, re-route it if that is * not the case, and ask the user to report if the * resulting voltage is sane.
*/ if (!(reg2c & BIT(1))) {
reg2c |= BIT(1);
superio_outb(sioaddr, IT87_SIO_PINX2_REG,
reg2c);
sio_data->need_in7_reroute = true;
pr_notice("Routing internal VCCH5V to in7.\n");
}
pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n");
pr_notice("Please report if it displays a reasonable voltage.\n");
}
if (reg2c & BIT(0))
sio_data->internal |= BIT(0); if (reg2c & BIT(1))
sio_data->internal |= BIT(1);
/* Check if fan3 is there or not */ if (reg27 & BIT(6))
sio_data->skip_pwm |= BIT(2); if (reg27 & BIT(7))
sio_data->skip_fan |= BIT(2);
/* Check if fan2 is there or not */
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);
sio_data->skip_in |= BIT(5); /* No VIN5 */
sio_data->skip_in |= BIT(6); /* No VIN6 */
/* Check for fan4, fan5 */ if (has_five_fans(config)) {
reg = superio_inb(sioaddr, IT87_SIO_GPIO2_REG); switch (sio_data->type) { case it8718: if (reg & BIT(5))
sio_data->skip_fan |= BIT(3); if (reg & BIT(4))
sio_data->skip_fan |= BIT(4); break; case it8720: case it8721: case it8728: if (!(reg & BIT(5)))
sio_data->skip_fan |= BIT(3); if (!(reg & BIT(4)))
sio_data->skip_fan |= BIT(4); break; default: break;
}
}
reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG); if (!sio_data->skip_vid) { /* We need at least 4 VID pins */ if (reg & 0x0f) {
pr_info("VID is disabled (pins used for GPIO)\n");
sio_data->skip_vid = 1;
}
}
/* Check if fan3 is there or not */ if (reg & BIT(6))
sio_data->skip_pwm |= BIT(2); if (reg & BIT(7))
sio_data->skip_fan |= BIT(2);
/* Check if fan2 is there or not */
reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG); if (reg & BIT(1))
sio_data->skip_pwm |= BIT(1); if (reg & BIT(2))
sio_data->skip_fan |= BIT(1);
/* * The IT8720F has no VIN7 pin, so VCCH5V should always be * routed internally to VIN7 with an internal divider. * Curiously, there still is a configuration bit to control * this, which means it can be set incorrectly. And even * more curiously, many boards out there are improperly * configured, even though the IT8720F datasheet claims * that the internal routing of VCCH5V to VIN7 is the default * setting. So we force the internal routing in this case. * * On IT8782F, VIN7 is multiplexed with one of the UART6 pins. * If UART6 is enabled, re-route VIN7 to the internal divider * if that is not already the case.
*/ if ((sio_data->type == it8720 || uart6) && !(reg & BIT(1))) {
reg |= BIT(1);
superio_outb(sioaddr, IT87_SIO_PINX2_REG, reg);
sio_data->need_in7_reroute = true;
pr_notice("Routing internal VCCH5V to in7\n");
} if (reg & BIT(0))
sio_data->internal |= BIT(0); if (reg & BIT(1))
sio_data->internal |= BIT(1);
/* * On IT8782F, UART6 pins overlap with VIN5, VIN6, and VIN7. * While VIN7 can be routed to the internal voltage divider, * VIN5 and VIN6 are not available if UART6 is enabled. * * Also, temp3 is not available if UART6 is enabled and TEMPIN3 * is the temperature source. Since we can not read the * temperature source here, skip_temp is preliminary.
*/ if (uart6) {
sio_data->skip_in |= BIT(5) | BIT(6);
sio_data->skip_temp |= BIT(2);
}
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
} if (sio_data->beep_pin)
pr_info("Beeping is supported\n");
/* Set values based on DMI matches */ if (dmi_data)
sio_data->skip_pwm |= dmi_data->skip_pwm;
/* * Some chips seem to have default value 0xff for all limit * registers. For low voltage limits it makes no sense and triggers * alarms, so change to 0 instead. For high temperature limits, it * means -1 degree C, which surprisingly doesn't trigger an alarm, * but is still confusing, so change to 127 degrees C.
*/ staticvoid it87_check_limit_regs(struct it87_data *data)
{ int i, reg;
for (i = 0; i < NUM_VIN_LIMIT; i++) {
reg = it87_read_value(data, IT87_REG_VIN_MIN(i)); if (reg == 0xff)
it87_write_value(data, IT87_REG_VIN_MIN(i), 0);
} for (i = 0; i < NUM_TEMP_LIMIT; i++) {
reg = it87_read_value(data, IT87_REG_TEMP_HIGH(i)); if (reg == 0xff)
it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
}
}
/* Check if voltage monitors are reset manually or by some reason */ staticvoid it87_check_voltage_monitors_reset(struct it87_data *data)
{ int reg;
reg = it87_read_value(data, IT87_REG_VIN_ENABLE); if ((reg & 0xff) == 0) { /* Enable all voltage monitors */
it87_write_value(data, IT87_REG_VIN_ENABLE, 0xff);
}
}
/* Check if tachometers are reset manually or by some reason */ staticvoid it87_check_tachometers_reset(struct platform_device *pdev)
{ struct it87_sio_data *sio_data = dev_get_platdata(&pdev->dev); struct it87_data *data = platform_get_drvdata(pdev);
u8 mask, fan_main_ctrl;
/* Called when we have found a new IT87. */ staticvoid it87_init_device(struct platform_device *pdev)
{ struct it87_sio_data *sio_data = dev_get_platdata(&pdev->dev); struct it87_data *data = platform_get_drvdata(pdev); int tmp, i;
/* * For each PWM channel: * - If it is in automatic mode, setting to manual mode should set * the fan to full speed by default. * - If it is in manual mode, we need a mapping to temperature * channels to use when later setting to automatic mode later. * Use a 1:1 mapping by default (we are clueless.) * In both cases, the value can (and should) be changed by the user * prior to switching to a different mode. * Note that this is no longer needed for the IT8721F and later, as * these have separate registers for the temperature mapping and the * manual duty cycle.
*/ for (i = 0; i < NUM_AUTO_PWM; i++) {
data->pwm_temp_map[i] = i;
data->pwm_duty[i] = 0x7f; /* Full speed */
data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */
}
it87_check_limit_regs(data);
/* * Temperature channels are not forcibly enabled, as they can be * set to two different sensor types and we can't guess which one * is correct for a given system. These channels can be enabled at * run-time through the temp{1-3}_type sysfs accessors if needed.
*/
/* Fan input pins may be used for alternative functions */
data->has_fan &= ~sio_data->skip_fan;
/* Check if pwm5, pwm6 are 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);
}
it87_start_monitoring(data);
}
/* Return 1 if and only if the PWM interface is safe to use */ staticint it87_check_pwm(struct device *dev)
{ struct it87_data *data = dev_get_drvdata(dev); /* * Some BIOSes fail to correctly configure the IT87 fans. All fans off * and polarity set to active low is sign that this is the case so we * disable pwm control to protect the user.
*/ int tmp = it87_read_value(data, IT87_REG_FAN_CTL);
if ((tmp & 0x87) == 0) { if (fix_pwm_polarity) { /* * The user asks us to attempt a chip reconfiguration. * This means switching to active high polarity and * inverting all fan speed values.
*/ int i;
u8 pwm[3];
for (i = 0; i < ARRAY_SIZE(pwm); i++)
pwm[i] = it87_read_value(data,
IT87_REG_PWM[i]);
/* * If any fan is in automatic pwm mode, the polarity * might be correct, as suspicious as it seems, so we * better don't change anything (but still disable the * PWM interface).
*/ if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) {
dev_info(dev, "Reconfiguring PWM to active high polarity\n");
it87_write_value(data, IT87_REG_FAN_CTL,
tmp | 0x87); for (i = 0; i < 3; i++)
it87_write_value(data,
IT87_REG_PWM[i],
0x7f & ~pwm[i]); return 1;
}
dev_info(dev, "PWM configuration is too broken to be fixed\n");
}
/* Check for additional temperature sensors */ if ((reg & 0x03) >= 0x02)
data->has_temp |= BIT(3); if (((reg >> 2) & 0x03) >= 0x02)
data->has_temp |= BIT(4); if (((reg >> 4) & 0x03) >= 0x02)
data->has_temp |= BIT(5);
/* Check for additional voltage sensors */ if ((reg & 0x03) == 0x01)
data->has_in |= BIT(10); if (((reg >> 2) & 0x03) == 0x01)
data->has_in |= BIT(11); if (((reg >> 4) & 0x03) == 0x01)
data->has_in |= BIT(12);
}
data->has_beep = !!sio_data->beep_pin;
/* Initialize the IT87 chip */
it87_init_device(pdev);
smbus_enable(data);
if (!sio_data->skip_vid) {
data->has_vid = true;
data->vrm = vid_which_vrm(); /* VID reading from Super-I/O config space if available */
data->vid = sio_data->vid_value;
}
/* callback function for DMI */ staticint it87_dmi_cb(conststruct dmi_system_id *dmi_entry)
{
dmi_data = dmi_entry->driver_data;
if (dmi_data && dmi_data->skip_pwm)
pr_info("Disabling pwm2 due to hardware constraints\n");
return 1;
}
/* * On the Shuttle SN68PT, FAN_CTL2 is apparently not * connected to a fan, but to something else. One user * has reported instant system power-off when changing * the PWM2 duty cycle, so we disable it. * I use the board name string as the trigger in case * the same board is ever used in other systems.
*/ staticstruct it87_dmi_data nvidia_fn68pt = {
.skip_pwm = BIT(1),
};
staticint __init sm_it87_init(void)
{ int sioaddr[2] = { REG_2E, REG_4E }; struct it87_sio_data sio_data; unsignedshort isa_address[2]; bool found = false; int i, err;
err = platform_driver_register(&it87_driver); if (err) return err;
dmi_check_system(it87_dmi_table);
for (i = 0; i < ARRAY_SIZE(sioaddr); i++) {
memset(&sio_data, 0, sizeof(struct it87_sio_data));
isa_address[i] = 0;
err = it87_find(sioaddr[i], &isa_address[i], &sio_data, i); if (err || isa_address[i] == 0) continue; /* * Don't register second chip if its ISA address matches * the first chip's ISA address.
*/ if (i && isa_address[i] == isa_address[0]) break;
err = it87_device_add(i, isa_address[i], &sio_data); if (err) goto exit_dev_unregister;
found = true;
/* * IT8705F may respond on both SIO addresses. * Stop probing after finding one.
*/ if (sio_data.type == it87) break;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.115Bemerkung:
(vorverarbeitet am 2026-04-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.