]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/hwmon/w83795.c
hwmon: (w83795) Pack similar register reads
[net-next-2.6.git] / drivers / hwmon / w83795.c
index ec8a1d1f7d7911b1cbe9cda7f35ed0ab864ec1c7..e25a2e31df3f6c7fc1a5143db7f67bc10347e780 100644 (file)
@@ -66,23 +66,6 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
 #define W83795_REG_FANIN_CTRL2         0x07
 #define W83795_REG_VMIGB_CTRL          0x08
 
-#define TEMP_CTRL_DISABLE              0
-#define TEMP_CTRL_TD                   1
-#define TEMP_CTRL_VSEN                 2
-#define TEMP_CTRL_TR                   3
-#define TEMP_CTRL_SHIFT                        4
-#define TEMP_CTRL_HASIN_SHIFT          5
-/* temp mode may effect VSEN17-12 (in20-15) */
-static const u16 W83795_REG_TEMP_CTRL[][6] = {
-       /* Disable, TD, VSEN, TR, register shift value, has_in shift num */
-       {0x00, 0x01, 0x02, 0x03, 0, 17},        /* TR1 */
-       {0x00, 0x04, 0x08, 0x0C, 2, 18},        /* TR2 */
-       {0x00, 0x10, 0x20, 0x30, 4, 19},        /* TR3 */
-       {0x00, 0x40, 0x80, 0xC0, 6, 20},        /* TR4 */
-       {0x00, 0x00, 0x02, 0x03, 0, 15},        /* TR5 */
-       {0x00, 0x00, 0x08, 0x0C, 2, 16},        /* TR6 */
-};
-
 #define TEMP_READ                      0
 #define TEMP_CRIT                      1
 #define TEMP_CRIT_HYST                 2
