]> git.sur5r.net Git - groeck-it87/blobdiff - it87.c
Always restore previous bank register after reading/writing data
[groeck-it87] / it87.c
diff --git a/it87.c b/it87.c
index eae64f38ee1fe8d5927e8fba85efd2a1f7017230..e1d3b2ac603ff598e014db9fa86bd27bb734e656 100644 (file)
--- a/it87.c
+++ b/it87.c
@@ -86,6 +86,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 +723,6 @@ struct it87_data {
        const struct attribute_group *groups[7];
        enum chips type;
        u32 features;
-       u8 bank;
        u8 peci_mask;
        u8 old_peci_mask;
 
@@ -917,16 +920,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 +944,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 +961,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,6 +1321,15 @@ 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;
@@ -1314,27 +1340,11 @@ static int get_temp_type(struct it87_data *data, int index)
                u8 src1, src2;
 
                src1 = (it87_read_value(data, s1reg) >> ((index % 2) * 4)) & 0x0f;
-               src2 = it87_read_value(data, IT87_REG_TEMP_SRC2);
 
                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 +1355,7 @@ static int get_temp_type(struct it87_data *data, int index)
                                index = src1;
                                break;
                        }
+                       src2 = it87_read_value(data, IT87_REG_TEMP_SRC2);
                        switch(src1) {
                        case 3:
                                type = (src2 & BIT(index)) ? 6 : 5;
@@ -1363,8 +1374,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 +1706,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 +1719,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);
@@ -3660,7 +3674,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 +3814,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 +3863,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