diff options
author | Florian Zumbiehl <florz@florz.de> | 2011-11-01 20:19:06 +0100 |
---|---|---|
committer | Rudolf Marek <r.marek@assembler.cz> | 2011-11-22 23:07:03 +0100 |
commit | 85392a8c985b11388efb4a07ef1b1481d9a511e2 (patch) | |
tree | 57a50896b1a23e94ee4e17b0a8ecdb64c622f6b7 /src/superio/winbond | |
parent | 04a8d6239f43c16a2f8f2d0c9893ddecdc3340a6 (diff) |
implement hwmon fan divisor setting for w83697hf
Change-Id: I887ac1142875ca1dc1a1eb8eebec402fbe7512c3
Signed-off-by: Florian Zumbiehl <florz@florz.de>
Reviewed-on: http://review.coreboot.org/384
Reviewed-by: Rudolf Marek <r.marek@assembler.cz>
Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/superio/winbond')
-rw-r--r-- | src/superio/winbond/w83697hf/chip.h | 3 | ||||
-rw-r--r-- | src/superio/winbond/w83697hf/superio.c | 34 |
2 files changed, 36 insertions, 1 deletions
diff --git a/src/superio/winbond/w83697hf/chip.h b/src/superio/winbond/w83697hf/chip.h index 1a1cbcc038..2359b6679f 100644 --- a/src/superio/winbond/w83697hf/chip.h +++ b/src/superio/winbond/w83697hf/chip.h @@ -26,7 +26,8 @@ extern struct chip_operations superio_winbond_w83697hf_ops; struct superio_winbond_w83697hf_config { - + unsigned int hwmon_fan1_divisor; + unsigned int hwmon_fan2_divisor; }; #endif diff --git a/src/superio/winbond/w83697hf/superio.c b/src/superio/winbond/w83697hf/superio.c index d2cbcbd642..8f090d0b66 100644 --- a/src/superio/winbond/w83697hf/superio.c +++ b/src/superio/winbond/w83697hf/superio.c @@ -41,10 +41,44 @@ static void pnp_exit_ext_func_mode(device_t dev) outb(0xaa, dev->path.pnp.port); } +static void hwmon_set_fan_divisor(unsigned int base, int num, unsigned int divisor) { + unsigned char enc, buf; + + if (divisor) { + enc = log2(divisor); + if (1 << enc != divisor || enc > 7) + die("invalid fan divisor"); + outb(0x4e, base + 5); + outb(0x00, base + 6); + outb(0x47, base + 5); + outb((inb(base + 6) & ~(0x30 << (num * 2))) | ((enc & 3) << (4 + num * 2)), base + 6); + outb(0x5d, base + 5); + buf = inb(base + 6); + /* the above inb() auto-increments the address pointer ... */ + outb(0x5d, base + 5); + outb((buf & ~(0x20 << num)) | ((enc & 4) << (3 + num)), base + 6); + } +} + static void w83697hf_init(device_t dev) { + struct resource *res0; + struct superio_winbond_w83697hf_config *cfg; + if (!dev->enabled) return; + + cfg = dev->chip_info; + + switch (dev->path.pnp.device) { + case W83697HF_HWM: + if (cfg) { + res0 = find_resource(dev, PNP_IDX_IO0); + hwmon_set_fan_divisor(res0->base, 0, cfg->hwmon_fan1_divisor); + hwmon_set_fan_divisor(res0->base, 1, cfg->hwmon_fan2_divisor); + } + break; + } } static void w83697hf_pnp_set_resources(device_t dev) |