aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83627ehf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/w83627ehf.c')
-rw-r--r--drivers/hwmon/w83627ehf.c56
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). */
316static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) 313static 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 */
324static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) 322static 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
422static 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
424static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) 447static 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,