Added support for the Watchdog Timer built in the IT871[268] Super I/Os.

The WDT supports any value between 1 and 65535 seconds (or minutes, but
but the driver only uses seconds).
This commit is contained in:
xtraeme 2007-12-29 06:05:06 +00:00
parent 8fb14189dc
commit 7abc984e72
3 changed files with 157 additions and 44 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: itesio.4,v 1.3 2007/11/15 15:34:54 xtraeme Exp $
.\" $NetBSD: itesio.4,v 1.4 2007/12/29 06:05:11 xtraeme Exp $
.\" $OpenBSD: it.4,v 1.7 2006/03/29 14:10:51 jsg Exp $
.\"
.\" Copyright (c) 2006-2007 Juan Romero Pardines <juan@xtrarom.org>
@ -25,22 +25,22 @@
.\" (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 November 15, 2007
.Dd December 29, 2007
.Dt ITESIO 4
.Os
.Sh NAME
.Nm itesio
.Nd ITE IT87xxF and compatibles Super I/O
.Nd ITE IT87xxF Super I/O driver
.Sh SYNOPSIS
.Cd "itesio0 at isa? port 0x2e"
.Sh DESCRIPTION
The
.Nm
driver provides support for the Hardware monitor part of the
driver provides support for the Environment Controller and the Watchdog Timer
on the
.Tn IT87xxF
and compatibles Super I/O to be used with the
.Xr envsys 4
interface.
Super I/Os, and may be used to monitor hardware sensors or setting up a
watchdog timeout value for the system.
.Pp
The
.Nm
@ -63,6 +63,13 @@ driver has 15 sensors:
.It Li "Fan1" Ta "RPM" Ta "System Fan"
.It Li "Fan2" Ta "RPM" Ta "Aux Fan"
.El
.Pp
The
.Nm
Watchdog Timer is configurable via the
.Xr wdogctl 8
utility and has a resolution between 1 and 65535 seconds. The Watchdog
Timer is not supported on the IT8705 Super I/O.
.Sh SEE ALSO
.Xr envsys 4 ,
.Xr envstat 8
@ -79,9 +86,7 @@ The
.Nm
driver was written by
.An Julien Bordet Aq zejames@greyhats.org
and was ported to
.Nx
by
and
.An Juan Romero Pardines Aq juan@xtrarom.org .
.Sh BUGS
Interrupt support is unimplemented.

View File

