From f83a64de348c2d1013a09e1230f2b64cb75c2f77 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sat, 14 Jan 2006 15:14:34 +0000 Subject: Rename nslm7x.c into lm78.c and nslm7xvar.h into lm78var.h, and clean up lm78var.h. Now that I've completely rewritten the driver, replace copyright with my own. suggested by deraadt@ --- sys/conf/files | 6 +- sys/dev/i2c/files.i2c | 4 +- sys/dev/i2c/lm_i2c.c | 4 +- sys/dev/ic/lm78.c | 712 +++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/ic/lm78var.h | 146 ++++++++++ sys/dev/ic/nslm7x.c | 733 ------------------------------------------------- sys/dev/ic/nslm7xvar.h | 167 ----------- sys/dev/isa/files.isa | 4 +- sys/dev/isa/lm_isa.c | 20 +- 9 files changed, 880 insertions(+), 916 deletions(-) create mode 100644 sys/dev/ic/lm78.c create mode 100644 sys/dev/ic/lm78var.h delete mode 100644 sys/dev/ic/nslm7x.c delete mode 100644 sys/dev/ic/nslm7xvar.h diff --git a/sys/conf/files b/sys/conf/files index b3685bdca8a..c7ccf1cdc62 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.360 2006/01/09 21:19:48 jsg Exp $ +# $OpenBSD: files,v 1.361 2006/01/14 15:14:32 kettenis Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -331,9 +331,9 @@ file dev/ic/iha.c iha device trm: scsi file dev/ic/trm.c trm -# National Semiconductor LM7[89] and compatible hardware monitors +# National Semiconductor LM78/79/81 and compatible hardware monitors device lm -file dev/ic/nslm7x.c lm +file dev/ic/lm78.c lm # Atheros AR5k (802.11/a/b/g) Hardware Abstraction Layer define ar5xxx diff --git a/sys/dev/i2c/files.i2c b/sys/dev/i2c/files.i2c index 30a3a46327d..cdc5f59fbbf 100644 --- a/sys/dev/i2c/files.i2c +++ b/sys/dev/i2c/files.i2c @@ -1,4 +1,4 @@ -# $OpenBSD: files.i2c,v 1.27 2006/01/13 23:56:46 grange Exp $ +# $OpenBSD: files.i2c,v 1.28 2006/01/14 15:14:33 kettenis Exp $ # $NetBSD: files.i2c,v 1.3 2003/10/20 16:24:10 briggs Exp $ define i2c {[addr = -1], [size = -1]} @@ -84,7 +84,7 @@ device adt attach adt at i2c file dev/i2c/adt7460.c adt -# National Semiconductor LM7[89] and compatible hardware monitors +# National Semiconductor LM78/79/81 and compatible hardware monitors attach lm at i2c with lm_i2c file dev/i2c/lm_i2c.c lm_i2c diff --git a/sys/dev/i2c/lm_i2c.c b/sys/dev/i2c/lm_i2c.c index 5bdfadd0c36..bf826a5556d 100644 --- a/sys/dev/i2c/lm_i2c.c +++ b/sys/dev/i2c/lm_i2c.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lm_i2c.c,v 1.6 2006/01/09 22:41:39 kettenis Exp $ */ +/* $OpenBSD: lm_i2c.c,v 1.7 2006/01/14 15:14:33 kettenis Exp $ */ /* * Copyright (c) 2005 Mark Kettenis @@ -24,7 +24,7 @@ #include #include -#include +#include struct lm_i2c_softc { struct lm_softc sc_lmsc; diff --git a/sys/dev/ic/lm78.c b/sys/dev/ic/lm78.c new file mode 100644 index 00000000000..344aaae4f89 --- /dev/null +++ b/sys/dev/ic/lm78.c @@ -0,0 +1,712 @@ +/* $OpenBSD: lm78.c,v 1.1 2006/01/14 15:14:33 kettenis Exp $ */ + +/* + * Copyright (c) 2005, 2006 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(LMDEBUG) +#define DPRINTF(x) do { printf x; } while (0) +#else +#define DPRINTF(x) +#endif + +struct cfdriver lm_cd = { + NULL, "lm", DV_DULL +}; + +int lm_match(struct lm_softc *); +int wb_match(struct lm_softc *); +int def_match(struct lm_softc *); + +void lm_setup_sensors(struct lm_softc *, struct lm_sensor *); +void lm_refresh(void *); + +void lm_refresh_sensor_data(struct lm_softc *); +void lm_refresh_volts(struct lm_softc *, int); +void lm_refresh_nvolts(struct lm_softc *, int); +void lm_refresh_temp(struct lm_softc *, int); +void lm_refresh_fanrpm(struct lm_softc *, int); + +void wb_refresh_sensor_data(struct lm_softc *); +void wb_refresh_n12volts(struct lm_softc *, int); +void wb_refresh_n5volts(struct lm_softc *, int); +void wb_refresh_temp(struct lm_softc *, int); +void wb_refresh_fanrpm(struct lm_softc *, int); +void wb_w83792d_refresh_fanrpm(struct lm_softc *, int); + +struct lm_chip { + int (*chip_match)(struct lm_softc *); +}; + +struct lm_chip lm_chips[] = { + { wb_match }, + { lm_match }, + { def_match } /* Must be last */ +}; + +struct lm_sensor lm78_sensors[] = { + /* Voltage */ + { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 40000 }, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, lm_refresh_nvolts, 40000 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x26, lm_refresh_nvolts, 16667 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, lm_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, lm_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, lm_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor w83627hf_sensors[] = { + /* Voltage */ + { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000 }, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, + { "5VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volts, 15151 }, + { "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volts, 10000 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, + { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor w83637hf_sensors[] = { + /* Voltage */ + { "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 38000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16667 }, + { "-12V", SENSOR_VOLTS_DC, 0, 0x24, wb_refresh_n12volts, 10000 }, + { "5VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volts, 16667 }, + { "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volts, 10000 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, + { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor w83697hf_sensors[] = { + /* Voltage */ + { "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V",SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000 }, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, + { "5VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volts, 15151 }, + { "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volts, 10000 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor w83781d_sensors[] = { + /* Voltage */ + { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 15050 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000}, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, lm_refresh_nvolts, 34768 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x26, lm_refresh_nvolts, 15050 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, + { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, lm_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, lm_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, lm_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor w83782d_sensors[] = { + /* Voltage */ + { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "VINR0", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000}, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, + { "5VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volts, 15151 }, + { "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volts, 10000 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, + { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor w83783s_sensors[] = { + /* Voltage */ + { "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000 }, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor w83791d_sensors[] = { + /* Voltage */ + { "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "VINR0", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000}, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, + { "5VSB", SENSOR_VOLTS_DC, 0, 0xb0, lm_refresh_volts, 15151 }, + { "VBAT", SENSOR_VOLTS_DC, 0, 0xb1, lm_refresh_volts, 10000 }, + { "VINR1", SENSOR_VOLTS_DC, 0, 0xb2, lm_refresh_volts, 10000 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 0, 0xc0, wb_refresh_temp }, + { "Temp3", SENSOR_TEMP, 0, 0xc8, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, + { "Fan4", SENSOR_FANRPM, 0, 0xba, wb_refresh_fanrpm }, + { "Fan5", SENSOR_FANRPM, 0, 0xbb, wb_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor w83792d_sensors[] = { + /* Voltage */ + { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x23, wb_refresh_n5volts, 10000 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000}, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x26, lm_refresh_volts, 16800 }, + { "5VSB", SENSOR_VOLTS_DC, 0, 0xb0, lm_refresh_volts, 15151 }, + { "VBAT", SENSOR_VOLTS_DC, 0, 0xb1, lm_refresh_volts, 10000 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 0, 0xc0, wb_refresh_temp }, + { "Temp3", SENSOR_TEMP, 0, 0xc8, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_w83792d_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_w83792d_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_w83792d_refresh_fanrpm }, + { "Fan4", SENSOR_FANRPM, 0, 0xb8, wb_w83792d_refresh_fanrpm }, + { "Fan5", SENSOR_FANRPM, 0, 0xb9, wb_w83792d_refresh_fanrpm }, + { "Fan6", SENSOR_FANRPM, 0, 0xba, wb_w83792d_refresh_fanrpm }, + { "Fan7", SENSOR_FANRPM, 0, 0xbe, wb_w83792d_refresh_fanrpm }, + + { NULL } +}; + +struct lm_sensor as99127f_sensors[] = { + /* Voltage */ + { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, + { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, + { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, + { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, + { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000 }, + { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, + { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, + + /* Temperature */ + { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, + { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, + { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, + + /* Fans */ + { "Fan1", SENSOR_FANRPM, 0, 0x28, lm_refresh_fanrpm }, + { "Fan2", SENSOR_FANRPM, 0, 0x29, lm_refresh_fanrpm }, + { "Fan3", SENSOR_FANRPM, 0, 0x2a, lm_refresh_fanrpm }, + + { NULL } +}; + +void +lm_attach(struct lm_softc *sc) +{ + u_int i, config; + + for (i = 0; i < sizeof(lm_chips) / sizeof(lm_chips[0]); i++) + if (lm_chips[i].chip_match(sc)) + break; + + if (sensor_task_register(sc, lm_refresh, 5)) { + printf("%s: unable to register update task\n", + sc->sc_dev.dv_xname); + return; + } + + /* Start the monitoring loop */ + config = sc->lm_readreg(sc, LM_CONFIG); + sc->lm_writereg(sc, LM_CONFIG, config | 0x01); + + /* Add sensors */ + for (i = 0; i < sc->numsensors; ++i) + SENSOR_ADD(&sc->sensors[i]); +} + +int +lm_match(struct lm_softc *sc) +{ + int chipid; + + /* See if we have an LM78 or LM79. */ + chipid = sc->lm_readreg(sc, LM_CHIPID) & LM_CHIPID_MASK; + switch(chipid) { + case LM_CHIPID_LM78: + printf(": LM78\n"); + break; + case LM_CHIPID_LM78J: + printf(": LM78J\n"); + break; + case LM_CHIPID_LM79: + printf(": LM79\n"); + break; + case LM_CHIPID_LM81: + printf(": LM81\n"); + break; + default: + return 0; + } + + lm_setup_sensors(sc, lm78_sensors); + sc->refresh_sensor_data = lm_refresh_sensor_data; + return 1; +} + +int +def_match(struct lm_softc *sc) +{ + int chipid; + + chipid = sc->lm_readreg(sc, LM_CHIPID) & LM_CHIPID_MASK; + printf(": unknown chip (ID %d)\n", chipid); + + lm_setup_sensors(sc, lm78_sensors); + sc->refresh_sensor_data = lm_refresh_sensor_data; + return 1; +} + +int +wb_match(struct lm_softc *sc) +{ + int banksel, vendid, chipid, devid; + + /* Read vendor ID */ + banksel = sc->lm_readreg(sc, WB_BANKSEL); + sc->lm_writereg(sc, WB_BANKSEL, WB_BANKSEL_HBAC); + vendid = sc->lm_readreg(sc, WB_VENDID) << 8; + sc->lm_writereg(sc, WB_BANKSEL, 0); + vendid |= sc->lm_readreg(sc, WB_VENDID); + sc->lm_writereg(sc, WB_BANKSEL, banksel); + DPRINTF(("winbond vend id 0x%x\n", j)); + if (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS) + return 0; + + /* Read device/chip ID */ + sc->lm_writereg(sc, WB_BANKSEL, WB_BANKSEL_B0); + devid = sc->lm_readreg(sc, LM_CHIPID); + chipid = sc->lm_readreg(sc, WB_BANK0_CHIPID); + sc->lm_writereg(sc, WB_BANKSEL, banksel); + DPRINTF(("winbond chip id 0x%x\n", chipid)); + switch(chipid) { + case WB_CHIPID_W83627HF: + printf(": W83627HF\n"); + lm_setup_sensors(sc, w83627hf_sensors); + break; + case WB_CHIPID_W83627THF: + printf(": W83627THF\n"); + lm_setup_sensors(sc, w83627hf_sensors); + break; + case WB_CHIPID_W83637HF: + printf(": W83637HF\n"); + lm_setup_sensors(sc, w83637hf_sensors); + break; + case WB_CHIPID_W83697HF: + printf(": W83697HF\n"); + lm_setup_sensors(sc, w83697hf_sensors); + break; + case WB_CHIPID_W83781D: + case WB_CHIPID_W83781D_2: + printf(": W83781D\n"); + lm_setup_sensors(sc, w83781d_sensors); + break; + case WB_CHIPID_W83782D: + printf(": W83782D\n"); + lm_setup_sensors(sc, w83782d_sensors); + break; + case WB_CHIPID_W83783S: + printf(": W83783S\n"); + lm_setup_sensors(sc, w83783s_sensors); + break; + case WB_CHIPID_W83791D: + case WB_CHIPID_W83791D_2: + printf(": W83791D\n"); + lm_setup_sensors(sc, w83791d_sensors); + break; + case WB_CHIPID_W83792D: + if (devid >= 0x10 && devid <= 0x29) + printf(": W83782D rev %c\n", 'A' + devid - 0x10); + else + printf(": W83782D rev 0x%x\n", devid); + lm_setup_sensors(sc, w83792d_sensors); + break; + case WB_CHIPID_AS99127F: + if (vendid == WB_VENDID_ASUS) { + printf(": AS99127F\n"); + lm_setup_sensors(sc, w83781d_sensors); + } else { + printf(": AS99127F rev 2\n"); + lm_setup_sensors(sc, as99127f_sensors); + } + break; + default: + printf(": unknown Winbond chip (ID 0x%x)\n", chipid); + /* Handle as a standard LM78. */ + lm_setup_sensors(sc, lm78_sensors); + sc->refresh_sensor_data = lm_refresh_sensor_data; + return 1; + } + + sc->refresh_sensor_data = wb_refresh_sensor_data; + return 1; +} + +void +lm_setup_sensors(struct lm_softc *sc, struct lm_sensor *sensors) +{ + int i; + + for (i = 0; sensors[i].desc; i++) { + strlcpy(sc->sensors[i].device, sc->sc_dev.dv_xname, + sizeof(sc->sensors[i].device)); + sc->sensors[i].type = sensors[i].type; + strlcpy(sc->sensors[i].desc, sensors[i].desc, + sizeof(sc->sensors[i].desc)); + sc->sensors[i].rfact = sensors[i].rfact; + sc->numsensors++; + } + sc->lm_sensors = sensors; +} + +void +lm_refresh(void *arg) +{ + struct lm_softc *sc = arg; + + sc->refresh_sensor_data(sc); +} + +void +lm_refresh_sensor_data(struct lm_softc *sc) +{ + int i; + + for (i = 0; i < sc->numsensors; i++) + sc->lm_sensors[i].refresh(sc, i); +} + +void +lm_refresh_volts(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int data; + + data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); + sensor->value = (data << 4); + sensor->value *= sensor->rfact; + sensor->value /= 10; +} + +void +lm_refresh_nvolts(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int data; + + data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); + sensor->value = (data << 4); + sensor->value *= sensor->rfact; + sensor->value /= 10; + sensor->value *= -1; +} + +void +lm_refresh_temp(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int sdata; + + sdata = sc->lm_readreg(sc, sc->lm_sensors[n].reg); + if (sdata & 0x80) + sdata -= 0x100; + sensor->value = sdata * 1000000 + 273150000; +} + +void +lm_refresh_fanrpm(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int data, divisor = 1; + + /* + * We might get more accurate fan readings by adjusting the + * divisor, but that might interfere with APM or other SMM + * BIOS code reading the fan speeds. + */ + + /* FAN3 has a fixed fan divisor. */ + if (sc->lm_sensors[n].reg == LM_FAN1 || + sc->lm_sensors[n].reg == LM_FAN2) { + data = sc->lm_readreg(sc, LM_VIDFAN); + if (sc->lm_sensors[n].reg == LM_FAN1) + divisor = (data >> 4) & 0x03; + else + divisor = (data >> 6) & 0x03; + } + + data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); + if (data == 0xff || data == 0x00) { + sensor->flags |= SENSOR_FINVALID; + sensor->value = 0; + } else { + sensor->flags &= ~SENSOR_FINVALID; + sensor->value = 1350000 / (data << divisor); + } +} + +void +wb_refresh_sensor_data(struct lm_softc *sc) +{ + int banksel, bank, i; + + /* + * Properly save and restore bank selection register. + */ + + banksel = bank = sc->lm_readreg(sc, WB_BANKSEL); + for (i = 0; i < sc->numsensors; i++) { + if (bank != sc->lm_sensors[i].bank) { + bank = sc->lm_sensors[i].bank; + sc->lm_writereg(sc, WB_BANKSEL, bank); + } + sc->lm_sensors[i].refresh(sc, i); + } + sc->lm_writereg(sc, WB_BANKSEL, banksel); +} + +void +wb_refresh_n12volts(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int data; + + data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); + sensor->value = (((data << 4) * 1000) - (WB_VREF * 806)) / 194; + sensor->value *= sensor->rfact; + sensor->value /= 10; +} + +void +wb_refresh_n5volts(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int data; + + data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); + sensor->value = (((data << 4) * 1000) - (WB_VREF * 682)) / 318; + sensor->value *= sensor->rfact; + sensor->value /= 10; +} + +void +wb_refresh_temp(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int sdata; + + sdata = sc->lm_readreg(sc, sc->lm_sensors[n].reg) << 1; + sdata += sc->lm_readreg(sc, sc->lm_sensors[n].reg + 1) >> 7; + if (sdata & 0x100) + sdata -= 0x200; + sensor->value = sdata * 500000 + 273150000; +} + +void +wb_refresh_fanrpm(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int fan, data, divisor = 0; + + /* + * This is madness; the fan divisor bits are scattered all + * over the place. + */ + + if (sc->lm_sensors[n].reg == LM_FAN1 || + sc->lm_sensors[n].reg == LM_FAN2 || + sc->lm_sensors[n].reg == LM_FAN3) { + data = sc->lm_readreg(sc, WB_BANK0_VBAT); + fan = (sc->lm_sensors[n].reg - LM_FAN1); + if ((data >> 5) & (1 << fan)) + divisor |= 0x04; + } + + if (sc->lm_sensors[n].reg == LM_FAN1 || + sc->lm_sensors[n].reg == LM_FAN2) { + data = sc->lm_readreg(sc, LM_VIDFAN); + if (sc->lm_sensors[n].reg == LM_FAN1) + divisor |= (data >> 4) & 0x03; + else + divisor |= (data >> 6) & 0x03; + } else if (sc->lm_sensors[n].reg == LM_FAN3) { + data = sc->lm_readreg(sc, WB_PIN); + divisor |= (data >> 6) & 0x03; + } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 || + sc->lm_sensors[n].reg == WB_BANK0_FAN5) { + data = sc->lm_readreg(sc, WB_BANK0_FAN45); + if (sc->lm_sensors[n].reg == WB_BANK0_FAN4) + divisor |= (data >> 0) & 0x07; + else + divisor |= (data >> 4) & 0x07; + } + + data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); + if (data == 0xff || data == 0x00) { + sensor->flags |= SENSOR_FINVALID; + sensor->value = 0; + } else { + sensor->flags &= ~SENSOR_FINVALID; + sensor->value = 1350000 / (data << divisor); + } +} + +void +wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n) +{ + struct sensor *sensor = &sc->sensors[n]; + int reg, shift, data, divisor = 1; + + switch (sc->lm_sensors[n].reg) { + case 0x28: + reg = 0x47; shift = 0; + break; + case 0x29: + reg = 0x47; shift = 4; + break; + case 0x2a: + reg = 0x5b; shift = 0; + break; + case 0xb8: + reg = 0x5b; shift = 4; + break; + case 0xb9: + reg = 0x5c; shift = 0; + break; + case 0xba: + reg = 0x5c; shift = 4; + break; + case 0xbe: + reg = 0x9e; shift = 0; + break; + default: + reg = 0; + break; + } + + data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); + if (data == 0xff || data == 0x00) { + sensor->flags |= SENSOR_FINVALID; + sensor->value = 0; + } else { + if (reg != 0) + divisor = (sc->lm_readreg(sc, reg) >> shift) & 0x7; + sensor->flags &= ~SENSOR_FINVALID; + sensor->value = 1350000 / (data << divisor); + } +} diff --git a/sys/dev/ic/lm78var.h b/sys/dev/ic/lm78var.h new file mode 100644 index 00000000000..69d08a7843a --- /dev/null +++ b/sys/dev/ic/lm78var.h @@ -0,0 +1,146 @@ +/* $OpenBSD: lm78var.h,v 1.1 2006/01/14 15:14:33 kettenis Exp $ */ + +/* + * Copyright (c) 2005, 2006 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * National Semiconductor LM78/79/81 registers + */ + +#define LM_POST_RAM 0x00 /* POST RAM occupies 0x00 -- 0x1f */ +#define LM_VALUE_RAM 0x20 /* Value RAM occupies 0x20 -- 0x3f */ +#define LM_FAN1 0x28 /* FAN1 reading */ +#define LM_FAN2 0x29 /* FAN2 reading */ +#define LM_FAN3 0x2a /* FAN3 reading */ + +#define LM_CONFIG 0x40 /* Configuration */ +#define LM_ISR1 0x41 /* Interrupt Status 1 */ +#define LM_ISR2 0x42 /* Interrupt Status 2 */ +#define LM_SMI1 0x43 /* SMI# Mask 1 */ +#define LM_SMI2 0x44 /* SMI# Mask 2 */ +#define LM_NMI1 0x45 /* NMI Mask 1 */ +#define LM_NMI2 0x46 /* NMI Mask 2 */ +#define LM_VIDFAN 0x47 /* VID/Fan Divisor */ +#define LM_SBUSADDR 0x48 /* Serial Bus Address */ +#define LM_CHIPID 0x49 /* Chip Reset/ID */ + +/* Chip IDs */ + +#define LM_CHIPID_LM78 0x00 +#define LM_CHIPID_LM78J 0x40 +#define LM_CHIPID_LM79 0xC0 +#define LM_CHIPID_LM81 0x80 +#define LM_CHIPID_MASK 0xfe + +/* + * Winbond registers + * + * Several models exists. The W83781D is mostly compatible with the + * LM78, but has two extra temperatures. Later models add extra + * voltage sensors, fans and bigger fan divisors to accomodate slow + * running fans. To accomodate the extra sensors some models have + * different memory banks. + */ + +#define WB_T23ADDR 0x4a /* Temperature 2 and 3 Serial Bus Address */ +#define WB_PIN 0x4b /* Pin Control */ +#define WB_BANKSEL 0x4e /* Bank Select */ +#define WB_VENDID 0x4f /* Vendor ID */ + +/* Bank 0 regs */ +#define WB_BANK0_CHIPID 0x58 /* Chip ID */ +#define WB_BANK0_FAN45 0x5c /* Fan 4/5 Divisor Control (W83791D only) */ +#define WB_BANK0_VBAT 0x5d /* VBAT Monitor Control */ +#define WB_BANK0_FAN4 0xba /* Fan 4 reading (W83791D only) */ +#define WB_BANK0_FAN5 0xbb /* Fan 5 reading (W83791D only) */ + +/* Bank 1 registers */ +#define WB_BANK1_T2H 0x50 /* Temperature 2 High Byte */ +#define WB_BANK1_T2L 0x51 /* Temperature 2 Low Byte */ + +/* Bank 2 registers */ +#define WB_BANK2_T3H 0x50 /* Temperature 3 High Byte */ +#define WB_BANK2_T3L 0x51 /* Temperature 3 Low Byte */ + +/* Bank 4 registers (W83782D/W83627HF and later models only) */ +#define WB_BANK4_T1OFF 0x54 /* Temperature 1 Offset */ +#define WB_BANK4_T2OFF 0x55 /* Temperature 2 Offset */ +#define WB_BANK4_T3OFF 0x56 /* Temperature 3 Offset */ + +/* Bank 5 registers (W83782D/W83627HF and later models only) */ +#define WB_BANK5_5VSB 0x50 /* 5VSB reading */ +#define WB_BANK5_VBAT 0x51 /* VBAT reading */ + +/* Bank selection */ +#define WB_BANKSEL_B0 0x00 /* Bank 0 */ +#define WB_BANKSEL_B1 0x01 /* Bank 1 */ +#define WB_BANKSEL_B2 0x02 /* Bank 2 */ +#define WB_BANKSEL_B3 0x03 /* Bank 3 */ +#define WB_BANKSEL_B4 0x04 /* Bank 4 */ +#define WB_BANKSEL_B5 0x05 /* Bank 5 */ +#define WB_BANKSEL_HBAC 0x80 /* Register 0x4f Hight Byte Access */ + +/* Vendor IDs */ +#define WB_VENDID_WINBOND 0x5ca3 /* Winbond */ +#define WB_VENDID_ASUS 0x12c3 /* ASUS */ + +/* Chip IDs */ +#define WB_CHIPID_W83781D 0x10 +#define WB_CHIPID_W83781D_2 0x11 +#define WB_CHIPID_W83627HF 0x21 +#define WB_CHIPID_AS99127F 0x31 /* Asus W83781D clone */ +#define WB_CHIPID_W83782D 0x30 +#define WB_CHIPID_W83783S 0x40 +#define WB_CHIPID_W83697HF 0x60 +#define WB_CHIPID_W83791D 0x71 +#define WB_CHIPID_W83791D_2 0x72 +#define WB_CHIPID_W83792D 0x7a +#define WB_CHIPID_W83637HF 0x80 +#define WB_CHIPID_W83627THF 0x90 + +/* Reference voltage (mV) */ +#define WB_VREF 3600 + +#define WB_MAX_SENSORS 19 + +struct lm_softc; + +struct lm_sensor { + char *desc; + enum sensor_type type; + u_int8_t bank; + u_int8_t reg; + void (*refresh)(struct lm_softc *, int); + u_int rfact; +}; + +struct lm_softc { + struct device sc_dev; + + bus_space_tag_t lm_iot; + bus_space_handle_t lm_ioh; + + int sc_flags; + struct sensor sensors[WB_MAX_SENSORS]; + struct lm_sensor *lm_sensors; + u_int numsensors; + void (*refresh_sensor_data) (struct lm_softc *); + + u_int8_t (*lm_readreg)(struct lm_softc *, int); + void (*lm_writereg)(struct lm_softc *, int, int); +}; + +void lm_attach(struct lm_softc *); diff --git a/sys/dev/ic/nslm7x.c b/sys/dev/ic/nslm7x.c deleted file mode 100644 index 30ca6c2360d..00000000000 --- a/sys/dev/ic/nslm7x.c +++ /dev/null @@ -1,733 +0,0 @@ -/* $OpenBSD: nslm7x.c,v 1.18 2006/01/12 22:45:46 kettenis Exp $ */ -/* $NetBSD: nslm7x.c,v 1.17 2002/11/15 14:55:41 ad Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Squier. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#if defined(LMDEBUG) -#define DPRINTF(x) do { printf x; } while (0) -#else -#define DPRINTF(x) -#endif - -struct cfdriver lm_cd = { - NULL, "lm", DV_DULL -}; - -int lm_match(struct lm_softc *); -int wb_match(struct lm_softc *); -int def_match(struct lm_softc *); - -void lm_setup_sensors(struct lm_softc *, struct lm_sensor *); -void lm_refresh(void *); - -void lm_refresh_sensor_data(struct lm_softc *); -void lm_refresh_volts(struct lm_softc *, int); -void lm_refresh_nvolts(struct lm_softc *, int); -void lm_refresh_temp(struct lm_softc *, int); -void lm_refresh_fanrpm(struct lm_softc *, int); - -void wb_refresh_sensor_data(struct lm_softc *); -void wb_refresh_n12volts(struct lm_softc *, int); -void wb_refresh_n5volts(struct lm_softc *, int); -void wb_refresh_temp(struct lm_softc *, int); -void wb_refresh_fanrpm(struct lm_softc *, int); -void wb_w83792d_refresh_fanrpm(struct lm_softc *, int); - -struct lm_chip { - int (*chip_match)(struct lm_softc *); -}; - -struct lm_chip lm_chips[] = { - { wb_match }, - { lm_match }, - { def_match } /* Must be last */ -}; - -struct lm_sensor lm78_sensors[] = { - /* Voltage */ - { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 40000 }, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, lm_refresh_nvolts, 40000 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x26, lm_refresh_nvolts, 16667 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, lm_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, lm_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, lm_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor w83627hf_sensors[] = { - /* Voltage */ - { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000 }, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, - { "5VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volts, 15151 }, - { "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volts, 10000 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, - { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor w83637hf_sensors[] = { - /* Voltage */ - { "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 38000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16667 }, - { "-12V", SENSOR_VOLTS_DC, 0, 0x24, wb_refresh_n12volts, 10000 }, - { "5VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volts, 16667 }, - { "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volts, 10000 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, - { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor w83697hf_sensors[] = { - /* Voltage */ - { "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V",SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000 }, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, - { "5VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volts, 15151 }, - { "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volts, 10000 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor w83781d_sensors[] = { - /* Voltage */ - { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 15050 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000}, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, lm_refresh_nvolts, 34768 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x26, lm_refresh_nvolts, 15050 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, - { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, lm_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, lm_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, lm_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor w83782d_sensors[] = { - /* Voltage */ - { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "VINR0", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000}, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, - { "5VSB", SENSOR_VOLTS_DC, 5, 0x50, lm_refresh_volts, 15151 }, - { "VBAT", SENSOR_VOLTS_DC, 5, 0x51, lm_refresh_volts, 10000 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, - { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor w83783s_sensors[] = { - /* Voltage */ - { "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000 }, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor w83791d_sensors[] = { - /* Voltage */ - { "VCore", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "VINR0", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000}, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, - { "5VSB", SENSOR_VOLTS_DC, 0, 0xb0, lm_refresh_volts, 15151 }, - { "VBAT", SENSOR_VOLTS_DC, 0, 0xb1, lm_refresh_volts, 10000 }, - { "VINR1", SENSOR_VOLTS_DC, 0, 0xb2, lm_refresh_volts, 10000 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 0, 0xc0, wb_refresh_temp }, - { "Temp3", SENSOR_TEMP, 0, 0xc8, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_refresh_fanrpm }, - { "Fan4", SENSOR_FANRPM, 0, 0xba, wb_refresh_fanrpm }, - { "Fan5", SENSOR_FANRPM, 0, 0xbb, wb_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor w83792d_sensors[] = { - /* Voltage */ - { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x23, wb_refresh_n5volts, 10000 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000}, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x26, lm_refresh_volts, 16800 }, - { "5VSB", SENSOR_VOLTS_DC, 0, 0xb0, lm_refresh_volts, 15151 }, - { "VBAT", SENSOR_VOLTS_DC, 0, 0xb1, lm_refresh_volts, 10000 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 0, 0xc0, wb_refresh_temp }, - { "Temp3", SENSOR_TEMP, 0, 0xc8, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, wb_w83792d_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, wb_w83792d_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, wb_w83792d_refresh_fanrpm }, - { "Fan4", SENSOR_FANRPM, 0, 0xb8, wb_w83792d_refresh_fanrpm }, - { "Fan5", SENSOR_FANRPM, 0, 0xb9, wb_w83792d_refresh_fanrpm }, - { "Fan6", SENSOR_FANRPM, 0, 0xba, wb_w83792d_refresh_fanrpm }, - { "Fan7", SENSOR_FANRPM, 0, 0xbe, wb_w83792d_refresh_fanrpm }, - - { NULL } -}; - -struct lm_sensor as99127f_sensors[] = { - /* Voltage */ - { "VCore A", SENSOR_VOLTS_DC, 0, 0x20, lm_refresh_volts, 10000 }, - { "VCore B", SENSOR_VOLTS_DC, 0, 0x21, lm_refresh_volts, 10000 }, - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x22, lm_refresh_volts, 10000 }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x23, lm_refresh_volts, 16800 }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x24, lm_refresh_volts, 38000 }, - { "-12V", SENSOR_VOLTS_DC, 0, 0x25, wb_refresh_n12volts, 10000 }, - { "-5V", SENSOR_VOLTS_DC, 0, 0x26, wb_refresh_n5volts, 10000 }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0, 0x27, lm_refresh_temp }, - { "Temp2", SENSOR_TEMP, 1, 0x50, wb_refresh_temp }, - { "Temp3", SENSOR_TEMP, 2, 0x50, wb_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x28, lm_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x29, lm_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x2a, lm_refresh_fanrpm }, - - { NULL } -}; - -void -lm_attach(struct lm_softc *sc) -{ - u_int i, config; - - for (i = 0; i < sizeof(lm_chips) / sizeof(lm_chips[0]); i++) - if (lm_chips[i].chip_match(sc)) - break; - - if (sensor_task_register(sc, lm_refresh, 5)) { - printf("%s: unable to register update task\n", - sc->sc_dev.dv_xname); - return; - } - - /* Start the monitoring loop */ - config = sc->lm_readreg(sc, LMD_CONFIG); - sc->lm_writereg(sc, LMD_CONFIG, config | 0x01); - - /* Add sensors */ - for (i = 0; i < sc->numsensors; ++i) - SENSOR_ADD(&sc->sensors[i]); -} - -int -lm_match(struct lm_softc *sc) -{ - int chipid; - - /* See if we have an LM78 or LM79. */ - chipid = sc->lm_readreg(sc, LMD_CHIPID) & LM_ID_MASK; - switch(chipid) { - case LM_ID_LM78: - printf(": LM78\n"); - break; - case LM_ID_LM78J: - printf(": LM78J\n"); - break; - case LM_ID_LM79: - printf(": LM79\n"); - break; - case LM_ID_LM81: - printf(": LM81\n"); - break; - default: - return 0; - } - - lm_setup_sensors(sc, lm78_sensors); - sc->refresh_sensor_data = lm_refresh_sensor_data; - return 1; -} - -int -def_match(struct lm_softc *sc) -{ - int chipid; - - chipid = sc->lm_readreg(sc, LMD_CHIPID) & LM_ID_MASK; - printf(": unknown chip (ID %d)\n", chipid); - - lm_setup_sensors(sc, lm78_sensors); - sc->refresh_sensor_data = lm_refresh_sensor_data; - return 1; -} - -int -wb_match(struct lm_softc *sc) -{ - int banksel, vendid, chipid, devid; - - /* Read vendor ID */ - banksel = sc->lm_readreg(sc, WB_BANKSEL); - sc->lm_writereg(sc, WB_BANKSEL, WB_BANKSEL_HBAC); - vendid = sc->lm_readreg(sc, WB_VENDID) << 8; - sc->lm_writereg(sc, WB_BANKSEL, 0); - vendid |= sc->lm_readreg(sc, WB_VENDID); - sc->lm_writereg(sc, WB_BANKSEL, banksel); - DPRINTF(("winbond vend id 0x%x\n", j)); - if (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS) - return 0; - - /* Read device/chip ID */ - sc->lm_writereg(sc, WB_BANKSEL, WB_BANKSEL_B0); - devid = sc->lm_readreg(sc, LMD_CHIPID); - chipid = sc->lm_readreg(sc, WB_BANK0_CHIPID); - sc->lm_writereg(sc, WB_BANKSEL, banksel); - DPRINTF(("winbond chip id 0x%x\n", chipid)); - switch(chipid) { - case WB_CHIPID_W83627HF: - printf(": W83627HF\n"); - lm_setup_sensors(sc, w83627hf_sensors); - break; - case WB_CHIPID_W83627THF: - printf(": W83627THF\n"); - lm_setup_sensors(sc, w83627hf_sensors); - break; - case WB_CHIPID_W83637HF: - printf(": W83637HF\n"); - lm_setup_sensors(sc, w83637hf_sensors); - break; - case WB_CHIPID_W83697HF: - printf(": W83697HF\n"); - lm_setup_sensors(sc, w83697hf_sensors); - break; - case WB_CHIPID_W83781D: - case WB_CHIPID_W83781D_2: - printf(": W83781D\n"); - lm_setup_sensors(sc, w83781d_sensors); - break; - case WB_CHIPID_W83782D: - printf(": W83782D\n"); - lm_setup_sensors(sc, w83782d_sensors); - break; - case WB_CHIPID_W83783S: - printf(": W83783S\n"); - lm_setup_sensors(sc, w83783s_sensors); - break; - case WB_CHIPID_W83791D: - case WB_CHIPID_W83791D_2: - printf(": W83791D\n"); - lm_setup_sensors(sc, w83791d_sensors); - break; - case WB_CHIPID_W83792D: - if (devid >= 0x10 && devid <= 0x29) - printf(": W83782D rev %c\n", 'A' + devid - 0x10); - else - printf(": W83782D rev 0x%x\n", devid); - lm_setup_sensors(sc, w83792d_sensors); - break; - case WB_CHIPID_AS99127F: - if (vendid == WB_VENDID_ASUS) { - printf(": AS99127F\n"); - lm_setup_sensors(sc, w83781d_sensors); - } else { - printf(": AS99127F rev 2\n"); - lm_setup_sensors(sc, as99127f_sensors); - } - break; - default: - printf(": unknown Winbond chip (ID 0x%x)\n", chipid); - /* Handle as a standard LM78. */ - lm_setup_sensors(sc, lm78_sensors); - sc->refresh_sensor_data = lm_refresh_sensor_data; - return 1; - } - - sc->refresh_sensor_data = wb_refresh_sensor_data; - return 1; -} - -void -lm_setup_sensors(struct lm_softc *sc, struct lm_sensor *sensors) -{ - int i; - - for (i = 0; sensors[i].desc; i++) { - strlcpy(sc->sensors[i].device, sc->sc_dev.dv_xname, - sizeof(sc->sensors[i].device)); - sc->sensors[i].type = sensors[i].type; - strlcpy(sc->sensors[i].desc, sensors[i].desc, - sizeof(sc->sensors[i].desc)); - sc->sensors[i].rfact = sensors[i].rfact; - sc->numsensors++; - } - sc->lm_sensors = sensors; -} - -void -lm_refresh(void *arg) -{ - struct lm_softc *sc = arg; - - sc->refresh_sensor_data(sc); -} - -void -lm_refresh_sensor_data(struct lm_softc *sc) -{ - int i; - - for (i = 0; i < sc->numsensors; i++) - sc->lm_sensors[i].refresh(sc, i); -} - -void -lm_refresh_volts(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int data; - - data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); - sensor->value = (data << 4); - sensor->value *= sensor->rfact; - sensor->value /= 10; -} - -void -lm_refresh_nvolts(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int data; - - data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); - sensor->value = (data << 4); - sensor->value *= sensor->rfact; - sensor->value /= 10; - sensor->value *= -1; -} - -void -lm_refresh_temp(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int sdata; - - sdata = sc->lm_readreg(sc, sc->lm_sensors[n].reg); - if (sdata & 0x80) - sdata -= 0x100; - sensor->value = sdata * 1000000 + 273150000; -} - -void -lm_refresh_fanrpm(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int data, divisor = 1; - - /* - * We might get more accurate fan readings by adjusting the - * divisor, but that might interfere with APM or other SMM - * BIOS code reading the fan speeds. - */ - - /* FAN3 has a fixed fan divisor. */ - if (sc->lm_sensors[n].reg == LMD_FAN1 || - sc->lm_sensors[n].reg == LMD_FAN2) { - data = sc->lm_readreg(sc, LMD_VIDFAN); - if (sc->lm_sensors[n].reg == LMD_FAN1) - divisor = (data >> 4) & 0x03; - else - divisor = (data >> 6) & 0x03; - } - - data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); - if (data == 0xff || data == 0x00) { - sensor->flags |= SENSOR_FINVALID; - sensor->value = 0; - } else { - sensor->flags &= ~SENSOR_FINVALID; - sensor->value = 1350000 / (data << divisor); - } -} - -void -wb_refresh_sensor_data(struct lm_softc *sc) -{ - int banksel, bank, i; - - /* - * Properly save and restore bank selection register. - */ - - banksel = bank = sc->lm_readreg(sc, WB_BANKSEL); - for (i = 0; i < sc->numsensors; i++) { - if (bank != sc->lm_sensors[i].bank) { - bank = sc->lm_sensors[i].bank; - sc->lm_writereg(sc, WB_BANKSEL, bank); - } - sc->lm_sensors[i].refresh(sc, i); - } - sc->lm_writereg(sc, WB_BANKSEL, banksel); -} - -void -wb_refresh_n12volts(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int data; - - data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); - sensor->value = (((data << 4) * 1000) - (WB_VREF * 806)) / 194; - sensor->value *= sensor->rfact; - sensor->value /= 10; -} - -void -wb_refresh_n5volts(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int data; - - data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); - sensor->value = (((data << 4) * 1000) - (WB_VREF * 682)) / 318; - sensor->value *= sensor->rfact; - sensor->value /= 10; -} - -void -wb_refresh_temp(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int sdata; - - sdata = sc->lm_readreg(sc, sc->lm_sensors[n].reg) << 1; - sdata += sc->lm_readreg(sc, sc->lm_sensors[n].reg + 1) >> 7; - if (sdata & 0x100) - sdata -= 0x200; - sensor->value = sdata * 500000 + 273150000; -} - -void -wb_refresh_fanrpm(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int fan, data, divisor = 0; - - /* - * This is madness; the fan divisor bits are scattered all - * over the place. - */ - - if (sc->lm_sensors[n].reg == LMD_FAN1 || - sc->lm_sensors[n].reg == LMD_FAN2 || - sc->lm_sensors[n].reg == LMD_FAN3) { - data = sc->lm_readreg(sc, WB_BANK0_FANBAT); - fan = (sc->lm_sensors[n].reg - LMD_FAN1); - if ((data >> 5) & (1 << fan)) - divisor |= 0x04; - } - - if (sc->lm_sensors[n].reg == LMD_FAN1 || - sc->lm_sensors[n].reg == LMD_FAN2) { - data = sc->lm_readreg(sc, LMD_VIDFAN); - if (sc->lm_sensors[n].reg == LMD_FAN1) - divisor |= (data >> 4) & 0x03; - else - divisor |= (data >> 6) & 0x03; - } else if (sc->lm_sensors[n].reg == LMD_FAN3) { - data = sc->lm_readreg(sc, WB_PIN); - divisor |= (data >> 6) & 0x03; - } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 || - sc->lm_sensors[n].reg == WB_BANK0_FAN5) { - data = sc->lm_readreg(sc, WB_BANK0_FAN45); - if (sc->lm_sensors[n].reg == WB_BANK0_FAN4) - divisor |= (data >> 0) & 0x07; - else - divisor |= (data >> 4) & 0x07; - } - - data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); - if (data == 0xff || data == 0x00) { - sensor->flags |= SENSOR_FINVALID; - sensor->value = 0; - } else { - sensor->flags &= ~SENSOR_FINVALID; - sensor->value = 1350000 / (data << divisor); - } -} - -void -wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n) -{ - struct sensor *sensor = &sc->sensors[n]; - int reg, shift, data, divisor = 1; - - switch (sc->lm_sensors[n].reg) { - case 0x28: - reg = 0x47; shift = 0; - break; - case 0x29: - reg = 0x47; shift = 4; - break; - case 0x2a: - reg = 0x5b; shift = 0; - break; - case 0xb8: - reg = 0x5b; shift = 4; - break; - case 0xb9: - reg = 0x5c; shift = 0; - break; - case 0xba: - reg = 0x5c; shift = 4; - break; - case 0xbe: - reg = 0x9e; shift = 0; - break; - default: - reg = 0; - break; - } - - data = sc->lm_readreg(sc, sc->lm_sensors[n].reg); - if (data == 0xff || data == 0x00) { - sensor->flags |= SENSOR_FINVALID; - sensor->value = 0; - } else { - if (reg != 0) - divisor = (sc->lm_readreg(sc, reg) >> shift) & 0x7; - sensor->flags &= ~SENSOR_FINVALID; - sensor->value = 1350000 / (data << divisor); - } -} diff --git a/sys/dev/ic/nslm7xvar.h b/sys/dev/ic/nslm7xvar.h deleted file mode 100644 index 92311d614f3..00000000000 --- a/sys/dev/ic/nslm7xvar.h +++ /dev/null @@ -1,167 +0,0 @@ -/* $OpenBSD: nslm7xvar.h,v 1.11 2006/01/12 22:45:46 kettenis Exp $ */ -/* $NetBSD: nslm7xvar.h,v 1.10 2002/11/15 14:55:42 ad Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Squier. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_ISA_NSLM7XVAR_H_ -#define _DEV_ISA_NSLM7XVAR_H_ - -/* ctl registers */ - -#define LMC_ADDR 0x05 -#define LMC_DATA 0x06 - -/* data registers */ - -#define LMD_SENSORBASE 0x20 /* Sensors occupy 0x20 -- 0x2a */ -#define LMD_FAN1 0x28 -#define LMD_FAN2 0x29 -#define LMD_FAN3 0x2a - -#define LMD_CONFIG 0x40 /* Configuration */ -#define LMD_ISR1 0x41 /* Interrupt Status 1 */ -#define LMD_ISR2 0x42 /* Interrupt Status 2 */ -#define LMD_SMI1 0x43 /* SMI Mask 1 */ -#define LMD_SMI2 0x44 /* SMI Mask 2 */ -#define LMD_NMI1 0x45 /* NMI Mask 1 */ -#define LMD_NMI2 0x46 /* NMI Mask 2 */ -#define LMD_VIDFAN 0x47 /* VID/Fan Divisor */ -#define LMD_SBUSADDR 0x48 /* Serial Bus Address */ -#define LMD_CHIPID 0x49 /* Chip Reset/ID */ - -/* misc constants */ - -#define LM_ID_LM78 0x00 -#define LM_ID_LM78J 0x40 -#define LM_ID_LM79 0xC0 -#define LM_ID_LM81 0x80 -#define LM_ID_MASK 0xfe - -/* - * Additional registers for the Winbond chips: - * W83781D: mostly LM78 compatible; extra temp sensors in bank 1 & 2. - * W83782D & W83627HF: voltage sensors needs different handling, more FAN - * dividers; extra voltage sensors in bank 4. - * W83791D: extra fans; all sensors accessable through bank 0. - */ -#define WB_T23ADDR 0x4a /* temp sens 2/3 I2C addr */ -#define WB_PIN 0x4b /* pin & fan3 divider */ -#define WB_BANKSEL 0x4e /* banck select register */ -#define WB_BANKSEL_B0 0x00 /* select bank 0 */ -#define WB_BANKSEL_B1 0x01 /* select bank 1 */ -#define WB_BANKSEL_B2 0x02 /* select bank 2 */ -#define WB_BANKSEL_B3 0x03 /* select bank 3 */ -#define WB_BANKSEL_B4 0x04 /* select bank 4 */ -#define WB_BANKSEL_B5 0x05 /* select bank 5 */ -#define WB_BANKSEL_HBAC 0x80 /* hight byte access */ - -#define WB_VENDID 0x4f /* vendor ID register */ -#define WB_VENDID_WINBOND 0x5ca3 -#define WB_VENDID_ASUS 0x12c3 - -/* Bank 0 regs */ -#define WB_BANK0_CHIPID 0x58 -#define WB_CHIPID_W83781D 0x10 -#define WB_CHIPID_W83781D_2 0x11 -#define WB_CHIPID_W83627HF 0x21 -#define WB_CHIPID_AS99127F 0x31 /* Asus W83781D clone */ -#define WB_CHIPID_W83782D 0x30 -#define WB_CHIPID_W83783S 0x40 -#define WB_CHIPID_W83697HF 0x60 -#define WB_CHIPID_W83791D 0x71 -#define WB_CHIPID_W83791D_2 0x72 -#define WB_CHIPID_W83792D 0x7a -#define WB_CHIPID_W83637HF 0x80 -#define WB_CHIPID_W83627THF 0x90 -#define WB_BANK0_FAN45 0x5c /* fan4/5 divider; W83791D only */ -#define WB_BANK0_FANBAT 0x5d -#define WB_BANK0_FAN4 0xba /* W83791D only */ -#define WB_BANK0_FAN5 0xbb /* W83791D only */ - -/* Bank 1 regs */ -#define WB_BANK1_T2H 0x50 -#define WB_BANK1_T2L 0x51 - -/* Bank 2 regs */ -#define WB_BANK2_T3H 0x50 -#define WB_BANK2_T3L 0x51 - -/* Bank 4 regs W83782D/W83627HF and later models only */ -#define WB_BANK4_T1OFF 0x54 -#define WB_BANK4_T2OFF 0x55 -#define WB_BANK4_T3OFF 0x56 - -/* Bank 5 regs W83782D/W83627HF and later models only */ -#define WB_BANK5_5VSB 0x50 -#define WB_BANK5_VBAT 0x51 - -/* Reference voltage */ -#define WB_VREF 3600 - -#define WB_MAX_SENSORS 19 - -struct lm_softc; - -struct lm_sensor { - char *desc; - enum sensor_type type; - u_int8_t bank; - u_int8_t reg; - void (*refresh)(struct lm_softc *, int); - u_int rfact; -}; - -struct lm_softc { - struct device sc_dev; - - int lm_iobase; - bus_space_tag_t lm_iot; - bus_space_handle_t lm_ioh; - - int sc_flags; - struct sensor sensors[WB_MAX_SENSORS]; - struct lm_sensor *lm_sensors; - u_int numsensors; - void (*refresh_sensor_data) (struct lm_softc *); - - u_int8_t (*lm_readreg)(struct lm_softc *, int); - void (*lm_writereg)(struct lm_softc *, int, int); -}; - -void lm_attach(struct lm_softc *); - -#endif /* _DEV_ISA_NSLM7XVAR_H_ */ diff --git a/sys/dev/isa/files.isa b/sys/dev/isa/files.isa index 219a00962e4..c5a45f270d1 100644 --- a/sys/dev/isa/files.isa +++ b/sys/dev/isa/files.isa @@ -1,4 +1,4 @@ -# $OpenBSD: files.isa,v 1.91 2005/08/05 03:52:32 jsg Exp $ +# $OpenBSD: files.isa,v 1.92 2006/01/14 15:14:33 kettenis Exp $ # $NetBSD: files.isa,v 1.21 1996/05/16 03:45:55 mycroft Exp $ # # Config file and device description for machine-independent ISA code. @@ -374,7 +374,7 @@ file dev/isa/midi_pcppi.c midi_pcppi attach lpt at isa with lpt_isa file dev/isa/lpt_isa.c lpt_isa needs-flag -# National Semiconductor LM7[89] and compatible hardware monitors +# National Semiconductor LM78/79/81 and compatible hardware monitors attach lm at isa with lm_isa file dev/isa/lm_isa.c lm_isa diff --git a/sys/dev/isa/lm_isa.c b/sys/dev/isa/lm_isa.c index 7e550620324..1007a66872a 100644 --- a/sys/dev/isa/lm_isa.c +++ b/sys/dev/isa/lm_isa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lm_isa.c,v 1.4 2006/01/12 22:34:51 kettenis Exp $ */ +/* $OpenBSD: lm_isa.c,v 1.5 2006/01/14 15:14:33 kettenis Exp $ */ /* $NetBSD: lm_isa.c,v 1.9 2002/11/15 14:55:44 ad Exp $ */ /*- @@ -46,7 +46,11 @@ #include #include -#include +#include + +/* ISA registers */ +#define LMC_ADDR 0x05 +#define LMC_DATA 0x06 #if defined(LMDEBUG) #define DPRINTF(x) do { printf x; } while (0) @@ -91,12 +95,14 @@ lm_isa_match(struct device *parent, void *match, void *aux) goto found; /* - * Probe for LM78/79/81. + * Probe for National Semiconductor LM78/79/81. * - * XXX Assumes the address has not been changed from the - * power up default. - */ - bus_space_write_1(iot, ioh, LMC_ADDR, LMD_SBUSADDR); + * XXX This assumes the address has not been changed from the + * power up default. This is probably a reasonable + * assumption, and if it isn't true, we should be able to + * access the chip using the serial bus. + */ + bus_space_write_1(iot, ioh, LMC_ADDR, LM_SBUSADDR); addr = bus_space_read_1(iot, ioh, LMC_DATA); if ((addr & 0xfc) == 0x2c) goto found; -- cgit v1.2.3