diff options
Diffstat (limited to 'drivers/hwmon/w83627ehf.c')
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index c51ae2e17758..d9a9ec7dd84a 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -309,18 +309,16 @@ static inline int is_word_sized(u16 reg) | |||
309 | || (reg & 0x00ff) == 0x55)); | 309 | || (reg & 0x00ff) == 0x55)); |
310 | } | 310 | } |
311 | 311 | ||
312 | /* We assume that the default bank is 0, thus the following two functions do | 312 | /* Registers 0x50-0x5f are banked */ |
313 | nothing for registers which live in bank 0. For others, they respectively | ||
314 | set the bank register to the correct value (before the register is | ||
315 | accessed), and back to 0 (afterwards). */ | ||
316 | static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) | 313 | static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) |
317 | { | 314 | { |
318 | if (reg & 0xff00) { | 315 | if ((reg & 0x00f0) == 0x50) { |
319 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); | 316 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
320 | outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); | 317 | outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); |
321 | } | 318 | } |
322 | } | 319 | } |
323 | 320 | ||
321 | /* Not strictly necessary, but play it safe for now */ | ||
324 | static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) | 322 | static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) |
325 | { | 323 | { |
326 | if (reg & 0xff00) { | 324 | if (reg & 0xff00) { |
@@ -421,6 +419,31 @@ static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) | |||
421 | } | 419 | } |
422 | } | 420 | } |
423 | 421 | ||
422 | static void w83627ehf_update_fan_div(struct w83627ehf_data *data) | ||
423 | { | ||
424 | int i; | ||
425 | |||
426 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); | ||
427 | data->fan_div[0] = (i >> 4) & 0x03; | ||
428 | data->fan_div[1] = (i >> 6) & 0x03; | ||
429 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); | ||
430 | data->fan_div[2] = (i >> 6) & 0x03; | ||
431 | i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); | ||
432 | data->fan_div[0] |= (i >> 3) & 0x04; | ||
433 | data->fan_div[1] |= (i >> 4) & 0x04; | ||
434 | data->fan_div[2] |= (i >> 5) & 0x04; | ||
435 | if (data->has_fan & ((1 << 3) | (1 << 4))) { | ||
436 | i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); | ||
437 | data->fan_div[3] = i & 0x03; | ||
438 | data->fan_div[4] = ((i >> 2) & 0x03) | ||
439 | | ((i >> 5) & 0x04); | ||
440 | } | ||
441 | if (data->has_fan & (1 << 3)) { | ||
442 | i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); | ||
443 | data->fan_div[3] |= (i >> 5) & 0x04; | ||
444 | } | ||
445 | } | ||
446 | |||
424 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | 447 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) |
425 | { | 448 | { |
426 | struct w83627ehf_data *data = dev_get_drvdata(dev); | 449 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
@@ -432,25 +455,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
432 | if (time_after(jiffies, data->last_updated + HZ + HZ/2) | 455 | if (time_after(jiffies, data->last_updated + HZ + HZ/2) |
433 | || !data->valid) { | 456 | || !data->valid) { |
434 | /* Fan clock dividers */ | 457 | /* Fan clock dividers */ |
435 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); | 458 | w83627ehf_update_fan_div(data); |
436 | data->fan_div[0] = (i >> 4) & 0x03; | ||
437 | data->fan_div[1] = (i >> 6) & 0x03; | ||
438 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); | ||
439 | data->fan_div[2] = (i >> 6) & 0x03; | ||
440 | i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); | ||
441 | data->fan_div[0] |= (i >> 3) & 0x04; | ||
442 | data->fan_div[1] |= (i >> 4) & 0x04; | ||
443 | data->fan_div[2] |= (i >> 5) & 0x04; | ||
444 | if (data->has_fan & ((1 << 3) | (1 << 4))) { | ||
445 | i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); | ||
446 | data->fan_div[3] = i & 0x03; | ||
447 | data->fan_div[4] = ((i >> 2) & 0x03) | ||
448 | | ((i >> 5) & 0x04); | ||
449 | } | ||
450 | if (data->has_fan & (1 << 3)) { | ||
451 | i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); | ||
452 | data->fan_div[3] |= (i >> 5) & 0x04; | ||
453 | } | ||
454 | 459 | ||
455 | /* Measured voltages and limits */ | 460 | /* Measured voltages and limits */ |
456 | for (i = 0; i < data->in_num; i++) { | 461 | for (i = 0; i < data->in_num; i++) { |
@@ -1312,6 +1317,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1312 | if (!(i & (1 << 1)) && (!fan5pin)) | 1317 | if (!(i & (1 << 1)) && (!fan5pin)) |
1313 | data->has_fan |= (1 << 4); | 1318 | data->has_fan |= (1 << 4); |
1314 | 1319 | ||
1320 | /* Read fan clock dividers immediately */ | ||
1321 | w83627ehf_update_fan_div(data); | ||
1322 | |||
1315 | /* Register sysfs hooks */ | 1323 | /* Register sysfs hooks */ |
1316 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) | 1324 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) |
1317 | if ((err = device_create_file(dev, | 1325 | if ((err = device_create_file(dev, |