]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/hwmon/w83627hf.c
[SCSI] lpfc 8.2.3 : Remove flawed MBX_STOP_IOCB logic
[linux-2.6-omap-h63xx.git] / drivers / hwmon / w83627hf.c
index 2169d8c8bbe4a23ffa20698c83b3639d98b07a8b..879d0a6544ccfb865ef0c6ddeead32e542f3a0bd 100644 (file)
@@ -170,20 +170,16 @@ superio_exit(void)
 #define W83781D_REG_IN(nr)     ((nr < 7) ? (0x20 + (nr)) : \
                                           (0x550 + (nr) - 7))
 
-#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr))
-#define W83781D_REG_FAN(nr) (0x27 + (nr))
-
-#define W83781D_REG_TEMP2_CONFIG 0x152
-#define W83781D_REG_TEMP3_CONFIG 0x252
-#define W83781D_REG_TEMP(nr)           ((nr == 3) ? (0x0250) : \
-                                       ((nr == 2) ? (0x0150) : \
-                                                    (0x27)))
-#define W83781D_REG_TEMP_HYST(nr)      ((nr == 3) ? (0x253) : \
-                                       ((nr == 2) ? (0x153) : \
-                                                    (0x3A)))
-#define W83781D_REG_TEMP_OVER(nr)      ((nr == 3) ? (0x255) : \
-                                       ((nr == 2) ? (0x155) : \
-                                                    (0x39)))
+/* nr:0-2 for fans:1-3 */
+#define W83627HF_REG_FAN_MIN(nr)       (0x3b + (nr))
+#define W83627HF_REG_FAN(nr)           (0x28 + (nr))
+
+#define W83627HF_REG_TEMP2_CONFIG 0x152
+#define W83627HF_REG_TEMP3_CONFIG 0x252
+/* these are zero-based, unlike config constants above */
+static const u16 w83627hf_reg_temp[]           = { 0x27, 0x150, 0x250 };
+static const u16 w83627hf_reg_temp_hyst[]      = { 0x3A, 0x153, 0x253 };
+static const u16 w83627hf_reg_temp_over[]      = { 0x39, 0x155, 0x255 };
 
 #define W83781D_REG_BANK 0x4E
 
@@ -360,12 +356,9 @@ struct w83627hf_data {
        u8 in_min[9];           /* Register value */
        u8 fan[3];              /* Register value */
        u8 fan_min[3];          /* Register value */
-       u8 temp;
-       u8 temp_max;            /* Register value */
-       u8 temp_max_hyst;       /* Register value */
-       u16 temp_add[2];        /* Register value */
-       u16 temp_max_add[2];    /* Register value */
-       u16 temp_max_hyst_add[2]; /* Register value */
+       u16 temp[3];            /* Register value */
+       u16 temp_max[3];        /* Register value */
+       u16 temp_max_hyst[3];   /* Register value */
        u8 fan_div[3];          /* Register encoding, shifted right */
        u8 vid;                 /* Register encoding, combined */
        u32 alarms;             /* Register encoding, combined */
@@ -590,7 +583,7 @@ store_fan_min(struct device *dev, struct device_attribute *devattr,
 
        mutex_lock(&data->update_lock);
        data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-       w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1),
+       w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr),
                             data->fan_min[nr]);
 
        mutex_unlock(&data->update_lock);
@@ -611,12 +604,10 @@ show_temp(struct device *dev, struct device_attribute *devattr, char *buf)
 {
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = w83627hf_update_device(dev);
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               return sprintf(buf, "%ld\n",
-                       (long)LM75_TEMP_FROM_REG(data->temp_add[nr-2]));
-       } else {        /* TEMP1 */
-               return sprintf(buf, "%ld\n", (long)TEMP_FROM_REG(data->temp));
-       }
+
+       u16 tmp = data->temp[nr];
+       return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
+                                         : (long) TEMP_FROM_REG(tmp));
 }
 
 static ssize_t
