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.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 1128eac7023b..5a627b9db3e8 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -304,6 +304,7 @@ struct w83627ehf_data {
304 unsigned long last_updated; /* In jiffies */ 304 unsigned long last_updated; /* In jiffies */
305 305
306 /* Register values */ 306 /* Register values */
307 u8 bank; /* current register bank */
307 u8 in_num; /* number of in inputs we have */ 308 u8 in_num; /* number of in inputs we have */
308 u8 in[10]; /* Register value */ 309 u8 in[10]; /* Register value */
309 u8 in_max[10]; /* Register value */ 310 u8 in_max[10]; /* Register value */
@@ -347,21 +348,19 @@ struct w83627ehf_sio_data {
347 enum kinds kind; 348 enum kinds kind;
348}; 349};
349 350
350/* Registers 0x50-0x5f are banked */ 351/*
352 * On older chips, only registers 0x50-0x5f are banked.
353 * On more recent chips, all registers are banked.
354 * Assume that is the case and set the bank number for each access.
355 * Cache the bank number so it only needs to be set if it changes.
356 */
351static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) 357static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg)
352{ 358{
353 if ((reg & 0x00f0) == 0x50) { 359 u8 bank = reg >> 8;
354 outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); 360 if (data->bank != bank) {
355 outb_p(reg >> 8, data->addr + DATA_REG_OFFSET);
356 }
357}
358
359/* Not strictly necessary, but play it safe for now */
360static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg)
361{
362 if (reg & 0xff00) {
363 outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); 361 outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET);
364 outb_p(0, data->addr + DATA_REG_OFFSET); 362 outb_p(bank, data->addr + DATA_REG_OFFSET);
363 data->bank = bank;
365 } 364 }
366} 365}
367 366
@@ -379,10 +378,8 @@ static u16 w83627ehf_read_value(struct w83627ehf_data *data, u16 reg)
379 data->addr + ADDR_REG_OFFSET); 378 data->addr + ADDR_REG_OFFSET);
380 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); 379 res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
381 } 380 }
382 w83627ehf_reset_bank(data, reg);
383 381
384 mutex_unlock(&data->lock); 382 mutex_unlock(&data->lock);
385
386 return res; 383 return res;
387} 384}
388 385
@@ -401,7 +398,6 @@ static int w83627ehf_write_value(struct w83627ehf_data *data, u16 reg,
401 data->addr + ADDR_REG_OFFSET); 398 data->addr + ADDR_REG_OFFSET);
402 } 399 }
403 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); 400 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
404 w83627ehf_reset_bank(data, reg);
405 401
406 mutex_unlock(&data->lock); 402 mutex_unlock(&data->lock);
407 return 0; 403 return 0;