summaryrefslogtreecommitdiff
path: root/sys/dev/isa
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isa')
-rw-r--r--sys/dev/isa/it.c121
-rw-r--r--sys/dev/isa/itvar.h14
2 files changed, 75 insertions, 60 deletions
diff --git a/sys/dev/isa/it.c b/sys/dev/isa/it.c
index 11707b69918..9484894d9e2 100644
--- a/sys/dev/isa/it.c
+++ b/sys/dev/isa/it.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: it.c,v 1.27 2007/12/24 14:07:47 form Exp $ */
+/* $OpenBSD: it.c,v 1.28 2008/04/03 20:28:05 form Exp $ */
/*
- * Copyright (c) 2007 Oleg Safiullin <form@pdp-11.org.ru>
+ * Copyright (c) 2007-2008 Oleg Safiullin <form@pdp-11.org.ru>
* Copyright (c) 2006-2007 Juan Romero Pardines <juan@xtrarom.org>
* Copyright (c) 2003 Julien Bordet <zejames@greyhats.org>
* All rights reserved.
@@ -50,7 +50,7 @@ int it_match(struct device *, void *, void *);
void it_attach(struct device *, struct device *, void *);
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);
+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);
@@ -98,78 +98,75 @@ int it_vrfact[IT_VOLT_COUNT] = {
RFACT(68, 100), RFACT_NONE
};
-int it_found;
+LIST_HEAD(, it_softc) it_softc_list = LIST_HEAD_INITIALIZER(&it_softc_list);
int
it_match(struct device *parent, void *match, void *aux)
{
struct isa_attach_args *ia = aux;
+ struct it_softc *sc;
bus_space_handle_t ioh;
- bus_addr_t iobase;
+ int ec_iobase, found = 0;
u_int16_t cr;
- if (it_found || ia->ipa_io[0].base == IOBASEUNK)
- return (0);
-
- /* map EC i/o space */
- if (bus_space_map(ia->ia_iot, ia->ipa_io[0].base, 8, 0, &ioh) != 0) {
- DPRINTF(("it_probe: can't map EC i/o space"));
- return (0);
- }
-
- /* get vendor id */
- bus_space_write_1(ia->ia_iot, ioh, IT_EC_ADDR, IT_EC_VENDID);
- cr = bus_space_read_1(ia->ia_iot, ioh, IT_EC_DATA);
-
- /* unmap EC i/o space */
- bus_space_unmap(ia->ia_iot, ioh, 8);
-
- /* check for ITE vendor ID */
- if (cr != IT_VEND_ITE)
+ if (ia->ipa_io[0].base != IO_IT1 && ia->ipa_io[0].base != IO_IT2)
return (0);
/* map i/o space */
- if (bus_space_map(ia->ia_iot, IO_IT, 2, 0, &ioh) != 0) {
- DPRINTF(("it_probe: can't map i/o space"));
+ if (bus_space_map(ia->ia_iot, ia->ipa_io[0].base, 2, 0, &ioh) != 0) {
+ DPRINTF(("it_match: can't map i/o space"));
return (0);
}
/* enter MB PnP mode */
- it_enter(ia->ia_iot, ioh);
+ it_enter(ia->ia_iot, ioh, ia->ipa_io[0].base);
+
+ /*
+ * SMSC or similar SuperIO chips use 0x55 magic to enter PnP mode
+ * and 0xaa to exit. These chips also enter PnP mode via ITE
+ * `enter MB PnP mode' sequence, so force chip to exit PnP mode
+ * if this is the case.
+ */
+ bus_space_write_1(ia->ia_iot, ioh, IT_IO_ADDR, 0xaa);
/* get chip id */
cr = it_readreg(ia->ia_iot, ioh, IT_CHIPID1) << 8;
cr |= it_readreg(ia->ia_iot, ioh, IT_CHIPID2);
- /* get environment controller base address */
- it_writereg(ia->ia_iot, ioh, IT_LDN, IT_EC_LDN);
- iobase = it_readreg(ia->ia_iot, ioh, IT_EC_MSB) << 8;
- iobase |= it_readreg(ia->ia_iot, ioh, IT_EC_LSB);
-
- /* exit MB PnP mode and unmap */
- it_exit(ia->ia_iot, ioh);
- bus_space_unmap(ia->ia_iot, ioh, 2);
-
- /* check if EC i/o base address match */
- if (ia->ipa_io[0].base != iobase)
- return (0);
-
switch (cr) {
case IT_ID_8705:
case IT_ID_8712:
case IT_ID_8716:
case IT_ID_8718:
case IT_ID_8726:
- ia->ipa_nio = 1;
- ia->ipa_io[0].length = 8;
- ia->ipa_nmem = ia->ipa_nirq = ia->ipa_ndrq = 0;
+ /* get environment controller base address */
+ it_writereg(ia->ia_iot, ioh, IT_LDN, IT_EC_LDN);
+ ec_iobase = it_readreg(ia->ia_iot, ioh, IT_EC_MSB) << 8;
+ ec_iobase |= it_readreg(ia->ia_iot, ioh, IT_EC_LSB);
+
+ /* check if device already attached */
+ LIST_FOREACH(sc, &it_softc_list, sc_list)
+ if (sc->sc_ec_iobase == ec_iobase)
+ break;
+
+ if (sc == NULL) {
+ ia->ipa_nio = 1;
+ ia->ipa_io[0].length = 2;
+ ia->ipa_nmem = ia->ipa_nirq = ia->ipa_ndrq = 0;
+ found++;
+ }
+
break;
- default:
- return (0);
}
- return (1);
+ /* exit MB PnP mode */
+ it_exit(ia->ia_iot, ioh);
+
+ /* unmap i/o space */
+ bus_space_unmap(ia->ia_iot, ioh, 2);
+
+ return (found);
}
void
@@ -181,21 +178,25 @@ it_attach(struct device *parent, struct device *self, void *aux)
u_int8_t cr;
sc->sc_iot = ia->ia_iot;
- if (bus_space_map(sc->sc_iot, IO_IT, 2, 0, &sc->sc_ioh) != 0) {
+ 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;
}
- it_found++;
-
/* enter MB PnP mode */
- it_enter(sc->sc_iot, sc->sc_ioh);
+ 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);
+ sc->sc_ec_iobase = it_readreg(sc->sc_iot, sc->sc_ioh, IT_EC_MSB) << 8;
+ sc->sc_ec_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);
@@ -207,11 +208,20 @@ it_attach(struct device *parent, struct device *self, void *aux)
/* exit MB PnP mode and unmap */
it_exit(sc->sc_iot, sc->sc_ioh);
- printf(": IT%xF rev 0x%02x\n", sc->sc_chipid, sc->sc_chiprev);
+ LIST_INSERT_HEAD(&it_softc_list, sc, sc_list);
+
+ printf(": IT%xF rev 0x%02x", sc->sc_chipid, sc->sc_chiprev);
+
+ if (sc->sc_ec_iobase == 0) {
+ printf(", EC disabled\n");
+ return;
+ }
+
+ printf(", EC port 0x%x\n", sc->sc_ec_iobase);
/* map environment controller i/o space */
sc->sc_ec_iot = ia->ia_iot;
- if (bus_space_map(sc->sc_ec_iot, ia->ipa_io[0].base, 8, 0,
+ if (bus_space_map(sc->sc_ec_iot, sc->sc_ec_iobase, 8, 0,
&sc->sc_ec_ioh) != 0) {
printf("%s: can't map EC i/o space\n", sc->sc_dev.dv_xname);
return;
@@ -262,12 +272,15 @@ it_writereg(bus_space_tag_t iot, bus_space_handle_t ioh, int r, u_int8_t v)
}
void
-it_enter(bus_space_tag_t iot, bus_space_handle_t ioh)
+it_enter(bus_space_tag_t iot, bus_space_handle_t ioh, int iobase)
{
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);
- 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
@@ -384,7 +397,7 @@ it_wdog_cb(void *arg, int period)
struct it_softc *sc = arg;
/* enter MB PnP mode and select WDT device */
- it_enter(sc->sc_iot, sc->sc_ioh);
+ 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 */
diff --git a/sys/dev/isa/itvar.h b/sys/dev/isa/itvar.h
index 98522c49252..b70cc3a409f 100644
--- a/sys/dev/isa/itvar.h
+++ b/sys/dev/isa/itvar.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: itvar.h,v 1.7 2007/12/23 17:44:07 form Exp $ */
+/* $OpenBSD: itvar.h,v 1.8 2008/04/03 20:28:05 form Exp $ */
/*
- * Copyright (c) 2007 Oleg Safiullin <form@pdp-11.org.ru>
+ * Copyright (c) 2007-2008 Oleg Safiullin <form@pdp-11.org.ru>
* Copyright (c) 2006-2007 Juan Romero Pardines <juan@xtrarom.org>
* Copyright (c) 2003 Julien Bordet <zejames@greyhats.org>
* All rights reserved.
@@ -34,13 +34,12 @@
#define IT_EC_NUMSENSORS 15
#define IT_EC_VREF 4096
-#define IO_IT 0x2e
+#define IO_IT1 0x2e
+#define IO_IT2 0x4e
#define IT_IO_ADDR 0x00
#define IT_IO_DATA 0x01
-#define IT_VEND_ITE 0x90
-
#define IT_ID_8705 0x8705
#define IT_ID_8712 0x8712
#define IT_ID_8716 0x8716
@@ -67,7 +66,6 @@
#define IT_EC_FANEXTBASE 0x18
#define IT_EC_VOLTBASE 0x20
#define IT_EC_TEMPBASE 0x29
-#define IT_EC_VENDID 0x58
#define IT_WDT_LDN 0x07
@@ -82,6 +80,8 @@ struct it_softc {
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ int sc_iobase;
+ int sc_ec_iobase;
u_int16_t sc_chipid;
u_int8_t sc_chiprev;
@@ -90,6 +90,8 @@ struct it_softc {
struct ksensor sc_sensors[IT_EC_NUMSENSORS];
struct ksensordev sc_sensordev;
+
+ LIST_ENTRY(it_softc) sc_list;
};
#endif /* _DEV_ISA_ITVAR_H_ */