diff options
-rw-r--r-- | share/man/man4/it.4 | 66 | ||||
-rw-r--r-- | sys/arch/amd64/conf/GENERIC | 8 | ||||
-rw-r--r-- | sys/arch/i386/conf/GENERIC | 8 | ||||
-rw-r--r-- | sys/dev/isa/files.isa | 5 | ||||
-rw-r--r-- | sys/dev/isa/it.c | 492 | ||||
-rw-r--r-- | sys/dev/isa/itvar.h | 98 | ||||
-rw-r--r-- | sys/dev/isa/lm78_isa.c | 8 |
7 files changed, 394 insertions, 291 deletions
diff --git a/share/man/man4/it.4 b/share/man/man4/it.4 index 1de3852a6cf..c857513a1e0 100644 --- a/share/man/man4/it.4 +++ b/share/man/man4/it.4 @@ -1,6 +1,6 @@ -.\" $OpenBSD: it.4,v 1.9 2007/05/31 19:19:50 jmc Exp $ +.\" $OpenBSD: it.4,v 1.10 2007/12/18 21:17:54 form Exp $ .\" -.\" Copyright (c) 2003 Julien Bordet <zejames@greygats.org> +.\" Copyright (c) 2007 Oleg Safiullin <form@pdp-11.org.ru> .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -23,50 +23,51 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 31 2007 $ +.Dd $Mdocdate: December 18 2007 $ .Dt IT 4 .Os .Sh NAME .Nm it -.Nd ITE IT8705F, IT8712F, and SiS SiS950 temperature, voltage, -and fan sensor +.Nd ITE IT8705F/IT8712F/IT8716F/IT8718F/IT8726F and SiS SiS950 temperature, +voltage, and fan sensor with watchdog timer. .Sh SYNOPSIS -.Cd "it0 at isa? port 0x290" -.Cd "it1 at isa? port 0xc00" -.Cd "it2 at isa? port 0xd00" +.Cd "it0 at isa?" .Sh DESCRIPTION The .Nm -driver provides support for the -.Tn IT8705F , IT8712F -and +driver provides support for the ITE +.Tn IT8705F , IT8712F , IT8716F , IT8718F , IT8726F +and SiS .Tn SiS950 -hardware monitors to be used with the +hardware monitors and +.Xr watchdog 4 +timer to be used with the .Xr sysctl 8 interface. .Pp Most supported devices possess 15 sensors: .Bl -column "Sensor" "Units" "Typical" -offset indent .It Sy "Sensor" Ta Sy "Units" Ta Sy "Typical Use" -.It Li "Fan0" Ta "RPM" Ta "CPU Fan" -.It Li "Fan1" Ta "RPM" Ta "Fan" -.It Li "Fan2" Ta "RPM" Ta "Fan" -.It Li "IN0" Ta "uV DC" Ta "Core voltage" -.It Li "IN1" Ta "uV DC" Ta "Core voltage" -.It Li "IN2" Ta "uV DC" Ta "+3.3V" -.It Li "IN3" Ta "uV DC" Ta "+5V" -.It Li "IN4" Ta "uV DC" Ta "+12V" -.It Li "IN5" Ta "uV DC" Ta "Unknown" -.It Li "IN6" Ta "uV DC" Ta "-12V" -.It Li "IN7" Ta "uV DC" Ta "-5V" -.It Li "IN8" Ta "uV DC" Ta "VBAT" -.It Li "Temp" Ta "uK" Ta "Motherboard Temperature" -.It Li "Temp" Ta "uK" Ta "Motherboard Temperature" -.It Li "Temp" Ta "uK" Ta "CPU Temperature" +.It Li "temp0" Ta "uK" Ta "CPU Temperature" +.It Li "temp1" Ta "uK" Ta "Motherboard Temperature" +.It Li "temp2" Ta "uK" Ta "Unused" +.It Li "fan0" Ta "RPM" Ta "CPU Fan" +.It Li "fan1" Ta "RPM" Ta "Chassis Fan" +.It Li "fan2" Ta "RPM" Ta "Power Fan" +.It Li "volt0" Ta "uV DC" Ta "Core voltage" +.It Li "volt1" Ta "uV DC" Ta "Core voltage" +.It Li "volt2" Ta "uV DC" Ta "+3.3V" +.It Li "volt3" Ta "uV DC" Ta "+5V" +.It Li "volt4" Ta "uV DC" Ta "+12V" +.It Li "volt5" Ta "uV DC" Ta "-5V" +.It Li "volt6" Ta "uV DC" Ta "-12V" +.It Li "volt7" Ta "uV DC" Ta "+5VSB" +.It Li "volt8" Ta "uV DC" Ta "VBAT" .El .Pp For some devices, sensors' names and numbers will be different. .Sh SEE ALSO +.Xr watchdog 4 , .Xr sensorsd 8 , .Xr sysctl 8 .Sh HISTORY @@ -75,9 +76,8 @@ The driver first appeared in .Ox 3.4 . .Sh AUTHORS -The -.Nm -driver was written by -.An Julien Bordet Aq zejames@greyhats.org . -.Sh BUGS -Interrupt support is unimplemented. +.Bl -tag -width indent -compact +.It "Julien Bordet" Aq zejames@greyhats.org +Initial design. +.It "Oleg Safiullin" Aq form@pdp-11.org.ru +Complete rewrite. diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index ffe077d5b60..0ee7f03a01e 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.207 2007/12/05 19:17:14 deraadt Exp $ +# $OpenBSD: GENERIC,v 1.208 2007/12/18 21:17:54 form Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -71,9 +71,9 @@ lm0 at isa? port 0x290 #lm1 at isa? port 0x280 #lm2 at isa? port 0x310 -it0 at isa? port 0x290 # IT8705F, IT8712F and SiS970 hardware -it1 at isa? port 0xc00 # monitors -it2 at isa? port 0xd00 +it0 at isa? # ITE IT8705F, IT8712F, IT8716F, IT8718F, + # IT8726F and SiS SiS950 monitors and + # watchdog timer viaenv* at pci? # VIA VT82C686A hardware monitor #viasio* at isa? port 0x2e flags 0x0000 # VIA VT1211 LPC Super I/O diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index ac05736d1f1..2e55e239316 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.595 2007/12/05 19:17:13 deraadt Exp $ +# $OpenBSD: GENERIC,v 1.596 2007/12/18 21:17:54 form Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -120,9 +120,9 @@ iic* at nviic? amdpm* at pci? # AMD-7xx/8111 and NForce SMBus controller iic* at amdpm? -it0 at isa? port 0x290 # IT8705F, IT8712F and SiS970 hardware -it1 at isa? port 0xc00 # monitors -it2 at isa? port 0xd00 +it0 at isa? # ITE IT8705F, IT8712F, IT8716F, + # IT8718F, IT8726F and SiS SiS950 + # monitors and watchdog timer viaenv* at pci? # VIA VT82C686A hardware monitor viasio* at isa? port 0x2e flags 0x0000 # VIA VT1211 LPC Super I/O viasio* at isa? port 0x4e flags 0x0000 diff --git a/sys/dev/isa/files.isa b/sys/dev/isa/files.isa index 9f879455fdf..f43d2761b4e 100644 --- a/sys/dev/isa/files.isa +++ b/sys/dev/isa/files.isa @@ -1,4 +1,4 @@ -# $OpenBSD: files.isa,v 1.99 2007/07/04 17:10:30 henning Exp $ +# $OpenBSD: files.isa,v 1.100 2007/12/18 21:17:54 form 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. @@ -350,7 +350,8 @@ device gscsio: i2cbus attach gscsio at isa file dev/isa/gscsio.c gscsio -# IT8705F, IT8712F and SiS970 hardware monitors +# ITE IT8705F, IT8712F, IT8716F, IT8718F, IT8726F and SiS SiS970 hardware +# monitors and watchdog timers device it attach it at isa file dev/isa/it.c it diff --git a/sys/dev/isa/it.c b/sys/dev/isa/it.c index 79c51ac1baa..9d36c0ed997 100644 --- a/sys/dev/isa/it.c +++ b/sys/dev/isa/it.c @@ -1,7 +1,7 @@ -/* $OpenBSD: it.c,v 1.23 2007/06/24 05:34:35 dlg Exp $ */ +/* $OpenBSD: it.c,v 1.24 2007/12/18 21:17:54 form Exp $ */ /* - * Copyright (c) 2003 Julien Bordet <zejames@greyhats.org> + * Copyright (c) 2007 Oleg Safiullin <form@pdp-11.org.ru> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,292 +28,396 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> -#include <sys/kernel.h> #include <sys/sensors.h> + #include <machine/bus.h> #include <dev/isa/isareg.h> #include <dev/isa/isavar.h> - #include <dev/isa/itvar.h> + #if defined(ITDEBUG) #define DPRINTF(x) do { printf x; } while (0) #else #define DPRINTF(x) #endif -/* - * IT87-compatible chips can typically measure voltages up to 4.096 V. - * To measure higher voltages the input is attenuated with (external) - * resistors. Negative voltages are measured using a reference - * voltage. So we have to convert the sensor values back to real - * voltages by applying the appropriate resistor factor. - */ -#define RFACT_NONE 10000 -#define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y)) -int it_match(struct device *, void *, void *); +int it_probe(struct isa_attach_args *, bus_addr_t); +int it_match(struct device *, void *, void *); void it_attach(struct device *, struct device *, void *); -u_int8_t it_readreg(struct it_softc *, int); -void it_writereg(struct it_softc *, int, int); -void it_setup_volt(struct it_softc *, int, int); -void it_setup_temp(struct it_softc *, int, int); -void it_setup_fan(struct it_softc *, int, int); - -void it_generic_stemp(struct it_softc *, struct ksensor *); -void it_generic_svolt(struct it_softc *, struct ksensor *); -void it_generic_fanrpm(struct it_softc *, struct ksensor *); +u_int8_t it_readreg(bus_space_tag_t, bus_space_handle_t, int); +void it_writereg(bus_space_tag_t, bus_space_handle_t, int, u_int8_t); +void it_enter(bus_space_tag_t, bus_space_handle_t, int); +void it_exit(bus_space_tag_t, bus_space_handle_t); + +u_int8_t it_ec_readreg(struct it_softc *, int); +void it_ec_writereg(struct it_softc *, int, u_int8_t); +void it_ec_refresh(void *arg); + +int it_wdog_cb(void *, int); + + +struct { + int type; + const char *desc; +} it_sensors[IT_EC_NUMSENSORS] = { +#define IT_TEMP_BASE 0 +#define IT_TEMP_COUNT 3 + { SENSOR_TEMP, NULL }, + { SENSOR_TEMP, NULL }, + { SENSOR_TEMP, NULL }, + +#define IT_FAN_BASE 3 +#define IT_FAN_COUNT 3 + { SENSOR_FANRPM, NULL }, + { SENSOR_FANRPM, NULL }, + { SENSOR_FANRPM, NULL }, + +#define IT_VOLT_BASE 6 +#define IT_VOLT_COUNT 9 + { SENSOR_VOLTS_DC, "VCORE_A" }, + { SENSOR_VOLTS_DC, "VCORE_B" }, + { SENSOR_VOLTS_DC, "+3.3V" }, + { SENSOR_VOLTS_DC, "+5V" }, + { SENSOR_VOLTS_DC, "+12V" }, + { SENSOR_VOLTS_DC, "-5V" }, + { SENSOR_VOLTS_DC, "-12V" }, + { SENSOR_VOLTS_DC, "+5VSB" }, + { SENSOR_VOLTS_DC, "VBAT" } +}; -void it_refresh_sensor_data(struct it_softc *); -void it_refresh(void *); +#define RFACT_NONE 10000 +#define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y)) -struct cfattach it_ca = { - sizeof(struct it_softc), - it_match, - it_attach +int it_vrfact[IT_VOLT_COUNT] = { + RFACT_NONE, RFACT_NONE, RFACT_NONE, RFACT(68, 100), RFACT(30, 10), + RFACT(21, 10), RFACT(83, 20), + RFACT(68, 100), RFACT_NONE }; -struct cfdriver it_cd = { - NULL, "it", DV_DULL -}; +int it_found; -const int it_vrfact[] = { - RFACT_NONE, - RFACT_NONE, - RFACT_NONE, - RFACT(68, 100), - RFACT(30, 10), - RFACT(21, 10), - RFACT(83, 20), - RFACT(68, 100), - RFACT_NONE -}; int -it_match(struct device *parent, void *match, void *aux) +it_probe(struct isa_attach_args *ia, bus_addr_t iobase) { - bus_space_tag_t iot; bus_space_handle_t ioh; - struct isa_attach_args *ia = aux; - int iobase; - u_int8_t cr; - - iot = ia->ia_iot; - iobase = ia->ipa_io[0].base; + u_int16_t cr; - if (bus_space_map(iot, iobase, 8, 0, &ioh)) { - DPRINTF(("it: can't map i/o space\n")); + /* map i/o space */ + if (bus_space_map(ia->ia_iot, iobase, 2, 0, &ioh) != 0) { + DPRINTF(("it_probe: can't map i/o space")); return (0); } - /* Check Vendor ID */ - bus_space_write_1(iot, ioh, ITC_ADDR, ITD_CHIPID); - cr = bus_space_read_1(iot, ioh, ITC_DATA); - bus_space_unmap(iot, ioh, 8); - DPRINTF(("it: vendor id 0x%x\n", cr)); - if (cr != IT_ID_IT87) + /* enter MB PnP mode */ + it_enter(ia->ia_iot, ioh, iobase); + + /* get chip id */ + cr = it_readreg(ia->ia_iot, ioh, IT_CHIPID1) << 8; + cr |= it_readreg(ia->ia_iot, ioh, IT_CHIPID2); + + /* exit MB PnP mode and unmap */ + it_exit(ia->ia_iot, ioh); + bus_space_unmap(ia->ia_iot, ioh, 2); + + switch (cr) { + case IT_ID_8705: + case IT_ID_8712: + case IT_ID_8716: + case IT_ID_8718: + case IT_ID_8726: + ia->ipa_io[0].base = iobase; + ia->ipa_nio = 1; + ia->ipa_io[0].length = 2; + ia->ipa_nmem = ia->ipa_nirq = ia->ipa_ndrq = 0; + break; + default: return (0); - - ia->ipa_nio = 1; - ia->ipa_io[0].length = 8; - ia->ipa_nmem = 0; - ia->ipa_nirq = 0; - ia->ipa_ndrq = 0; + } return (1); } +int +it_match(struct device *parent, void *match, void *aux) +{ + struct isa_attach_args *ia = aux; + + if (!it_found) { + if (ia->ipa_io[0].base == IOBASEUNK) { + if (it_probe(ia, IO_IT1) || it_probe(ia, IO_IT2)) + return (1); + } else if (ia->ipa_io[0].base == IO_IT1 || + ia->ipa_io[0].base == IO_IT2) + return (it_probe(ia, ia->ipa_io[0].base)); + } + + return (0); +} + void it_attach(struct device *parent, struct device *self, void *aux) { struct it_softc *sc = (void *)self; - int iobase; - bus_space_tag_t iot; struct isa_attach_args *ia = aux; - int i; + int i, iobase; u_int8_t cr; - iobase = ia->ipa_io[0].base; - iot = sc->it_iot = ia->ia_iot; - - if (bus_space_map(iot, iobase, 8, 0, &sc->it_ioh)) { + sc->sc_iot = ia->ia_iot; + sc->sc_iobase = ia->ipa_io[0].base; + if (bus_space_map(sc->sc_iot, sc->sc_iobase, 2, 0, &sc->sc_ioh) != 0) { printf(": can't map i/o space\n"); return; } - i = it_readreg(sc, ITD_CHIPID); - switch (i) { - case IT_ID_IT87: - printf(": IT87\n"); - break; + it_found++; + + /* enter MB PnP mode */ + it_enter(sc->sc_iot, sc->sc_ioh, sc->sc_iobase); + + /* get chip id and rev */ + sc->sc_chipid = it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPID1) << 8; + sc->sc_chipid |= it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPID2); + sc->sc_chiprev = it_readreg(sc->sc_iot, sc->sc_ioh, IT_CHIPREV); + + /* get environment controller base address */ + it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_EC_LDN); + iobase = it_readreg(sc->sc_iot, sc->sc_ioh, IT_EC_MSB) << 8; + iobase |= it_readreg(sc->sc_iot, sc->sc_ioh, IT_EC_LSB); + + /* initialize watchdog */ + if (sc->sc_chipid != IT_ID_8705) { + it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_WDT_LDN); + it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_CSR, 0x00); + it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TCR, 0x80); + wdog_register(sc, it_wdog_cb); + } + + /* exit MB PnP mode and unmap */ + it_exit(sc->sc_iot, sc->sc_ioh); + + printf(": IT%xF rev 0x%02x", sc->sc_chipid, sc->sc_chiprev); + + if (iobase == 0) { + printf(", EC disabled\n"); + return; + } + + printf(", EC port 0x%x\n", iobase); + + /* map environment controller i/o space */ + sc->sc_ec_iot = ia->ia_iot; + if (bus_space_map(sc->sc_ec_iot, iobase, 8, 0, &sc->sc_ec_ioh) != 0) { + printf("%s: can't map EC i/o space\n", sc->sc_dev.dv_xname); + return; } - sc->numsensors = IT_NUM_SENSORS; + /* initialize sensor structures */ + for (i = 0; i < IT_EC_NUMSENSORS; i++) { + sc->sc_sensors[i].type = it_sensors[i].type; - it_setup_fan(sc, 0, 3); - it_setup_volt(sc, 3, 9); - it_setup_temp(sc, 12, 3); + if (it_sensors[i].desc != NULL) + snprintf(sc->sc_sensors[i].desc, + sizeof(sc->sc_sensors[i].desc), + it_sensors[i].desc); + } - if (sensor_task_register(sc, it_refresh, 5) == NULL) { - printf("%s: unable to register update task\n", + /* register update task */ + if (sensor_task_register(sc, it_ec_refresh, IT_EC_INTERVAL) == NULL) { + printf(": unable to register update task\n", sc->sc_dev.dv_xname); + bus_space_unmap(sc->sc_ec_iot, sc->sc_ec_ioh, 8); return; } - /* Activate monitoring */ - cr = it_readreg(sc, ITD_CONFIG); - cr |= 0x01 | 0x08; - it_writereg(sc, ITD_CONFIG, cr); - - /* Initialize sensors */ - strlcpy(sc->sensordev.xname, sc->sc_dev.dv_xname, - sizeof(sc->sensordev.xname)); - for (i = 0; i < sc->numsensors; ++i) - sensor_attach(&sc->sensordev, &sc->sensors[i]); - sensordev_install(&sc->sensordev); + /* activate monitoring */ + cr = it_ec_readreg(sc, IT_EC_CFG); + it_ec_writereg(sc, IT_EC_CFG, cr | 0x09); + + /* initialize sensors */ + strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, + sizeof(sc->sc_sensordev.xname)); + for (i = 0; i < IT_EC_NUMSENSORS; i++) + sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]); + sensordev_install(&sc->sc_sensordev); } u_int8_t -it_readreg(struct it_softc *sc, int reg) +it_readreg(bus_space_tag_t iot, bus_space_handle_t ioh, int r) { - bus_space_write_1(sc->it_iot, sc->it_ioh, ITC_ADDR, reg); - return (bus_space_read_1(sc->it_iot, sc->it_ioh, ITC_DATA)); + bus_space_write_1(iot, ioh, IT_IO_ADDR, r); + return (bus_space_read_1(iot, ioh, IT_IO_DATA)); } void -it_writereg(struct it_softc *sc, int reg, int val) +it_writereg(bus_space_tag_t iot, bus_space_handle_t ioh, int r, u_int8_t v) { - bus_space_write_1(sc->it_iot, sc->it_ioh, ITC_ADDR, reg); - bus_space_write_1(sc->it_iot, sc->it_ioh, ITC_DATA, val); + bus_space_write_1(iot, ioh, IT_IO_ADDR, r); + bus_space_write_1(iot, ioh, IT_IO_DATA, v); } void -it_setup_volt(struct it_softc *sc, int start, int n) +it_enter(bus_space_tag_t iot, bus_space_handle_t ioh, int iobase) { - int i; - - for (i = 0; i < n; ++i) { - sc->sensors[start + i].type = SENSOR_VOLTS_DC; - } - - snprintf(sc->sensors[start + 0].desc, sizeof(sc->sensors[0].desc), - "VCORE_A"); - snprintf(sc->sensors[start + 1].desc, sizeof(sc->sensors[1].desc), - "VCORE_B"); - snprintf(sc->sensors[start + 2].desc, sizeof(sc->sensors[2].desc), - "+3.3V"); - snprintf(sc->sensors[start + 3].desc, sizeof(sc->sensors[3].desc), - "+5V"); - snprintf(sc->sensors[start + 4].desc, sizeof(sc->sensors[4].desc), - "+12V"); - snprintf(sc->sensors[start + 5].desc, sizeof(sc->sensors[5].desc), - "Unused"); - snprintf(sc->sensors[start + 6].desc, sizeof(sc->sensors[6].desc), - "-12V"); - snprintf(sc->sensors[start + 7].desc, sizeof(sc->sensors[7].desc), - "+5VSB"); - snprintf(sc->sensors[start + 8].desc, sizeof(sc->sensors[8].desc), - "VBAT"); + bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x87); + bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x01); + bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x55); + if (iobase == IO_IT1) + bus_space_write_1(iot, ioh, IT_IO_ADDR, 0x55); + else + bus_space_write_1(iot, ioh, IT_IO_ADDR, 0xaa); } void -it_setup_temp(struct it_softc *sc, int start, int n) +it_exit(bus_space_tag_t iot, bus_space_handle_t ioh) { - int i; - - for (i = 0; i < n; ++i) - sc->sensors[start + i].type = SENSOR_TEMP; + bus_space_write_1(iot, ioh, IT_IO_ADDR, IT_CCR); + bus_space_write_1(iot, ioh, IT_IO_DATA, 0x02); } -void -it_setup_fan(struct it_softc *sc, int start, int n) +u_int8_t +it_ec_readreg(struct it_softc *sc, int r) { - int i; - - for (i = 0; i < n; ++i) - sc->sensors[start + i].type = SENSOR_FANRPM; + bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, IT_EC_ADDR, r); + return (bus_space_read_1(sc->sc_ec_iot, sc->sc_ec_ioh, IT_EC_DATA)); } void -it_generic_stemp(struct it_softc *sc, struct ksensor *sensors) +it_ec_writereg(struct it_softc *sc, int r, u_int8_t v) { - int i, sdata; - - for (i = 0; i < 3; i++) { - sdata = it_readreg(sc, ITD_SENSORTEMPBASE + i); - /* Convert temperature to Fahrenheit degres */ - sensors[i].value = sdata * 1000000 + 273150000; - } + bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, IT_EC_ADDR, r); + bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, IT_EC_DATA, v); } void -it_generic_svolt(struct it_softc *sc, struct ksensor *sensors) +it_ec_refresh(void *arg) { - int i, sdata; + struct it_softc *sc = arg; + int i, sdata, mode, divisor, odivisor, ndivisor; + + /* refresh temp sensors */ + for (i = 0; i < IT_TEMP_COUNT; i++) { + sdata = it_ec_readreg(sc, IT_EC_TEMPBASE + i); + /* convert to degF */ + sc->sc_sensors[IT_TEMP_BASE + i].value = + sdata * 1000000 + 273150000; + } - for (i = 0; i < 9; i++) { - sdata = it_readreg(sc, ITD_SENSORVOLTBASE + i); - DPRINTF(("sdata[volt%d] 0x%x\n", i, sdata)); + /* refresh volt sensors */ + for (i = 0; i < IT_VOLT_COUNT; i++) { + sdata = it_ec_readreg(sc, IT_EC_VOLTBASE + i); /* voltage returned as (mV >> 4) */ - sensors[i].value = (sdata << 4); + sc->sc_sensors[IT_VOLT_BASE + i].value = sdata << 4; /* these two values are negative and formula is different */ if (i == 5 || i == 6) - sensors[i].value = ((sdata << 4) - IT_VREF); + sc->sc_sensors[IT_VOLT_BASE + i].value -= IT_EC_VREF; /* rfact is (factor * 10^4) */ - sensors[i].value *= it_vrfact[i]; + sc->sc_sensors[IT_VOLT_BASE + i].value *= it_vrfact[i]; /* division by 10 gets us back to uVDC */ - sensors[i].value /= 10; + sc->sc_sensors[IT_VOLT_BASE + i].value /= 10; if (i == 5 || i == 6) - sensors[i].value += IT_VREF * 1000; + sc->sc_sensors[IT_VOLT_BASE + i].value += + IT_EC_VREF * 1000; } -} -void -it_generic_fanrpm(struct it_softc *sc, struct ksensor *sensors) -{ - int i, sdata, divisor, odivisor, ndivisor; - - odivisor = ndivisor = divisor = it_readreg(sc, ITD_FAN); - for (i = 0; i < 3; i++, divisor >>= 3) { - sensors[i].flags &= ~SENSOR_FINVALID; - if ((sdata = it_readreg(sc, ITD_SENSORFANBASE + i)) == 0xff) { - sensors[i].flags |= SENSOR_FINVALID; - if (i == 2) - ndivisor ^= 0x40; - else { - ndivisor &= ~(7 << (i * 3)); - ndivisor |= ((divisor + 1) & 7) << (i * 3); - } - } else if (sdata == 0) { - sensors[i].value = 0; + /* refresh fan sensors */ + if (sc->sc_chipid == IT_ID_8705 || sc->sc_chipid == IT_ID_8712) + odivisor = ndivisor = divisor = + it_ec_readreg(sc, IT_EC_FAN_DIV); + else { + mode = it_ec_readreg(sc, IT_EC_FAN_ECR); + divisor = -1; + } + + for (i = 0; i < IT_FAN_COUNT; i++) { + sc->sc_sensors[IT_FAN_BASE + i].flags &= ~SENSOR_FINVALID; + sdata = it_ec_readreg(sc, IT_EC_FANBASE + i); + + if (divisor != -1) { + /* + * Use 8-bit FAN Tachometer & FAN Divisor registers + */ + if (sdata == 0xff) { + sc->sc_sensors[IT_FAN_BASE + i].flags |= + SENSOR_FINVALID; + if (i == 2) + ndivisor ^= 0x40; + else { + ndivisor &= ~(7 << (i * 3)); + ndivisor |= ((divisor + 1) & 7) << + (i * 3); + } + } else if (sdata != 0) { + if (i == 2) + divisor = divisor & 1 ? 3 : 1; + sc->sc_sensors[IT_FAN_BASE + i].value = + 1350000 / (sdata << (divisor & 7)); + } else + sc->sc_sensors[IT_FAN_BASE + i].value = 0; + + if (ndivisor != odivisor) + it_ec_writereg(sc, IT_EC_FAN_DIV, ndivisor); } else { - if (i == 2) - divisor = divisor & 1 ? 3 : 1; - sensors[i].value = 1350000 / (sdata << (divisor & 7)); + /* + * Use 16-bit FAN tachometer register + */ + if (mode & (1 << i)) + sdata |= it_ec_readreg(sc, + IT_EC_FANEXTBASE + i) << 8; + if (sdata == ((mode & (1 << i)) ? 0xffff : 0xff)) + sc->sc_sensors[IT_FAN_BASE + i].flags |= + SENSOR_FINVALID; + else if (sdata != 0) + sc->sc_sensors[IT_FAN_BASE + i].value = + 675000 / sdata; + else + sc->sc_sensors[IT_FAN_BASE + i].value = 0; } } - if (ndivisor != odivisor) - it_writereg(sc, ITD_FAN, ndivisor); } -/* - * pre: last read occurred >= 1.5 seconds ago - * post: sensors[] current data are the latest from the chip - */ -void -it_refresh_sensor_data(struct it_softc *sc) +int +it_wdog_cb(void *arg, int period) { - /* Refresh our stored data for every sensor */ - it_generic_stemp(sc, &sc->sensors[12]); - it_generic_svolt(sc, &sc->sensors[3]); - it_generic_fanrpm(sc, &sc->sensors[0]); -} + struct it_softc *sc = arg; -void -it_refresh(void *arg) -{ - struct it_softc *sc = (struct it_softc *)arg; + /* enter MB PnP mode and select WDT device */ + it_enter(sc->sc_iot, sc->sc_ioh, sc->sc_iobase); + it_writereg(sc->sc_iot, sc->sc_ioh, IT_LDN, IT_WDT_LDN); + + /* disable watchdog timeout */ + it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TCR, 0x80); - it_refresh_sensor_data(sc); + /* 1000s should be enough for everyone */ + if (period > 1000) + period = 1000; + else if (period < 0) + period = 0; + + /* set watchdog timeout */ + it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_MSB, period >> 8); + it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_LSB, period & 0xff); + + if (period > 0) + /* enable watchdog timeout */ + it_writereg(sc->sc_iot, sc->sc_ioh, IT_WDT_TCR, 0xc0); + + /* exit MB PnP mode */ + it_exit(sc->sc_iot, sc->sc_ioh); + + return (period); } + + +struct cfattach it_ca = { + sizeof(struct it_softc), + it_match, + it_attach +}; + +struct cfdriver it_cd = { + NULL, "it", DV_DULL +}; diff --git a/sys/dev/isa/itvar.h b/sys/dev/isa/itvar.h index 4bd39aa4783..913729ad41d 100644 --- a/sys/dev/isa/itvar.h +++ b/sys/dev/isa/itvar.h @@ -1,7 +1,7 @@ -/* $OpenBSD: itvar.h,v 1.4 2007/03/22 16:55:31 deraadt Exp $ */ +/* $OpenBSD: itvar.h,v 1.5 2007/12/18 21:17:54 form Exp $ */ /* - * Copyright (c) 2003 Julien Bordet <zejames@greyhats.org> + * Copyright (c) 2007 Oleg Safiullin <form@pdp-11.org.ru> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,68 +25,68 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _DEV_ISA_ITVAR_H -#define _DEV_ISA_ITVAR_H +#ifndef _DEV_ISA_ITVAR_H_ +#define _DEV_ISA_ITVAR_H_ -#define IT_NUM_SENSORS 15 +#define IT_EC_INTERVAL 5 +#define IT_EC_NUMSENSORS 15 +#define IT_EC_VREF 4096 -/* chip ids */ -#define IT_ID_IT87 0x90 +#define IO_IT1 0x2e +#define IO_IT2 0x4e -/* ctl registers */ +#define IT_IO_ADDR 0x00 +#define IT_IO_DATA 0x01 -#define ITC_ADDR 0x05 -#define ITC_DATA 0x06 +#define IT_ID_8705 0x8705 +#define IT_ID_8712 0x8712 +#define IT_ID_8716 0x8716 +#define IT_ID_8718 0x8718 +#define IT_ID_8726 0x8726 -/* data registers */ +#define IT_CCR 0x02 +#define IT_LDN 0x07 +#define IT_CHIPID1 0x20 +#define IT_CHIPID2 0x21 +#define IT_CHIPREV 0x22 -#define ITD_CONFIG 0x00 -#define ITD_ISR1 0x01 -#define ITD_ISR2 0x02 -#define ITD_ISR3 0x03 -#define ITD_SMI1 0x04 -#define ITD_SMI2 0x05 -#define ITD_SMI3 0x06 -#define ITD_IMR1 0x07 -#define ITD_IMR2 0x08 -#define ITD_IMR3 0x09 -#define ITD_VID 0x0a -#define ITD_FAN 0x0b +#define IT_EC_LDN 0x04 +#define IT_EC_MSB 0x60 +#define IT_EC_LSB 0x61 -#define ITD_FANMINBASE 0x10 -#define ITD_FANENABLE 0x13 +#define IT_EC_ADDR 0x05 +#define IT_EC_DATA 0x06 -#define ITD_SENSORFANBASE 0x0d /* Fan from 0x0d to 0x0f */ -#define ITD_SENSORVOLTBASE 0x20 /* Fan from 0x20 to 0x28 */ -#define ITD_SENSORTEMPBASE 0x29 /* Fan from 0x29 to 0x2b */ +#define IT_EC_CFG 0x00 +#define IT_EC_FAN_DIV 0x0b +#define IT_EC_FAN_ECR 0x0c +#define IT_EC_FANBASE 0x0d +#define IT_EC_FANEXTBASE 0x18 +#define IT_EC_VOLTBASE 0x20 +#define IT_EC_TEMPBASE 0x29 -#define ITD_VOLTMAXBASE 0x30 -#define ITD_VOLTMINBASE 0x31 +#define IT_WDT_LDN 0x07 -#define ITD_TEMPMAXBASE 0x40 -#define ITD_TEMPMINBASE 0x41 +#define IT_WDT_CSR 0x71 +#define IT_WDT_TCR 0x72 +#define IT_WDT_LSB 0x73 +#define IT_WDT_MSB 0x74 -#define ITD_SBUSADDR 0x48 -#define ITD_VOLTENABLE 0x50 -#define ITD_TEMPENABLE 0x51 - -#define ITD_CHIPID 0x58 - -#define IT_VREF (4096) /* Vref = 4.096 V */ struct it_softc { - struct device sc_dev; + struct device sc_dev; - bus_space_tag_t it_iot; - bus_space_handle_t it_ioh; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + int sc_iobase; + u_int16_t sc_chipid; + u_int8_t sc_chiprev; - struct ksensor sensors[IT_NUM_SENSORS]; - struct ksensordev sensordev; - u_int numsensors; - void (*refresh_sensor_data)(struct it_softc *); + bus_space_tag_t sc_ec_iot; + bus_space_handle_t sc_ec_ioh; - u_int8_t (*it_readreg)(struct it_softc *, int); - void (*it_writereg)(struct it_softc *, int, int); + struct ksensor sc_sensors[IT_EC_NUMSENSORS]; + struct ksensordev sc_sensordev; }; -#endif +#endif /* _DEV_ISA_ITVAR_H_ */ diff --git a/sys/dev/isa/lm78_isa.c b/sys/dev/isa/lm78_isa.c index 8ee1bf6efaf..be84ec3ea4f 100644 --- a/sys/dev/isa/lm78_isa.c +++ b/sys/dev/isa/lm78_isa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lm78_isa.c,v 1.2 2007/07/01 21:48:57 cnst Exp $ */ +/* $OpenBSD: lm78_isa.c,v 1.3 2007/12/18 21:17:54 form Exp $ */ /* * Copyright (c) 2005, 2006 Mark Kettenis @@ -26,7 +26,6 @@ #include <dev/isa/isavar.h> #include <dev/ic/lm78var.h> -#include <dev/isa/itvar.h> /* ISA registers */ #define LMC_ADDR 0x05 @@ -85,9 +84,8 @@ lm_isa_match(struct device *parent, void *match, void *aux) goto found; /* Probe for ITE chips (and don't attach if we find one). */ - bus_space_write_1(iot, ioh, LMC_ADDR, ITD_CHIPID); - vendid = bus_space_read_1(iot, ioh, LMC_DATA); - if (vendid == IT_ID_IT87) + bus_space_write_1(iot, ioh, LMC_ADDR, 0x58); + if ((vendid = bus_space_read_1(iot, ioh, LMC_DATA)) == 0x90) goto notfound; /* |