X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=it87.c;h=87ee0882127e81190ea36764747da002162e6bf0;hb=4d29188e4fc9066866304259f6584caa4d3dcea1;hp=eae64f38ee1fe8d5927e8fba85efd2a1f7017230;hpb=aeafb7be7c845d3a60691a32c6e1d86eca623691;p=groeck-it87 diff --git a/it87.c b/it87.c index eae64f3..87ee088 100644 --- a/it87.c +++ b/it87.c @@ -74,6 +74,7 @@ #include #include #include "compat.h" +#include "version.h" #define DRVNAME "it87" @@ -86,6 +87,10 @@ static unsigned short force_id; module_param(force_id, ushort, 0); MODULE_PARM_DESC(force_id, "Override the detected device ID"); +static bool ignore_resource_conflict; +module_param(ignore_resource_conflict, bool, 0); +MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict"); + static struct platform_device *it87_pdev[2]; #define REG_2E 0x2e /* The register to read/write */ @@ -719,7 +724,6 @@ struct it87_data { const struct attribute_group *groups[7]; enum chips type; u32 features; - u8 bank; u8 peci_mask; u8 old_peci_mask; @@ -750,6 +754,7 @@ struct it87_data { s8 temp[NUM_TEMP][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */ u8 num_temp_limit; /* Number of temperature limit registers */ u8 num_temp_offset; /* Number of temperature offset registers */ + u8 temp_src[4]; /* Up to 4 temperature source registers */ u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */ u8 extra; /* Register value (IT87_REG_TEMP_EXTRA) */ u8 fan_div[NUM_FAN_DIV];/* Register encoding, shifted right */ @@ -917,16 +922,21 @@ static void _it87_write_value(struct it87_data *data, u8 reg, u8 value) outb_p(value, data->addr + IT87_DATA_REG_OFFSET); } -static void it87_set_bank(struct it87_data *data, u8 bank) +static u8 it87_set_bank(struct it87_data *data, u8 bank) { - if (has_bank_sel(data) && bank != data->bank) { + u8 _bank = bank; + + if (has_bank_sel(data)) { 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); + _bank = breg >> 5; + if (bank != _bank) { + breg &= 0x1f; + breg |= (bank << 5); + _it87_write_value(data, IT87_REG_BANK, breg); + } } + return _bank; } /* @@ -936,8 +946,14 @@ static void it87_set_bank(struct it87_data *data, u8 bank) */ static int it87_read_value(struct it87_data *data, u16 reg) { - it87_set_bank(data, reg >> 8); - return _it87_read_value(data, reg & 0xff); + u8 bank; + int val; + + bank = it87_set_bank(data, reg >> 8); + val = _it87_read_value(data, reg & 0xff); + it87_set_bank(data, bank); + + return val; } /* @@ -947,8 +963,11 @@ static int it87_read_value(struct it87_data *data, u16 reg) */ static void it87_write_value(struct it87_data *data, u16 reg, u8 value) { - it87_set_bank(data, reg >> 8); + u8 bank; + + bank = it87_set_bank(data, reg >> 8); _it87_write_value(data, reg & 0xff, value); + it87_set_bank(data, bank); } static void it87_update_pwm_ctrl(struct it87_data *data, int nr) @@ -1304,37 +1323,29 @@ static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp, static SENSOR_DEVICE_ATTR_2(temp6_offset, S_IRUGO | S_IWUSR, show_temp, set_temp, 5, 3); +static const u8 temp_types_8686[NUM_TEMP][9] = { + { 0, 8, 8, 8, 8, 8, 8, 8, 7 }, + { 0, 6, 8, 8, 6, 0, 0, 0, 7 }, + { 0, 6, 5, 8, 6, 0, 0, 0, 7 }, + { 4, 8, 8, 8, 8, 8, 8, 8, 7 }, + { 4, 6, 8, 8, 6, 0, 0, 0, 7 }, + { 4, 6, 5, 8, 6, 0, 0, 0, 7 }, +}; + static int get_temp_type(struct it87_data *data, int index) { u8 reg, extra; int type = 0; if (has_bank_sel(data)) { - int s1reg = IT87_REG_TEMP_SRC1[index/2] >> ((index % 2) * 4); u8 src1, src2; - src1 = (it87_read_value(data, s1reg) >> ((index % 2) * 4)) & 0x0f; - src2 = it87_read_value(data, IT87_REG_TEMP_SRC2); + src1 = (data->temp_src[index / 2] >> ((index % 2) * 4)) & 0x0f; switch (data->type) { case it8686: - switch (src1) { - case 0: - if (index >= 3) - return 4; - break; - case 1: - if (index == 1 || index == 2 || - index == 4 || index == 5) - return 6; - break; - case 2: - if (index == 2 || index == 6) - return 5; - break; - default: - break; - } + if (src1 < 9) + type = temp_types_8686[index][src1]; break; case it8625: if (index < 3) @@ -1345,6 +1356,7 @@ static int get_temp_type(struct it87_data *data, int index) index = src1; break; } + src2 = data->temp_src[3]; switch(src1) { case 3: type = (src2 & BIT(index)) ? 6 : 5; @@ -1363,8 +1375,8 @@ static int get_temp_type(struct it87_data *data, int index) return 0; } } - if (index >= 3) - return 0; + if (type || index >= 3) + return type; reg = it87_read_value(data, IT87_REG_TEMP_ENABLE); extra = it87_read_value(data, IT87_REG_TEMP_EXTRA); @@ -1695,6 +1707,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, if (has_newer_autopwm(data)) { ctrl = temp_map_to_reg(data, nr, data->pwm_temp_map[nr]); + ctrl &= 0x7f; } else { ctrl = data->pwm_duty[nr]; } @@ -1707,7 +1720,9 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, if (has_newer_autopwm(data)) { ctrl = temp_map_to_reg(data, nr, data->pwm_temp_map[nr]); - if (val != 1) + if (val == 1) + ctrl &= 0x7f; + else ctrl |= 0x80; } else { ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80); @@ -3222,6 +3237,10 @@ static int __init it87_find(int sioaddr, unsigned short *address, /* Check for pwm2, fan2 */ if (reg29 & BIT(1)) sio_data->skip_pwm |= BIT(1); + /* + * Note: Table 6-1 in datasheet claims that FAN_TAC2 + * would be enabled with 29h[2]=0. + */ if (reg2d & BIT(4)) sio_data->skip_fan |= BIT(1); @@ -3252,7 +3271,7 @@ static int __init it87_find(int sioaddr, unsigned short *address, sio_data->skip_fan |= BIT(3); if (reg26 & BIT(5)) sio_data->skip_pwm |= BIT(4); - if (!(reg26 & BIT(4))) + if (reg26 & BIT(4)) sio_data->skip_fan |= BIT(4); } @@ -3566,6 +3585,13 @@ static void it87_init_device(struct platform_device *pdev) } } + if (has_bank_sel(data)) { + for (i = 0; i < 3; i++) + data->temp_src[i] = + it87_read_value(data, IT87_REG_TEMP_SRC1[i]); + data->temp_src[3] = it87_read_value(data, IT87_REG_TEMP_SRC2); + } + /* Start monitoring */ it87_write_value(data, IT87_REG_CONFIG, (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) @@ -3660,7 +3686,6 @@ static int it87_probe(struct platform_device *pdev) data->pwm_num_temp_map = it87_devices[sio_data->type].num_temp_map; 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. @@ -3801,8 +3826,10 @@ static int __init it87_device_add(int index, unsigned short address, int err; err = acpi_check_resource_conflict(&res); - if (err) - return err; + if (err) { + if (!ignore_resource_conflict) + return err; + } pdev = platform_device_alloc(DRVNAME, address); if (!pdev) @@ -3848,7 +3875,7 @@ struct it87_dmi_data { * 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 IT9792E (0x8733). It also appears to affect + * 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. * DMI entries for those systems will be added as they become available and @@ -3912,6 +3939,8 @@ static int __init sm_it87_init(void) bool found = false; int i, err; + pr_info("it87 driver version %s\n", IT87_DRIVER_VERSION); + if (dmi) dmi_data = dmi->driver_data;