@@ -625,13 +616,10 @@ show_temp_max(struct device *dev, struct device_attribute *devattr,
 {
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = w83627hf_update_device(dev);
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               return sprintf(buf, "%ld\n",
-                       (long)LM75_TEMP_FROM_REG(data->temp_max_add[nr-2]));
-       } else {        /* TEMP1 */
-               return sprintf(buf, "%ld\n",
-                       (long)TEMP_FROM_REG(data->temp_max));
-       }
+
+       u16 tmp = data->temp_max[nr];
+       return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
+                                         : (long) TEMP_FROM_REG(tmp));
 }
 
 static ssize_t
@@ -640,13 +628,10 @@ show_temp_max_hyst(struct device *dev, struct device_attribute *devattr,
 {
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = w83627hf_update_device(dev);
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               return sprintf(buf, "%ld\n",
-                       (long)LM75_TEMP_FROM_REG(data->temp_max_hyst_add[nr-2]));
-       } else {        /* TEMP1 */
-               return sprintf(buf, "%ld\n",
-                       (long)TEMP_FROM_REG(data->temp_max_hyst));
-       }
+
+       u16 tmp = data->temp_max_hyst[nr];
+       return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp)
+                                         : (long) TEMP_FROM_REG(tmp));
 }
 
 static ssize_t
@@ -656,18 +641,11 @@ store_temp_max(struct device *dev, struct device_attribute *devattr,
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = dev_get_drvdata(dev);
        long val = simple_strtol(buf, NULL, 10);
+       u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
 
        mutex_lock(&data->update_lock);
-
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               data->temp_max_add[nr-2] = LM75_TEMP_TO_REG(val);
-               w83627hf_write_value(data, W83781D_REG_TEMP_OVER(nr),
-                               data->temp_max_add[nr-2]);
-       } else {        /* TEMP1 */
-               data->temp_max = TEMP_TO_REG(val);
-               w83627hf_write_value(data, W83781D_REG_TEMP_OVER(nr),
-                       data->temp_max);
-       }
+       data->temp_max[nr] = tmp;
+       w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp);
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -679,29 +657,22 @@ store_temp_max_hyst(struct device *dev, struct device_attribute *devattr,
        int nr = to_sensor_dev_attr(devattr)->index;
        struct w83627hf_data *data = dev_get_drvdata(dev);
        long val = simple_strtol(buf, NULL, 10);
+       u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
 
        mutex_lock(&data->update_lock);
-
-       if (nr >= 2) {  /* TEMP2 and TEMP3 */
-               data->temp_max_hyst_add[nr-2] = LM75_TEMP_TO_REG(val);
-               w83627hf_write_value(data, W83781D_REG_TEMP_HYST(nr),
-                               data->temp_max_hyst_add[nr-2]);
-       } else {        /* TEMP1 */
-               data->temp_max_hyst = TEMP_TO_REG(val);
-               w83627hf_write_value(data, W83781D_REG_TEMP_HYST(nr),
-                       data->temp_max_hyst);
-       }
+       data->temp_max_hyst[nr] = tmp;
+       w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp);
        mutex_unlock(&data->update_lock);
        return count;
 }
 
 #define sysfs_temp_decl(offset) \
 static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,               \
-                         show_temp, NULL, offset);                     \
+                         show_temp, NULL, offset - 1);                 \
 static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO|S_IWUSR,         \
-                         show_temp_max, store_temp_max, offset);       \
+                         show_temp_max, store_temp_max, offset - 1);   \
 static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO|S_IWUSR,    \
-                         show_temp_max_hyst, store_temp_max_hyst, offset);
+                         show_temp_max_hyst, store_temp_max_hyst, offset - 1);
 
 sysfs_temp_decl(1);
 sysfs_temp_decl(2);
@@ -844,7 +815,7 @@ store_fan_div(struct device *dev, struct device_attribute *devattr,
 
        /* Restore fan_min */
        data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-       w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+       w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr), data->fan_min[nr]);
 
        mutex_unlock(&data->update_lock);
        return count;
