root/dev/isa/lm78_isa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lm_isa_match
  2. lm_isa_attach
  3. lm_isa_readreg
  4. lm_isa_writereg

    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 }

/* [<][>][^][v][top][bottom][index][help] */