[BACK]Return to lm78_isa.c CVS log [TXT][DIR] Up to [local] / sys / dev / isa

Annotation of sys/dev/isa/lm78_isa.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: lm78_isa.c,v 1.2 2007/07/01 21:48:57 cnst Exp $       */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005, 2006 Mark Kettenis
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: #include <sys/param.h>
                     20: #include <sys/systm.h>
                     21: #include <sys/device.h>
                     22: #include <sys/sensors.h>
                     23: #include <machine/bus.h>
                     24:
                     25: #include <dev/isa/isareg.h>
                     26: #include <dev/isa/isavar.h>
                     27:
                     28: #include <dev/ic/lm78var.h>
                     29: #include <dev/isa/itvar.h>
                     30:
                     31: /* ISA registers */
                     32: #define LMC_ADDR       0x05
                     33: #define LMC_DATA       0x06
                     34:
                     35: extern struct cfdriver lm_cd;
                     36:
                     37: #if defined(LMDEBUG)
                     38: #define DPRINTF(x)             do { printf x; } while (0)
                     39: #else
                     40: #define DPRINTF(x)
                     41: #endif
                     42:
                     43: struct lm_isa_softc {
                     44:        struct lm_softc sc_lmsc;
                     45:
                     46:        bus_space_tag_t sc_iot;
                     47:        bus_space_handle_t sc_ioh;
                     48: };
                     49:
                     50: int  lm_isa_match(struct device *, void *, void *);
                     51: void lm_isa_attach(struct device *, struct device *, void *);
                     52: u_int8_t lm_isa_readreg(struct lm_softc *, int);
                     53: void lm_isa_writereg(struct lm_softc *, int, int);
                     54:
                     55: struct cfattach lm_isa_ca = {
                     56:        sizeof(struct lm_isa_softc),
                     57:        lm_isa_match,
                     58:        lm_isa_attach
                     59: };
                     60:
                     61: int
                     62: lm_isa_match(struct device *parent, void *match, void *aux)
                     63: {
                     64:        bus_space_tag_t iot;
                     65:        bus_addr_t iobase;
                     66:        bus_space_handle_t ioh;
                     67:        struct isa_attach_args *ia = aux;
                     68:        int banksel, vendid, chipid, addr;
                     69:
                     70:        iot = ia->ia_iot;
                     71:        iobase = ia->ipa_io[0].base;
                     72:
                     73:        if (bus_space_map(iot, iobase, 8, 0, &ioh)) {
                     74:                DPRINTF(("%s: can't map i/o space\n", __func__));
                     75:                return (0);
                     76:        }
                     77:
                     78:        /* Probe for Winbond chips. */
                     79:        bus_space_write_1(iot, ioh, LMC_ADDR, WB_BANKSEL);
                     80:        banksel = bus_space_read_1(iot, ioh, LMC_DATA);
                     81:        bus_space_write_1(iot, ioh, LMC_ADDR, WB_VENDID);
                     82:        vendid = bus_space_read_1(iot, ioh, LMC_DATA);
                     83:        if (((banksel & 0x80) && vendid == (WB_VENDID_WINBOND >> 8)) ||
                     84:            (!(banksel & 0x80) && vendid == (WB_VENDID_WINBOND & 0xff)))
                     85:                goto found;
                     86:
                     87:        /* Probe for ITE chips (and don't attach if we find one). */
                     88:        bus_space_write_1(iot, ioh, LMC_ADDR, ITD_CHIPID);
                     89:        vendid = bus_space_read_1(iot, ioh, LMC_DATA);
                     90:        if (vendid == IT_ID_IT87)
                     91:                goto notfound;
                     92:
                     93:        /*
                     94:         * Probe for National Semiconductor LM78/79/81.
                     95:         *
                     96:         * XXX This assumes the address has not been changed from the
                     97:         * power up default.  This is probably a reasonable
                     98:         * assumption, and if it isn't true, we should be able to
                     99:         * access the chip using the serial bus.
                    100:         */
                    101:        bus_space_write_1(iot, ioh, LMC_ADDR, LM_SBUSADDR);
                    102:        addr = bus_space_read_1(iot, ioh, LMC_DATA);
                    103:        if ((addr & 0xfc) == 0x2c) {
                    104:                bus_space_write_1(iot, ioh, LMC_ADDR, LM_CHIPID);
                    105:                chipid = bus_space_read_1(iot, ioh, LMC_DATA);
                    106:
                    107:                switch (chipid & LM_CHIPID_MASK) {
                    108:                case LM_CHIPID_LM78:
                    109:                case LM_CHIPID_LM78J:
                    110:                case LM_CHIPID_LM79:
                    111:                case LM_CHIPID_LM81:
                    112:                        goto found;
                    113:                }
                    114:        }
                    115:
                    116:  notfound:
                    117:        bus_space_unmap(iot, ioh, 8);
                    118:
                    119:        return (0);
                    120:
                    121:  found:
                    122:        bus_space_unmap(iot, ioh, 8);
                    123:
                    124:        ia->ipa_nio = 1;
                    125:        ia->ipa_io[0].length = 8;
                    126:
                    127:        ia->ipa_nmem = 0;
                    128:        ia->ipa_nirq = 0;
                    129:        ia->ipa_ndrq = 0;
                    130:
                    131:        return (1);
                    132: }
                    133:
                    134: void
                    135: lm_isa_attach(struct device *parent, struct device *self, void *aux)
                    136: {
                    137:        struct lm_isa_softc *sc = (struct lm_isa_softc *)self;
                    138:        struct isa_attach_args *ia = aux;
                    139:        struct lm_softc *lmsc;
                    140:        bus_addr_t iobase;
                    141:        int i;
                    142:        u_int8_t sbusaddr;
                    143:
                    144:        sc->sc_iot = ia->ia_iot;
                    145:        iobase = ia->ipa_io[0].base;
                    146:
                    147:        if (bus_space_map(sc->sc_iot, iobase, 8, 0, &sc->sc_ioh)) {
                    148:                printf(": can't map i/o space\n");
                    149:                return;
                    150:        }
                    151:
                    152:        /* Bus-independant attachment */
                    153:        sc->sc_lmsc.lm_writereg = lm_isa_writereg;
                    154:        sc->sc_lmsc.lm_readreg = lm_isa_readreg;
                    155:        lm_attach(&sc->sc_lmsc);
                    156:
                    157:        /*
                    158:         * Most devices supported by this driver can attach to iic(4)
                    159:         * as well.  However, we prefer to attach them to isa(4) since
                    160:         * that causes less overhead and is more reliable.  We look
                    161:         * through all previously attached devices, and if we find an
                    162:         * identical chip at the same serial bus address, we stop
                    163:         * updating its sensors and mark them as invalid.
                    164:         */
                    165:
                    166:        sbusaddr = lm_isa_readreg(&sc->sc_lmsc, LM_SBUSADDR);
                    167:        if (sbusaddr == 0)
                    168:                return;
                    169:
                    170:        for (i = 0; i < lm_cd.cd_ndevs; i++) {
                    171:                lmsc = lm_cd.cd_devs[i];
                    172:                if (lmsc == &sc->sc_lmsc)
                    173:                        continue;
                    174:                if (lmsc && lmsc->sbusaddr == sbusaddr &&
                    175:                    lmsc->chipid == sc->sc_lmsc.chipid)
                    176:                        config_detach(&lmsc->sc_dev, 0);
                    177:        }
                    178: }
                    179:
                    180: u_int8_t
                    181: lm_isa_readreg(struct lm_softc *lmsc, int reg)
                    182: {
                    183:        struct lm_isa_softc *sc = (struct lm_isa_softc *)lmsc;
                    184:
                    185:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMC_ADDR, reg);
                    186:        return (bus_space_read_1(sc->sc_iot, sc->sc_ioh, LMC_DATA));
                    187: }
                    188:
                    189: void
                    190: lm_isa_writereg(struct lm_softc *lmsc, int reg, int val)
                    191: {
                    192:        struct lm_isa_softc *sc = (struct lm_isa_softc *)lmsc;
                    193:
                    194:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMC_ADDR, reg);
                    195:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMC_DATA, val);
                    196: }

CVSweb