@@ -1170,7 +1141,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
        struct w83627hf_sio_data *sio_data = dev->platform_data;
        struct w83627hf_data *data;
        struct resource *res;
-       int err;
+       int err, i;
 
        static const char *names[] = {
                "w83627hf",
@@ -1204,9 +1175,9 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
        w83627hf_init_device(pdev);
 
        /* A few vars need to be filled upon startup */
-       data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1));
-       data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2));
-       data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3));
+       for (i = 0; i <= 2; i++)
+               data->fan_min[i] = w83627hf_read_value(
+                                       data, W83627HF_REG_FAN_MIN(i));
        w83627hf_update_fan_div(data);
 
        /* Register common device attributes */
@@ -1319,6 +1290,24 @@ static int __devexit w83627hf_remove(struct platform_device *pdev)
 }
 
 
+/* Registers 0x50-0x5f are banked */
+static inline void w83627hf_set_bank(struct w83627hf_data *data, u16 reg)
+{
+       if ((reg & 0x00f0) == 0x50) {
+               outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET);
+               outb_p(reg >> 8, data->addr + W83781D_DATA_REG_OFFSET);
+       }
+}
+
+/* Not strictly necessary, but play it safe for now */
+static inline void w83627hf_reset_bank(struct w83627hf_data *data, u16 reg)
+{
+       if (reg & 0xff00) {
+               outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET);
+               outb_p(0, data->addr + W83781D_DATA_REG_OFFSET);
+       }
+}
+
 static int w83627hf_read_value(struct w83627hf_data *data, u16 reg)
 {
        int res, word_sized;
@@ -1329,12 +1318,7 @@ static int w83627hf_read_value(struct w83627hf_data *data, u16 reg)
                  && (((reg & 0x00ff) == 0x50)
                   || ((reg & 0x00ff) == 0x53)
                   || ((reg & 0x00ff) == 0x55));
-       if (reg & 0xff00) {
-               outb_p(W83781D_REG_BANK,
-                      data->addr + W83781D_ADDR_REG_OFFSET);
-               outb_p(reg >> 8,
-                      data->addr + W83781D_DATA_REG_OFFSET);
-       }
+       w83627hf_set_bank(data, reg);
        outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET);
        res = inb_p(data->addr + W83781D_DATA_REG_OFFSET);
        if (word_sized) {
@@ -1344,11 +1328,7 @@ static int w83627hf_read_value(struct w83627hf_data *data, u16 reg)
                    (res << 8) + inb_p(data->addr +
                                       W83781D_DATA_REG_OFFSET);
        }
-       if (reg & 0xff00) {
-               outb_p(W83781D_REG_BANK,
-                      data->addr + W83781D_ADDR_REG_OFFSET);
-               outb_p(0, data->addr + W83781D_DATA_REG_OFFSET);
-       }
+       w83627hf_reset_bank(data, reg);
        mutex_unlock(&data->lock);
        return res;
 }
@@ -1419,12 +1399,7 @@ static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value)
                   || ((reg & 0xff00) == 0x200))
                  && (((reg & 0x00ff) == 0x53)
                   || ((reg & 0x00ff) == 0x55));
-       if (reg & 0xff00) {
-               outb_p(W83781D_REG_BANK,
-                      data->addr + W83781D_ADDR_REG_OFFSET);
-               outb_p(reg >> 8,
-                      data->addr + W83781D_DATA_REG_OFFSET);
-       }
+       w83627hf_set_bank(data, reg);
        outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET);
        if (word_sized) {
                outb_p(value >> 8,
@@ -1434,11 +1409,7 @@ static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value)
        }
        outb_p(value & 0xff,
               data->addr + W83781D_DATA_REG_OFFSET);
-       if (reg & 0xff00) {
-               outb_p(W83781D_REG_BANK,
-                      data->addr + W83781D_ADDR_REG_OFFSET);
-               outb_p(0, data->addr + W83781D_DATA_REG_OFFSET);
-       }
+       w83627hf_reset_bank(data, reg);
        mutex_unlock(&data->lock);
        return 0;
 }
