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/isa/fins.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 /*      $OpenBSD: fins.c,v 1.6 2022/04/08 15:02:28 naddy Exp $  */
    2 
    3 /*
    4  * Copyright (c) 2005, 2006 Mark Kettenis
    5  * Copyright (c) 2007, 2008 Geoff Steckel
    6  *
    7  * Permission to use, copy, modify, and distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  */
   19 
   20 #include <sys/param.h>
   21 #include <sys/systm.h>
   22 #include <sys/device.h>
   23 #include <sys/kernel.h>
   24 #include <sys/queue.h>
   25 #include <sys/sensors.h>
   26 #include <machine/bus.h>
   27 
   28 #include <dev/isa/isareg.h>
   29 #include <dev/isa/isavar.h>
   30 
   31 /* Derived from LM78 code.  Only handles chips attached to ISA bus */
   32 
   33 /*
   34  * Fintek F71805 registers and constants
   35  * http://www.fintek.com.tw/files/productfiles/F71805F_V025.pdf
   36  * This chip is a multi-io chip with many functions.
   37  * Each function may be relocated in I/O space by the BIOS.
   38  * The base address (2E or 4E) accesses a configuration space which
   39  * has pointers to the individual functions. The config space must be
   40  * unlocked with a cookie and relocked afterwards. The chip ID is stored
   41  * in config space so it is not normally visible.
   42  *
   43  * We assume that the monitor is enabled. We don't try to start or stop it.
   44  * The voltage dividers specified are from reading the chips on one board.
   45  * There is no way to determine what they are in the general case.
   46  * This section of the chip controls the fans. We don't do anything to them.
   47  */
   48 
   49 #define FINS_UNLOCK     0x87    /* magic constant - write 2x to select chip */
   50 #define FINS_LOCK       0xaa    /* magic constant - write 1x to deselect reg */
   51 
   52 /* ISA registers index to an internal register space on chip */
   53 #define FINS_ADDR       0x00
   54 #define FINS_DATA       0x01
   55 
   56 #define FINS_FUNC_SEL   0x07    /* select which chip function to access */
   57 #define FINS_CHIP       0x20    /* chip ID */
   58 #define FINS_MANUF      0x23    /* manufacturer ID */
   59 #define FINS_BASEADDR   0x60    /* I/O base of chip function */
   60 
   61 #define FINS_71806      0x0341  /* same as F71872 */
   62 #define FINS_71805      0x0406
   63 #define FINS_71882      0x0541  /* same as F71883 */
   64 #define FINS_71862      0x0601  /* same as F71863 */
   65 #define FINTEK_ID       0x1934
   66 
   67 #define FINS_FUNC_SENSORS       0x04
   68 #define FINS_FUNC_WATCHDOG      0x07
   69 
   70 /* sensors device registers */
   71 #define FINS_SENS_TMODE(sc)     ((sc)->fins_chipid <= FINS_71805 ? 0x01 : 0x6b)
   72 #define FINS_SENS_VDIVS         0x0e
   73 
   74 /* watchdog device registers (mapped straight to i/o port offsets) */
   75 #define FINS_WDOG_CR0   0x00
   76 #define FINS_WDOG_CR1   0x05
   77 #define FINS_WDOG_TIMER 0x06
   78 
   79 /* CR0 flags */
   80 #define FINS_WDOG_OUTEN 0x80
   81 
   82 /* CR1 flags */
   83 #define FINS_WDOG_EN    0x20
   84 #define FINS_WDOG_MINS  0x08
   85 
   86 #define FINS_MAX_SENSORS 18
   87 /*
   88  * Fintek chips typically measure voltages using 8mv steps.
   89  * To measure higher voltages the input is attenuated with (external)
   90  * resistors.  Negative voltages are measured using inverting op amps
   91  * and resistors.  So we have to convert the sensor values back to
   92  * real voltages by applying the appropriate resistor factor.
   93  */
   94 #define FRFACT_NONE     8000
   95 #define FRFACT(x, y)    (FRFACT_NONE * ((x) + (y)) / (y))
   96 #define FNRFACT(x, y)   (-FRFACT_NONE * (x) / (y))
   97 
   98 struct fins_softc;
   99 
  100 struct fins_sensor {
  101         char *fs_desc;
  102         void (*fs_refresh)(struct fins_softc *, int);
  103         enum sensor_type fs_type;
  104         int fs_aux;
  105         u_int8_t fs_reg;
  106 };
  107 
  108 struct fins_softc {
  109         struct device sc_dev;
  110 
  111         struct ksensor fins_ksensors[FINS_MAX_SENSORS];
  112         struct ksensordev fins_sensordev;
  113         struct sensor_task *fins_sensortask;
  114         const struct fins_sensor *fins_sensors;
  115 
  116         bus_space_handle_t sc_ioh_sens;
  117         bus_space_handle_t sc_ioh_wdog;
  118         bus_space_tag_t sc_iot;
  119 
  120         u_int16_t fins_chipid;
  121         u_int8_t fins_tempsel;
  122         u_int8_t fins_wdog_cr;
  123 };
  124 
  125 int  fins_match(struct device *, void *, void *);
  126 void fins_attach(struct device *, struct device *, void *);
  127 int  fins_activate(struct device *, int);
  128 
  129 void fins_unlock(bus_space_tag_t, bus_space_handle_t);
  130 void fins_lock(bus_space_tag_t, bus_space_handle_t);
  131 
  132 u_int8_t fins_read(bus_space_tag_t, bus_space_handle_t, int);
  133 u_int16_t fins_read_2(bus_space_tag_t, bus_space_handle_t, int);
  134 void fins_write(bus_space_tag_t, bus_space_handle_t, int, u_int8_t);
  135 
  136 static __inline u_int8_t fins_read_sens(struct fins_softc *, int);
  137 static __inline u_int16_t fins_read_sens_2(struct fins_softc *, int);
  138 
  139 static __inline u_int8_t fins_read_wdog(struct fins_softc *, int);
  140 static __inline void fins_write_wdog(struct fins_softc *, int, u_int8_t);
  141 
  142 void fins_setup_sensors(struct fins_softc *, const struct fins_sensor *);
  143 void fins_refresh(void *);
  144 
  145 void fins_get_rpm(struct fins_softc *, int);
  146 void fins_get_temp(struct fins_softc *, int);
  147 void fins_get_volt(struct fins_softc *, int);
  148 
  149 int fins_wdog_cb(void *, int);
  150 
  151 const struct cfattach fins_ca = {
  152         sizeof(struct fins_softc),
  153         fins_match,
  154         fins_attach,
  155         NULL,
  156         fins_activate
  157 };
  158 
  159 struct cfdriver fins_cd = {
  160         NULL, "fins", DV_DULL
  161 };
  162 
  163 const struct fins_sensor fins_71805_sensors[] = {
  164         { "+3.3V",  fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100),   0x10 },
  165         { "Vtt",    fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE,        0x11 },
  166         { "Vram",   fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100),   0x12 },
  167         { "Vchips", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(47, 100),    0x13 },
  168         { "+5V",    fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47),    0x14 },
  169         { "+12V",   fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 20),    0x15 },
  170         { "+1.5V",  fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE,        0x16 },
  171         { "Vcore",  fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE,        0x17 },
  172         { "Vsb",    fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47),    0x18 },
  173         { "Vsbint", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47),    0x19 },
  174         { "Vbat",   fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47),    0x1a },
  175 
  176         { NULL, fins_get_temp, SENSOR_TEMP, 0x01, 0x1b },
  177         { NULL, fins_get_temp, SENSOR_TEMP, 0x02, 0x1c },
  178         { NULL, fins_get_temp, SENSOR_TEMP, 0x04, 0x1d },
  179 
  180         { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0x20 },
  181         { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0x22 },
  182         { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0x24 },
  183 
  184         { NULL }
  185 };
  186 
  187 const struct fins_sensor fins_71882_sensors[] = {
  188         { "+3.3V",  fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100),   0x20 },
  189         { "Vcore",  fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE,        0x21 },
  190         { "Vram",   fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100),   0x22 },
  191         { "Vchips", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(47, 100),    0x23 },
  192         { "+5V",    fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47),    0x24 },
  193         { "+12V",   fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 20),    0x25 },
  194         { "+1.5V",  fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE,        0x26 },
  195         { "Vsb",    fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100),   0x27 },
  196         { "Vbat",   fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100),   0x28 },
  197 
  198         { NULL, fins_get_temp, SENSOR_TEMP, 0x02, 0x72 },
  199         { NULL, fins_get_temp, SENSOR_TEMP, 0x04, 0x74 },
  200         { NULL, fins_get_temp, SENSOR_TEMP, 0x08, 0x76 },
  201 
  202         { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0xa0 },
  203         { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0xb0 },
  204         { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0xc0 },
  205         { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0xd0 },
  206 
  207         { NULL }
  208 };
  209 
  210 int
  211 fins_match(struct device *parent, void *match, void *aux)
  212 {
  213         struct isa_attach_args *ia = aux;
  214         bus_space_handle_t ioh;
  215         bus_space_tag_t iot;
  216         int ret = 0;
  217         u_int16_t id;
  218 
  219         iot = ia->ia_iot;
  220         if (bus_space_map(iot, ia->ipa_io[0].base, 2, 0, &ioh))
  221                 return (0);
  222 
  223         /* Fintek uses magic cookie locks to distinguish their chips */
  224         fins_unlock(iot, ioh);
  225 
  226         fins_write(iot, ioh, FINS_FUNC_SEL, 0); /* IDs appear only in space 0 */
  227         if (fins_read_2(iot, ioh, FINS_MANUF) != FINTEK_ID)
  228                 goto match_done;
  229         id = fins_read_2(iot, ioh, FINS_CHIP);
  230         switch(id) {
  231         case FINS_71882:
  232         case FINS_71862:
  233                 ia->ipa_nio = 3;
  234                 fins_write(iot, ioh, FINS_FUNC_SEL, FINS_FUNC_WATCHDOG);
  235                 ia->ipa_io[2].base = fins_read_2(iot, ioh, FINS_BASEADDR);
  236                 ia->ipa_io[2].length = 8;
  237                 fins_write(iot, ioh, FINS_FUNC_SEL, FINS_FUNC_SENSORS);
  238                 ia->ipa_io[1].base = fins_read_2(iot, ioh, FINS_BASEADDR);
  239                 ia->ipa_io[1].base += 5;
  240                 break;
  241         case FINS_71806:
  242         case FINS_71805:
  243                 ia->ipa_nio = 2;
  244                 fins_write(iot, ioh, FINS_FUNC_SEL, FINS_FUNC_SENSORS);
  245                 ia->ipa_io[1].base = fins_read_2(iot, ioh, FINS_BASEADDR);
  246                 break;
  247         default:
  248                 goto match_done;
  249         }
  250         ia->ipa_io[0].length = ia->ipa_io[1].length = 2;
  251         ia->ipa_nmem = ia->ipa_nirq = ia->ipa_ndrq = 0;
  252         ia->ia_aux = (void *)(u_long)id;
  253         ret = 1;
  254 match_done:
  255         fins_lock(iot, ioh);
  256         return (ret);
  257 }
  258 
  259 void
  260 fins_attach(struct device *parent, struct device *self, void *aux)
  261 {
  262         struct fins_softc *sc = (struct fins_softc *)self;
  263         struct isa_attach_args *ia = aux;
  264         bus_addr_t iobase;
  265         u_int32_t iosize;
  266         u_int i;
  267 
  268         sc->sc_iot = ia->ia_iot;
  269         sc->fins_chipid = (u_int16_t)(u_long)ia->ia_aux;
  270         iobase = ia->ipa_io[1].base;
  271         iosize = ia->ipa_io[1].length;
  272         if (bus_space_map(sc->sc_iot, iobase, iosize, 0, &sc->sc_ioh_sens)) {
  273                 printf(": can't map sensor i/o space\n");
  274                 return;
  275         }
  276         switch(sc->fins_chipid) {
  277         case FINS_71882:
  278         case FINS_71862:
  279                 fins_setup_sensors(sc, fins_71882_sensors);
  280                 break;
  281         case FINS_71806:
  282         case FINS_71805:
  283                 fins_setup_sensors(sc, fins_71805_sensors);
  284                 break;
  285         }
  286         sc->fins_sensortask = sensor_task_register(sc, fins_refresh, 5);
  287         if (sc->fins_sensortask == NULL) {
  288                 printf(": can't register update task\n");
  289                 return;
  290         }
  291         for (i = 0; sc->fins_sensors[i].fs_refresh != NULL; ++i)
  292                 sensor_attach(&sc->fins_sensordev, &sc->fins_ksensors[i]);
  293         sensordev_install(&sc->fins_sensordev);
  294 
  295         if (sc->fins_chipid <= FINS_71805)
  296                 goto attach_done;
  297         iobase = ia->ipa_io[2].base;
  298         iosize = ia->ipa_io[2].length;
  299         if (bus_space_map(sc->sc_iot, iobase, iosize, 0, &sc->sc_ioh_wdog)) {
  300                 printf(": can't map watchdog i/o space\n");
  301                 return;
  302         }
  303         sc->fins_wdog_cr = fins_read_wdog(sc, FINS_WDOG_CR1);
  304         sc->fins_wdog_cr &= ~(FINS_WDOG_MINS | FINS_WDOG_EN);
  305         fins_write_wdog(sc, FINS_WDOG_CR1, sc->fins_wdog_cr);
  306         wdog_register(fins_wdog_cb, sc);
  307 attach_done:
  308         printf("\n");
  309 }
  310 
  311 int
  312 fins_activate(struct device *self, int act)
  313 {
  314         switch (act) {
  315         case DVACT_POWERDOWN:
  316                 wdog_shutdown(self);
  317                 break;
  318         }
  319 
  320         return (0);
  321 }
  322 
  323 u_int8_t
  324 fins_read(bus_space_tag_t iot, bus_space_handle_t ioh, int reg)
  325 {
  326         bus_space_write_1(iot, ioh, FINS_ADDR, reg);
  327         return (bus_space_read_1(iot, ioh, FINS_DATA));
  328 }
  329 
  330 u_int16_t
  331 fins_read_2(bus_space_tag_t iot, bus_space_handle_t ioh, int reg)
  332 {
  333         u_int16_t val;
  334 
  335         bus_space_write_1(iot, ioh, FINS_ADDR, reg);
  336         val = bus_space_read_1(iot, ioh, FINS_DATA) << 8;
  337         bus_space_write_1(iot, ioh, FINS_ADDR, reg + 1);
  338         return (val | bus_space_read_1(iot, ioh, FINS_DATA));
  339 }
  340 
  341 void
  342 fins_write(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, u_int8_t val)
  343 {
  344         bus_space_write_1(iot, ioh, FINS_ADDR, reg);
  345         bus_space_write_1(iot, ioh, FINS_DATA, val);
  346 }
  347 
  348 static __inline u_int8_t
  349 fins_read_sens(struct fins_softc *sc, int reg)
  350 {
  351         return (fins_read(sc->sc_iot, sc->sc_ioh_sens, reg));
  352 }
  353 
  354 static __inline u_int16_t
  355 fins_read_sens_2(struct fins_softc *sc, int reg)
  356 {
  357         return (fins_read_2(sc->sc_iot, sc->sc_ioh_sens, reg));
  358 }
  359 
  360 static __inline u_int8_t
  361 fins_read_wdog(struct fins_softc *sc, int reg)
  362 {
  363         return (bus_space_read_1(sc->sc_iot, sc->sc_ioh_wdog, reg));
  364 }
  365 
  366 static __inline void
  367 fins_write_wdog(struct fins_softc *sc, int reg, u_int8_t val)
  368 {
  369         bus_space_write_1(sc->sc_iot, sc->sc_ioh_wdog, reg, val);
  370 }
  371 
  372 void
  373 fins_unlock(bus_space_tag_t iot, bus_space_handle_t ioh)
  374 {
  375         bus_space_write_1(iot, ioh, 0, FINS_UNLOCK);
  376         bus_space_write_1(iot, ioh, 0, FINS_UNLOCK);
  377 }
  378 
  379 void
  380 fins_lock(bus_space_tag_t iot, bus_space_handle_t ioh)
  381 {
  382         bus_space_write_1(iot, ioh, 0, FINS_LOCK);
  383         bus_space_unmap(iot, ioh, 2);
  384 }
  385 
  386 void
  387 fins_setup_sensors(struct fins_softc *sc, const struct fins_sensor *sensors)
  388 {
  389         int i;
  390 
  391         for (i = 0; sensors[i].fs_refresh != NULL; ++i) {
  392                 sc->fins_ksensors[i].type = sensors[i].fs_type;
  393                 if (sensors[i].fs_desc != NULL)
  394                         strlcpy(sc->fins_ksensors[i].desc, sensors[i].fs_desc,
  395                                 sizeof(sc->fins_ksensors[i].desc));
  396         }
  397         strlcpy(sc->fins_sensordev.xname, sc->sc_dev.dv_xname,
  398                 sizeof(sc->fins_sensordev.xname));
  399         sc->fins_sensors = sensors;
  400         sc->fins_tempsel = fins_read_sens(sc, FINS_SENS_TMODE(sc));
  401 }
  402 
  403 #if 0
  404 void
  405 fins_get_dividers(struct fins_softc *sc)
  406 {
  407         int i, p, m;
  408         u_int16_t r = fins_read_sens_2(sc, FINS_SENS_VDIVS);
  409 
  410         for (i = 0; i < 6; ++i) {
  411                 p = (i < 4) ? i : i + 2;
  412                 m = (r & (0x03 << p)) >> p;
  413                 if (m == 3)
  414                         m = 4;
  415                 fins_71882_sensors[i + 1].fs_aux = FRFACT_NONE << m;
  416         }
  417 }
  418 #endif
  419 
  420 void
  421 fins_refresh(void *arg)
  422 {
  423         struct fins_softc *sc = arg;
  424         int i;
  425 
  426         for (i = 0; sc->fins_sensors[i].fs_refresh != NULL; ++i)
  427                 sc->fins_sensors[i].fs_refresh(sc, i);
  428 }
  429 
  430 void
  431 fins_get_volt(struct fins_softc *sc, int n)
  432 {
  433         struct ksensor *sensor = &sc->fins_ksensors[n];
  434         const struct fins_sensor *fs = &sc->fins_sensors[n];
  435         int data;
  436 
  437         data = fins_read_sens(sc, fs->fs_reg);
  438         if (data == 0xff || data == 0) {
  439                 sensor->flags |= SENSOR_FINVALID;
  440                 sensor->value = 0;
  441         } else {
  442                 sensor->flags &= ~SENSOR_FINVALID;
  443                 sensor->value = data * fs->fs_aux;
  444         }
  445 }
  446 
  447 /* The BIOS seems to add a fudge factor to the CPU temp of +5C */
  448 void
  449 fins_get_temp(struct fins_softc *sc, int n)
  450 {
  451         struct ksensor *sensor = &sc->fins_ksensors[n];
  452         const struct fins_sensor *fs = &sc->fins_sensors[n];
  453         u_int data;
  454         u_int max;
  455 
  456         /*
  457          * The data sheet says that the range of the temperature
  458          * sensor is between 0 and 127 or 140 degrees C depending on
  459          * what kind of sensor is used.
  460          * A disconnected sensor seems to read over 110 or so.
  461          */
  462         data = fins_read_sens(sc, fs->fs_reg);
  463         max = (sc->fins_tempsel & fs->fs_aux) ? 111 : 128;
  464         if (data == 0 || data >= max) { /* disconnected? */
  465                 sensor->flags |= SENSOR_FINVALID;
  466                 sensor->value = 0;
  467         } else {
  468                 sensor->flags &= ~SENSOR_FINVALID;
  469                 sensor->value = data * 1000000 + 273150000;
  470         }
  471 }
  472 
  473 /* The chip holds a fudge factor for BJT sensors */
  474 /* this is currently unused but might be reenabled */
  475 #if 0
  476 void
  477 fins_refresh_offset(struct fins_softc *sc, int n)
  478 {
  479         struct ksensor *sensor = &sc->fins_ksensors[n];
  480         const struct fins_sensor *fs = &sc->fins_sensors[n];
  481         u_int data;
  482 
  483         sensor->flags &= ~SENSOR_FINVALID;
  484         data = fins_read_sens(sc, fs->fs_reg);
  485         data |= ~0 * (data & 0x40);     /* sign extend 7-bit value */
  486         sensor->value = data * 1000000 + 273150000;
  487 }
  488 #endif
  489 
  490 /* fan speed appears to be a 12-bit number */
  491 void
  492 fins_get_rpm(struct fins_softc *sc, int n)
  493 {
  494         struct ksensor *sensor = &sc->fins_ksensors[n];
  495         const struct fins_sensor *fs = &sc->fins_sensors[n];
  496         int data;
  497 
  498         data = fins_read_sens_2(sc, fs->fs_reg);
  499         if (data >= 0xfff) {
  500                 sensor->value = 0;
  501                 sensor->flags |= SENSOR_FINVALID;
  502         } else {
  503                 sensor->value = 1500000 / data;
  504                 sensor->flags &= ~SENSOR_FINVALID;
  505         }
  506 }
  507 
  508 int
  509 fins_wdog_cb(void *arg, int period)
  510 {
  511         struct fins_softc *sc = arg;
  512         u_int8_t cr0, cr1, t;
  513 
  514         cr0 = fins_read_wdog(sc, FINS_WDOG_CR0) & ~FINS_WDOG_OUTEN;
  515         fins_write_wdog(sc, FINS_WDOG_CR0, cr0);
  516 
  517         cr1 = sc->fins_wdog_cr;
  518         if (period > 0xff) {
  519                 cr1 |= FINS_WDOG_MINS;
  520                 t = (period + 59) / 60;
  521                 period = (int)t * 60;
  522         } else if (period > 0)
  523                 t = period;
  524         else
  525                 return (0);
  526 
  527         fins_write_wdog(sc, FINS_WDOG_TIMER, t);
  528         fins_write_wdog(sc, FINS_WDOG_CR0, cr0 | FINS_WDOG_OUTEN);
  529         fins_write_wdog(sc, FINS_WDOG_CR1, cr1 | FINS_WDOG_EN);
  530         return (period);
  531 }

Cache object: f85753254c2fa94e08df379cd22ee88e


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