diff options
author | Alexander Yurchenko <grange@cvs.openbsd.org> | 2005-07-28 20:12:14 +0000 |
---|---|---|
committer | Alexander Yurchenko <grange@cvs.openbsd.org> | 2005-07-28 20:12:14 +0000 |
commit | 04bc583ecad4492bd759df4d05ffad33decea50a (patch) | |
tree | b3284639e1f2d5dfd5aaa3110b305ec452264e41 | |
parent | 6d77a5035c6df4cd7072d4697c679a8c0acf08cf (diff) |
Add viasio(4), a driver for VIA VT1211 LPC Super I/O found on
some VIA CPU based boards. The driver provides temperature,
voltage and fan tachometers values through the sysctl interface.
Rickard Dahlstrand <rd@tilde.se> asked for this driver and
provided access to the test board. Also tested by millert@.
ok millert@
-rw-r--r-- | share/man/man4/Makefile | 4 | ||||
-rw-r--r-- | share/man/man4/viasio.4 | 68 | ||||
-rw-r--r-- | sys/arch/amd64/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/arch/i386/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/dev/isa/files.isa | 7 | ||||
-rw-r--r-- | sys/dev/isa/viasio.c | 433 | ||||
-rw-r--r-- | sys/dev/isa/viasioreg.h | 246 |
7 files changed, 761 insertions, 5 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 32adf72c0ae..87e02b25f8d 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.304 2005/07/28 01:43:31 brad Exp $ +# $OpenBSD: Makefile,v 1.305 2005/07/28 20:12:13 grange Exp $ MAN= aac.4 ac97.4 acphy.4 addcom.4 adv.4 aha.4 ahb.4 ahc.4 ahd.4 \ aic.4 amdpm.4 ami.4 amphy.4 an.4 aria.4 ast.4 atalk.4 \ @@ -34,7 +34,7 @@ MAN= aac.4 ac97.4 acphy.4 addcom.4 adv.4 aha.4 ahb.4 ahc.4 ahd.4 \ ukphy.4 ulpt.4 umass.4 umct.4 umidi.4 umodem.4 ums.4 \ unix.4 upl.4 uplcom.4 urio.4 url.4 urlphy.4 usb.4 \ uscanner.4 usscanner.4 uvisor.4 uvscom.4 uyap.4 vga.4 vge.4 \ - viaenv.4 vlan.4 vnd.4 vr.4 watchdog.4 wb.4 wd.4 wdc.4 we.4 \ + viaenv.4 viasio.4 vlan.4 vnd.4 vr.4 watchdog.4 wb.4 wd.4 wdc.4 we.4 \ wi.4tbl wscons.4 wsdisplay.4 wskbd.4 wsmouse.4 wsmux.4 xe.4 \ xf86.4 xl.4 xmphy.4 yds.4 ym.4 zero.4 diff --git a/share/man/man4/viasio.4 b/share/man/man4/viasio.4 new file mode 100644 index 00000000000..a374d21b5ec --- /dev/null +++ b/share/man/man4/viasio.4 @@ -0,0 +1,68 @@ +.\" $OpenBSD: viasio.4,v 1.1 2005/07/28 20:12:13 grange Exp $ +.\" +.\" Copyright (c) 2005 Alexander Yurchenko <grange@openbsd.org> +.\" +.\" 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. +.\" +.Dd Jul 24, 2005 +.Dt VIASIO 4 +.Os +.Sh NAME +.Nm viasio +.Nd VIA VT1211 LPC Super I/O +.Sh SYNOPSIS +.Cd "viasio* at isa? port 0x2e flags 0x0000" +.Cd "viasio* at isa? port 0x4e flags 0x0000" +.Sh DESCRIPTION +The +.Nm +driver provides support for the VIA VT1211 LPC Super I/O IC. +Only hardware monitoring function is supported currently. +.Pp +Hardware monitor provides hardware monitoring capabilities +to be used with the +.Xr sysctl 8 +interface. +The following monitoring sensors are available: +.Bl -column "Sensor" "UnitsXXXXX" "Typical" -offset indent +.It Sy "Sensor" Ta Sy "Units" Ta Sy "Typical use" +.It Li "TEMP1" Ta "uK" Ta "Pentium II type thermal diode" +.It Li "UCH1" Ta "uK or uV DC" Ta "CPU temperature" +.It Li "UCH2" Ta "uK or uV DC" Ta "System temperature" +.It Li "UCH3" Ta "uK or uV DC" Ta "CPU core voltage" +.It Li "UCH4" Ta "uK or uV DC" Ta "+5V" +.It Li "UCH5" Ta "uK or uV DC" Ta "+12V" +.It Li "+3.3V" Ta "uV" Ta "Internal +3.3V" +.It Li "FAN1" Ta "RPM" Ta "Fan tachometer" +.It Li "FAN2" Ta "RPM" Ta "Fan tachometer" +.El +.Pp +If hardware monitor is not enabled by firmware the driver can try +to enable it if value 0x0001 is presented in the +.Ar flags . +Note that enabling hardware monitor can lead to unexpected results. +.Sh SEE ALSO +.Xr intro 4 , +.Xr isa 4 , +.Xr sensorsd 8 , +.Xr sysctl 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Ox 3.8 . +.Sh AUTHORS +The +.Nm +driver was written by +.An Alexander Yurchenko Aq grange@openbsd.org . diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index e47b1ef3e50..d8914bf8ff6 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.74 2005/07/06 07:24:54 deraadt Exp $ +# $OpenBSD: GENERIC,v 1.75 2005/07/28 20:12:13 grange Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -68,6 +68,8 @@ lm0 at isa? port 0x290 it0 at isa? port 0x290 # IT8705F, IT8712F and SiS970 hardware # monitors 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 #option PCMCIAVERBOSE diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index ac3541abbac..bda93ddc3a1 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.421 2005/07/28 01:45:05 brad Exp $ +# $OpenBSD: GENERIC,v 1.422 2005/07/28 20:12:13 grange Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -101,6 +101,8 @@ lmtemp0 at iic1 addr 0x48 # NS LM75/LM77 temperature sensor it0 at isa? port 0x290 # IT8705F, IT8712F and SiS970 hardware # monitors 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 # ISA PCMCIA controllers #option PCMCIAVERBOSE diff --git a/sys/dev/isa/files.isa b/sys/dev/isa/files.isa index e58c4afe6fd..8e29afbd394 100644 --- a/sys/dev/isa/files.isa +++ b/sys/dev/isa/files.isa @@ -1,4 +1,4 @@ -# $OpenBSD: files.isa,v 1.89 2005/03/08 20:00:25 tdeval Exp $ +# $OpenBSD: files.isa,v 1.90 2005/07/28 20:12:13 grange 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. @@ -393,6 +393,11 @@ device it attach it at isa file dev/isa/it.c it +# VIA VT1211 LPC Super I/O +device viasio +attach viasio at isa +file dev/isa/viasio.c viasio + # # PCMCIA PCIC (i82365SL and compatibles): # diff --git a/sys/dev/isa/viasio.c b/sys/dev/isa/viasio.c new file mode 100644 index 00000000000..bd71575067b --- /dev/null +++ b/sys/dev/isa/viasio.c @@ -0,0 +1,433 @@ +/* $OpenBSD: viasio.c,v 1.1 2005/07/28 20:12:13 grange Exp $ */ +/* + * Copyright (c) 2005 Alexander Yurchenko <grange@openbsd.org> + * + * 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. + */ + +/* + * VIA VT1211 LPC Super I/O driver. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/kernel.h> +#include <sys/sensors.h> +#include <sys/timeout.h> + +#include <machine/bus.h> + +#include <dev/isa/isareg.h> +#include <dev/isa/isavar.h> + +#include <dev/isa/viasioreg.h> + +#ifdef VIASIO_DEBUG +#define DPRINTF(x) printf x +#else +#define DPRINTF(x) +#endif + +/* autoconf flags */ +#define VIASIO_CFFLAGS_HM_ENABLE 0x0001 /* enable HM if disabled */ + +struct viasio_softc { + struct device sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + /* Hardware monitor */ + bus_space_handle_t sc_hm_ioh; + int sc_hm_clock; + struct sensor sc_hm_sensors[VT1211_HM_NSENSORS]; + struct timeout sc_hm_timo; +}; + +int viasio_probe(struct device *, void *, void *); +void viasio_attach(struct device *, struct device *, void *); + +void viasio_hm_init(struct viasio_softc *); +void viasio_hm_refresh(void *); + +struct cfattach viasio_ca = { + sizeof(struct viasio_softc), + viasio_probe, + viasio_attach +}; + +struct cfdriver viasio_cd = { + NULL, "viasio", DV_DULL +}; + +static __inline void +viasio_conf_enable(bus_space_tag_t iot, bus_space_handle_t ioh) +{ + bus_space_write_1(iot, ioh, VT1211_INDEX, VT1211_CONF_EN_MAGIC); + bus_space_write_1(iot, ioh, VT1211_INDEX, VT1211_CONF_EN_MAGIC); +} + +static __inline void +viasio_conf_disable(bus_space_tag_t iot, bus_space_handle_t ioh) +{ + bus_space_write_1(iot, ioh, VT1211_INDEX, VT1211_CONF_DS_MAGIC); +} + +static __inline u_int8_t +viasio_conf_read(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t index) +{ + bus_space_write_1(iot, ioh, VT1211_INDEX, index); + return (bus_space_read_1(iot, ioh, VT1211_DATA)); +} + +static __inline void +viasio_conf_write(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t index, + u_int8_t data) +{ + bus_space_write_1(iot, ioh, VT1211_INDEX, index); + bus_space_write_1(iot, ioh, VT1211_DATA, data); +} + +static __inline int64_t +viasio_raw2temp(int raw) +{ + int tblsize = sizeof(vt1211_hm_temptbl) / sizeof(vt1211_hm_temptbl[0]); + int i; + int raw1, raw2; + int64_t temp = -1, temp1, temp2; + + if (raw < vt1211_hm_temptbl[0].raw || + raw > vt1211_hm_temptbl[tblsize - 1].raw) + return (-1); + + for (i = 0; i < tblsize - 1; i++) { + raw1 = vt1211_hm_temptbl[i].raw; + temp1 = vt1211_hm_temptbl[i].temp; + raw2 = vt1211_hm_temptbl[i + 1].raw; + temp2 = vt1211_hm_temptbl[i + 1].temp; + + if (raw >= raw1 && raw <= raw2) { + /* linear interpolation */ + temp = temp1 + ((raw - raw1) * (temp2 - temp1)) / + (raw2 - raw1); + break; + } + } + + return (temp); +} + +int +viasio_probe(struct device *parent, void *match, void *aux) +{ + struct isa_attach_args *ia = aux; + bus_space_tag_t iot; + bus_space_handle_t ioh; + u_int8_t reg; + + /* Match by device ID */ + iot = ia->ia_iot; + if (bus_space_map(iot, ia->ipa_io[0].base, VT1211_IOSIZE, 0, &ioh)) + return (0); + viasio_conf_enable(iot, ioh); + reg = viasio_conf_read(iot, ioh, VT1211_ID); + DPRINTF(("viasio_probe: id 0x%02x\n", reg)); + viasio_conf_disable(iot, ioh); + bus_space_unmap(iot, ioh, VT1211_IOSIZE); + if (reg == VT1211_ID_VT1211) { + ia->ipa_nio = 1; + ia->ipa_io[0].length = VT1211_IOSIZE; + ia->ipa_nmem = 0; + ia->ipa_nirq = 0; + ia->ipa_ndrq = 0; + return (1); + } + + return (0); +} + +void +viasio_attach(struct device *parent, struct device *self, void *aux) +{ + struct viasio_softc *sc = (void *)self; + struct isa_attach_args *ia = aux; + u_int8_t reg; + + /* Map ISA I/O space */ + sc->sc_iot = ia->ia_iot; + if (bus_space_map(sc->sc_iot, ia->ipa_io[0].base, + VT1211_IOSIZE, 0, &sc->sc_ioh)) { + printf(": can't map I/O space\n"); + return; + } + + /* Enter configuration mode */ + viasio_conf_enable(sc->sc_iot, sc->sc_ioh); + + /* Read device revision */ + reg = viasio_conf_read(sc->sc_iot, sc->sc_ioh, VT1211_REV); + printf(": VT1211 rev 0x%02x\n", reg); + + /* Initialize logical devices */ + printf("%s", sc->sc_dev.dv_xname); + viasio_hm_init(sc); + printf("\n"); + + /* Escape from configuration mode */ + viasio_conf_disable(sc->sc_iot, sc->sc_ioh); +} + +void +viasio_hm_init(struct viasio_softc *sc) +{ + u_int8_t reg0, reg1; + u_int16_t iobase; + int i; + + printf(": HM"); + + /* Select HM logical device */ + viasio_conf_write(sc->sc_iot, sc->sc_ioh, VT1211_LDN, VT1211_LDN_HM); + + /* + * Check if logical device is activated by firmware. If not + * try to activate it only if requested. + */ + reg0 = viasio_conf_read(sc->sc_iot, sc->sc_ioh, VT1211_HM_ACT); + DPRINTF((": ACT 0x%02x", reg0)); + if ((reg0 & VT1211_HM_ACT_EN) == 0) { + if ((sc->sc_dev.dv_cfdata->cf_flags & + VIASIO_CFFLAGS_HM_ENABLE) != 0) { + reg0 |= VT1211_HM_ACT_EN; + viasio_conf_write(sc->sc_iot, sc->sc_ioh, + VT1211_HM_ACT, reg0); + reg0 = viasio_conf_read(sc->sc_iot, sc->sc_ioh, + VT1211_HM_ACT); + DPRINTF((", new ACT 0x%02x", reg0)); + if ((reg0 & VT1211_HM_ACT_EN) == 0) { + printf(": failed to activate"); + return; + } + } else { + printf(": not activated"); + return; + } + } + + /* Read HM I/O space address */ + reg0 = viasio_conf_read(sc->sc_iot, sc->sc_ioh, VT1211_HM_ADDR_LSB); + reg1 = viasio_conf_read(sc->sc_iot, sc->sc_ioh, VT1211_HM_ADDR_MSB); + iobase = (reg1 << 8) | reg0; + DPRINTF((", addr 0x%04x", iobase)); + + /* Map HM I/O space */ + if (bus_space_map(sc->sc_iot, iobase, VT1211_HM_IOSIZE, 0, + &sc->sc_hm_ioh)) { + printf(": can't map I/O space"); + return; + } + + /* + * Check if hardware monitoring is enabled by firmware. If not + * try to enable it only if requested. + */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_CONF); + DPRINTF((", CONF 0x%02x", reg0)); + if ((reg0 & VT1211_HM_CONF_START) == 0) { + if ((sc->sc_dev.dv_cfdata->cf_flags & + VIASIO_CFFLAGS_HM_ENABLE) != 0) { + reg0 |= VT1211_HM_CONF_START; + bus_space_write_1(sc->sc_iot, sc->sc_hm_ioh, + VT1211_HM_CONF, reg0); + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, + VT1211_HM_CONF); + DPRINTF((", new CONF 0x%02x", reg0)); + if ((reg0 & VT1211_HM_CONF_START) == 0) { + printf(": failed to enable monitoring"); + return; + } + } else { + printf(": monitoring not enabled"); + return; + } + } + + /* Read PWM clock frequency */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_PWMCS); + sc->sc_hm_clock = vt1211_hm_clock[reg0 & 0x07]; + DPRINTF((", PWMCS 0x%02x, %dHz", reg0, sc->sc_hm_clock)); + + /* Initialize sensors */ + for (i = 0; i < VT1211_HM_NSENSORS; i++) + strlcpy(sc->sc_hm_sensors[i].device, sc->sc_dev.dv_xname, + sizeof(sc->sc_hm_sensors[i].device)); + + /* Temperature reading 1 */ + sc->sc_hm_sensors[VT1211_HMS_TEMP1].type = SENSOR_TEMP; + strlcpy(sc->sc_hm_sensors[VT1211_HMS_TEMP1].desc, "TEMP1", + sizeof(sc->sc_hm_sensors[VT1211_HMS_TEMP1].desc)); + + /* Universal channels (UCH) 1-5 */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_UCHCONF); + DPRINTF((", UCHCONF 0x%02x", reg0)); + for (i = 1; i <= 5; i++) { + /* UCH can be configured either as thermal or voltage input */ + if (VT1211_HM_UCHCONF_ISTEMP(reg0, i)) { + sc->sc_hm_sensors[VT1211_HMS_UCH1 + i - 1].type = + SENSOR_TEMP; + } else { + sc->sc_hm_sensors[VT1211_HMS_UCH1 + i - 1].type = + SENSOR_VOLTS_DC; + sc->sc_hm_sensors[VT1211_HMS_UCH1 + i - 1].rfact = + vt1211_hm_vrfact[i - 1]; + } + snprintf(sc->sc_hm_sensors[VT1211_HMS_UCH1 + i - 1].desc, + sizeof(sc->sc_hm_sensors[VT1211_HMS_UCH1 + i - 1].desc), + "UCH%d", i); + } + + /* Internal +3.3V */ + sc->sc_hm_sensors[VT1211_HMS_33V].type = SENSOR_VOLTS_DC; + strlcpy(sc->sc_hm_sensors[VT1211_HMS_33V].desc, "+3.3V", + sizeof(sc->sc_hm_sensors[VT1211_HMS_33V].desc)); + sc->sc_hm_sensors[VT1211_HMS_33V].rfact = vt1211_hm_vrfact[5]; + + /* FAN reading 1, 2 */ + sc->sc_hm_sensors[VT1211_HMS_FAN1].type = SENSOR_FANRPM; + strlcpy(sc->sc_hm_sensors[VT1211_HMS_FAN1].desc, "FAN1", + sizeof(sc->sc_hm_sensors[VT1211_HMS_FAN1].desc)); + sc->sc_hm_sensors[VT1211_HMS_FAN2].type = SENSOR_FANRPM; + strlcpy(sc->sc_hm_sensors[VT1211_HMS_FAN2].desc, "FAN2", + sizeof(sc->sc_hm_sensors[VT1211_HMS_FAN2].desc)); + + /* Start sensors */ + for (i = 0; i < VT1211_HM_NSENSORS; i++) + SENSOR_ADD(&sc->sc_hm_sensors[i]); + timeout_set(&sc->sc_hm_timo, viasio_hm_refresh, sc); + timeout_add(&sc->sc_hm_timo, hz); +} + +void +viasio_hm_refresh(void *arg) +{ + struct viasio_softc *sc = arg; + u_int8_t reg0, reg1; + int64_t val, rfact; + int i; + + /* TEMP1 is a 10-bit thermal input */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_TEMP1); + reg1 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_TCONF1); + reg1 = VT1211_HM_TCONF1_TEMP1(reg1); + val = (reg0 << 2) | reg1; + + /* Convert to uK */ + /* XXX: conversion function is guessed */ + val = viasio_raw2temp(val); + if (val == -1) { + sc->sc_hm_sensors[VT1211_HMS_TEMP1].flags |= SENSOR_FINVALID; + } else { + sc->sc_hm_sensors[VT1211_HMS_TEMP1].flags &= ~SENSOR_FINVALID; + sc->sc_hm_sensors[VT1211_HMS_TEMP1].value = val; + } + + /* Universal channels 1-5 */ + for (i = 1; i <= 5; i++) { + if (sc->sc_hm_sensors[VT1211_HMS_UCH1 + i - 1].type == + SENSOR_TEMP) { + /* UCH is a 10-bit thermal input */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, + VT1211_HM_UCH1 + i - 1); + if (i == 1) { + reg1 = bus_space_read_1(sc->sc_iot, + sc->sc_hm_ioh, VT1211_HM_VID4); + reg1 = VT1211_HM_VID4_UCH1(reg1); + } else { + reg1 = bus_space_read_1(sc->sc_iot, + sc->sc_hm_ioh, VT1211_HM_ETR); + reg1 = VT1211_HM_ETR_UCH(reg1, i); + } + val = (reg0 << 2) | reg1; + + /* Convert to uK */ + /* XXX: conversion function is guessed */ + val = viasio_raw2temp(val); + if (val == -1) { + sc->sc_hm_sensors[VT1211_HMS_UCH1 + + i - 1].flags |= SENSOR_FINVALID; + } else { + sc->sc_hm_sensors[VT1211_HMS_UCH1 + + i - 1].flags &= ~SENSOR_FINVALID; + sc->sc_hm_sensors[VT1211_HMS_UCH1 + + i - 1].value = val; + } + } else { + /* UCH is a voltage input */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, + VT1211_HM_UCH1 + i - 1); + val = reg0; + + /* Convert to uV */ + /* XXX: conversion function is guessed */ + rfact = sc->sc_hm_sensors[VT1211_HMS_UCH1 + + i - 1].rfact; + sc->sc_hm_sensors[VT1211_HMS_UCH1 + i - 1].value = + ((val * 100000000000ULL) / (rfact * 958)); + } + } + + /* Read internal +3.3V */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_33V); + val = reg0; + + /* Convert to uV */ + /* XXX: conversion function is guessed */ + rfact = sc->sc_hm_sensors[VT1211_HMS_33V].rfact; + sc->sc_hm_sensors[VT1211_HMS_33V].value = ((val * 100000000000ULL) / + (rfact * 958)); + + /* Read FAN1 clock counter and divisor */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_FAN1); + reg1 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_FSCTL); + reg1 = VT1211_HM_FSCTL_DIV1(reg1); + val = reg0 << reg1; + + /* Convert to RPM */ + /* XXX: conversion function is guessed */ + if (val != 0) { + sc->sc_hm_sensors[VT1211_HMS_FAN1].value = + (sc->sc_hm_clock * 60 / 2) / val; + sc->sc_hm_sensors[VT1211_HMS_FAN1].flags &= ~SENSOR_FINVALID; + } else { + sc->sc_hm_sensors[VT1211_HMS_FAN1].flags |= SENSOR_FINVALID; + } + + /* Read FAN2 clock counter and divisor */ + reg0 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_FAN2); + reg1 = bus_space_read_1(sc->sc_iot, sc->sc_hm_ioh, VT1211_HM_FSCTL); + reg1 = VT1211_HM_FSCTL_DIV2(reg1); + val = reg0 << reg1; + + /* Convert to RPM */ + /* XXX: conversion function is guessed */ + if (val != 0) { + sc->sc_hm_sensors[VT1211_HMS_FAN2].value = + (sc->sc_hm_clock * 60 / 2) / val; + sc->sc_hm_sensors[VT1211_HMS_FAN2].flags &= ~SENSOR_FINVALID; + } else { + sc->sc_hm_sensors[VT1211_HMS_FAN2].flags |= SENSOR_FINVALID; + } + + timeout_add(&sc->sc_hm_timo, hz); +} diff --git a/sys/dev/isa/viasioreg.h b/sys/dev/isa/viasioreg.h new file mode 100644 index 00000000000..8b528f7c750 --- /dev/null +++ b/sys/dev/isa/viasioreg.h @@ -0,0 +1,246 @@ +/* $OpenBSD: viasioreg.h,v 1.1 2005/07/28 20:12:13 grange Exp $ */ +/* + * Copyright (c) 2005 Alexander Yurchenko <grange@openbsd.org> + * + * 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. + */ + +#ifndef _DEV_ISA_VIASIOREG_H_ +#define _DEV_ISA_VIASIOREG_H_ + +/* + * VIA VT1211 LPC Super I/O register definitions. + */ + +/* + * Obtained from the following datasheet: + * + * VT1211 + * Low Pin Count Super I/O And Hardware Monitor + * Revision 1.0 + * January 8, 2002 + * VIA TECHNOLOGIES, INC. + */ + +/* ISA bus registers */ +#define VT1211_INDEX 0x00 /* Configuration Index Register */ +#define VT1211_DATA 0x01 /* Configuration Data Register */ + +#define VT1211_IOSIZE 0x02 /* ISA I/O space size */ + +#define VT1211_CONF_EN_MAGIC 0x87 /* enable configuration mode */ +#define VT1211_CONF_DS_MAGIC 0xaa /* disable configuration mode */ + +/* Configuration Space Registers */ +#define VT1211_LDN 0x07 /* Logical Device Number */ +#define VT1211_ID 0x20 /* Device ID */ +#define VT1211_REV 0x21 /* Device Revision */ +#define VT1211_PDC 0x22 /* Power Down Control */ +#define VT1211_LPCWSS 0x23 /* LPC Wait State Select */ +#define VT1211_GPIO1PS 0x24 /* GPIO Port 1 Pin Select */ +#define VT1211_GPIO2PS 0x25 /* GPIO Port 2 Pin Select */ +#define VT1211_GPIO7PS 0x26 /* GPIO Port 7 Pin Select */ +#define VT1211_UART2PS 0x27 /* UART2 Multi Function Pin Select */ +#define VT1211_MIDIPS 0x28 /* MIDI Multi Function Pin Select */ +#define VT1211_HWMPS 0x29 /* HWM Multi Function Pin Select */ +#define VT1211_TMA 0x2e /* Test Mode A */ +#define VT1211_TMB 0x2f /* Test Mode B */ + +#define VT1211_ID_VT1211 0x3c /* VT1211 Device ID */ + +/* Logical Device Number (LDN) Assignments */ +#define VT1211_LDN_FDC 0x00 /* Floppy Disk Controller */ +#define VT1211_LDN_PP 0x01 /* Parallel Port */ +#define VT1211_LDN_UART1 0x02 /* Serial Port 1 */ +#define VT1211_LDN_UART2 0x03 /* Serial Port 2 */ +#define VT1211_LDN_MIDI 0x06 /* MIDI */ +#define VT1211_LDN_GMP 0x07 /* Game Port */ +#define VT1211_LDN_GPIO 0x08 /* GPIO */ +#define VT1211_LDN_WDG 0x09 /* Watch Dog */ +#define VT1211_LDN_WUC 0x0a /* Wake-up Control */ +#define VT1211_LDN_HM 0x0b /* Hardware Monitor */ +#define VT1211_LDN_VFIR 0x0c /* Very Fast IR */ +#define VT1211_LDN_ROM 0x0d /* Flash ROM */ + +/* Hardware Monitor Control Registers (LDN B) */ +#define VT1211_HM_ACT 0x30 /* Activate */ +#define VT1211_HM_ACT_EN (1 << 0) +#define VT1211_HM_ADDR_MSB 0x60 /* Address [15:8] */ +#define VT1211_HM_ADDR_LSB 0x61 /* Address [7:0] */ +#define VT1211_HM_IRQSEL 0x70 /* IRQ Select */ + +/* Hardware Monitor I/O Space Registers */ +#define VT1211_HM_SELD0 0x10 /* SELD[7:0] */ +#define VT1211_HM_SELD1 0x11 /* SELD[15:8] */ +#define VT1211_HM_SELD2 0x12 /* SELD[19:16] */ +#define VT1211_HM_ADATA_MSB 0x13 /* Analog Data D[15:8] */ +#define VT1211_HM_ADATA_LSB 0x14 /* Analog Data D[7:0] */ +#define VT1211_HM_DDATA 0x15 /* Digital Data D[7:0] */ +#define VT1211_HM_CHCNT 0x16 /* Channel Counter */ +#define VT1211_HM_DVCI 0x17 /* Data Valid & Channel Indications */ +#define VT1211_HM_SMBUSCTL 0x18 /* SMBus Control */ +#define VT1211_HM_AFECTL 0x19 /* AFE Control */ +#define VT1211_HM_AFETCTL 0x1a /* AFE Test Control */ +#define VT1211_HM_CHSET 0x1b /* Channel Setting */ +#define VT1211_HM_HTL3 0x1d /* Hot Temp Limit 3 */ +#define VT1211_HM_HTHL3 0x1e /* Hot Temp Hysteresis Limit 3 */ +#define VT1211_HM_TEMP1 0x1f /* Temperature Reading 1 */ +#define VT1211_HM_TEMP3 0x20 /* Temperature Reading 3 */ +#define VT1211_HM_UCH1 0x21 /* UCH1 */ +#define VT1211_HM_UCH2 0x22 /* UCH2 */ +#define VT1211_HM_UCH3 0x23 /* UCH3 */ +#define VT1211_HM_UCH4 0x24 /* UCH4 */ +#define VT1211_HM_UCH5 0x25 /* UCH5 */ +#define VT1211_HM_33V 0x26 /* +3.3V (Internal Vcc ) */ +#define VT1211_HM_FAN1 0x29 /* FAN1 Reading */ +#define VT1211_HM_FAN2 0x2a /* FAN2 Reading */ +#define VT1211_HM_UCH2HL 0x2b /* UCH2 High Limit */ +#define VT1211_HM_UCH2LL 0x2c /* UCH2 Low Limit */ +#define VT1211_HM_UCH3HL 0x2d /* UCH3 High Limit */ +#define VT1211_HM_UCH3LL 0x2e /* UCH3 Low Limit */ +#define VT1211_HM_UCH4HL 0x2f /* UCH4 High Limit */ +#define VT1211_HM_UCH4LL 0x30 /* UCH4 Low Limit */ +#define VT1211_HM_UCH5HL 0x31 /* UCH5 High Limit */ +#define VT1211_HM_UCH5LL 0x32 /* UCH5 Low Limit */ +#define VT1211_HM_33VHL 0x33 /* Internal +3.3V High Limit */ +#define VT1211_HM_33VLL 0x34 /* Internal +3.3V Low Limit */ +#define VT1211_HM_HTL1 0x39 /* Hot Temp Limit 1 */ +#define VT1211_HM_HTHL1 0x3a /* Hot Temp Hysteresis Limit 1 */ +#define VT1211_HM_FAN1CL 0x3b /* FAN1 Fan Count Limit */ +#define VT1211_HM_FAN2CL 0x3c /* FAN2 Fan Count Limit */ +#define VT1211_HM_UCH1HL 0x3d /* UCH1 High Limit */ +#define VT1211_HM_UCH1LL 0x3e /* UCH1 Low Limit */ +#define VT1211_HM_STEPID 0x3f /* Stepping ID Number */ +#define VT1211_HM_CONF 0x40 /* Configuration */ +#define VT1211_HM_CONF_START (1 << 0) +#define VT1211_HM_INTST1 0x41 /* Interrupt INT Status 1 */ +#define VT1211_HM_INTST2 0x42 /* Interrupt INT Status 2 */ +#define VT1211_HM_INTMASK1 0x43 /* INT Mask 1 */ +#define VT1211_HM_INTMASK2 0x44 /* INT Mask 2 */ +#define VT1211_HM_VID 0x45 /* VID */ +#define VT1211_HM_OVOFCTL 0x46 /* Over Voltage & Over Fan Control */ +#define VT1211_HM_FSCTL 0x47 /* Fan Speed Control */ +#define VT1211_HM_FSCTL_DIV1(v) (((v) >> 4) & 0x03) +#define VT1211_HM_FSCTL_DIV2(v) (((v) >> 6) & 0x03) +#define VT1211_HM_SBA 0x48 /* Serial Bus Address */ +#define VT1211_HM_VID4 0x49 /* VID 4 */ +#define VT1211_HM_VID4_UCH1(v) (((v) >> 4) & 0x03) +#define VT1211_HM_UCHCONF 0x4a /* Universal Channel Configuration */ +#define VT1211_HM_UCHCONF_ISTEMP(v, n) (((v) & (1 << ((n) + 1))) != 0) +#define VT1211_HM_TCONF1 0x4b /* Temperature Configuration 1 */ +#define VT1211_HM_TCONF1_TEMP1(v) (((v) >> 6) & 0x03) +#define VT1211_HM_TCONF2 0x4c /* Temperature Configuration 2 */ +#define VT1211_HM_ETR 0x4d /* Extended Temperature Resolution */ +#define VT1211_HM_ETR_UCH(v, n) (((v) >> (((n) - 2) * 2)) & 0x03) +#define VT1211_HM_OTCTL 0x4e /* Over Temperature Control */ +#define VT1211_HM_PWMCS 0x50 /* PWM Clock Select */ +#define VT1211_HM_PWMCTL 0x51 /* PWM Control */ +#define VT1211_HM_PWMFST 0x52 /* PWM Full Speed Temperature Value */ +#define VT1211_HM_PWMHST 0x53 /* PWM High Speed Temperature Value */ +#define VT1211_HM_PWMLST 0x54 /* PWM Low Speed Temperature Value */ +#define VT1211_HM_PWMFOT 0x55 /* PWM Fan Off Temperature Value */ +#define VT1211_HM_PWMO1HSDC 0x56 /* PWM Output 1 Hi Speed Duty Cycle */ +#define VT1211_HM_PWMO1LSDC 0x57 /* PWM Output 1 Lo Speed Duty Cycle */ +#define VT1211_HM_PWMO2HSDC 0x58 /* PWM Output 2 Hi Speed Duty Cycle */ +#define VT1211_HM_PWMO2LSDC 0x59 /* PWM Output 2 Lo Speed Duty Cycle */ +#define VT1211_HM_PWMO3HSDC 0x5a /* PWM Output 3 Hi Speed Duty Cycle */ +#define VT1211_HM_PWMO3LSDC 0x5b /* PWM Output 3 Lo Speed Duty Cycle */ +#define VT1211_HM_BEEPEN 0x5c /* BEEP Event Enable */ +#define VT1211_HM_FEBFD 0x5d /* Fan Event BEEP Frequency Divisor */ +#define VT1211_HM_VEBFD 0x5e /* Volt Event BEEP Frequency Divisor */ +#define VT1211_HM_TEBFD 0x5f /* Temp Event BEEP Frequency Divisor */ +#define VT1211_HM_PWM1CDC 0x60 /* PWM1 Current Duty Cycle */ +#define VT1211_HM_PWM2CDC 0x61 /* PWM2 Current Duty Cycle */ + +#define VT1211_HM_IOSIZE 0x80 /* Hardware monitor I/O space size */ + +/* PWM clock frequencies */ +static const int vt1211_hm_clock[] = { + 90000, 45000, 22500, 11250, 5630, 2800, 1400, 700 +}; + +/* Voltage inputs resistor factors */ +static const int vt1211_hm_vrfact[] = { + 5952, 8333, 5952, 4167, 1754, 6296 +}; + +/* Temperature conversion table */ +static const struct { + int raw; + int64_t temp; +} vt1211_hm_temptbl[] = { + { 592, 298150000LLU }, + { 600, 299130000LLU }, + { 608, 300130000LLU }, + { 616, 301140000LLU }, + { 624, 302150000LLU }, + { 632, 303170000LLU }, + { 640, 304210000LLU }, + { 648, 305250000LLU }, + { 656, 306310000LLU }, + { 664, 307380000LLU }, + { 672, 308470000LLU }, + { 680, 309570000LLU }, + { 688, 310690000LLU }, + { 696, 311830000LLU }, + { 704, 312990000LLU }, + { 712, 314170000LLU }, + { 720, 315380000LLU }, + { 728, 316610000LLU }, + { 736, 317860000LLU }, + { 744, 319150000LLU }, + { 752, 320460000LLU }, + { 760, 321810000LLU }, + { 768, 323200000LLU }, + { 776, 324620000LLU }, + { 784, 326090000LLU }, + { 792, 327610000LLU }, + { 800, 329170000LLU }, + { 808, 330790000LLU }, + { 816, 332470000LLU }, + { 824, 334220000LLU }, + { 832, 336040000LLU }, + { 840, 337940000LLU }, + { 848, 339940000LLU }, + { 856, 342030000LLU }, + { 864, 344230000LLU }, + { 872, 346560000LLU }, + { 880, 349030000LLU }, + { 888, 351670000LLU }, + { 896, 354490000LLU }, + { 904, 357530000LLU }, + { 912, 360830000LLU }, + { 920, 364430000LLU }, + { 928, 368410000LLU }, + { 936, 372830000LLU }, + { 944, 377820000LLU }, + { 952, 383530000LLU }, + { 960, 390210000LLU }, + { 968, 398230000LLU } +}; + +/* Hardware monitor sensors */ +enum { + VT1211_HMS_TEMP1 = 0, + VT1211_HMS_UCH1, + VT1211_HMS_UCH2, + VT1211_HMS_UCH3, + VT1211_HMS_UCH4, + VT1211_HMS_UCH5, + VT1211_HMS_33V, + VT1211_HMS_FAN1, + VT1211_HMS_FAN2, + VT1211_HM_NSENSORS /* must be the last */ +}; + +#endif /* !_DEV_ISA_VIASIOREG_H_ */ |