diff options
| author | xtraeme <xtraeme@NetBSD.org> | 2008-04-03 13:36:33 +0000 |
|---|---|---|
| committer | xtraeme <xtraeme@NetBSD.org> | 2008-04-03 13:36:33 +0000 |
| commit | 5cc216e9bb332826416edc5d963e9750c4f3bb8a (patch) | |
| tree | 27644cff0ce82a4476ee2a1ecfeadba8d88003ee /sys/dev | |
| parent | 11a00dfcb81eb48da795b2eb6d8488739334b72d (diff) | |
Add support for the SCH5307-NS and SCH5317 Super I/Os. They are
compatible with LPC47B397, only the device ID is changed.
Simplify and improve the code, and split device_t/softc.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/isa/smsc.c | 216 | ||||
| -rw-r--r-- | sys/dev/isa/smscvar.h | 12 |
2 files changed, 102 insertions, 126 deletions
diff --git a/sys/dev/isa/smsc.c b/sys/dev/isa/smsc.c index 3f93eadb309..ba85c89eb0a 100644 --- a/sys/dev/isa/smsc.c +++ b/sys/dev/isa/smsc.c @@ -1,4 +1,4 @@ -/* $NetBSD: smsc.c,v 1.6 2007/11/17 08:30:35 kefren Exp $ */ +/* $NetBSD: smsc.c,v 1.7 2008/04/03 13:36:33 xtraeme Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -47,50 +47,42 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: smsc.c,v 1.6 2007/11/17 08:30:35 kefren Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smsc.c,v 1.7 2008/04/03 13:36:33 xtraeme Exp $"); #include <sys/param.h> #include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/proc.h> #include <sys/device.h> -#include <sys/conf.h> -#include <sys/time.h> - #include <sys/bus.h> #include <dev/isa/isareg.h> #include <dev/isa/isavar.h> #include <dev/sysmon/sysmonvar.h> - #include <dev/isa/smscvar.h> -#include <sys/intr.h> - #if defined(LMDEBUG) #define DPRINTF(x) do { printf x; } while (0) #else #define DPRINTF(x) #endif -static int smsc_match(struct device *, struct cfdata *, void *); -static void smsc_attach(struct device *, struct device *, void *); -static int smsc_detach(struct device *, int); -static uint8_t smsc_readreg(struct smsc_softc *, int); -/*static void smsc_writereg(struct smsc_softc *, int, int);*/ +static int smsc_match(device_t, cfdata_t, void *); +static void smsc_attach(device_t, device_t, void *); +static int smsc_detach(device_t, int); + +static uint8_t smsc_readreg(bus_space_tag_t, bus_space_handle_t, int); +static void smsc_writereg(bus_space_tag_t, bus_space_handle_t, int, int); static void smsc_refresh(struct sysmon_envsys *, envsys_data_t *); -CFATTACH_DECL(smsc, sizeof(struct smsc_softc), +CFATTACH_DECL_NEW(smsc, sizeof(struct smsc_softc), smsc_match, smsc_attach, smsc_detach, NULL); /* * Probe for the SMSC Super I/O chip */ static int -smsc_match(struct device *parent, struct cfdata *match, void *aux) +smsc_match(device_t parent, cfdata_t match, void *aux) { bus_space_handle_t ioh; struct isa_attach_args *ia = aux; @@ -114,18 +106,21 @@ smsc_match(struct device *parent, struct cfdata *match, void *aux) bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_CONFIG_START); /* Then select the device id register */ - bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_DEVICE_ID); - - /* Finally, read the id from the chip */ - cr = bus_space_read_1(ia->ia_iot, ioh, SMSC_DATA); + cr = smsc_readreg(ia->ia_iot, ioh, SMSC_DEVICE_ID); /* Exit config mode, apparently this is important to do */ bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_CONFIG_END); - if (cr == SMSC_ID) + switch (cr) { + case SMSC_ID_47B397: + case SMSC_ID_SCH5307NS: + case SMSC_ID_SCH5317: rv = 1; - else + break; + default: rv = 0; + break; + } DPRINTF(("smsc: rv = %d, cr = %x\n", rv, cr)); @@ -145,53 +140,56 @@ smsc_match(struct device *parent, struct cfdata *match, void *aux) /* * Get the base address for the monitoring registers and set up the - * env sysmon framework. + * sysmon_envsys(9) framework. */ static void -smsc_attach(struct device *parent, struct device *self, void *aux) +smsc_attach(device_t parent, device_t self, void *aux) { struct smsc_softc *sc = device_private(self); struct isa_attach_args *ia = aux; bus_space_handle_t ioh; - uint8_t rev, msb, lsb; + uint8_t rev, msb, lsb, chipid; unsigned address; - char label[8]; int i; sc->sc_iot = ia->ia_iot; - /* To attach we need to find the actual i/o register space, - map the base registers in first. */ + aprint_naive("\n"); + + /* + * To attach we need to find the actual Hardware Monitor + * I/O address space. + */ if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh)) { aprint_error(": can't map base i/o space\n"); return; } - /* Enter config mode. */ + /* Enter config mode */ bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_CONFIG_START); - /* While we have the base registers mapped, grab the chip revision */ - bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_DEVICE_REVISION); - rev = bus_space_read_1(ia->ia_iot, ioh, SMSC_DATA); + /* + * While we have the base registers mapped, grab the chip + * revision and device ID. + */ + rev = smsc_readreg(ia->ia_iot, ioh, SMSC_DEVICE_REVISION); + chipid = smsc_readreg(ia->ia_iot, ioh, SMSC_DEVICE_ID); - /* Select the correct logical device */ - bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_LOGICAL_DEV_SEL); - bus_space_write_1(ia->ia_iot, ioh, SMSC_DATA, SMSC_LOGICAL_DEVICE); + /* Select the Hardware Monitor LDN */ + smsc_writereg(ia->ia_iot, ioh, SMSC_LOGICAL_DEV_SEL, + SMSC_LOGICAL_DEVICE); /* Read the base address for the registers. */ - bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_IO_BASE_MSB); - msb = bus_space_read_1(ia->ia_iot, ioh, SMSC_DATA); - bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_IO_BASE_LSB); - lsb = bus_space_read_1(ia->ia_iot, ioh, SMSC_DATA); + msb = smsc_readreg(ia->ia_iot, ioh, SMSC_IO_BASE_MSB); + lsb = smsc_readreg(ia->ia_iot, ioh, SMSC_IO_BASE_LSB); address = (msb << 8) | lsb; /* Exit config mode */ bus_space_write_1(ia->ia_iot, ioh, SMSC_ADDR, SMSC_CONFIG_END); - bus_space_unmap(ia->ia_iot, ioh, 2); - /* Map the i/o space for the registers. */ + /* Map the Hardware Monitor I/O space. */ if (bus_space_map(ia->ia_iot, address, 2, 0, &sc->sc_ioh)) { aprint_error(": can't map register i/o space\n"); return; @@ -199,81 +197,62 @@ smsc_attach(struct device *parent, struct device *self, void *aux) sc->sc_sme = sysmon_envsys_create(); - for (i = 0; i < 4; i++) { - sprintf(label, "Temp-%d", i); - strlcpy(sc->sc_sensor[i].desc, label, - sizeof(sc->sc_sensor[i].desc)); - sc->sc_sensor[i].units = ENVSYS_STEMP; - switch (i) { - case 0: - sc->sc_regs[i] = SMSC_TEMP1; - break; - - case 1: - sc->sc_regs[i] = SMSC_TEMP2; - break; - - case 2: - sc->sc_regs[i] = SMSC_TEMP3; - break; - - case 3: - sc->sc_regs[i] = SMSC_TEMP4; - break; - } +#define INITSENSOR(index, string, reg, type) \ + do { \ + strlcpy(sc->sc_sensor[index].desc, string, \ + sizeof(sc->sc_sensor[index].desc)); \ + sc->sc_sensor[index].units = type; \ + sc->sc_regs[index] = reg; \ + sc->sc_sensor[index].state = ENVSYS_SVALID; \ + } while (/* CONSTCOND */ 0) + + /* Temperature sensors */ + INITSENSOR(0, "Temp0", SMSC_TEMP1, ENVSYS_STEMP); + INITSENSOR(1, "Temp1", SMSC_TEMP2, ENVSYS_STEMP); + INITSENSOR(2, "Temp2", SMSC_TEMP3, ENVSYS_STEMP); + INITSENSOR(3, "Temp3", SMSC_TEMP4, ENVSYS_STEMP); + + /* Fan sensors */ + INITSENSOR(4, "Fan0", SMSC_FAN1_LSB, ENVSYS_SFANRPM); + INITSENSOR(5, "Fan1", SMSC_FAN2_LSB, ENVSYS_SFANRPM); + INITSENSOR(6, "Fan2", SMSC_FAN3_LSB, ENVSYS_SFANRPM); + INITSENSOR(7, "Fan3", SMSC_FAN4_LSB, ENVSYS_SFANRPM); + + for (i = 0; i < SMSC_MAX_SENSORS; i++) { if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i])) { sysmon_envsys_destroy(sc->sc_sme); + bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2); return; } - } - for (i = 4; i < SMSC_MAX_SENSORS; i++) { - sprintf(label, "Fan-%d", i - 3); - strlcpy(sc->sc_sensor[i].desc, label, - sizeof(sc->sc_sensor[i].desc)); - sc->sc_sensor[i].units = ENVSYS_SFANRPM; - switch (i) { - case 4: - sc->sc_regs[i] = SMSC_FAN1_LSB; - break; - - case 5: - sc->sc_regs[i] = SMSC_FAN2_LSB; - break; - - case 6: - sc->sc_regs[i] = SMSC_FAN3_LSB; - break; - - case 7: - sc->sc_regs[i] = SMSC_FAN4_LSB; - break; - - default: - aprint_error(": more fans than expected"); - break; - } - if (sysmon_envsys_sensor_attach(sc->sc_sme, - &sc->sc_sensor[i])) { - sysmon_envsys_destroy(sc->sc_sme); - return; - } - } - - sc->sc_sme->sme_name = sc->sc_dev.dv_xname; + sc->sc_sme->sme_name = device_xname(self); sc->sc_sme->sme_cookie = sc; sc->sc_sme->sme_refresh = smsc_refresh; if ((i = sysmon_envsys_register(sc->sc_sme)) != 0) { - aprint_error("%s: unable to register with sysmon (%d)\n", - sc->sc_dev.dv_xname, i); + aprint_error(": unable to register with sysmon (%d)\n", i); sysmon_envsys_destroy(sc->sc_sme); + bus_space_unmap(sc->sc_iot, sc->sc_ioh, 2); + return; + } + + switch (chipid) { + case SMSC_ID_47B397: + aprint_normal(": SMSC LPC47B397 Super I/O"); + break; + case SMSC_ID_SCH5307NS: + aprint_normal(": SMSC SCH5307-NS Super I/O"); + break; + case SMSC_ID_SCH5317: + aprint_normal(": SMSC SCH5317 Super I/O"); + break; } - aprint_normal(": monitor registers at 0x%04x (rev. %u)\n", - address, rev); + aprint_normal(" (rev %u)\n", rev); + aprint_normal_dev(self, "Hardware Monitor registers at 0x%04x\n", + address); } static int @@ -290,24 +269,21 @@ smsc_detach(struct device *self, int flags) * Read the value of the given register */ static uint8_t -smsc_readreg(struct smsc_softc *sc, int reg) +smsc_readreg(bus_space_tag_t iot, bus_space_handle_t ioh, int reg) { - bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMSC_ADDR, reg); - return bus_space_read_1(sc->sc_iot, sc->sc_ioh, SMSC_DATA); + bus_space_write_1(iot, ioh, SMSC_ADDR, reg); + return bus_space_read_1(iot, ioh, SMSC_DATA); } - /* - * Write the given value to the given register - here just for completeness - * it is unused in the current code. - + * Write the given value to the given register. + */ static void -smsc_writereg (struct smsc_softc *sc, int reg, int val) +smsc_writereg(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, int val) { - bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMSC_ADDR, reg); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, SMSC_DATA, val); + bus_space_write_1(iot, ioh, SMSC_ADDR, reg); + bus_space_write_1(iot, ioh, SMSC_DATA, val); } -*/ /* convert temperature read from the chip to micro kelvin */ static inline int @@ -358,18 +334,16 @@ smsc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) switch (edata->units) { case ENVSYS_STEMP: - edata->value_cur = smsc_temp2muk(smsc_readreg(sc, reg)); + edata->value_cur = + smsc_temp2muk(smsc_readreg(sc->sc_iot, sc->sc_ioh, reg)); break; case ENVSYS_SFANRPM: /* reading lsb first locks msb... */ - lsb = smsc_readreg(sc, reg); - msb = smsc_readreg(sc, reg + 1); /* XXX note explicit - assumption that msb is - the next register along */ + lsb = smsc_readreg(sc->sc_iot, sc->sc_ioh, reg); + msb = smsc_readreg(sc->sc_iot, sc->sc_ioh, reg + 1); rpm = (msb << 8) | lsb; edata->value_cur = smsc_reg2rpm(rpm); break; } - edata->state = ENVSYS_SVALID; } diff --git a/sys/dev/isa/smscvar.h b/sys/dev/isa/smscvar.h index ff4c73fd54f..cfbdc96a896 100644 --- a/sys/dev/isa/smscvar.h +++ b/sys/dev/isa/smscvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: smscvar.h,v 1.2 2007/11/16 08:00:15 xtraeme Exp $ */ +/* $NetBSD: smscvar.h,v 1.3 2008/04/03 13:36:33 xtraeme Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -49,8 +49,8 @@ /* Chip control registers */ #define SMSC_LOGICAL_DEV_SEL 0x07 /* Selector for logical device */ -#define SMSC_DEVICE_ID 0X20 /* Device ID register */ -#define SMSC_DEVICE_REVISION 0X21 /* Device revision */ +#define SMSC_DEVICE_ID 0x20 /* Device ID register */ +#define SMSC_DEVICE_REVISION 0x21 /* Device revision */ #define SMSC_IO_BASE_MSB 0x60 #define SMSC_IO_BASE_LSB 0x61 @@ -60,7 +60,9 @@ #define SMSC_CONFIG_START 0x55 /* Start configuration mode */ #define SMSC_CONFIG_END 0xAA /* End configuration mode */ -#define SMSC_ID 0x6F /* Chip Reset/ID */ +#define SMSC_ID_47B397 0x6F /* Chip ID */ +#define SMSC_ID_SCH5307NS 0x81 +#define SMSC_ID_SCH5317 0x85 /* Data registers */ #define SMSC_TEMP1 0x25 @@ -78,7 +80,7 @@ #define SMSC_FAN4_LSB 0x2E #define SMSC_FAN4_MSB 0x2F -#define SMSC_MAX_SENSORS 0x08 /* 4 temp sensors, 4 fan sensors */ +#define SMSC_MAX_SENSORS 8 /* 4 temp sensors, 4 fan sensors */ struct smsc_softc { struct device sc_dev; |
