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:
parent
8fb14189dc
commit
7abc984e72
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue