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/ic/nslm7x.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 /*      $NetBSD: nslm7x.c,v 1.27.10.2 2007/06/18 09:38:09 liamjfoy Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Bill Squier.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.27.10.2 2007/06/18 09:38:09 liamjfoy Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/kernel.h>
   45 #include <sys/proc.h>
   46 #include <sys/device.h>
   47 #include <sys/conf.h>
   48 #include <sys/time.h>
   49 
   50 #include <machine/bus.h>
   51 
   52 #include <dev/isa/isareg.h>
   53 #include <dev/isa/isavar.h>
   54 
   55 #include <dev/sysmon/sysmonvar.h>
   56 
   57 #include <dev/ic/nslm7xvar.h>
   58 
   59 #include <machine/intr.h>
   60 #include <machine/bus.h>
   61 
   62 #if defined(LMDEBUG)
   63 #define DPRINTF(x)      do { printf x; } while (0)
   64 #else
   65 #define DPRINTF(x)
   66 #endif
   67 
   68 /*
   69  * LM78-compatible chips can typically measure voltages up to 4.096 V.
   70  * To measure higher voltages the input is attenuated with (external)
   71  * resistors.  Negative voltages are measured using inverting op amps
   72  * and resistors.  So we have to convert the sensor values back to
   73  * real voltages by applying the appropriate resistor factor.
   74  */
   75 #define RFACT_NONE      10000
   76 #define RFACT(x, y)     (RFACT_NONE * ((x) + (y)) / (y))
   77 #define NRFACT(x, y)    (-RFACT_NONE * (x) / (y))
   78 
   79 const struct envsys_range lm_ranges[] = {       /* sc->sensors sub-intervals */
   80                                                 /* for each unit type */
   81         { 7, 7,    ENVSYS_STEMP   },
   82         { 8, 10,   ENVSYS_SFANRPM },
   83         { 1, 0,    ENVSYS_SVOLTS_AC },  /* None */
   84         { 0, 6,    ENVSYS_SVOLTS_DC },
   85         { 1, 0,    ENVSYS_SOHMS },      /* None */
   86         { 1, 0,    ENVSYS_SWATTS },     /* None */
   87         { 1, 0,    ENVSYS_SAMPS }       /* None */
   88 };
   89 
   90 static int lm_match(struct lm_softc *);
   91 static int wb_match(struct lm_softc *);
   92 static int def_match(struct lm_softc *);
   93 
   94 static void lm_generic_banksel(struct lm_softc *, int);
   95 static void lm_setup_sensors(struct lm_softc *, struct lm_sensor *);
   96 
   97 static void lm_refresh_sensor_data(struct lm_softc *);
   98 static void lm_refresh_volt(struct lm_softc *, int);
   99 static void lm_refresh_temp(struct lm_softc *, int);
  100 static void lm_refresh_fanrpm(struct lm_softc *, int);
  101 
  102 static void wb_refresh_sensor_data(struct lm_softc *);
  103 static void wb_w83637hf_refresh_vcore(struct lm_softc *, int);
  104 static void wb_refresh_nvolt(struct lm_softc *, int);
  105 static void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int);
  106 static void wb_refresh_temp(struct lm_softc *, int);
  107 static void wb_refresh_fanrpm(struct lm_softc *, int);
  108 static void wb_w83792d_refresh_fanrpm(struct lm_softc *, int);
  109 
  110 static void as_refresh_temp(struct lm_softc *, int);
  111 
  112 static int lm_gtredata(struct sysmon_envsys *, struct envsys_tre_data *);
  113 static int generic_streinfo_fan(struct lm_softc *, struct envsys_basic_info *,
  114            int, struct envsys_basic_info *);
  115 static int lm_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);
  116 static int wb781_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);
  117 static int wb782_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);
  118 
  119 struct lm_chip {
  120         int (*chip_match)(struct lm_softc *);
  121 };
  122 
  123 static struct lm_chip lm_chips[] = {
  124         { wb_match },
  125         { lm_match },
  126         { def_match } /* Must be last */
  127 };
  128 
  129 /* LM78/78J/79/81 */
  130 static struct lm_sensor lm78_sensors[] = {
  131         /* Voltage */
  132         {
  133                 .desc = "VCore A",
  134                 .type = ENVSYS_SVOLTS_DC,
  135                 .bank = 0,
  136                 .reg = 0x20,
  137                 .refresh = lm_refresh_volt,
  138                 .rfact = RFACT_NONE
  139         },
  140         {
  141                 .desc = "VCore B",
  142                 .type = ENVSYS_SVOLTS_DC,
  143                 .bank = 0,
  144                 .reg = 0x21,
  145                 .refresh = lm_refresh_volt,
  146                 .rfact = RFACT_NONE
  147         },
  148         {
  149                 .desc = "+3.3V",
  150                 .type = ENVSYS_SVOLTS_DC,
  151                 .bank = 0,
  152                 .reg = 0x22,
  153                 .refresh = lm_refresh_volt,
  154                 .rfact = RFACT_NONE
  155         },
  156         {
  157                 .desc = "+5V",
  158                 .type = ENVSYS_SVOLTS_DC,
  159                 .bank = 0,
  160                 .reg = 0x23,
  161                 .refresh = lm_refresh_volt,
  162                 .rfact = RFACT(68, 100)
  163         },
  164         {
  165                 .desc = "+12V",
  166                 .type = ENVSYS_SVOLTS_DC,
  167                 .bank = 0,
  168                 .reg = 0x24,
  169                 .refresh = lm_refresh_volt,
  170                 .rfact = RFACT(30, 10)
  171         },
  172         {
  173                 .desc = "-12V",
  174                 .type = ENVSYS_SVOLTS_DC,
  175                 .bank = 0,
  176                 .reg = 0x25,
  177                 .refresh = lm_refresh_volt,
  178                 .rfact = NRFACT(240, 60)
  179         },
  180         {
  181                 .desc = "-5V",
  182                 .type = ENVSYS_SVOLTS_DC,
  183                 .bank = 0,
  184                 .reg = 0x26,
  185                 .refresh = lm_refresh_volt,
  186                 .rfact = NRFACT(100, 60)
  187         },
  188         
  189         /* Temperature */
  190         {
  191                 .desc = "Temp0",
  192                 .type = ENVSYS_STEMP,
  193                 .bank = 0,
  194                 .reg = 0x27,
  195                 .refresh = lm_refresh_temp,
  196                 .rfact = 0
  197         },
  198 
  199         /* Fans */
  200         {
  201                 .desc = "Fan0",
  202                 .type = ENVSYS_SFANRPM,
  203                 .bank = 0,
  204                 .reg = 0x28,
  205                 .refresh = lm_refresh_fanrpm,
  206                 .rfact = 0
  207         },
  208         {
  209                 .desc = "Fan1",
  210                 .type = ENVSYS_SFANRPM,
  211                 .bank = 0,
  212                 .reg = 0x29,
  213                 .refresh = lm_refresh_fanrpm,
  214                 .rfact = 0
  215         },
  216         {
  217                 .desc = "Fan2",
  218                 .type = ENVSYS_SFANRPM,
  219                 .bank = 0,
  220                 .reg = 0x2a,
  221                 .refresh = lm_refresh_fanrpm,
  222                 .rfact = 0
  223         },
  224 
  225         { .desc = NULL }
  226 };
  227 
  228 /* W83627HF */
  229 static struct lm_sensor w83627hf_sensors[] = {
  230         /* Voltage */
  231         {
  232                 .desc = "VCore A",
  233                 .type = ENVSYS_SVOLTS_DC,
  234                 .bank = 0,
  235                 .reg = 0x20,
  236                 .refresh = lm_refresh_volt,
  237                 .rfact = RFACT_NONE
  238         },
  239         {
  240                 .desc = "VCore B",
  241                 .type = ENVSYS_SVOLTS_DC,
  242                 .bank = 0,
  243                 .reg = 0x21,
  244                 .refresh = lm_refresh_volt,
  245                 .rfact = RFACT_NONE
  246         },
  247         {
  248                 .desc = "+3.3V",
  249                 .type = ENVSYS_SVOLTS_DC,
  250                 .bank = 0,
  251                 .reg = 0x22,
  252                 .refresh = lm_refresh_volt,
  253                 .rfact = RFACT_NONE
  254         },
  255         {
  256                 .desc = "+5V",
  257                 .type = ENVSYS_SVOLTS_DC,
  258                 .bank = 0,
  259                 .reg = 0x23,
  260                 .refresh = lm_refresh_volt,
  261                 .rfact = RFACT(34, 50)
  262         },
  263         {
  264                 .desc = "+12V",
  265                 .type = ENVSYS_SVOLTS_DC,
  266                 .bank = 0,
  267                 .reg = 0x24,
  268                 .refresh = lm_refresh_volt,
  269                 .rfact = RFACT(28, 10)
  270         },
  271         {
  272                 .desc = "-12V",
  273                 .type = ENVSYS_SVOLTS_DC,
  274                 .bank = 0,
  275                 .reg = 0x25,
  276                 .refresh = wb_refresh_nvolt,
  277                 .rfact = RFACT(232, 56)
  278         },
  279         {
  280                 .desc = "-5V",
  281                 .type = ENVSYS_SVOLTS_DC,
  282                 .bank = 0,
  283                 .reg = 0x26,
  284                 .refresh = wb_refresh_nvolt,
  285                 .rfact = RFACT(120, 56)
  286         },
  287         {
  288                 .desc = "5VSB",
  289                 .type = ENVSYS_SVOLTS_DC,
  290                 .bank = 5,
  291                 .reg = 0x50,
  292                 .refresh = lm_refresh_volt,
  293                 .rfact = RFACT(17, 33)
  294         },
  295         {
  296                 .desc = "VBAT",
  297                 .type = ENVSYS_SVOLTS_DC,
  298                 .bank = 5,
  299                 .reg = 0x51,
  300                 .refresh = lm_refresh_volt,
  301                 .rfact = RFACT_NONE
  302         },
  303 
  304         /* Temperature */
  305         {
  306                 .desc = "Temp0",
  307                 .type = ENVSYS_STEMP,
  308                 .bank = 0,
  309                 .reg = 0x27,
  310                 .refresh = lm_refresh_temp,
  311                 .rfact = 0
  312         },
  313         {
  314                 .desc = "Temp1",
  315                 .type = ENVSYS_STEMP,
  316                 .bank = 1,
  317                 .reg = 0x50,
  318                 .refresh = wb_refresh_temp,
  319                 .rfact = 0
  320         },
  321         {
  322                 .desc = "Temp2",
  323                 .type = ENVSYS_STEMP,
  324                 .bank = 2,
  325                 .reg = 0x50,
  326                 .refresh = wb_refresh_temp,
  327                 .rfact = 0
  328         },
  329 
  330         /* Fans */
  331         {
  332                 .desc = "Fan0",
  333                 .type = ENVSYS_SFANRPM,
  334                 .bank = 0,
  335                 .reg = 0x28,
  336                 .refresh = wb_refresh_fanrpm,
  337                 .rfact = 0
  338         },
  339         {
  340                 .desc = "Fan1",
  341                 .type = ENVSYS_SFANRPM,
  342                 .bank = 0,
  343                 .reg = 0x29,
  344                 .refresh = wb_refresh_fanrpm,
  345                 .rfact = 0
  346         },
  347         {
  348                 .desc = "Fan2",
  349                 .type = ENVSYS_SFANRPM,
  350                 .bank = 0,
  351                 .reg = 0x2a,
  352                 .refresh = wb_refresh_fanrpm,
  353                 .rfact = 0
  354         },
  355 
  356         { .desc = NULL }
  357 };
  358 
  359 /* W8627EHF */
  360 
  361 /*
  362  * The W83627EHF can measure voltages up to 2.048 V instead of the
  363  * traditional 4.096 V.  For measuring positive voltages, this can be
  364  * accounted for by halving the resistor factor.  Negative voltages
  365  * need special treatment, also because the reference voltage is 2.048 V
  366  * instead of the traditional 3.6 V.
  367  */
  368 static struct lm_sensor w83627ehf_sensors[] = {
  369         /* Voltage */
  370         {
  371                 .desc = "VCore",
  372                 .type = ENVSYS_SVOLTS_DC,
  373                 .bank = 0,
  374                 .reg = 0x20,
  375                 .refresh = lm_refresh_volt,
  376                 .rfact = RFACT_NONE / 2
  377         },
  378         {
  379                 .desc = "+12V",
  380                 .type = ENVSYS_SVOLTS_DC,
  381                 .bank = 0,
  382                 .reg = 0x21,
  383                 .refresh = lm_refresh_volt,
  384                 .rfact = RFACT(56, 10) / 2
  385         },
  386         {
  387                 .desc = "+3.3V",
  388                 .type = ENVSYS_SVOLTS_DC,
  389                 .bank = 0,
  390                 .reg = 0x22,
  391                 .refresh = lm_refresh_volt,
  392                 .rfact = RFACT(34, 34) / 2
  393         },
  394         {
  395                 .desc = "+3.3V",
  396                 .type = ENVSYS_SVOLTS_DC,
  397                 .bank = 0,
  398                 .reg = 0x23,
  399                 .refresh = lm_refresh_volt,
  400                 .rfact = RFACT(34, 34) / 2
  401         },
  402         {
  403                 .desc = "-12V",
  404                 .type = ENVSYS_SVOLTS_DC,
  405                 .bank = 0,
  406                 .reg = 0x24,
  407                 .refresh = wb_w83627ehf_refresh_nvolt,
  408                 .rfact = 0
  409         },
  410         {
  411                 .desc = "Unknown",
  412                 .type = ENVSYS_SVOLTS_DC,
  413                 .bank = 0,
  414                 .reg = 0x25,
  415                 .refresh = lm_refresh_volt,
  416                 .rfact = RFACT_NONE / 2
  417         },
  418         {
  419                 .desc = "Unknown",
  420                 .type = ENVSYS_SVOLTS_DC,
  421                 .bank = 0,
  422                 .reg = 0x26,
  423                 .refresh = lm_refresh_volt,
  424                 .rfact = RFACT_NONE / 2
  425         },
  426         {
  427                 .desc = "3.3VSB",
  428                 .type = ENVSYS_SVOLTS_DC,
  429                 .bank = 5,
  430                 .reg = 0x50,
  431                 .refresh = lm_refresh_volt,
  432                 .rfact = RFACT(34, 34) / 2
  433         },
  434         {
  435                 .desc = "VBAT",
  436                 .type = ENVSYS_SVOLTS_DC,
  437                 .bank = 5,
  438                 .reg = 0x51,
  439                 .refresh = lm_refresh_volt,
  440                 .rfact = RFACT_NONE / 2
  441         },
  442         {
  443                 .desc = "Unknown",
  444                 .type = ENVSYS_SVOLTS_DC,
  445                 .bank = 5,
  446                 .reg = 0x52,
  447                 .refresh = lm_refresh_volt,
  448                 .rfact = RFACT_NONE / 2
  449         },
  450 
  451         /* Temperature */
  452         {
  453                 .desc = "Temp0",
  454                 .type = ENVSYS_STEMP,
  455                 .bank = 0,
  456                 .reg = 0x27,
  457                 .refresh = lm_refresh_temp,
  458                 .rfact = 0
  459         },
  460         {
  461                 .desc = "Temp1",
  462                 .type = ENVSYS_STEMP,
  463                 .bank = 1,
  464                 .reg = 0x50,
  465                 .refresh = wb_refresh_temp,
  466                 .rfact = 0
  467         },
  468         {
  469                 .desc = "Temp2",
  470                 .type = ENVSYS_STEMP,
  471                 .bank = 2,
  472                 .reg = 0x50,
  473                 .refresh = wb_refresh_temp,
  474                 .rfact = 0
  475         },
  476 
  477         /* Fans */
  478         {
  479                 .desc = "Fan0",
  480                 .type = ENVSYS_SFANRPM,
  481                 .bank = 0,
  482                 .reg = 0x28,
  483                 .refresh = wb_refresh_fanrpm,
  484                 .rfact = 0
  485         },
  486         {
  487                 .desc = "Fan1",
  488                 .type = ENVSYS_SFANRPM,
  489                 .bank = 0,
  490                 .reg = 0x29,
  491                 .refresh = wb_refresh_fanrpm,
  492                 .rfact = 0
  493         },
  494         {
  495                 .desc = "Fan2",
  496                 .type = ENVSYS_SFANRPM,
  497                 .bank = 0,
  498                 .reg = 0x2a,
  499                 .refresh = wb_refresh_fanrpm,
  500                 .rfact = 0
  501         },
  502 
  503         { .desc = NULL }
  504 };
  505 
  506 /*  W83627DHG */
  507 static struct lm_sensor w83627dhg_sensors[] = {
  508         /* Voltage */
  509         {
  510                 .desc = "VCore",
  511                 .type = ENVSYS_SVOLTS_DC,
  512                 .bank = 0,
  513                 .reg = 0x20,
  514                 .refresh = lm_refresh_volt,
  515                 .rfact = RFACT_NONE / 2
  516         },
  517         {
  518                 .desc = "+12V",
  519                 .type = ENVSYS_SVOLTS_DC,
  520                 .bank = 0,
  521                 .reg = 0x21,
  522                 .refresh = lm_refresh_volt,
  523                 .rfact = RFACT(56, 10) / 2
  524         },
  525         {
  526                 .desc = "+3.3V",
  527                 .type = ENVSYS_SVOLTS_DC,
  528                 .bank = 0,
  529                 .reg = 0x22,
  530                 .refresh = lm_refresh_volt,
  531                 .rfact = RFACT_NONE
  532         },
  533         {
  534                 .desc = "AVCC",
  535                 .type = ENVSYS_SVOLTS_DC,
  536                 .bank = 0,
  537                 .reg = 0x23,
  538                 .refresh = lm_refresh_volt,
  539                 .rfact = RFACT_NONE
  540         },
  541         {
  542                 .desc = "+5V",
  543                 .type = ENVSYS_SVOLTS_DC,
  544                 .bank = 0,
  545                 .reg = 0x25,
  546                 .refresh = lm_refresh_volt,
  547                 .rfact = RFACT(32, 56)
  548         },
  549         /* 
  550          * I'm not sure about which one is -12V or -5V.
  551          */
  552 #if 0
  553         {
  554                 .desc = "-12V",
  555                 .type = ENVSYS_SVOLTS_DC,
  556                 .bank = 0,
  557                 .reg = 0x24,
  558                 .refresh = wb_refresh_nvolt,
  559                 .rfact = RFACT(232, 60)
  560         },
  561         {
  562                 .desc = "-5V",
  563                 .type = ENVSYS_SVOLTS_DC,
  564                 .bank = 0,
  565                 .reg = 0x26,
  566                 .refresh = wb_w83627ehf_refresh_nvolt
  567                 .rfact = 0
  568         },
  569 #endif
  570         {
  571                 .desc = "+3.3VSB",
  572                 .type = ENVSYS_SVOLTS_DC,
  573                 .bank = 5,
  574                 .reg = 0x50,
  575                 .refresh = lm_refresh_volt,
  576                 .rfact = RFACT_NONE
  577         },
  578         {
  579                 .desc = "VBAT",
  580                 .type = ENVSYS_SVOLTS_DC,
  581                 .bank = 5,
  582                 .reg = 0x51,
  583                 .refresh = lm_refresh_volt,
  584                 .rfact = RFACT_NONE
  585         },
  586 
  587         /* Temperature */
  588         {
  589                 .desc = "System Temp",
  590                 .type = ENVSYS_STEMP,
  591                 .bank = 0,
  592                 .reg = 0x27,
  593                 .refresh = lm_refresh_temp,
  594                 .rfact = 0
  595         },
  596         {
  597                 .desc = "CPU Temp",
  598                 .type = ENVSYS_STEMP,
  599                 .bank = 1,
  600                 .reg = 0x50,
  601                 .refresh = wb_refresh_temp,
  602                 .rfact = 0
  603         },
  604         {
  605                 .desc = "Aux Temp",
  606                 .type = ENVSYS_STEMP,
  607                 .bank = 2,
  608                 .reg = 0x50,
  609                 .refresh = wb_refresh_temp,
  610                 .rfact = 0
  611         },
  612 
  613         /* Fans */
  614         {
  615                 .desc = "System Fan",
  616                 .type = ENVSYS_SFANRPM,
  617                 .bank = 0,
  618                 .reg = 0x28,
  619                 .refresh = wb_refresh_fanrpm,
  620                 .rfact = 0
  621         },
  622         {
  623                 .desc = "CPU Fan",
  624                 .type = ENVSYS_SFANRPM,
  625                 .bank = 0,
  626                 .reg = 0x29,
  627                 .refresh = wb_refresh_fanrpm,
  628                 .rfact = 0
  629         },
  630         {
  631                 .desc = "Aux Fan",
  632                 .type = ENVSYS_SFANRPM,
  633                 .bank = 0,
  634                 .reg = 0x2a,
  635                 .refresh = wb_refresh_fanrpm,
  636                 .rfact = 0
  637         },
  638 
  639         { .desc = NULL }
  640 };
  641 
  642 /* W83637HF */
  643 static struct lm_sensor w83637hf_sensors[] = {
  644         /* Voltage */
  645         {
  646                 .desc = "VCore",
  647                 .type = ENVSYS_SVOLTS_DC,
  648                 .bank = 0,
  649                 .reg = 0x20,
  650                 .refresh = wb_w83637hf_refresh_vcore,
  651                 .rfact = 0
  652         },
  653         {
  654                 .desc = "+12V",
  655                 .type = ENVSYS_SVOLTS_DC,
  656                 .bank = 0,
  657                 .reg = 0x21,
  658                 .refresh = lm_refresh_volt,
  659                 .rfact = RFACT(28, 10)
  660         },
  661         {
  662                 .desc = "+3.3V",
  663                 .type = ENVSYS_SVOLTS_DC,
  664                 .bank = 0,
  665                 .reg = 0x22,
  666                 .refresh = lm_refresh_volt,
  667                 .rfact = RFACT_NONE
  668         },
  669         {
  670                 .desc = "+5V",
  671                 .type = ENVSYS_SVOLTS_DC,
  672                 .bank = 0,
  673                 .reg = 0x23,
  674                 .refresh = lm_refresh_volt,
  675                 .rfact = RFACT(34, 51)
  676         },
  677         {
  678                 .desc = "-12V",
  679                 .type = ENVSYS_SVOLTS_DC,
  680                 .bank = 0,
  681                 .reg = 0x24,
  682                 .refresh = wb_refresh_nvolt,
  683                 .rfact = RFACT(232, 56)
  684         },
  685         {
  686                 .desc = "5VSB",
  687                 .type = ENVSYS_SVOLTS_DC,
  688                 .bank = 5,
  689                 .reg = 0x50,
  690                 .refresh = lm_refresh_volt,
  691                 .rfact = RFACT(34, 51)
  692         },
  693         {
  694                 .desc = "VBAT",
  695                 .type = ENVSYS_SVOLTS_DC,
  696                 .bank = 5,
  697                 .reg = 0x51,
  698                 .refresh = lm_refresh_volt,
  699                 .rfact = RFACT_NONE
  700         },
  701 
  702         /* Temperature */
  703         {
  704                 .desc = "Temp0",
  705                 .type = ENVSYS_STEMP,
  706                 .bank = 0,
  707                 .reg = 0x27,
  708                 .refresh = lm_refresh_temp,
  709                 .rfact = 0
  710         },
  711         {
  712                 .desc = "Temp1",
  713                 .type = ENVSYS_STEMP,
  714                 .bank = 1,
  715                 .reg = 0x50,
  716                 .refresh = wb_refresh_temp,
  717                 .rfact = 0
  718         },
  719         {
  720                 .desc = "Temp2",
  721                 .type = ENVSYS_STEMP,
  722                 .bank = 2,
  723                 .reg = 0x50,
  724                 .refresh = wb_refresh_temp,
  725                 .rfact = 0
  726         },
  727 
  728         /* Fans */
  729         {
  730                 .desc = "Fan0",
  731                 .type = ENVSYS_SFANRPM,
  732                 .bank = 0,
  733                 .reg = 0x28,
  734                 .refresh = wb_refresh_fanrpm,
  735                 .rfact = 0
  736         },
  737         {
  738                 .desc = "Fan1",
  739                 .type = ENVSYS_SFANRPM,
  740                 .bank = 0,
  741                 .reg = 0x29,
  742                 .refresh = wb_refresh_fanrpm,
  743                 .rfact = 0
  744         },
  745         {
  746                 .desc = "Fan2",
  747                 .type = ENVSYS_SFANRPM,
  748                 .bank = 0,
  749                 .reg = 0x2a,
  750                 .refresh = wb_refresh_fanrpm,
  751                 .rfact = 0
  752         },
  753 
  754         { .desc = NULL }
  755 };
  756 
  757 /* W83697HF */
  758 static struct lm_sensor w83697hf_sensors[] = {
  759         /* Voltage */
  760         {
  761                 .desc = "VCore",
  762                 .type = ENVSYS_SVOLTS_DC,
  763                 .bank = 0,
  764                 .reg = 0x20,
  765                 .refresh = lm_refresh_volt,
  766                 .rfact = RFACT_NONE
  767         },
  768         {
  769                 .desc = "+3.3V",
  770                 .type = ENVSYS_SVOLTS_DC,
  771                 .bank = 0,
  772                 .reg = 0x22,
  773                 .refresh = lm_refresh_volt,
  774                 .rfact = RFACT_NONE
  775         },
  776         {
  777                 .desc = "+5V",
  778                 .type = ENVSYS_SVOLTS_DC,
  779                 .bank = 0,
  780                 .reg = 0x23,
  781                 .refresh = lm_refresh_volt,
  782                 .rfact = RFACT(34, 50)
  783         },
  784         {
  785                 .desc = "+12V",
  786                 .type = ENVSYS_SVOLTS_DC,
  787                 .bank = 0,
  788                 .reg = 0x24,
  789                 .refresh = lm_refresh_volt,
  790                 .rfact = RFACT(28, 10)
  791         },
  792         {
  793                 .desc = "-12V",
  794                 .type = ENVSYS_SVOLTS_DC,
  795                 .bank = 0,
  796                 .reg = 0x25,
  797                 .refresh = wb_refresh_nvolt,
  798                 .rfact = RFACT(232, 56)
  799         },
  800         {
  801                 .desc = "-5V",
  802                 .type = ENVSYS_SVOLTS_DC,
  803                 .bank = 0,
  804                 .reg = 0x26,
  805                 .refresh = wb_refresh_nvolt,
  806                 .rfact = RFACT(120, 56)
  807         },
  808         {
  809                 .desc = "5VSB",
  810                 .type = ENVSYS_SVOLTS_DC,
  811                 .bank = 5,
  812                 .reg = 0x50,
  813                 .refresh = lm_refresh_volt,
  814                 .rfact = RFACT(17, 33)
  815         },
  816         {
  817                 .desc = "VBAT",
  818                 .type = ENVSYS_SVOLTS_DC,
  819                 .bank = 5,
  820                 .reg = 0x51,
  821                 .refresh = lm_refresh_volt,
  822                 .rfact = RFACT_NONE
  823         },
  824 
  825         /* Temperature */
  826         {
  827                 .desc = "Temp0",
  828                 .type = ENVSYS_STEMP,
  829                 .bank = 0,
  830                 .reg = 0x27,
  831                 .refresh = lm_refresh_temp,
  832                 .rfact = 0
  833         },
  834         {
  835                 .desc = "Temp1",
  836                 .type = ENVSYS_STEMP,
  837                 .bank = 1,
  838                 .reg = 0x50,
  839                 .refresh = wb_refresh_temp,
  840                 .rfact = 0
  841         },
  842 
  843         /* Fans */
  844         {
  845                 .desc = "Fan0",
  846                 .type = ENVSYS_SFANRPM,
  847                 .bank = 0,
  848                 .reg = 0x28,
  849                 .refresh = wb_refresh_fanrpm,
  850                 .rfact = 0
  851         },
  852         {
  853                 .desc = "Fan1",
  854                 .type = ENVSYS_SFANRPM,
  855                 .bank = 0,
  856                 .reg = 0x29,
  857                 .refresh = wb_refresh_fanrpm,
  858                 .rfact = 0
  859         },
  860 
  861         { .desc = NULL }
  862 };
  863 
  864 /* W83781D */
  865 
  866 /*
  867  * The datasheet doesn't mention the (internal) resistors used for the
  868  * +5V, but using the values from the W83782D datasheets seems to
  869  * provide sensible results.
  870  */
  871 static struct lm_sensor w83781d_sensors[] = {
  872         /* Voltage */
  873         {
  874                 .desc = "VCore A",
  875                 .type = ENVSYS_SVOLTS_DC,
  876                 .bank = 0,
  877                 .reg = 0x20,
  878                 .refresh = lm_refresh_volt,
  879                 .rfact = RFACT_NONE
  880         },
  881         {
  882                 .desc = "VCore B",
  883                 .type = ENVSYS_SVOLTS_DC,
  884                 .bank = 0,
  885                 .reg = 0x21,
  886                 .refresh = lm_refresh_volt,
  887                 .rfact = RFACT_NONE
  888         },
  889         {
  890                 .desc = "+3.3V",
  891                 .type = ENVSYS_SVOLTS_DC,
  892                 .bank = 0,
  893                 .reg = 0x22,
  894                 .refresh = lm_refresh_volt,
  895                 .rfact = RFACT_NONE
  896         },
  897         {
  898                 .desc = "+5V",
  899                 .type = ENVSYS_SVOLTS_DC,
  900                 .bank = 0,
  901                 .reg = 0x23,
  902                 .refresh = lm_refresh_volt,
  903                 .rfact = RFACT(34, 50)
  904         },
  905         {
  906                 .desc = "+12V",
  907                 .type = ENVSYS_SVOLTS_DC,
  908                 .bank = 0,
  909                 .reg = 0x24,
  910                 .refresh = lm_refresh_volt,
  911                 .rfact = RFACT(28, 10)
  912         },
  913         {
  914                 .desc = "-12V",
  915                 .type = ENVSYS_SVOLTS_DC,
  916                 .bank = 0,
  917                 .reg = 0x25,
  918                 .refresh = lm_refresh_volt,
  919                 .rfact = NRFACT(2100, 604)
  920         },
  921         {
  922                 .desc = "-5V",
  923                 .type = ENVSYS_SVOLTS_DC,
  924                 .bank = 0,
  925                 .reg = 0x26,
  926                 .refresh = lm_refresh_volt,
  927                 .rfact = NRFACT(909, 604)
  928         },
  929 
  930         /* Temperature */
  931         {
  932                 .desc = "Temp0",
  933                 .type = ENVSYS_STEMP,
  934                 .bank = 0,
  935                 .reg = 0x27,
  936                 .refresh = lm_refresh_temp,
  937                 .rfact = 0
  938         },
  939         {
  940                 .desc = "Temp1",
  941                 .type = ENVSYS_STEMP,
  942                 .bank = 1,
  943                 .reg = 0x50,
  944                 .refresh = wb_refresh_temp,
  945                 .rfact = 0
  946         },
  947         {
  948                 .desc = "Temp2",
  949                 .type = ENVSYS_STEMP,
  950                 .bank = 2,
  951                 .reg = 0x50,
  952                 .refresh = wb_refresh_temp,
  953                 .rfact = 0
  954         },
  955 
  956         /* Fans */
  957         {
  958                 .desc = "Fan0",
  959                 .type = ENVSYS_SFANRPM,
  960                 .bank = 0,
  961                 .reg = 0x28,
  962                 .refresh = lm_refresh_fanrpm,
  963                 .rfact = 0
  964         },
  965         {
  966                 .desc = "Fan1",
  967                 .type = ENVSYS_SFANRPM,
  968                 .bank = 0,
  969                 .reg = 0x29,
  970                 .refresh = lm_refresh_fanrpm,
  971                 .rfact = 0
  972         },
  973         {
  974                 .desc = "Fan2",
  975                 .type = ENVSYS_SFANRPM,
  976                 .bank = 0,
  977                 .reg = 0x2a,
  978                 .refresh = lm_refresh_fanrpm,
  979                 .rfact = 0
  980         },
  981 
  982         { .desc = NULL }
  983 };
  984 
  985 /* W83782D */
  986 static struct lm_sensor w83782d_sensors[] = {
  987         /* Voltage */
  988         {
  989                 .desc = "VCore",
  990                 .type = ENVSYS_SVOLTS_DC,
  991                 .bank = 0,
  992                 .reg = 0x20,
  993                 .refresh = lm_refresh_volt,
  994                 .rfact = RFACT_NONE
  995         },
  996         {
  997                 .desc = "VINR0",
  998                 .type = ENVSYS_SVOLTS_DC,
  999                 .bank = 0,
 1000                 .reg = 0x21,
 1001                 .refresh = lm_refresh_volt,
 1002                 .rfact = RFACT_NONE
 1003         },
 1004         {
 1005                 .desc = "+3.3V",
 1006                 .type = ENVSYS_SVOLTS_DC,
 1007                 .bank = 0,
 1008                 .reg = 0x22,
 1009                 .refresh = lm_refresh_volt,
 1010                 .rfact = RFACT_NONE
 1011         },
 1012         {
 1013                 .desc = "+5V",
 1014                 .type = ENVSYS_SVOLTS_DC,
 1015                 .bank = 0,
 1016                 .reg = 0x23,
 1017                 .refresh = lm_refresh_volt,
 1018                 .rfact = RFACT(34, 50)
 1019         },
 1020         {
 1021                 .desc = "+12V",
 1022                 .type = ENVSYS_SVOLTS_DC,
 1023                 .bank = 0,
 1024                 .reg = 0x24,
 1025                 .refresh = lm_refresh_volt,
 1026                 .rfact = RFACT(28, 10)
 1027         },
 1028         {
 1029                 .desc = "-12V",
 1030                 .type = ENVSYS_SVOLTS_DC,
 1031                 .bank = 0,
 1032                 .reg = 0x25,
 1033                 .refresh = wb_refresh_nvolt,
 1034                 .rfact = RFACT(232, 56)
 1035         },
 1036         {
 1037                 .desc = "-5V",
 1038                 .type = ENVSYS_SVOLTS_DC,
 1039                 .bank = 0,
 1040                 .reg = 0x26,
 1041                 .refresh = wb_refresh_nvolt,
 1042                 .rfact = RFACT(120, 56)
 1043         },
 1044         {
 1045                 .desc = "5VSB",
 1046                 .type = ENVSYS_SVOLTS_DC,
 1047                 .bank = 5,
 1048                 .reg = 0x50,
 1049                 .refresh = lm_refresh_volt,
 1050                 .rfact = RFACT(17, 33)
 1051         },
 1052         {
 1053                 .desc = "VBAT",
 1054                 .type = ENVSYS_SVOLTS_DC,
 1055                 .bank = 5,
 1056                 .reg = 0x51,
 1057                 .refresh = lm_refresh_volt,
 1058                 .rfact = RFACT_NONE
 1059         },
 1060 
 1061         /* Temperature */
 1062         {
 1063                 .desc = "Temp0",
 1064                 .type = ENVSYS_STEMP,
 1065                 .bank = 0,
 1066                 .reg = 0x27,
 1067                 .refresh = lm_refresh_temp,
 1068                 .rfact = 0
 1069         },
 1070         {
 1071                 .desc = "Temp1",
 1072                 .type = ENVSYS_STEMP,
 1073                 .bank = 1,
 1074                 .reg = 0x50,
 1075                 .refresh = wb_refresh_temp,
 1076                 .rfact = 0
 1077         },
 1078         {
 1079                 .desc = "Temp2",
 1080                 .type = ENVSYS_STEMP,
 1081                 .bank = 2,
 1082                 .reg = 0x50,
 1083                 .refresh = wb_refresh_temp,
 1084                 .rfact = 0
 1085         },
 1086 
 1087         /* Fans */
 1088         {
 1089                 .desc = "Fan0",
 1090                 .type = ENVSYS_SFANRPM,
 1091                 .bank = 0,
 1092                 .reg = 0x28,
 1093                 .refresh = wb_refresh_fanrpm,
 1094                 .rfact = 0
 1095         },
 1096         {
 1097                 .desc = "Fan1",
 1098                 .type = ENVSYS_SFANRPM,
 1099                 .bank = 0,
 1100                 .reg = 0x29,
 1101                 .refresh = wb_refresh_fanrpm,
 1102                 .rfact = 0
 1103         },
 1104         {
 1105                 .desc = "Fan2",
 1106                 .type = ENVSYS_SFANRPM,
 1107                 .bank = 0,
 1108                 .reg = 0x2a,
 1109                 .refresh = wb_refresh_fanrpm,
 1110                 .rfact = 0
 1111         },
 1112 
 1113         { .desc = NULL }
 1114 };
 1115 
 1116 /* W83783S */
 1117 static struct lm_sensor w83783s_sensors[] = {
 1118         /* Voltage */
 1119         {
 1120                 .desc = "VCore",
 1121                 .type = ENVSYS_SVOLTS_DC,
 1122                 .bank = 0,
 1123                 .reg = 0x20,
 1124                 .refresh = lm_refresh_volt,
 1125                 .rfact = RFACT_NONE
 1126         },
 1127         {
 1128                 .desc = "+3.3V",
 1129                 .type = ENVSYS_SVOLTS_DC,
 1130                 .bank = 0,
 1131                 .reg = 0x22,
 1132                 .refresh = lm_refresh_volt,
 1133                 .rfact = RFACT_NONE
 1134         },
 1135         {
 1136                 .desc = "+5V",
 1137                 .type = ENVSYS_SVOLTS_DC,
 1138                 .bank = 0,
 1139                 .reg = 0x23,
 1140                 .refresh = lm_refresh_volt,
 1141                 .rfact = RFACT(34, 50)
 1142         },
 1143         {
 1144                 .desc = "+12V",
 1145                 .type = ENVSYS_SVOLTS_DC,
 1146                 .bank = 0,
 1147                 .reg = 0x24,
 1148                 .refresh = lm_refresh_volt,
 1149                 .rfact = RFACT(28, 10)
 1150         },
 1151         {
 1152                 .desc = "-12V",
 1153                 .type = ENVSYS_SVOLTS_DC,
 1154                 .bank = 0,
 1155                 .reg = 0x25,
 1156                 .refresh = wb_refresh_nvolt,
 1157                 .rfact = RFACT(232, 56)
 1158         },
 1159         {
 1160                 .desc = "-5V",
 1161                 .type = ENVSYS_SVOLTS_DC,
 1162                 .bank = 0,
 1163                 .reg = 0x26,
 1164                 .refresh = wb_refresh_nvolt,
 1165                 .rfact = RFACT(120, 56)
 1166         },
 1167 
 1168         /* Temperature */
 1169         {
 1170                 .desc = "Temp0",
 1171                 .type = ENVSYS_STEMP,
 1172                 .bank = 0,
 1173                 .reg = 0x27,
 1174                 .refresh = lm_refresh_temp,
 1175                 .rfact = 0
 1176         },
 1177         {
 1178                 .desc = "Temp1",
 1179                 .type = ENVSYS_STEMP,
 1180                 .bank = 1,
 1181                 .reg = 0x50,
 1182                 .refresh = wb_refresh_temp,
 1183                 .rfact = 0
 1184         },
 1185 
 1186         /* Fans */
 1187         {
 1188                 .desc = "Fan0",
 1189                 .type = ENVSYS_SFANRPM,
 1190                 .bank = 0,
 1191                 .reg = 0x28,
 1192                 .refresh = wb_refresh_fanrpm,
 1193                 .rfact = 0
 1194         },
 1195         {
 1196                 .desc = "Fan1",
 1197                 .type = ENVSYS_SFANRPM,
 1198                 .bank = 0,
 1199                 .reg = 0x29,
 1200                 .refresh = wb_refresh_fanrpm,
 1201                 .rfact = 0
 1202         },
 1203         {
 1204                 .desc = "Fan2",
 1205                 .type = ENVSYS_SFANRPM,
 1206                 .bank = 0,
 1207                 .reg = 0x2a,
 1208                 .refresh = wb_refresh_fanrpm,
 1209                 .rfact = 0
 1210         },
 1211 
 1212         { .desc = NULL }
 1213 };
 1214 
 1215 /* W83791D */
 1216 static struct lm_sensor w83791d_sensors[] = {
 1217         /* Voltage */
 1218         {
 1219                 .desc = "VCore",
 1220                 .type = ENVSYS_SVOLTS_DC,
 1221                 .bank = 0,
 1222                 .reg = 0x20,
 1223                 .refresh = lm_refresh_volt,
 1224                 .rfact = 10000
 1225         },
 1226         {
 1227                 .desc = "VINR0",
 1228                 .type = ENVSYS_SVOLTS_DC,
 1229                 .bank = 0,
 1230                 .reg = 0x21,
 1231                 .refresh = lm_refresh_volt,
 1232                 .rfact = 10000
 1233         },
 1234         {
 1235                 .desc = "+3.3V",
 1236                 .type = ENVSYS_SVOLTS_DC,
 1237                 .bank = 0,
 1238                 .reg = 0x22,
 1239                 .refresh = lm_refresh_volt,
 1240                 .rfact = 10000
 1241         },
 1242         {
 1243                 .desc = "+5V",
 1244                 .type = ENVSYS_SVOLTS_DC,
 1245                 .bank = 0,
 1246                 .reg = 0x23,
 1247                 .refresh = lm_refresh_volt,
 1248                 .rfact = RFACT(34, 50)
 1249         },
 1250         {
 1251                 .desc = "+12V",
 1252                 .type = ENVSYS_SVOLTS_DC,
 1253                 .bank = 0,
 1254                 .reg = 0x24,
 1255                 .refresh = lm_refresh_volt,
 1256                 .rfact = RFACT(28, 10)
 1257         },
 1258         {
 1259                 .desc = "-12V",
 1260                 .type = ENVSYS_SVOLTS_DC,
 1261                 .bank = 0,
 1262                 .reg = 0x25,
 1263                 .refresh = wb_refresh_nvolt,
 1264                 .rfact = RFACT(232, 56)
 1265         },
 1266         {
 1267                 .desc = "-5V",
 1268                 .type = ENVSYS_SVOLTS_DC,
 1269                 .bank = 0,
 1270                 .reg = 0x26,
 1271                 .refresh = wb_refresh_nvolt,
 1272                 .rfact = RFACT(120, 56)
 1273         },
 1274         {
 1275                 .desc = "5VSB",
 1276                 .type = ENVSYS_SVOLTS_DC,
 1277                 .bank = 0,
 1278                 .reg = 0xb0,
 1279                 .refresh = lm_refresh_volt,
 1280                 .rfact = RFACT(17, 33)
 1281         },
 1282         {
 1283                 .desc = "VBAT",
 1284                 .type = ENVSYS_SVOLTS_DC,
 1285                 .bank = 0,
 1286                 .reg = 0xb1,
 1287                 .refresh = lm_refresh_volt,
 1288                 .rfact = RFACT_NONE
 1289         },
 1290         {
 1291                 .desc = "VINR1",
 1292                 .type = ENVSYS_SVOLTS_DC,
 1293                 .bank = 0,
 1294                 .reg = 0xb2,
 1295                 .refresh = lm_refresh_volt,
 1296                 .rfact = RFACT_NONE
 1297         },
 1298 
 1299         /* Temperature */
 1300         {
 1301                 .desc = "Temp0",
 1302                 .type = ENVSYS_STEMP,
 1303                 .bank = 0,
 1304                 .reg = 0x27,
 1305                 .refresh = lm_refresh_temp,
 1306                 .rfact = 0
 1307         },
 1308         {
 1309                 .desc = "Temp1",
 1310                 .type = ENVSYS_STEMP,
 1311                 .bank = 0,
 1312                 .reg = 0xc0,
 1313                 .refresh = wb_refresh_temp,
 1314                 .rfact = 0
 1315         },
 1316         {
 1317                 .desc = "Temp2",
 1318                 .type = ENVSYS_STEMP,
 1319                 .bank = 0,
 1320                 .reg = 0xc8,
 1321                 .refresh = wb_refresh_temp,
 1322                 .rfact = 0
 1323         },
 1324 
 1325         /* Fans */
 1326         {
 1327                 .desc = "Fan0",
 1328                 .type = ENVSYS_SFANRPM,
 1329                 .bank = 0,
 1330                 .reg = 0x28,
 1331                 .refresh = wb_refresh_fanrpm,
 1332                 .rfact = 0
 1333         },
 1334         {
 1335                 .desc = "Fan1",
 1336                 .type = ENVSYS_SFANRPM,
 1337                 .bank = 0,
 1338                 .reg = 0x29,
 1339                 .refresh = wb_refresh_fanrpm,
 1340                 .rfact = 0
 1341         },
 1342         {
 1343                 .desc = "Fan2",
 1344                 .type = ENVSYS_SFANRPM,
 1345                 .bank = 0,
 1346                 .reg = 0x2a,
 1347                 .refresh = wb_refresh_fanrpm,
 1348                 .rfact = 0
 1349         },
 1350         {
 1351                 .desc = "Fan3",
 1352                 .type = ENVSYS_SFANRPM,
 1353                 .bank = 0,
 1354                 .reg = 0xba,
 1355                 .refresh = wb_refresh_fanrpm,
 1356                 .rfact = 0
 1357         },
 1358         {
 1359                 .desc = "Fan4",
 1360                 .type = ENVSYS_SFANRPM,
 1361                 .bank = 0,
 1362                 .reg = 0xbb,
 1363                 .refresh = wb_refresh_fanrpm,
 1364                 .rfact = 0
 1365         },
 1366 
 1367         { .desc = NULL }
 1368 };
 1369 
 1370 /* W83792D */
 1371 static struct lm_sensor w83792d_sensors[] = {
 1372         /* Voltage */
 1373         {
 1374                 .desc = "VCore A",
 1375                 .type = ENVSYS_SVOLTS_DC,
 1376                 .bank = 0,
 1377                 .reg = 0x20,
 1378                 .refresh = lm_refresh_volt,
 1379                 .rfact = RFACT_NONE
 1380         },
 1381         {
 1382                 .desc = "VCore B",
 1383                 .type = ENVSYS_SVOLTS_DC,
 1384                 .bank = 0,
 1385                 .reg = 0x21,
 1386                 .refresh = lm_refresh_volt,
 1387                 .rfact = RFACT_NONE
 1388         },
 1389         {
 1390                 .desc = "+3.3V",
 1391                 .type = ENVSYS_SVOLTS_DC,
 1392                 .bank = 0,
 1393                 .reg = 0x22,
 1394                 .refresh = lm_refresh_volt,
 1395                 .rfact = RFACT_NONE
 1396         },
 1397         {
 1398                 .desc = "-5V",
 1399                 .type = ENVSYS_SVOLTS_DC,
 1400                 .bank = 0,
 1401                 .reg = 0x23,
 1402                 .refresh = wb_refresh_nvolt,
 1403                 .rfact = RFACT(120, 56)
 1404         },
 1405         {
 1406                 .desc = "+12V",
 1407                 .type = ENVSYS_SVOLTS_DC,
 1408                 .bank = 0,
 1409                 .reg = 0x24,
 1410                 .refresh = lm_refresh_volt,
 1411                 .rfact = RFACT(28, 10)
 1412         },
 1413         {
 1414                 .desc = "-12V",
 1415                 .type = ENVSYS_SVOLTS_DC,
 1416                 .bank = 0,
 1417                 .reg = 0x25,
 1418                 .refresh = wb_refresh_nvolt,
 1419                 .rfact = RFACT(232, 56)
 1420         },
 1421         {
 1422                 .desc = "+5V",
 1423                 .type = ENVSYS_SVOLTS_DC,
 1424                 .bank = 0,
 1425                 .reg = 0x26,
 1426                 .refresh = lm_refresh_volt,
 1427                 .rfact = RFACT(34, 50)
 1428         },
 1429         {
 1430                 .desc = "5VSB",
 1431                 .type = ENVSYS_SVOLTS_DC,
 1432                 .bank = 0,
 1433                 .reg = 0xb0,
 1434                 .refresh = lm_refresh_volt,
 1435                 .rfact = RFACT(17, 33)
 1436         },
 1437         {
 1438                 .desc = "VBAT",
 1439                 .type = ENVSYS_SVOLTS_DC,
 1440                 .bank = 0,
 1441                 .reg = 0xb1,
 1442                 .refresh = lm_refresh_volt,
 1443                 .rfact = RFACT_NONE
 1444         },
 1445 
 1446         /* Temperature */
 1447         {
 1448                 .desc = "Temp0",
 1449                 .type = ENVSYS_STEMP,
 1450                 .bank = 0,
 1451                 .reg = 0x27,
 1452                 .refresh = lm_refresh_temp,
 1453                 .rfact = 0
 1454         },
 1455         {
 1456                 .desc = "Temp1",
 1457                 .type = ENVSYS_STEMP,
 1458                 .bank = 0,
 1459                 .reg = 0xc0,
 1460                 .refresh = wb_refresh_temp,
 1461                 .rfact = 0
 1462         },
 1463         {
 1464                 .desc = "Temp2",
 1465                 .type = ENVSYS_STEMP,
 1466                 .bank = 0,
 1467                 .reg = 0xc8,
 1468                 .refresh = wb_refresh_temp,
 1469                 .rfact = 0
 1470         },
 1471 
 1472         /* Fans */
 1473         {
 1474                 .desc = "Fan0",
 1475                 .type = ENVSYS_SFANRPM,
 1476                 .bank = 0,
 1477                 .reg = 0x28,
 1478                 .refresh = wb_w83792d_refresh_fanrpm,
 1479                 .rfact = 0
 1480         },
 1481         {
 1482                 .desc = "Fan1",
 1483                 .type = ENVSYS_SFANRPM,
 1484                 .bank = 0,
 1485                 .reg = 0x29,
 1486                 .refresh = wb_w83792d_refresh_fanrpm,
 1487                 .rfact = 0
 1488         },
 1489         {
 1490                 .desc = "Fan2",
 1491                 .type = ENVSYS_SFANRPM,
 1492                 .bank = 0,
 1493                 .reg = 0x2a,
 1494                 .refresh = wb_w83792d_refresh_fanrpm,
 1495                 .rfact = 0
 1496         },
 1497         {
 1498                 .desc = "Fan3",
 1499                 .type = ENVSYS_SFANRPM,
 1500                 .bank = 0,
 1501                 .reg = 0xb8,
 1502                 .refresh = wb_w83792d_refresh_fanrpm,
 1503                 .rfact = 0
 1504         },
 1505         {
 1506                 .desc = "Fan4",
 1507                 .type = ENVSYS_SFANRPM,
 1508                 .bank = 0,
 1509                 .reg = 0xb9,
 1510                 .refresh = wb_w83792d_refresh_fanrpm,
 1511                 .rfact = 0
 1512         },
 1513         {
 1514                 .desc = "Fan5",
 1515                 .type = ENVSYS_SFANRPM,
 1516                 .bank = 0,
 1517                 .reg = 0xba,
 1518                 .refresh = wb_w83792d_refresh_fanrpm,
 1519                 .rfact = 0
 1520         },
 1521         {
 1522                 .desc = "Fan6",
 1523                 .type = ENVSYS_SFANRPM,
 1524                 .bank = 0,
 1525                 .reg = 0xbe,
 1526                 .refresh = wb_w83792d_refresh_fanrpm,
 1527                 .rfact = 0
 1528         },
 1529 
 1530         { .desc = NULL }
 1531 };
 1532 
 1533 /* AS99127F */
 1534 static struct lm_sensor as99127f_sensors[] = {
 1535         /* Voltage */
 1536         {
 1537                 .desc = "VCore A",
 1538                 .type = ENVSYS_SVOLTS_DC,
 1539                 .bank = 0,
 1540                 .reg = 0x20,
 1541                 .refresh = lm_refresh_volt,
 1542                 .rfact = RFACT_NONE
 1543         },
 1544         {
 1545                 .desc = "VCore B",
 1546                 .type = ENVSYS_SVOLTS_DC,
 1547                 .bank = 0,
 1548                 .reg = 0x21,
 1549                 .refresh = lm_refresh_volt,
 1550                 .rfact = RFACT_NONE
 1551         },
 1552         {
 1553                 .desc = "+3.3V",
 1554                 .type = ENVSYS_SVOLTS_DC,
 1555                 .bank = 0,
 1556                 .reg = 0x22,
 1557                 .refresh = lm_refresh_volt,
 1558                 .rfact = RFACT_NONE
 1559         },
 1560         {
 1561                 .desc = "+5V",
 1562                 .type = ENVSYS_SVOLTS_DC,
 1563                 .bank = 0,
 1564                 .reg = 0x23,
 1565                 .refresh = lm_refresh_volt,
 1566                 .rfact = RFACT(34, 50)
 1567         },
 1568         {
 1569                 .desc = "+12V",
 1570                 .type = ENVSYS_SVOLTS_DC,
 1571                 .bank = 0,
 1572                 .reg = 0x24,
 1573                 .refresh = lm_refresh_volt,
 1574                 .rfact = RFACT(28, 10)
 1575         },
 1576         {
 1577                 .desc = "-12V",
 1578                 .type = ENVSYS_SVOLTS_DC,
 1579                 .bank = 0,
 1580                 .reg = 0x25,
 1581                 .refresh = wb_refresh_nvolt,
 1582                 .rfact = RFACT(232, 56)
 1583         },
 1584         {
 1585                 .desc = "-5V",
 1586                 .type = ENVSYS_SVOLTS_DC,
 1587                 .bank = 0,
 1588                 .reg = 0x26,
 1589                 .refresh = wb_refresh_nvolt,
 1590                 .rfact = RFACT(120, 56)
 1591         },
 1592 
 1593         /* Temperature */
 1594         {
 1595                 .desc = "Temp0",
 1596                 .type = ENVSYS_STEMP,
 1597                 .bank = 0,
 1598                 .reg = 0x27,
 1599                 .refresh = lm_refresh_temp,
 1600                 .rfact = 0
 1601         },
 1602         {
 1603                 .desc = "Temp1",
 1604                 .type = ENVSYS_STEMP,
 1605                 .bank = 1,
 1606                 .reg = 0x50,
 1607                 .refresh = as_refresh_temp,
 1608                 .rfact = 0
 1609         },
 1610         {
 1611                 .desc = "Temp2",
 1612                 .type = ENVSYS_STEMP,
 1613                 .bank = 2,
 1614                 .reg = 0x50,
 1615                 .refresh = as_refresh_temp,
 1616                 .rfact = 0
 1617         },
 1618 
 1619         /* Fans */
 1620         {
 1621                 .desc = "Fan0",
 1622                 .type = ENVSYS_SFANRPM,
 1623                 .bank = 0,
 1624                 .reg = 0x28,
 1625                 .refresh = lm_refresh_fanrpm,
 1626                 .rfact = 0
 1627         },
 1628         {
 1629                 .desc = "Fan1",
 1630                 .type = ENVSYS_SFANRPM,
 1631                 .bank = 0,
 1632                 .reg = 0x29,
 1633                 .refresh = lm_refresh_fanrpm,
 1634                 .rfact = 0
 1635         },
 1636         {
 1637                 .desc = "Fan2",
 1638                 .type = ENVSYS_SFANRPM,
 1639                 .bank = 0,
 1640                 .reg = 0x2a,
 1641                 .refresh = lm_refresh_fanrpm,
 1642                 .rfact = 0
 1643         },
 1644 
 1645         { .desc = NULL }
 1646 };
 1647 
 1648 static void
 1649 lm_generic_banksel(struct lm_softc *lmsc, int bank)
 1650 {
 1651         (*lmsc->lm_writereg)(lmsc, WB_BANKSEL, bank);
 1652 }
 1653 
 1654 /*
 1655  * bus independent probe
 1656  */
 1657 int
 1658 lm_probe(bus_space_tag_t iot, bus_space_handle_t ioh)
 1659 {
 1660         uint8_t cr;
 1661         int rv;
 1662 
 1663         /* Check for some power-on defaults */
 1664         bus_space_write_1(iot, ioh, LMC_ADDR, LMD_CONFIG);
 1665 
 1666         /* Perform LM78 reset */
 1667         bus_space_write_1(iot, ioh, LMC_DATA, 0x80);
 1668 
 1669         /* XXX - Why do I have to reselect the register? */
 1670         bus_space_write_1(iot, ioh, LMC_ADDR, LMD_CONFIG);
 1671         cr = bus_space_read_1(iot, ioh, LMC_DATA);
 1672 
 1673         /* XXX - spec says *only* 0x08! */
 1674         if ((cr == 0x08) || (cr == 0x01) || (cr == 0x03))
 1675                 rv = 1;
 1676         else
 1677                 rv = 0;
 1678 
 1679         DPRINTF(("lm: rv = %d, cr = %x\n", rv, cr));
 1680 
 1681         return rv;
 1682 }
 1683 
 1684 
 1685 /*
 1686  * pre:  lmsc contains valid busspace tag and handle
 1687  */
 1688 void
 1689 lm_attach(struct lm_softc *lmsc)
 1690 {
 1691         uint32_t i;
 1692 
 1693         for (i = 0; i < __arraycount(lm_chips); i++)
 1694                 if (lm_chips[i].chip_match(lmsc))
 1695                         break;
 1696 
 1697         /* Start the monitoring loop */
 1698         (*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01);
 1699 
 1700         /* Indicate we have never read the registers */
 1701         timerclear(&lmsc->lastread);
 1702 
 1703         /* Initialize sensors */
 1704         for (i = 0; i < lmsc->numsensors; ++i) {
 1705                 lmsc->sensors[i].sensor = lmsc->info[i].sensor = i;
 1706                 lmsc->sensors[i].validflags = (ENVSYS_FVALID|ENVSYS_FCURVALID);
 1707                 lmsc->info[i].validflags = ENVSYS_FVALID;
 1708                 lmsc->sensors[i].warnflags = ENVSYS_WARN_OK;
 1709         }
 1710         /*
 1711          * Hook into the System Monitor.
 1712          */
 1713         lmsc->sc_sysmon.sme_ranges = lm_ranges;
 1714         lmsc->sc_sysmon.sme_sensor_info = lmsc->info;
 1715         lmsc->sc_sysmon.sme_sensor_data = lmsc->sensors;
 1716         lmsc->sc_sysmon.sme_cookie = lmsc;
 1717 
 1718         lmsc->sc_sysmon.sme_gtredata = lm_gtredata;
 1719         /* sme_streinfo set in chip-specific attach */
 1720 
 1721         lmsc->sc_sysmon.sme_nsensors = lmsc->numsensors;
 1722         lmsc->sc_sysmon.sme_envsys_version = 1000;
 1723 
 1724         if (sysmon_envsys_register(&lmsc->sc_sysmon))
 1725                 aprint_error("%s: unable to register with sysmon\n",
 1726                     lmsc->sc_dev.dv_xname);
 1727 }
 1728 
 1729 static int
 1730 lm_match(struct lm_softc *sc)
 1731 {
 1732         const char *model = NULL;
 1733         int chipid;
 1734 
 1735         /* See if we have an LM78/LM78J/LM79 or LM81 */
 1736         chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK;
 1737         switch(chipid) {
 1738         case LM_ID_LM78:
 1739                 model = "LM78";
 1740                 break;
 1741         case LM_ID_LM78J:
 1742                 model = "LM78J";
 1743                 break;
 1744         case LM_ID_LM79:
 1745                 model = "LM79";
 1746                 break;
 1747         case LM_ID_LM81:
 1748                 model = "LM81";
 1749                 break;
 1750         default:
 1751                 return 0;
 1752         }
 1753 
 1754         aprint_normal(": National Semiconductor %s Hardware monitor\n", model);
 1755 
 1756         lm_setup_sensors(sc, lm78_sensors);
 1757         sc->sc_sysmon.sme_streinfo = lm_streinfo;
 1758         sc->refresh_sensor_data = lm_refresh_sensor_data;
 1759         return 1;
 1760 }
 1761 
 1762 static int
 1763 def_match(struct lm_softc *sc)
 1764 {
 1765         int chipid;
 1766 
 1767         chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK;
 1768         aprint_error(": Unknown chip (ID %d)\n", chipid);
 1769 
 1770         lm_setup_sensors(sc, lm78_sensors);
 1771         sc->sc_sysmon.sme_streinfo = lm_streinfo;
 1772         sc->refresh_sensor_data = lm_refresh_sensor_data;
 1773         return 1;
 1774 }
 1775 
 1776 static int
 1777 wb_match(struct lm_softc *sc)
 1778 {
 1779         const char *model;
 1780         int banksel, vendid, devid;
 1781 
 1782         model = NULL;
 1783 
 1784         /* Read vendor ID */
 1785         banksel = (*sc->lm_readreg)(sc, WB_BANKSEL);
 1786         lm_generic_banksel(sc, WB_BANKSEL_HBAC);
 1787 
 1788         vendid = (*sc->lm_readreg)(sc, WB_VENDID) << 8;
 1789         lm_generic_banksel(sc, 0);
 1790         vendid |= (*sc->lm_readreg)(sc, WB_VENDID);
 1791         DPRINTF(("winbond vend id 0x%x\n", vendid));
 1792         if (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)
 1793                 return 0;
 1794 
 1795         /* Read device/chip ID */
 1796         lm_generic_banksel(sc, WB_BANKSEL_B0);
 1797         devid = (*sc->lm_readreg)(sc, LMD_CHIPID);
 1798         sc->chipid = (*sc->lm_readreg)(sc, WB_BANK0_CHIPID);
 1799         lm_generic_banksel(sc, banksel);
 1800         DPRINTF(("winbond chip id 0x%x\n", sc->chipid));
 1801 
 1802         switch(sc->chipid) {
 1803         case WB_CHIPID_W83627HF:
 1804                 model = "W83627HF";
 1805                 lm_setup_sensors(sc, w83627hf_sensors);
 1806                 break;
 1807         case WB_CHIPID_W83627THF:
 1808                 model = "W83627THF";
 1809                 lm_setup_sensors(sc, w83637hf_sensors);
 1810                 break;
 1811         case WB_CHIPID_W83627EHF:
 1812                 model = "W83627EHF";
 1813                 lm_setup_sensors(sc, w83627ehf_sensors);
 1814                 break;
 1815         case WB_CHIPID_W83627DHG:
 1816                 model = "W83627DHG";
 1817                 lm_setup_sensors(sc, w83627dhg_sensors);
 1818                 break;
 1819         case WB_CHIPID_W83637HF:
 1820                 model = "W83637HF";
 1821                 lm_generic_banksel(sc, WB_BANKSEL_B0);
 1822                 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9)
 1823                         sc->vrm9 = 1;
 1824                 lm_generic_banksel(sc, banksel);
 1825                 lm_setup_sensors(sc, w83637hf_sensors);
 1826                 break;
 1827         case WB_CHIPID_W83697HF:
 1828                 model = "W83697HF";
 1829                 lm_setup_sensors(sc, w83697hf_sensors);
 1830                 break;
 1831         case WB_CHIPID_W83781D:
 1832         case WB_CHIPID_W83781D_2:
 1833                 model = "W83781D";
 1834                 lm_setup_sensors(sc, w83781d_sensors);
 1835                 sc->sc_sysmon.sme_streinfo = wb781_streinfo;
 1836                 break;
 1837         case WB_CHIPID_W83782D:
 1838                 model = "W83782D";
 1839                 lm_setup_sensors(sc, w83782d_sensors);
 1840                 sc->sc_sysmon.sme_streinfo = wb782_streinfo;
 1841                 break;
 1842         case WB_CHIPID_W83783S:
 1843                 model = "W83783S";
 1844                 lm_setup_sensors(sc, w83783s_sensors);
 1845                 break;
 1846         case WB_CHIPID_W83791D:
 1847                 model = "W83791D";
 1848                 lm_setup_sensors(sc, w83791d_sensors);
 1849                 break;
 1850         case WB_CHIPID_W83791SD:
 1851                 model = "W83791SD";
 1852                 break;
 1853         case WB_CHIPID_W83792D:
 1854                 model = "W83792D";
 1855                 lm_setup_sensors(sc, w83792d_sensors);
 1856                 break;
 1857         case WB_CHIPID_AS99127F:
 1858                 if (vendid == WB_VENDID_ASUS) {
 1859                         model = "AS99127F";
 1860                         lm_setup_sensors(sc, w83781d_sensors);
 1861                 } else {
 1862                         model = "AS99127F rev 2";
 1863                         lm_setup_sensors(sc, as99127f_sensors);
 1864                 }
 1865                 break;
 1866         default:
 1867                 aprint_normal(": unknown Winbond chip (ID 0x%x)\n",
 1868                     sc->chipid);
 1869                 /* Handle as a standard LM78. */
 1870                 lm_setup_sensors(sc, lm78_sensors);
 1871                 sc->refresh_sensor_data = lm_refresh_sensor_data;
 1872                 return 1;
 1873         }
 1874 
 1875         aprint_normal(": Winbond %s Hardware monitor\n", model);
 1876 
 1877         sc->sc_sysmon.sme_streinfo = lm_streinfo;
 1878         sc->refresh_sensor_data = wb_refresh_sensor_data;
 1879         return 1;
 1880 }
 1881 
 1882 static void
 1883 lm_setup_sensors(struct lm_softc *sc, struct lm_sensor *sensors)
 1884 {
 1885         int i;
 1886 
 1887         for (i = 0; sensors[i].desc; i++) {
 1888                 sc->sensors[i].units = sc->info[i].units = sensors[i].type;
 1889                 strlcpy(sc->info[i].desc, sensors[i].desc,
 1890                     sizeof(sc->info[i].desc));
 1891                 sc->numsensors++;
 1892         }
 1893         sc->lm_sensors = sensors;
 1894 }
 1895 
 1896 static void
 1897 lm_refresh_sensor_data(struct lm_softc *sc)
 1898 {
 1899         int i;
 1900 
 1901         /* Refresh our stored data for every sensor */
 1902         for (i = 0; i < sc->numsensors; i++)
 1903                 sc->lm_sensors[i].refresh(sc, i);
 1904 }
 1905 
 1906 static void
 1907 lm_refresh_volt(struct lm_softc *sc, int n)
 1908 {
 1909         int data;
 1910 
 1911         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 1912         DPRINTF(("%s: volt[%d] 0x%x\n", __func__, n, data)); 
 1913         sc->sensors[n].cur.data_s = (data << 4);
 1914         sc->sensors[n].cur.data_s *= sc->lm_sensors[n].rfact;
 1915         sc->sensors[n].cur.data_s /= 10;
 1916         sc->info[n].rfact = sc->lm_sensors[n].rfact;
 1917 }
 1918 
 1919 #define INVALIDATE_SENSOR(x)                                            \
 1920         do {                                                            \
 1921                 sc->sensors[(x)].validflags &= ~ENVSYS_FCURVALID;       \
 1922                 sc->sensors[(x)].cur.data_us = 0;                       \
 1923         } while (/* CONSTCOND */ 0)
 1924 
 1925 static void
 1926 lm_refresh_temp(struct lm_softc *sc, int n)
 1927 {
 1928         int sdata;
 1929 
 1930         /*
 1931          * The data sheet suggests that the range of the temperature
 1932          * sensor is between -55 degC and +125 degC.
 1933          */
 1934         sdata = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 1935         if (sdata > 0x7d && sdata < 0xc9) {
 1936                 INVALIDATE_SENSOR(n);
 1937         } else {
 1938                 if (sdata & 0x80)
 1939                         sdata -= 0x100;
 1940                 sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
 1941                 sc->sensors[n].cur.data_us = sdata * 1000000 + 273150000;
 1942         }
 1943 }
 1944 
 1945 static void
 1946 lm_refresh_fanrpm(struct lm_softc *sc, int n)
 1947 {
 1948         int data, divisor = 1;
 1949 
 1950         /*
 1951          * We might get more accurate fan readings by adjusting the
 1952          * divisor, but that might interfere with APM or other SMM
 1953          * BIOS code reading the fan speeds.
 1954          */
 1955 
 1956         /* FAN3 has a fixed fan divisor. */
 1957         if (sc->lm_sensors[n].reg == LMD_FAN1 ||
 1958             sc->lm_sensors[n].reg == LMD_FAN2) {
 1959                 data = (*sc->lm_readreg)(sc, LMD_VIDFAN);
 1960                 if (sc->lm_sensors[n].reg == LMD_FAN1)
 1961                         divisor = (data >> 4) & 0x03;
 1962                 else
 1963                         divisor = (data >> 6) & 0x03;
 1964         }
 1965 
 1966         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 1967         if (data == 0xff || data == 0x00) {
 1968                 INVALIDATE_SENSOR(n);
 1969         } else {
 1970                 sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
 1971                 sc->sensors[n].cur.data_us = 1350000 / (data << divisor);
 1972         }
 1973 }
 1974 
 1975 static void
 1976 wb_refresh_sensor_data(struct lm_softc *sc)
 1977 {
 1978         int banksel, bank, i;
 1979 
 1980         /*
 1981          * Properly save and restore bank selection register.
 1982          */
 1983 
 1984         banksel = bank = sc->lm_readreg(sc, WB_BANKSEL);
 1985         for (i = 0; i < sc->numsensors; i++) {
 1986                 if (bank != sc->lm_sensors[i].bank) {
 1987                         bank = sc->lm_sensors[i].bank;
 1988                         lm_generic_banksel(sc, bank);
 1989                 }
 1990                 sc->lm_sensors[i].refresh(sc, i);
 1991         }
 1992         lm_generic_banksel(sc, banksel);
 1993 }
 1994 
 1995 static void
 1996 wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n)
 1997 {
 1998         int data;
 1999 
 2000         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2001 
 2002         /*
 2003          * Depending on the voltage detection method,
 2004          * one of the following formulas is used:
 2005          *      VRM8 method: value = raw * 0.016V
 2006          *      VRM9 method: value = raw * 0.00488V + 0.70V
 2007          */
 2008         if (sc->vrm9)
 2009                 sc->sensors[n].cur.data_s = (data * 4880) + 700000;
 2010         else
 2011                 sc->sensors[n].cur.data_s = (data * 16000);
 2012 }
 2013 
 2014 static void
 2015 wb_refresh_nvolt(struct lm_softc *sc, int n)
 2016 {
 2017         int data;
 2018 
 2019         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2020         sc->sensors[n].cur.data_s = ((data << 4) - WB_VREF);
 2021         sc->sensors[n].cur.data_s *= sc->lm_sensors[n].rfact;
 2022         sc->sensors[n].cur.data_s /= 10;
 2023         sc->sensors[n].cur.data_s += WB_VREF * 1000;
 2024 }
 2025 
 2026 static void
 2027 wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n)
 2028 {
 2029         int data;
 2030 
 2031         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2032         sc->sensors[n].cur.data_s = ((data << 3) - WB_W83627EHF_VREF);
 2033         sc->sensors[n].cur.data_s *= RFACT(232, 10);
 2034         sc->sensors[n].cur.data_s /= 10;
 2035         sc->sensors[n].cur.data_s += WB_W83627EHF_VREF * 1000;
 2036 }
 2037 
 2038 static void
 2039 wb_refresh_temp(struct lm_softc *sc, int n)
 2040 {
 2041         int sdata;
 2042 
 2043         /*
 2044          * The data sheet suggests that the range of the temperature
 2045          * sensor is between -55 degC and +125 degC.  However, values
 2046          * around -48 degC seem to be a very common bogus values.
 2047          * Since such values are unreasonably low, we use -45 degC for
 2048          * the lower limit instead.
 2049          */
 2050         sdata = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
 2051         sdata += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
 2052         if (sdata > 0x0fa && sdata < 0x1a6) {
 2053                 INVALIDATE_SENSOR(n);
 2054         } else {
 2055                 if (sdata & 0x100)
 2056                         sdata -= 0x200;
 2057                 sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
 2058                 sc->sensors[n].cur.data_us = sdata * 500000 + 273150000;
 2059         }
 2060 }
 2061 
 2062 static void
 2063 wb_refresh_fanrpm(struct lm_softc *sc, int n)
 2064 {
 2065         int fan, data, divisor = 0;
 2066 
 2067         /* 
 2068          * This is madness; the fan divisor bits are scattered all
 2069          * over the place.
 2070          */
 2071 
 2072         if (sc->lm_sensors[n].reg == LMD_FAN1 ||
 2073             sc->lm_sensors[n].reg == LMD_FAN2 ||
 2074             sc->lm_sensors[n].reg == LMD_FAN3) {
 2075                 data = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
 2076                 fan = (sc->lm_sensors[n].reg - LMD_FAN1);
 2077                 if ((data >> 5) & (1 << fan))
 2078                         divisor |= 0x04;
 2079         }
 2080 
 2081         if (sc->lm_sensors[n].reg == LMD_FAN1 ||
 2082             sc->lm_sensors[n].reg == LMD_FAN2) {
 2083                 data = (*sc->lm_readreg)(sc, LMD_VIDFAN);
 2084                 if (sc->lm_sensors[n].reg == LMD_FAN1)
 2085                         divisor |= (data >> 4) & 0x03;
 2086                 else
 2087                         divisor |= (data >> 6) & 0x03;
 2088         } else if (sc->lm_sensors[n].reg == LMD_FAN3) {
 2089                 data = (*sc->lm_readreg)(sc, WB_PIN);
 2090                 divisor |= (data >> 6) & 0x03;
 2091         } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 ||
 2092                    sc->lm_sensors[n].reg == WB_BANK0_FAN5) {
 2093                 data = (*sc->lm_readreg)(sc, WB_BANK0_FAN45);
 2094                 if (sc->lm_sensors[n].reg == WB_BANK0_FAN4)
 2095                         divisor |= (data >> 0) & 0x07;
 2096                 else
 2097                         divisor |= (data >> 4) & 0x07;
 2098         }
 2099 
 2100         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2101         if (data == 0xff || data == 0x00) {
 2102                 INVALIDATE_SENSOR(n);
 2103         } else {
 2104                 sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
 2105                 sc->sensors[n].cur.data_us = 1350000 / (data << divisor);
 2106         }
 2107 }
 2108 
 2109 static void
 2110 wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n)
 2111 {
 2112         int reg, shift, data, divisor = 1;
 2113 
 2114         shift = 0;
 2115 
 2116         switch (sc->lm_sensors[n].reg) {
 2117         case 0x28:
 2118                 reg = 0x47; shift = 0;
 2119                 break;
 2120         case 0x29:
 2121                 reg = 0x47; shift = 4;
 2122                 break;
 2123         case 0x2a:
 2124                 reg = 0x5b; shift = 0;
 2125                 break;
 2126         case 0xb8:
 2127                 reg = 0x5b; shift = 4;
 2128                 break;
 2129         case 0xb9:
 2130                 reg = 0x5c; shift = 0;
 2131                 break;
 2132         case 0xba:
 2133                 reg = 0x5c; shift = 4;
 2134                 break;
 2135         case 0xbe:
 2136                 reg = 0x9e; shift = 0;
 2137                 break;
 2138         default:
 2139                 reg = 0;
 2140                 break;
 2141         }
 2142 
 2143         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2144         if (data == 0xff || data == 0x00) {
 2145                 INVALIDATE_SENSOR(n);
 2146         } else {
 2147                 if (reg != 0)
 2148                         divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7;
 2149                 sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
 2150                 sc->sensors[n].cur.data_us = 1350000 / (data << divisor);
 2151         }
 2152 }
 2153 
 2154 static void
 2155 as_refresh_temp(struct lm_softc *sc, int n)
 2156 {
 2157         int sdata;
 2158 
 2159         /*
 2160          * It seems a shorted temperature diode produces an all-ones
 2161          * bit pattern.
 2162          */
 2163         sdata = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
 2164         sdata += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
 2165         if (sdata == 0x1ff) {
 2166                 INVALIDATE_SENSOR(n);
 2167         } else {
 2168                 if (sdata & 0x100)
 2169                         sdata -= 0x200;
 2170                 sc->sensors[n].validflags |= (ENVSYS_FVALID|ENVSYS_FCURVALID);
 2171                 sc->sensors[n].cur.data_us = sdata * 500000 + 273150000;
 2172         }
 2173 }
 2174 
 2175 #undef INVALIDATE_SENSOR
 2176 
 2177 static int
 2178 lm_gtredata(struct sysmon_envsys *sme, envsys_tre_data_t *tred)
 2179 {
 2180         static const struct timeval onepointfive = { 1, 500000 };
 2181         struct timeval t, utv;
 2182         struct lm_softc *sc = sme->sme_cookie;
 2183 
 2184         /* read new values at most once every 1.5 seconds */
 2185         getmicrouptime(&utv);
 2186         timeradd(&sc->lastread, &onepointfive, &t);
 2187         if (timercmp(&utv, &t, >)) {
 2188                 sc->lastread = utv;
 2189                 sc->refresh_sensor_data(sc);
 2190         }
 2191 
 2192         *tred = sc->sensors[tred->sensor];
 2193 
 2194         return 0;
 2195 }
 2196 
 2197 static int
 2198 generic_streinfo_fan(struct lm_softc *sc, envsys_basic_info_t *info, int n,
 2199         envsys_basic_info_t *binfo)
 2200 {
 2201         uint8_t sdata;
 2202         int divisor;
 2203 
 2204         /* FAN1 and FAN2 can have divisors set, but not FAN3 */
 2205         if ((sc->info[binfo->sensor].units == ENVSYS_SFANRPM)
 2206             && (n < 2)) {
 2207                 if (binfo->rpms == 0) {
 2208                         binfo->validflags = 0;
 2209                         return 0;
 2210                 }
 2211 
 2212                 /* write back the nominal FAN speed  */
 2213                 info->rpms = binfo->rpms;
 2214 
 2215                 /* 153 is the nominal FAN speed value */
 2216                 divisor = 1350000 / (binfo->rpms * 153);
 2217 
 2218                 /* ...but we need lg(divisor) */
 2219                 if (divisor <= 1)
 2220                     divisor = 0;
 2221                 else if (divisor <= 2)
 2222                     divisor = 1;
 2223                 else if (divisor <= 4)
 2224                     divisor = 2;
 2225                 else
 2226                     divisor = 3;
 2227 
 2228                 /*
 2229                  * FAN1 div is in bits <5:4>, FAN2 div is
 2230                  * in <7:6>
 2231                  */
 2232                 sdata = (*sc->lm_readreg)(sc, LMD_VIDFAN);
 2233                 if ( n == 0 ) {  /* FAN1 */
 2234                     divisor <<= 4;
 2235                     sdata = (sdata & 0xCF) | divisor;
 2236                 } else { /* FAN2 */
 2237                     divisor <<= 6;
 2238                     sdata = (sdata & 0x3F) | divisor;
 2239                 }
 2240 
 2241                 (*sc->lm_writereg)(sc, LMD_VIDFAN, sdata);
 2242         }
 2243         return 0;
 2244 
 2245 }
 2246 
 2247 static int
 2248 lm_streinfo(struct sysmon_envsys *sme, envsys_basic_info_t *binfo)
 2249 {
 2250          struct lm_softc *sc = sme->sme_cookie;
 2251 
 2252          if (sc->info[binfo->sensor].units == ENVSYS_SVOLTS_DC)
 2253                   sc->info[binfo->sensor].rfact = binfo->rfact;
 2254          else {
 2255                 if (sc->info[binfo->sensor].units == ENVSYS_SFANRPM) {
 2256                         generic_streinfo_fan(sc, &sc->info[binfo->sensor],
 2257                             binfo->sensor - 8, binfo);
 2258                 }
 2259                 strlcpy(sc->info[binfo->sensor].desc, binfo->desc,
 2260                     sizeof(sc->info[binfo->sensor].desc));
 2261                 binfo->validflags = ENVSYS_FVALID;
 2262          }
 2263          return 0;
 2264 }
 2265 
 2266 static int
 2267 wb781_streinfo(struct sysmon_envsys *sme, envsys_basic_info_t *binfo)
 2268 {
 2269          struct lm_softc *sc = sme->sme_cookie;
 2270          int divisor;
 2271          uint8_t sdata;
 2272          int i;
 2273 
 2274          if (sc->info[binfo->sensor].units == ENVSYS_SVOLTS_DC)
 2275                   sc->info[binfo->sensor].rfact = binfo->rfact;
 2276          else {
 2277                 if (sc->info[binfo->sensor].units == ENVSYS_SFANRPM) {
 2278                         if (binfo->rpms == 0) {
 2279                                 binfo->validflags = 0;
 2280                                 return 0;
 2281                         }
 2282 
 2283                         /* write back the nominal FAN speed  */
 2284                         sc->info[binfo->sensor].rpms = binfo->rpms;
 2285 
 2286                         /* 153 is the nominal FAN speed value */
 2287                         divisor = 1350000 / (binfo->rpms * 153);
 2288 
 2289                         /* ...but we need lg(divisor) */
 2290                         for (i = 0; i < 7; i++) {
 2291                                 if (divisor <= (1 << i))
 2292                                         break;
 2293                         }
 2294                         divisor = i;
 2295 
 2296                         if (binfo->sensor == 10 || binfo->sensor == 11) {
 2297                                 /*
 2298                                  * FAN1 div is in bits <5:4>, FAN2 div
 2299                                  * is in <7:6>
 2300                                  */
 2301                                 sdata = (*sc->lm_readreg)(sc, LMD_VIDFAN);
 2302                                 if ( binfo->sensor == 10 ) {  /* FAN1 */
 2303                                          sdata = (sdata & 0xCF) |
 2304                                              ((divisor & 0x3) << 4);
 2305                                 } else { /* FAN2 */
 2306                                          sdata = (sdata & 0x3F) |
 2307                                              ((divisor & 0x3) << 6);
 2308                                 }
 2309                                 (*sc->lm_writereg)(sc, LMD_VIDFAN, sdata);
 2310                         } else {
 2311                                 /* FAN3 is in WB_PIN <7:6> */
 2312                                 sdata = (*sc->lm_readreg)(sc, WB_PIN);
 2313                                 sdata = (sdata & 0x3F) |
 2314                                      ((divisor & 0x3) << 6);
 2315                                 (*sc->lm_writereg)(sc, WB_PIN, sdata);
 2316                         }
 2317                 }
 2318                 strlcpy(sc->info[binfo->sensor].desc, binfo->desc,
 2319                     sizeof(sc->info[binfo->sensor].desc));
 2320                 binfo->validflags = ENVSYS_FVALID;
 2321          }
 2322          return 0;
 2323 }
 2324 
 2325 static int
 2326 wb782_streinfo(struct sysmon_envsys *sme, envsys_basic_info_t *binfo)
 2327 {
 2328          struct lm_softc *sc = sme->sme_cookie;
 2329          int divisor;
 2330          uint8_t sdata;
 2331          int i;
 2332 
 2333          if (sc->info[binfo->sensor].units == ENVSYS_SVOLTS_DC)
 2334                   sc->info[binfo->sensor].rfact = binfo->rfact;
 2335          else {
 2336                 if (sc->info[binfo->sensor].units == ENVSYS_SFANRPM) {
 2337                         if (binfo->rpms == 0) {
 2338                                 binfo->validflags = 0;
 2339                                 return 0;
 2340                         }
 2341 
 2342                         /* write back the nominal FAN speed  */
 2343                         sc->info[binfo->sensor].rpms = binfo->rpms;
 2344 
 2345                         /* 153 is the nominal FAN speed value */
 2346                         divisor = 1350000 / (binfo->rpms * 153);
 2347 
 2348                         /* ...but we need lg(divisor) */
 2349                         for (i = 0; i < 7; i++) {
 2350                                 if (divisor <= (1 << i))
 2351                                         break;
 2352                         }
 2353                         divisor = i;
 2354 
 2355                         if (binfo->sensor == 12 || binfo->sensor == 13) {
 2356                                 /*
 2357                                  * FAN1 div is in bits <5:4>, FAN2 div
 2358                                  * is in <7:6>
 2359                                  */
 2360                                 sdata = (*sc->lm_readreg)(sc, LMD_VIDFAN);
 2361                                 if ( binfo->sensor == 12 ) {  /* FAN1 */
 2362                                          sdata = (sdata & 0xCF) |
 2363                                              ((divisor & 0x3) << 4);
 2364                                 } else { /* FAN2 */
 2365                                          sdata = (sdata & 0x3F) |
 2366                                              ((divisor & 0x3) << 6);
 2367                                 }
 2368                                 (*sc->lm_writereg)(sc, LMD_VIDFAN, sdata);
 2369                         } else {
 2370                                 /* FAN3 is in WB_PIN <7:6> */
 2371                                 sdata = (*sc->lm_readreg)(sc, WB_PIN);
 2372                                 sdata = (sdata & 0x3F) |
 2373                                      ((divisor & 0x3) << 6);
 2374                                 (*sc->lm_writereg)(sc, WB_PIN, sdata);
 2375                         }
 2376                         /* Bit 2 of divisor is in WB_BANK0_VBAT */
 2377                         lm_generic_banksel(sc, WB_BANKSEL_B0);
 2378                         sdata = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
 2379                         sdata &= ~(0x20 << (binfo->sensor - 12));
 2380                         sdata |= (divisor & 0x4) << (binfo->sensor - 9);
 2381                         (*sc->lm_writereg)(sc, WB_BANK0_VBAT, sdata);
 2382                 }
 2383 
 2384                 strlcpy(sc->info[binfo->sensor].desc, binfo->desc,
 2385                     sizeof(sc->info[binfo->sensor].desc));
 2386                 binfo->validflags = ENVSYS_FVALID;
 2387         }
 2388         return 0;
 2389 }

Cache object: 8961fed60ebc3588db9b4c67fff9e1f1


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