@@ -1514,23 +1485,23 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev)
 
        if(init) {
                /* Enable temp2 */
-               tmp = w83627hf_read_value(data, W83781D_REG_TEMP2_CONFIG);
+               tmp = w83627hf_read_value(data, W83627HF_REG_TEMP2_CONFIG);
                if (tmp & 0x01) {
                        dev_warn(&pdev->dev, "Enabling temp2, readings "
                                 "might not make sense\n");
-                       w83627hf_write_value(data, W83781D_REG_TEMP2_CONFIG,
+                       w83627hf_write_value(data, W83627HF_REG_TEMP2_CONFIG,
                                tmp & 0xfe);
                }
 
                /* Enable temp3 */
                if (type != w83697hf) {
                        tmp = w83627hf_read_value(data,
-                               W83781D_REG_TEMP3_CONFIG);
+                               W83627HF_REG_TEMP3_CONFIG);
                        if (tmp & 0x01) {
                                dev_warn(&pdev->dev, "Enabling temp3, "
                                         "readings might not make sense\n");
                                w83627hf_write_value(data,
-                                       W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
+                                       W83627HF_REG_TEMP3_CONFIG, tmp & 0xfe);
                        }
                }
        }
@@ -1563,7 +1534,7 @@ static void w83627hf_update_fan_div(struct w83627hf_data *data)
 static struct w83627hf_data *w83627hf_update_device(struct device *dev)
 {
        struct w83627hf_data *data = dev_get_drvdata(dev);
-       int i;
+       int i, num_temps = (data->type == w83697hf) ? 2 : 3;
 
        mutex_lock(&data->update_lock);
 
@@ -1584,12 +1555,12 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
                            w83627hf_read_value(data,
                                               W83781D_REG_IN_MAX(i));
                }
-               for (i = 1; i <= 3; i++) {
-                       data->fan[i - 1] =
-                           w83627hf_read_value(data, W83781D_REG_FAN(i));
-                       data->fan_min[i - 1] =
+               for (i = 0; i <= 2; i++) {
+                       data->fan[i] =
+                           w83627hf_read_value(data, W83627HF_REG_FAN(i));
+                       data->fan_min[i] =
                            w83627hf_read_value(data,
-                                              W83781D_REG_FAN_MIN(i));
+                                              W83627HF_REG_FAN_MIN(i));
                }
                for (i = 0; i <= 2; i++) {
                        u8 tmp = w83627hf_read_value(data,
@@ -1616,25 +1587,13 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
                                        break;
                        }
                }
-
-               data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1));
-               data->temp_max =
-                   w83627hf_read_value(data, W83781D_REG_TEMP_OVER(1));
-               data->temp_max_hyst =
-                   w83627hf_read_value(data, W83781D_REG_TEMP_HYST(1));
-               data->temp_add[0] =
-                   w83627hf_read_value(data, W83781D_REG_TEMP(2));
-               data->temp_max_add[0] =
-                   w83627hf_read_value(data, W83781D_REG_TEMP_OVER(2));
-               data->temp_max_hyst_add[0] =
-                   w83627hf_read_value(data, W83781D_REG_TEMP_HYST(2));
-               if (data->type != w83697hf) {
-                       data->temp_add[1] =
-                         w83627hf_read_value(data, W83781D_REG_TEMP(3));
-                       data->temp_max_add[1] =
-                         w83627hf_read_value(data, W83781D_REG_TEMP_OVER(3));
-                       data->temp_max_hyst_add[1] =
-                         w83627hf_read_value(data, W83781D_REG_TEMP_HYST(3));
+               for (i = 0; i < num_temps; i++) {
+                       data->temp[i] = w83627hf_read_value(
+                                               data, w83627hf_reg_temp[i]);
+                       data->temp_max[i] = w83627hf_read_value(
+                                               data, w83627hf_reg_temp_over[i]);
+                       data->temp_max_hyst[i] = w83627hf_read_value(
+                                               data, w83627hf_reg_temp_hyst[i]);
                }
 
                w83627hf_update_fan_div(data);