@ -1,4 +1,4 @@
/* $NetBSD: itesio_isa.c,v 1.8 2007/12/13 15:36:29 xtraeme Exp $ */
/* $NetBSD: itesio_isa.c,v 1.9 2007/12/29 06:05:06 xtraeme Exp $ */
/* Derived from $OpenBSD: it.c,v 1.19 2006/04/10 00:57:54 deraadt Exp $ */
/*
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: itesio_isa.c,v 1.8 2007/12/13 15:36:29 xtraeme Exp $");
__KERNEL_RCSID(0, "$NetBSD: itesio_isa.c,v 1.9 2007/12/29 06:05:06 xtraeme Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -90,6 +90,10 @@ static void itesio_refresh_volts(struct itesio_softc *, envsys_data_t *);
static void itesio_refresh_fans(struct itesio_softc *, envsys_data_t *);
static void itesio_refresh(struct sysmon_envsys *, envsys_data_t *);
/* sysmon_wdog glue */
static int itesio_wdt_setmode(struct sysmon_wdog *);
static int itesio_wdt_tickle(struct sysmon_wdog *);
/* rfact values for voltage sensors */
static const int itesio_vrfact[] = {
RFACT_NONE, /* VCORE_A */
@ -150,13 +154,13 @@ itesio_isa_attach(device_t parent, device_t self, void *aux)
{
struct itesio_softc *sc = device_private(self);
struct isa_attach_args *ia = aux;
bus_space_handle_t ioh;
int i;
uint8_t cr;
ia->ia_iot = sc->sc_iot;
sc->sc_iot = ia->ia_iot;
if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh)) {
if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 2, 0,
&sc->sc_ioh)) {
aprint_error(": can't map i/o space\n");
return;
}
@ -166,34 +170,37 @@ itesio_isa_attach(device_t parent, device_t self, void *aux)
/*
* Enter to the Super I/O MB PNP mode.
*/
itesio_enter(ia->ia_iot, ioh);
itesio_enter(sc->sc_iot, sc->sc_ioh);
/*
* Get info from the Super I/O Global Configuration Registers:
* Chip IDs and Device Revision.
*/
sc->sc_chipid = (itesio_readreg(ia->ia_iot, ioh, ITESIO_CHIPID1) << 8);
sc->sc_chipid |= itesio_readreg(ia->ia_iot, ioh, ITESIO_CHIPID2);
sc->sc_devrev = (itesio_readreg(ia->ia_iot, ioh, ITESIO_DEVREV) & 0x0f);
sc->sc_chipid = (itesio_readreg(sc->sc_iot, sc->sc_ioh,
ITESIO_CHIPID1) << 8);
sc->sc_chipid |= itesio_readreg(sc->sc_iot, sc->sc_ioh,
ITESIO_CHIPID2);
sc->sc_devrev = (itesio_readreg(sc->sc_iot, sc->sc_ioh,
ITESIO_DEVREV) & 0x0f);
/*
* Select the EC LDN to get the Base Address.
*/
itesio_writereg(ia->ia_iot, ioh, ITESIO_LDNSEL, ITESIO_EC_LDN);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_LDNSEL, ITESIO_EC_LDN);
sc->sc_hwmon_baseaddr =
(itesio_readreg(ia->ia_iot, ioh, ITESIO_EC_MSB) << 8);
sc->sc_hwmon_baseaddr |= itesio_readreg(ia->ia_iot, ioh, ITESIO_EC_LSB);
(itesio_readreg(sc->sc_iot, sc->sc_ioh, ITESIO_EC_MSB) << 8);
sc->sc_hwmon_baseaddr |= itesio_readreg(sc->sc_iot, sc->sc_ioh,
ITESIO_EC_LSB);
/*
* We are done, exit MB PNP mode and unmap I/O space.
* We are done, exit MB PNP mode.
*/
itesio_exit(ia->ia_iot, ioh);
bus_space_unmap(sc->sc_iot, ioh, 2);
itesio_exit(sc->sc_iot, sc->sc_ioh);
aprint_normal(": iTE IT%4xF Super I/O (rev %d)\n",
sc->sc_chipid, sc->sc_devrev);
aprint_normal_dev(self, "Hardware Monitor registers at 0x%x\n",
sc->sc_hwmon_baseaddr);
if (bus_space_map(sc->sc_iot, sc->sc_hwmon_baseaddr, 8, 0,
&sc->sc_ioh)) {
if (bus_space_map(sc->sc_ec_iot, sc->sc_hwmon_baseaddr, 8, 0,
&sc->sc_ec_ioh)) {
aprint_error_dev(self, "cannot map hwmon i/o space\n");
return;
}
@ -236,12 +243,36 @@ itesio_isa_attach(device_t parent, device_t self, void *aux)
aprint_error_dev(self,
"unable to register with sysmon (%d)\n", i);
sysmon_envsys_destroy(sc->sc_sme);
bus_space_unmap(sc->sc_iot, sc->sc_ioh, 8);
bus_space_unmap(sc->sc_ec_iot, sc->sc_ec_ioh, 8);
return;
}
sc->sc_hwmon_enabled = true;
if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
/* The IT8705 doesn't support a WDT */
if (sc->sc_chipid == ITESIO_ID8705) {
bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2);
return;
}
/*
* Initialize the watchdog timer.
*/
sc->sc_smw.smw_name = device_xname(self);
sc->sc_smw.smw_cookie = sc;
sc->sc_smw.smw_setmode = itesio_wdt_setmode;
sc->sc_smw.smw_tickle = itesio_wdt_tickle;
sc->sc_smw.smw_period = 60;
if (sysmon_wdog_register(&sc->sc_smw)) {
aprint_error_dev(self, "unable to register watchdog timer\n");
bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2);
return;
}
sc->sc_wdt_enabled = true;
aprint_normal_dev(self, "Watchdog Timer present\n");
}
static int
@ -252,7 +283,12 @@ itesio_isa_detach(device_t self, int flags)
if (sc->sc_hwmon_enabled)
sysmon_envsys_unregister(sc->sc_sme);
if (sc->sc_hwmon_mapped)
bus_space_unmap(sc->sc_iot, sc->sc_ioh, 8);
bus_space_unmap(sc->sc_ec_iot, sc->sc_ec_ioh, 8);
if (sc->sc_wdt_enabled) {
sysmon_wdog_register(&sc->sc_smw);
bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2);
}
return 0;
}
@ -262,15 +298,15 @@ itesio_isa_detach(device_t self, int flags)
static uint8_t
itesio_ecreadreg(struct itesio_softc *sc, int reg)
{
bus_space_write_1(sc->sc_iot, sc->sc_ioh, ITESIO_EC_ADDR, reg);
return bus_space_read_1(sc->sc_iot, sc->sc_ioh, ITESIO_EC_DATA);
bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, ITESIO_EC_ADDR, reg);
return bus_space_read_1(sc->sc_ec_iot, sc->sc_ec_ioh, ITESIO_EC_DATA);
}
static void
itesio_ecwritereg(struct itesio_softc *sc, int reg, int val)
{
bus_space_write_1(sc->sc_iot, sc->sc_ioh, ITESIO_EC_ADDR, reg);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, ITESIO_EC_DATA, val);
bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, ITESIO_EC_ADDR, reg);
bus_space_write_1(sc->sc_ec_iot, sc->sc_ec_ioh, ITESIO_EC_DATA, val);
}
/*
@ -486,3 +522,59 @@ itesio_refresh(struct sysmon_envsys *sme, struct envsys_data *edata)
else
itesio_refresh_fans(sc, edata);
}
static int
itesio_wdt_setmode(struct sysmon_wdog *smw)
{
struct itesio_softc *sc = smw->smw_cookie;
int period = smw->smw_period;
/* Enter MB PNP mode and select the WDT LDN */
itesio_enter(sc->sc_iot, sc->sc_ioh);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_LDNSEL, ITESIO_WDT_LDN);
if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
/* Disable the watchdog */
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_CTL, 0);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_CNF, 0);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_TMO_MSB, 0);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_TMO_LSB, 0);
} else {
/* Enable the watchdog */
if (period > ITESIO_WDT_MAXTIMO || period < 1)
period = smw->smw_period = ITESIO_WDT_MAXTIMO;
period *= 2;
/* set the timeout and start the watchdog */
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_TMO_MSB,
period >> 8);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_TMO_LSB,
period & 0xff);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_CNF,
ITESIO_WDT_CNF_SECS | ITESIO_WDT_CNF_KRST |
ITESIO_WDT_CNF_PWROK);
}
/* we are done, exit MB PNP mode */
itesio_exit(sc->sc_iot, sc->sc_ioh);
return 0;
}
static int
itesio_wdt_tickle(struct sysmon_wdog *smw)
{
struct itesio_softc *sc = smw->smw_cookie;
int period = smw->smw_period * 2;
/* refresh timeout value and exit */
itesio_enter(sc->sc_iot, sc->sc_ioh);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_LDNSEL, ITESIO_WDT_LDN);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_TMO_MSB,
period >> 8);
itesio_writereg(sc->sc_iot, sc->sc_ioh, ITESIO_WDT_TMO_LSB,
period & 0xff);
itesio_exit(sc->sc_iot, sc->sc_ioh);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: itesio_isavar.h,v 1.3 2007/11/16 08:00:15 xtraeme Exp $ */
/* $NetBSD: itesio_isavar.h,v 1.4 2007/12/29 06:05:11 xtraeme Exp $ */
/* $OpenBSD: itvar.h,v 1.2 2003/11/05 20:57:10 grange Exp $ */
/*
@ -42,6 +42,17 @@
#define ITESIO_EC_MSB 0x60 /* EC Base Address (MSB) */
#define ITESIO_EC_LSB 0x61 /* EC Base Address (LSB) */
#define ITESIO_WDT_LDN 0x07 /* Watchdog Logical Device Number */
#define ITESIO_WDT_CTL 0x71 /* Watchdog Control Register */
#define ITESIO_WDT_CNF 0x72 /* Watchdog Configuration Register */
#define ITESIO_WDT_CNF_SECS (1<<7) /* Use seconds for the timer */
#define ITESIO_WDT_CNF_KRST (1<<6) /* Enable KRST */
#define ITESIO_WDT_CNF_PWROK (1<<4) /* Enable PWROK */
#define ITESIO_WDT_TMO_LSB 0x73 /* Watchdog Timeout Value LSB */
#define ITESIO_WDT_TMO_MSB 0x74 /* Watchdog Timeout Value MSB */
#define ITESIO_WDT_MAXTIMO 0xffff /* either seconds or minutes */
#define ITESIO_CHIPID1 0x20 /* Chip ID 1 */
#define ITESIO_CHIPID2 0x21 /* Chip ID 2 */
#define ITESIO_DEVREV 0x22 /* Device Revision */
@ -79,7 +90,7 @@
#define ITESIO_EC_FANMINBASE 0x10
#define ITESIO_EC_FANENABLE 0x13
#define ITESIO_EC_SENSORFANBASE 0x0d /* Fan from 0x0d to 0x0f */
#define ITESIO_EC_SENSORFANBASE 0x0d /* Fan from 0x0d to 0x0f */
#define ITESIO_EC_SENSORFANEXTBASE 0x18 /* Fan (MSB) from 0x18 to 0x1A */
#define ITESIO_EC_SENSORVOLTBASE 0x20 /* Voltage from 0x20 to 0x28 */
#define ITESIO_EC_SENSORTEMPBASE 0x29 /* Temperature from 0x29 to 0x2b */
@ -126,18 +137,23 @@
#define ITESIO_EC_VREF (4096) /* Vref = 4.096 V */
struct itesio_softc {
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
struct sysmon_envsys *sc_sme;
envsys_data_t sc_sensor[IT_NUM_SENSORS];
bus_space_tag_t sc_ec_iot;
bus_space_handle_t sc_ec_ioh;
struct sysmon_wdog sc_smw;
struct sysmon_envsys *sc_sme;
envsys_data_t sc_sensor[IT_NUM_SENSORS];
uint16_t sc_hwmon_baseaddr;
bool sc_hwmon_mapped;
bool sc_hwmon_enabled;
uint16_t sc_hwmon_baseaddr;
bool sc_hwmon_mapped;
bool sc_hwmon_enabled;
bool sc_wdt_enabled;
uint16_t sc_chipid;
uint8_t sc_devrev;
uint16_t sc_chipid;
uint8_t sc_devrev;
};
#endif /* _DEV_ISA_ITSIO_ISAVAR_H_ */