@@ -145,8 +128,6 @@ static const u8 W83795_REG_IN_HL_LSB[] = {
        (((type) == 1) ? W83795_REG_IN_HL_LSB[(index)] \
        : (W83795_REG_IN_HL_LSB[(index)] + 1))
 
-#define IN_LSB_REG_NUM                 10
-
 #define IN_LSB_SHIFT                   0
 #define IN_LSB_IDX                     1
 static const u8 IN_LSB_SHIFT_IDX[][2] = {
@@ -175,10 +156,6 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = {
 };
 
 
-/* 3VDD, 3VSB, VBAT * 0.006 */
-#define REST_VLT_BEGIN                 12  /* the 13th volt to 15th */
-#define REST_VLT_END                   14  /* the 13th volt to 15th */
-
 #define W83795_REG_FAN(index)          (0x2E + (index))
 #define W83795_REG_FAN_MIN_HL(index)   (0xB6 + (index))
 #define W83795_REG_FAN_MIN_LSB(index)  (0xC4 + (index) / 2)
@@ -187,14 +164,12 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = {
 
 #define W83795_REG_VID_CTRL            0x6A
 
-#define ALARM_BEEP_REG_NUM             6
 #define W83795_REG_ALARM(index)                (0x41 + (index))
 #define W83795_REG_BEEP(index)         (0x50 + (index))
 
 #define W83795_REG_CLR_CHASSIS         0x4D
 
 
-#define W83795_REG_TEMP_NUM            6
 #define W83795_REG_FCMS1               0x201
 #define W83795_REG_FCMS2               0x208
 #define W83795_REG_TFMR(index)         (0x202 + (index))
@@ -203,15 +178,11 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = {
 #define W83795_REG_TSS(index)          (0x209 + (index))
 
 #define PWM_OUTPUT                     0
-#define PWM_START                      1
-#define PWM_NONSTOP                    2
-#define PWM_STOP_TIME                  3
-#define PWM_FREQ                       4
-#define W83795_REG_PWM(index, nr) \
-       (((nr) == 0 ? 0x210 : \
-         (nr) == 1 ? 0x220 : \
-         (nr) == 2 ? 0x228 : \
-         (nr) == 3 ? 0x230 : 0x218) + (index))
+#define PWM_FREQ                       1
+#define PWM_START                      2
+#define PWM_NONSTOP                    3
+#define PWM_STOP_TIME                  4
+#define W83795_REG_PWM(index, nr)      (0x210 + (nr) * 8 + (index))
 
 #define W83795_REG_FTSH(index)         (0x240 + (index) * 2)
 #define W83795_REG_FTSL(index)         (0x241 + (index) * 2)
@@ -250,7 +221,8 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = {
 
 static inline u16 in_from_reg(u8 index, u16 val)
 {
-       if ((index >= REST_VLT_BEGIN) && (index <= REST_VLT_END))
+       /* 3VDD, 3VSB and VBAT: 6 mV/bit; other inputs: 2 mV/bit */
+       if (index >= 12 && index <= 14)
                return val * 6;
        else
                return val * 2;
@@ -258,7 +230,7 @@ static inline u16 in_from_reg(u8 index, u16 val)
 
 static inline u16 in_to_reg(u8 index, u16 val)
 {
-       if ((index >= REST_VLT_BEGIN) && (index <= REST_VLT_END))
+       if (index >= 12 && index <= 14)
                return val / 6;
        else
                return val / 2;
@@ -366,7 +338,7 @@ struct w83795_data {
        u8 has_temp;            /* Enable monitor temp6-1 or not */
        s8 temp[6][5];          /* current, crit, crit_hyst, warn, warn_hyst */
        u8 temp_read_vrlsb[6];
-       u8 temp_mode;           /* bit 0: TR mode, bit 1: TD mode */
+       u8 temp_mode;           /* Bit vector, 0 = TR, 1 = TD */
        u8 temp_src[3];         /* Register value */
 
        u8 enable_dts;          /* Enable PECI and SB-TSI,
@@ -380,8 +352,8 @@ struct w83795_data {
        u8 has_pwm;             /* 795g supports 8 pwm, 795adg only supports 2,
                                 * no config register, only affected by chip
                                 * type */
-       u8 pwm[8][5];           /* Register value, output, start, non stop, stop
-                                * time, freq */
+       u8 pwm[8][5];           /* Register value, output, freq, start,
+                                *  non stop, stop time */
        u16 clkin;              /* CLKIN frequency in kHz */
        u8 pwm_fcms[2];         /* Register value */
        u8 pwm_tfmr[6];         /* Register value */
@@ -516,13 +488,6 @@ static struct w83795_data *w83795_update_device(struct device *dev)
 
        /* Update temperature */
        for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
-               /* even stop monitor, register still keep value, just read out
-                * it */
-               if (!(data->has_temp & (1 << i))) {
-                       data->temp[i][TEMP_READ] = 0;
-                       data->temp_read_vrlsb[i] = 0;
-                       continue;
-               }
                data->temp[i][TEMP_READ] =
                        w83795_read(client, W83795_REG_TEMP[i][TEMP_READ]);
                data->temp_read_vrlsb[i] =
@@ -548,7 +513,7 @@ static struct w83795_data *w83795_update_device(struct device *dev)
        }
 
        /* update alarm */
-       for (i = 0; i < ALARM_BEEP_REG_NUM; i++)
+       for (i = 0; i < ARRAY_SIZE(data->alarms); i++)
                data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i));
 
        data->last_updated = jiffies;
@@ -1170,22 +1135,12 @@ show_dts_mode(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct w83795_data *data = i2c_get_clientdata(client);
-       struct sensor_device_attribute_2 *sensor_attr =
-           to_sensor_dev_attr_2(attr);
-       int index = sensor_attr->index;
-       u8 tmp;
+       int tmp;
 
-       if (data->enable_dts == 0)
-               return sprintf(buf, "%d\n", 0);
-
-       if ((data->has_dts >> index) & 0x01) {
-               if (data->enable_dts & 2)
-                       tmp = 5;
-               else
-                       tmp = 6;
-       } else {
-               tmp = 0;
-       }
+       if (data->enable_dts & 2)
+               tmp = 5;
+       else
+               tmp = 6;
 
        return sprintf(buf, "%d\n", tmp);
 }
@@ -1238,14 +1193,6 @@ store_dts_ext(struct device *dev, struct device_attribute *attr,
 }
 
 
-/*
-       Type 3:  Thermal diode
-       Type 4:  Thermistor
-
-       Temp5-6, default TR
-       Temp1-4, default TD
-*/
-
 static ssize_t
 show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -1254,20 +1201,17 @@ show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf)
        struct sensor_device_attribute_2 *sensor_attr =
            to_sensor_dev_attr_2(attr);
        int index = sensor_attr->index;
-       u8 tmp;
+       int tmp;
 
-       if (data->has_temp >> index & 0x01) {
-               if (data->temp_mode >> index & 0x01)
-                       tmp = 3;
-               else
-                       tmp = 4;
-       } else {
-               tmp = 0;
-       }
+       if (data->temp_mode & (1 << index))
+               tmp = 3;        /* Thermal diode */
+       else
+               tmp = 4;        /* Thermistor */
 
        return sprintf(buf, "%d\n", tmp);
 }
 
+/* Only for temp1-4 (temp5-6 can only be thermistor) */
 static ssize_t
 store_temp_mode(struct device *dev, struct device_attribute *attr,
                const char *buf, size_t count)
@@ -1277,45 +1221,31 @@ store_temp_mode(struct device *dev, struct device_attribute *attr,
        struct sensor_device_attribute_2 *sensor_attr =
            to_sensor_dev_attr_2(attr);
        int index = sensor_attr->index;
+       int reg_shift;
        unsigned long val;
        u8 tmp;
-       u32 mask;
 
        if (strict_strtoul(buf, 10, &val) < 0)
                return -EINVAL;
        if ((val != 4) && (val != 3))
                return -EINVAL;
-       if ((index > 3) && (val == 3))
-               return -EINVAL;
 
        mutex_lock(&data->update_lock);
        if (val == 3) {
-               val = TEMP_CTRL_TD;
-               data->has_temp |= 1 << index;
+               /* Thermal diode */
+               val = 0x01;
                data->temp_mode |= 1 << index;
        } else if (val == 4) {
-               val = TEMP_CTRL_TR;
-               data->has_temp |= 1 << index;
-               tmp = 1 << index;
-               data->temp_mode &= ~tmp;
+               /* Thermistor */
+               val = 0x03;
+               data->temp_mode &= ~(1 << index);
        }
 
-       if (index > 3)
-               tmp = w83795_read(client, W83795_REG_TEMP_CTRL1);
-       else
-               tmp = w83795_read(client, W83795_REG_TEMP_CTRL2);
-
-       mask = 0x03 << W83795_REG_TEMP_CTRL[index][TEMP_CTRL_SHIFT];
-       tmp &= ~mask;
-       tmp |= W83795_REG_TEMP_CTRL[index][val];
-
-       mask = 1 << W83795_REG_TEMP_CTRL[index][TEMP_CTRL_HASIN_SHIFT];
-       data->has_in &= ~mask;
-
-       if (index > 3)
-               w83795_write(client, W83795_REG_TEMP_CTRL1, tmp);
-       else
-               w83795_write(client, W83795_REG_TEMP_CTRL2, tmp);
+       reg_shift = 2 * index;
+       tmp = w83795_read(client, W83795_REG_TEMP_CTRL2);
+       tmp &= ~(0x03 << reg_shift);
+       tmp |= val << reg_shift;
+       w83795_write(client, W83795_REG_TEMP_CTRL2, tmp);
 
        mutex_unlock(&data->update_lock);
        return count;
@@ -1513,7 +1443,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
                show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) }
 
 #define SENSOR_ATTR_TEMP(index) {                                      \
-       SENSOR_ATTR_2(temp##index##_type, S_IRUGO | S_IWUSR,            \
+       SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \
                show_temp_mode, store_temp_mode, NOT_USED, index - 1),  \
        SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp,          \
                NULL, TEMP_READ, index - 1),                            \
@@ -1969,7 +1899,7 @@ static int w83795_probe(struct i2c_client *client,
                }
        }
 
-       /* First update the voltages measured value and limits */
+       /* Read the voltage limits */
        for (i = 0; i < ARRAY_SIZE(data->in); i++) {
                if (!(data->has_in & (1 << i)))
                        continue;
@@ -1977,11 +1907,8 @@ static int w83795_probe(struct i2c_client *client,
                        w83795_read(client, W83795_REG_IN[i][IN_MAX]);
                data->in[i][IN_LOW] =
                        w83795_read(client, W83795_REG_IN[i][IN_LOW]);
-               tmp = w83795_read(client, W83795_REG_IN[i][IN_READ]) << 2;
-               tmp |= w83795_read(client, W83795_REG_VRLSB) >> 6;
-               data->in[i][IN_READ] = tmp;
        }
-       for (i = 0; i < IN_LSB_REG_NUM; i++) {
+       for (i = 0; i < ARRAY_SIZE(data->in_lsb); i++) {
                if ((i == 2 && data->chip_type == w83795adg) ||
                    (i >= 4 && !(data->has_in & (1 << (i + 11)))))
                        continue;
@@ -1992,7 +1919,7 @@ static int w83795_probe(struct i2c_client *client,
        }
        data->has_gain = w83795_read(client, W83795_REG_VMIGB_CTRL) & 0x0f;
 
-       /* First update fan and limits */
+       /* Read the fan limits */
        for (i = 0; i < ARRAY_SIZE(data->fan); i++) {
                /* Each register contains LSB for 2 fans, but we want to
                 * read it only once to save time */
@@ -2005,45 +1932,22 @@ static int w83795_probe(struct i2c_client *client,
                        w83795_read(client, W83795_REG_FAN_MIN_HL(i)) << 4;
                data->fan_min[i] |=
                        (tmp >> W83795_REG_FAN_MIN_LSB_SHIFT(i)) & 0x0F;
-               data->fan[i] = w83795_read(client, W83795_REG_FAN(i)) << 4;
-               data->fan[i] |= w83795_read(client, W83795_REG_VRLSB) >> 4;
        }
 
-       /* temperature and limits */
+       /* Read the temperature limits */
        for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
                if (!(data->has_temp & (1 << i)))
                        continue;
-               data->temp[i][TEMP_CRIT] =
-                       w83795_read(client, W83795_REG_TEMP[i][TEMP_CRIT]);
-               data->temp[i][TEMP_CRIT_HYST] =
-                       w83795_read(client, W83795_REG_TEMP[i][TEMP_CRIT_HYST]);
-               data->temp[i][TEMP_WARN] =
-                       w83795_read(client, W83795_REG_TEMP[i][TEMP_WARN]);
-               data->temp[i][TEMP_WARN_HYST] =
-                       w83795_read(client, W83795_REG_TEMP[i][TEMP_WARN_HYST]);
-               data->temp[i][TEMP_READ] =
-                       w83795_read(client, W83795_REG_TEMP[i][TEMP_READ]);
-               data->temp_read_vrlsb[i] =
-                       w83795_read(client, W83795_REG_VRLSB);
+               for (tmp = TEMP_CRIT; tmp <= TEMP_WARN_HYST; tmp++)
+                       data->temp[i][tmp] =
+                               w83795_read(client, W83795_REG_TEMP[i][tmp]);
        }
 
-       /* dts temperature and limits */
+       /* Read the DTS limits */
        if (data->enable_dts != 0) {
-               data->dts_ext[DTS_CRIT] =
-                       w83795_read(client, W83795_REG_DTS_EXT(DTS_CRIT));
-               data->dts_ext[DTS_CRIT_HYST] =
-                       w83795_read(client, W83795_REG_DTS_EXT(DTS_CRIT_HYST));
-               data->dts_ext[DTS_WARN] =
-                       w83795_read(client, W83795_REG_DTS_EXT(DTS_WARN));
-               data->dts_ext[DTS_WARN_HYST] =
-                       w83795_read(client, W83795_REG_DTS_EXT(DTS_WARN_HYST));
-               for (i = 0; i < ARRAY_SIZE(data->dts); i++) {
-                       if (!(data->has_dts & (1 << i)))
-                               continue;
-                       data->dts[i] = w83795_read(client, W83795_REG_DTS(i));
-                       data->dts_read_vrlsb[i] =
-                               w83795_read(client, W83795_REG_VRLSB);
-               }
+               for (i = DTS_CRIT; i <= DTS_WARN_HYST; i++)
+                       data->dts_ext[i] =
+                               w83795_read(client, W83795_REG_DTS_EXT(i));
        }
 
        /* First update temp source selction */
@@ -2057,14 +1961,13 @@ static int w83795_probe(struct i2c_client *client,
                data->has_pwm = 2;
        data->pwm_fcms[0] = w83795_read(client, W83795_REG_FCMS1);
        data->pwm_fcms[1] = w83795_read(client, W83795_REG_FCMS2);
-       for (i = 0; i < W83795_REG_TEMP_NUM; i++)
+       for (i = 0; i < ARRAY_SIZE(data->pwm_tfmr); i++)
                data->pwm_tfmr[i] = w83795_read(client, W83795_REG_TFMR(i));
        data->pwm_fomc = w83795_read(client, W83795_REG_FOMC);
        for (i = 0; i < data->has_pwm; i++) {
-               for (tmp = 0; tmp < 5; tmp++) {
+               for (tmp = PWM_FREQ; tmp <= PWM_STOP_TIME; tmp++)
                        data->pwm[i][tmp] =
                                w83795_read(client, W83795_REG_PWM(i, tmp));
-               }
        }
        for (i = 0; i < 8; i++) {
                data->target_speed[i] =
@@ -2074,7 +1977,7 @@ static int w83795_probe(struct i2c_client *client,
        }
        data->tol_speed = w83795_read(client, W83795_REG_TFTS) & 0x3f;
 
-       for (i = 0; i < W83795_REG_TEMP_NUM; i++) {
+       for (i = 0; i < ARRAY_SIZE(data->pwm_temp); i++) {
                data->pwm_temp[i][TEMP_PWM_TTTI] =
                        w83795_read(client, W83795_REG_TTTI(i)) & 0x7f;
                data->pwm_temp[i][TEMP_PWM_CTFS] =
@@ -2083,7 +1986,7 @@ static int w83795_probe(struct i2c_client *client,
                data->pwm_temp[i][TEMP_PWM_HCT] = (tmp >> 4) & 0x0f;
                data->pwm_temp[i][TEMP_PWM_HOT] = tmp & 0x0f;
        }
-       for (i = 0; i < W83795_REG_TEMP_NUM; i++) {
+       for (i = 0; i < ARRAY_SIZE(data->sf4_reg); i++) {
                for (tmp = 0; tmp < 7; tmp++) {
                        data->sf4_reg[i][SF4_TEMP][tmp] =
                                w83795_read(client,
@@ -2099,11 +2002,9 @@ static int w83795_probe(struct i2c_client *client,
                        w83795_read(client, W83795_REG_SETUP_PWM(i));
        }
 
-       /* alarm and beep */
-       for (i = 0; i < ALARM_BEEP_REG_NUM; i++) {
-               data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i));
+       /* Read beep settings */
+       for (i = 0; i < ARRAY_SIZE(data->beeps); i++)
                data->beeps[i] = w83795_read(client, W83795_REG_BEEP(i));
-       }
 
        err = w83795_handle_files(dev, device_create_file);
        if (err)