The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/powermng/lm/lm78_isa.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2005, 2006 Mark Kettenis
    3  * Copyright (c) 2007 Constantine A. Murenin, Google Summer of Code
    4  *
    5  * Permission to use, copy, modify, and distribute this software for any
    6  * purpose with or without fee is hereby granted, provided that the above
    7  * copyright notice and this permission notice appear in all copies.
    8  *
    9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16  *
   17  * $OpenBSD: lm78_isa.c,v 1.2 2007/07/01 21:48:57 cnst Exp $
   18  */
   19 
   20 #include <sys/param.h>
   21 #include <sys/kernel.h>
   22 #include <sys/bus.h>
   23 #include <sys/module.h>
   24 #include <sys/rman.h>
   25 
   26 #include <bus/isa/isavar.h>
   27 
   28 #include <sys/systm.h>
   29 
   30 #include <sys/sensors.h>
   31 
   32 #include "lm78var.h"
   33 
   34 /* ISA registers */
   35 #define LMC_ADDR        0x05
   36 #define LMC_DATA        0x06
   37 
   38 #if defined(LMDEBUG)
   39 #define DPRINTF(x)              do { kprintf x; } while (0)
   40 #else
   41 #define DPRINTF(x)
   42 #endif
   43 
   44 struct lm_isa_softc {
   45         struct lm_softc sc_lmsc;
   46 
   47         struct resource *sc_iores;
   48         int sc_iorid;
   49         bus_space_tag_t sc_iot;
   50         bus_space_handle_t sc_ioh;
   51 };
   52 
   53 static int lm_isa_probe(struct device *);
   54 static int lm_isa_attach(struct device *);
   55 static int lm_isa_detach(struct device *);
   56 u_int8_t lm_isa_readreg(struct lm_softc *, int);
   57 void lm_isa_writereg(struct lm_softc *, int, int);
   58 
   59 static device_method_t lm_isa_methods[] = {
   60         /* Methods from the device interface */
   61         DEVMETHOD(device_probe,         lm_isa_probe),
   62         DEVMETHOD(device_attach,        lm_isa_attach),
   63         DEVMETHOD(device_detach,        lm_isa_detach),
   64 
   65         /* Terminate method list */
   66         DEVMETHOD_END
   67 };
   68 
   69 static driver_t lm_isa_driver = {
   70         "lm",
   71         lm_isa_methods,
   72         sizeof (struct lm_isa_softc)
   73 };
   74 
   75 static devclass_t lm_devclass;
   76 
   77 DRIVER_MODULE(lm, isa, lm_isa_driver, lm_devclass, NULL, NULL);
   78 
   79 int
   80 lm_isa_probe(struct device *dev)
   81 {
   82         struct lm_isa_softc *sc = device_get_softc(dev);
   83         struct resource *iores;
   84         int iorid = 0;
   85         bus_space_tag_t iot;
   86         bus_space_handle_t ioh;
   87         int banksel, vendid, chipid, addr;
   88 
   89         iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &iorid,
   90             0ul, ~0ul, 8, RF_ACTIVE);
   91         if (iores == NULL) {
   92                 DPRINTF(("%s: can't map i/o space\n", __func__));
   93                 return (1);
   94         }
   95         iot = rman_get_bustag(iores);
   96         ioh = rman_get_bushandle(iores);
   97 
   98         /* Probe for Winbond chips. */
   99         bus_space_write_1(iot, ioh, LMC_ADDR, WB_BANKSEL);
  100         banksel = bus_space_read_1(iot, ioh, LMC_DATA);
  101         bus_space_write_1(iot, ioh, LMC_ADDR, WB_VENDID);
  102         vendid = bus_space_read_1(iot, ioh, LMC_DATA);
  103         if (((banksel & 0x80) && vendid == (WB_VENDID_WINBOND >> 8)) ||
  104             (!(banksel & 0x80) && vendid == (WB_VENDID_WINBOND & 0xff)))
  105                 goto found;
  106 
  107         /* Probe for ITE chips (and don't attach if we find one). */
  108         bus_space_write_1(iot, ioh, LMC_ADDR, 0x58 /*ITD_CHIPID*/);
  109         vendid = bus_space_read_1(iot, ioh, LMC_DATA);
  110         if (vendid == 0x90 /*IT_ID_IT87*/)
  111                 goto notfound;
  112 
  113         /*
  114          * Probe for National Semiconductor LM78/79/81.
  115          *
  116          * XXX This assumes the address has not been changed from the
  117          * power up default.  This is probably a reasonable
  118          * assumption, and if it isn't true, we should be able to
  119          * access the chip using the serial bus.
  120          */
  121         bus_space_write_1(iot, ioh, LMC_ADDR, LM_SBUSADDR);
  122         addr = bus_space_read_1(iot, ioh, LMC_DATA);
  123         if ((addr & 0xfc) == 0x2c) {
  124                 bus_space_write_1(iot, ioh, LMC_ADDR, LM_CHIPID);
  125                 chipid = bus_space_read_1(iot, ioh, LMC_DATA);
  126 
  127                 switch (chipid & LM_CHIPID_MASK) {
  128                 case LM_CHIPID_LM78:
  129                 case LM_CHIPID_LM78J:
  130                 case LM_CHIPID_LM79:
  131                 case LM_CHIPID_LM81:
  132                         goto found;
  133                 }
  134         }
  135 
  136  notfound:
  137         bus_release_resource(dev, SYS_RES_IOPORT, iorid, iores);
  138 
  139         return (1);
  140 
  141  found:
  142         /* Bus-independent probe */
  143         sc->sc_lmsc.sc_dev = dev;
  144         sc->sc_iot = iot;
  145         sc->sc_ioh = ioh;
  146         sc->sc_lmsc.lm_writereg = lm_isa_writereg;
  147         sc->sc_lmsc.lm_readreg = lm_isa_readreg;
  148         lm_probe(&sc->sc_lmsc);
  149 
  150         bus_release_resource(dev, SYS_RES_IOPORT, iorid, iores);
  151         sc->sc_iot = 0;
  152         sc->sc_ioh = 0;
  153 
  154         return (0);
  155 }
  156 
  157 int
  158 lm_isa_attach(struct device *dev)
  159 {
  160         struct lm_isa_softc *sc = device_get_softc(dev);
  161 #ifdef notyet
  162         struct lm_softc *lmsc;
  163         int i;
  164         u_int8_t sbusaddr;
  165 #endif
  166 
  167         sc->sc_iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_iorid,
  168             0ul, ~0ul, 8, RF_ACTIVE);
  169         if (sc->sc_iores == NULL) {
  170                 device_printf(dev, "can't map i/o space\n");
  171                 return (1);
  172         }
  173         sc->sc_iot = rman_get_bustag(sc->sc_iores);
  174         sc->sc_ioh = rman_get_bushandle(sc->sc_iores);
  175 
  176         /* Bus-independent attachment */
  177         lm_attach(&sc->sc_lmsc);
  178 
  179 #ifdef notyet
  180         /*
  181          * Most devices supported by this driver can attach to iic(4)
  182          * as well.  However, we prefer to attach them to isa(4) since
  183          * that causes less overhead and is more reliable.  We look
  184          * through all previously attached devices, and if we find an
  185          * identical chip at the same serial bus address, we stop
  186          * updating its sensors and mark them as invalid.
  187          */
  188 
  189         sbusaddr = lm_isa_readreg(&sc->sc_lmsc, LM_SBUSADDR);
  190         if (sbusaddr == 0)
  191                 return (0);
  192 
  193         for (i = 0; i < lm_cd.cd_ndevs; i++) {
  194                 lmsc = lm_cd.cd_devs[i];
  195                 if (lmsc == &sc->sc_lmsc)
  196                         continue;
  197                 if (lmsc && lmsc->sbusaddr == sbusaddr &&
  198                     lmsc->chipid == sc->sc_lmsc.chipid)
  199                         config_detach(&lmsc->sc_dev, 0);
  200         }
  201 #endif
  202         return (0);
  203 }
  204 
  205 int
  206 lm_isa_detach(struct device *dev)
  207 {
  208         struct lm_isa_softc *sc = device_get_softc(dev);
  209         int error;
  210 
  211         /* Bus-independent detachment */
  212         error = lm_detach(&sc->sc_lmsc);
  213         if (error)
  214                 return (error);
  215 
  216         error = bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_iorid,
  217             sc->sc_iores);
  218         if (error)
  219                 return (error);
  220 
  221         return (0);
  222 }
  223 
  224 u_int8_t
  225 lm_isa_readreg(struct lm_softc *lmsc, int reg)
  226 {
  227         struct lm_isa_softc *sc = (struct lm_isa_softc *)lmsc;
  228 
  229         bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMC_ADDR, reg);
  230         return (bus_space_read_1(sc->sc_iot, sc->sc_ioh, LMC_DATA));
  231 }
  232 
  233 void
  234 lm_isa_writereg(struct lm_softc *lmsc, int reg, int val)
  235 {
  236         struct lm_isa_softc *sc = (struct lm_isa_softc *)lmsc;
  237 
  238         bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMC_ADDR, reg);
  239         bus_space_write_1(sc->sc_iot, sc->sc_ioh, LMC_DATA, val);
  240 }

Cache object: 050d053c03217c2a9d2ce181277bc8af


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.