aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <guenter.roeck@ericsson.com>2011-02-11 11:00:58 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-03-15 01:39:18 -0400
commit26bc440e3f14df5daff4d1ff0f37de5e260cea18 (patch)
tree26c639e33085a935fb683708416fde45d2f73abb
parentec3e5a16446fef1891611fe3bdfa5954d1ddf5e4 (diff)
hwmon: (w83627ehf) Use 16 bit fan count registers if supported
Some of the chips supported by this driver have 13 bit or 16 bit fan count registers. This patch improves support for those registers, specifically for NCT6775F. With the changes in this patch, fan speed is reported correctly even if the fan divider is set to a low value, which results in a fan speed reading above 0xff. With this patch, the width of fan count registers is no longer used to determine if the chip has fan divider register(s) or not. A dedicated flag is used instead to determine if this is the case. Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com> Acked-by: Ian Dobson <i.dobson@planet-ian.com>
-rw-r--r--drivers/hwmon/w83627ehf.c86
1 files changed, 59 insertions, 27 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index b3b4f2b41dcf..df6e50260e01 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -234,7 +234,7 @@ static const u16 NCT6775_REG_FAN_STOP_TIME[] = { 0x107, 0x207, 0x307 };
234static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309 }; 234static const u16 NCT6775_REG_PWM[] = { 0x109, 0x209, 0x309 };
235static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a }; 235static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
236static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b }; 236static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
237static const u16 NCT6776_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 }; 237static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
238static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642}; 238static const u16 NCT6776_REG_FAN_MIN[] = { 0x63a, 0x63c, 0x63e, 0x640, 0x642};
239 239
240static const u16 NCT6775_REG_TEMP[] 240static const u16 NCT6775_REG_TEMP[]
@@ -342,21 +342,36 @@ static inline u8 step_time_to_reg(unsigned int msec, u8 mode)
342 (msec + 200) / 400), 1, 255); 342 (msec + 200) / 400), 1, 255);
343} 343}
344 344
345static inline unsigned int 345static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
346fan_from_reg(int reg, u16 val, unsigned int div)
347{ 346{
348 if (val == 0) 347 if (reg == 0 || reg == 255)
349 return 0; 348 return 0;
350 if (is_word_sized(reg)) { 349 return 1350000U / (reg << divreg);
351 if ((val & 0xff1f) == 0xff1f) 350}
352 return 0; 351
353 val = (val & 0x1f) | ((val & 0xff00) >> 3); 352static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
354 } else { 353{
355 if (val == 255 || div == 0) 354 if ((reg & 0xff1f) == 0xff1f)
356 return 0; 355 return 0;
357 val *= div; 356
358 } 357 reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
359 return 1350000U / val; 358
359 if (reg == 0)
360 return 0;
361
362 return 1350000U / reg;
363}
364
365static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
366{
367 if (reg == 0 || reg == 0xffff)
368 return 0;
369
370 /*
371 * Even though the registers are 16 bit wide, the fan divisor
372 * still applies.
373 */
374 return 1350000U / (reg << divreg);
360} 375}
361 376
362static inline unsigned int 377static inline unsigned int
@@ -424,6 +439,9 @@ struct w83627ehf_data {
424 const u16 *REG_FAN_MAX_OUTPUT; 439 const u16 *REG_FAN_MAX_OUTPUT;
425 const u16 *REG_FAN_STEP_OUTPUT; 440 const u16 *REG_FAN_STEP_OUTPUT;
426 441
442 unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
443 unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
444
427 struct mutex update_lock; 445 struct mutex update_lock;
428 char valid; /* !=0 if following fields are valid */ 446 char valid; /* !=0 if following fields are valid */
429 unsigned long last_updated; /* In jiffies */ 447 unsigned long last_updated; /* In jiffies */
@@ -439,6 +457,7 @@ struct w83627ehf_data {
439 u8 fan_div[5]; 457 u8 fan_div[5];
440 u8 has_fan; /* some fan inputs can be disabled */ 458 u8 has_fan; /* some fan inputs can be disabled */
441 u8 has_fan_min; /* some fans don't have min register */ 459 u8 has_fan_min; /* some fans don't have min register */
460 bool has_fan_div;
442 u8 temp_type[3]; 461 u8 temp_type[3];
443 s16 temp[9]; 462 s16 temp[9];
444 s16 temp_max[9]; 463 s16 temp_max[9];
@@ -769,8 +788,8 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
769 /* If we failed to measure the fan speed and clock 788 /* If we failed to measure the fan speed and clock
770 divider can be increased, let's try that for next 789 divider can be increased, let's try that for next
771 time */ 790 time */
772 if (!is_word_sized(data->REG_FAN[i]) 791 if (data->has_fan_div
773 && (data->fan[i] == 0xff 792 && (data->fan[i] >= 0xff
774 || (sio_data->kind == nct6775 793 || (sio_data->kind == nct6775
775 && data->fan[i] == 0x00)) 794 && data->fan[i] == 0x00))
776 && data->fan_div[i] < 0x07) { 795 && data->fan_div[i] < 0x07) {
@@ -966,9 +985,7 @@ show_fan(struct device *dev, struct device_attribute *attr, char *buf)
966 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); 985 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
967 int nr = sensor_attr->index; 986 int nr = sensor_attr->index;
968 return sprintf(buf, "%d\n", 987 return sprintf(buf, "%d\n",
969 fan_from_reg(data->REG_FAN[nr], 988 data->fan_from_reg(data->fan[nr], data->fan_div[nr]));
970 data->fan[nr],
971 div_from_reg(data->fan_div[nr])));
972} 989}
973 990
974static ssize_t 991static ssize_t
@@ -978,9 +995,8 @@ show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
978 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); 995 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
979 int nr = sensor_attr->index; 996 int nr = sensor_attr->index;
980 return sprintf(buf, "%d\n", 997 return sprintf(buf, "%d\n",
981 fan_from_reg(data->REG_FAN_MIN[nr], 998 data->fan_from_reg_min(data->fan_min[nr],
982 data->fan_min[nr], 999 data->fan_div[nr]));
983 div_from_reg(data->fan_div[nr])));
984} 1000}
985 1001
986static ssize_t 1002static ssize_t
@@ -1010,7 +1026,11 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
1010 return err; 1026 return err;
1011 1027
1012 mutex_lock(&data->update_lock); 1028 mutex_lock(&data->update_lock);
1013 if (is_word_sized(data->REG_FAN_MIN[nr])) { 1029 if (!data->has_fan_div) {
1030 /*
1031 * Only NCT6776F for now, so we know that this is a 13 bit
1032 * register
1033 */
1014 if (!val) { 1034 if (!val) {
1015 val = 0xff1f; 1035 val = 0xff1f;
1016 } else { 1036 } else {
@@ -1034,7 +1054,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
1034 new_div = 7; /* 128 == (1 << 7) */ 1054 new_div = 7; /* 128 == (1 << 7) */
1035 dev_warn(dev, "fan%u low limit %lu below minimum %u, set to " 1055 dev_warn(dev, "fan%u low limit %lu below minimum %u, set to "
1036 "minimum\n", nr + 1, val, 1056 "minimum\n", nr + 1, val,
1037 fan_from_reg(data->REG_FAN_MIN[nr], 254, 128)); 1057 data->fan_from_reg_min(254, 7));
1038 } else if (!reg) { 1058 } else if (!reg) {
1039 /* Speed above this value cannot possibly be represented, 1059 /* Speed above this value cannot possibly be represented,
1040 even with the lowest divider (1) */ 1060 even with the lowest divider (1) */
@@ -1042,7 +1062,7 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
1042 new_div = 0; /* 1 == (1 << 0) */ 1062 new_div = 0; /* 1 == (1 << 0) */
1043 dev_warn(dev, "fan%u low limit %lu above maximum %u, set to " 1063 dev_warn(dev, "fan%u low limit %lu above maximum %u, set to "
1044 "maximum\n", nr + 1, val, 1064 "maximum\n", nr + 1, val,
1045 fan_from_reg(data->REG_FAN_MIN[nr], 1, 1)); 1065 data->fan_from_reg_min(1, 0));
1046 } else { 1066 } else {
1047 /* Automatically pick the best divider, i.e. the one such 1067 /* Automatically pick the best divider, i.e. the one such
1048 that the min limit will correspond to a register value 1068 that the min limit will correspond to a register value
@@ -1943,9 +1963,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1943 } 1963 }
1944 1964
1945 if (sio_data->kind == nct6775) { 1965 if (sio_data->kind == nct6775) {
1966 data->has_fan_div = true;
1967 data->fan_from_reg = fan_from_reg16;
1968 data->fan_from_reg_min = fan_from_reg8;
1946 data->REG_PWM = NCT6775_REG_PWM; 1969 data->REG_PWM = NCT6775_REG_PWM;
1947 data->REG_TARGET = NCT6775_REG_TARGET; 1970 data->REG_TARGET = NCT6775_REG_TARGET;
1948 data->REG_FAN = W83627EHF_REG_FAN; 1971 data->REG_FAN = NCT6775_REG_FAN;
1949 data->REG_FAN_MIN = W83627EHF_REG_FAN_MIN; 1972 data->REG_FAN_MIN = W83627EHF_REG_FAN_MIN;
1950 data->REG_FAN_START_OUTPUT = NCT6775_REG_FAN_START_OUTPUT; 1973 data->REG_FAN_START_OUTPUT = NCT6775_REG_FAN_START_OUTPUT;
1951 data->REG_FAN_STOP_OUTPUT = NCT6775_REG_FAN_STOP_OUTPUT; 1974 data->REG_FAN_STOP_OUTPUT = NCT6775_REG_FAN_STOP_OUTPUT;
@@ -1953,14 +1976,20 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1953 data->REG_FAN_MAX_OUTPUT = NCT6775_REG_FAN_MAX_OUTPUT; 1976 data->REG_FAN_MAX_OUTPUT = NCT6775_REG_FAN_MAX_OUTPUT;
1954 data->REG_FAN_STEP_OUTPUT = NCT6775_REG_FAN_STEP_OUTPUT; 1977 data->REG_FAN_STEP_OUTPUT = NCT6775_REG_FAN_STEP_OUTPUT;
1955 } else if (sio_data->kind == nct6776) { 1978 } else if (sio_data->kind == nct6776) {
1979 data->has_fan_div = false;
1980 data->fan_from_reg = fan_from_reg13;
1981 data->fan_from_reg_min = fan_from_reg13;
1956 data->REG_PWM = NCT6775_REG_PWM; 1982 data->REG_PWM = NCT6775_REG_PWM;
1957 data->REG_TARGET = NCT6775_REG_TARGET; 1983 data->REG_TARGET = NCT6775_REG_TARGET;
1958 data->REG_FAN = NCT6776_REG_FAN; 1984 data->REG_FAN = NCT6775_REG_FAN;
1959 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN; 1985 data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
1960 data->REG_FAN_START_OUTPUT = NCT6775_REG_FAN_START_OUTPUT; 1986 data->REG_FAN_START_OUTPUT = NCT6775_REG_FAN_START_OUTPUT;
1961 data->REG_FAN_STOP_OUTPUT = NCT6775_REG_FAN_STOP_OUTPUT; 1987 data->REG_FAN_STOP_OUTPUT = NCT6775_REG_FAN_STOP_OUTPUT;
1962 data->REG_FAN_STOP_TIME = NCT6775_REG_FAN_STOP_TIME; 1988 data->REG_FAN_STOP_TIME = NCT6775_REG_FAN_STOP_TIME;
1963 } else if (sio_data->kind == w83667hg_b) { 1989 } else if (sio_data->kind == w83667hg_b) {
1990 data->has_fan_div = true;
1991 data->fan_from_reg = fan_from_reg8;
1992 data->fan_from_reg_min = fan_from_reg8;
1964 data->REG_PWM = W83627EHF_REG_PWM; 1993 data->REG_PWM = W83627EHF_REG_PWM;
1965 data->REG_TARGET = W83627EHF_REG_TARGET; 1994 data->REG_TARGET = W83627EHF_REG_TARGET;
1966 data->REG_FAN = W83627EHF_REG_FAN; 1995 data->REG_FAN = W83627EHF_REG_FAN;
@@ -1973,6 +2002,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1973 data->REG_FAN_STEP_OUTPUT = 2002 data->REG_FAN_STEP_OUTPUT =
1974 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B; 2003 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B;
1975 } else { 2004 } else {
2005 data->has_fan_div = true;
2006 data->fan_from_reg = fan_from_reg8;
2007 data->fan_from_reg_min = fan_from_reg8;
1976 data->REG_PWM = W83627EHF_REG_PWM; 2008 data->REG_PWM = W83627EHF_REG_PWM;
1977 data->REG_TARGET = W83627EHF_REG_TARGET; 2009 data->REG_TARGET = W83627EHF_REG_TARGET;
1978 data->REG_FAN = W83627EHF_REG_FAN; 2010 data->REG_FAN = W83627EHF_REG_FAN;