summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorOleg Safiullin <form@cvs.openbsd.org>2007-12-18 21:17:55 +0000
committerOleg Safiullin <form@cvs.openbsd.org>2007-12-18 21:17:55 +0000
commitae4477b7459bc815ac50a13f5116111583162e76 (patch)
tree05a9f6e6afc9b44e913983eb423178bc60676e00 /sys
parent6419734f0d7db56ba7400f42ff11714b3b3a0b93 (diff)
New it(4) driver.
Supports ITE IT8705/8712/8716/8718/8726 and SiS SiS950 hardware monitors and ITE IT8712F/8716F/8718F/8726F watchdog timer.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/conf/GENERIC8
-rw-r--r--sys/arch/i386/conf/GENERIC8
-rw-r--r--sys/dev/isa/files.isa5
-rw-r--r--sys/dev/isa/it.c492
-rw-r--r--sys/dev/isa/itvar.h98
-rw-r--r--sys/dev/isa/lm78_isa.c8
6 files changed, 361 insertions, 258 deletions
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;
/*