[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     ! 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