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.79 2022/12/16 00:02:28 msaitoh 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  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.79 2022/12/16 00:02:28 msaitoh Exp $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/kernel.h>
   38 #include <sys/proc.h>
   39 #include <sys/device.h>
   40 #include <sys/module.h>
   41 #include <sys/conf.h>
   42 #include <sys/time.h>
   43 
   44 #include <sys/bus.h>
   45 
   46 #include <dev/isa/isareg.h>
   47 #include <dev/isa/isavar.h>
   48 #include <dev/isa/wbsioreg.h>
   49 
   50 #include <dev/sysmon/sysmonvar.h>
   51 
   52 #include <dev/ic/nslm7xvar.h>
   53 
   54 #include <sys/intr.h>
   55 
   56 #if defined(LMDEBUG)
   57 #define DPRINTF(x)      do { printf x; } while (0)
   58 #else
   59 #define DPRINTF(x)
   60 #endif
   61 
   62 /*
   63  * LM78-compatible chips can typically measure voltages up to 4.096 V.
   64  * To measure higher voltages the input is attenuated with (external)
   65  * resistors.  Negative voltages are measured using inverting op amps
   66  * and resistors.  So we have to convert the sensor values back to
   67  * real voltages by applying the appropriate resistor factor.
   68  */
   69 #define RFACT_NONE      10000
   70 #define RFACT(x, y)     (RFACT_NONE * ((x) + (y)) / (y))
   71 #define NRFACT(x, y)    (-RFACT_NONE * (x) / (y))
   72 
   73 #define LM_REFRESH_TIMO (2 * hz)        /* 2 seconds */
   74 
   75 static const struct wb_product *wb_lookup(struct lm_softc *,
   76     const struct wb_product *, uint16_t);
   77 static int wb_match(struct lm_softc *);
   78 static int wb_attach(struct lm_softc *);
   79 static int nslm_match(struct lm_softc *);
   80 static int nslm_attach(struct lm_softc *);
   81 static int def_match(struct lm_softc *);
   82 static int def_attach(struct lm_softc *);
   83 static void wb_temp_diode_type(struct lm_softc *, int);
   84 static uint16_t wb_read_vendorid(struct lm_softc *);
   85 
   86 static void lm_refresh(void *);
   87 
   88 static void lm_generic_banksel(struct lm_softc *, uint8_t);
   89 static void lm_setup_sensors(struct lm_softc *, const struct lm_sensor *);
   90 static void lm_refresh_sensor_data(struct lm_softc *);
   91 static void lm_refresh_volt(struct lm_softc *, int);
   92 static void lm_refresh_temp(struct lm_softc *, int);
   93 static void lm_refresh_fanrpm(struct lm_softc *, int);
   94 
   95 static void wb_refresh_sensor_data(struct lm_softc *);
   96 static void wb_w83637hf_refresh_vcore(struct lm_softc *, int);
   97 static void wb_refresh_nvolt(struct lm_softc *, int);
   98 static void wb_w83627ehf_refresh_nvolt(struct lm_softc *, int);
   99 static void wb_refresh_temp(struct lm_softc *, int);
  100 static void wb_refresh_fanrpm(struct lm_softc *, int);
  101 static void wb_w83792d_refresh_fanrpm(struct lm_softc *, int);
  102 static void wb_nct6776f_refresh_fanrpm(struct lm_softc *, int);
  103 
  104 static void as_refresh_temp(struct lm_softc *, int);
  105 
  106 struct lm_chip {
  107         int (*chip_match)(struct lm_softc *);
  108         int (*chip_attach)(struct lm_softc *);
  109 };
  110 
  111 static struct lm_chip lm_chips[] = {
  112         { wb_match,     wb_attach },
  113         { nslm_match,   nslm_attach },
  114         { def_match,    def_attach } /* Must be last */
  115 };
  116 
  117 /* LM78/78J/79/81 */
  118 static const struct lm_sensor lm78_sensors[] = {
  119         /* Voltage */
  120         {
  121                 .desc = "VCore A",
  122                 .type = ENVSYS_SVOLTS_DC,
  123                 .bank = 0,
  124                 .reg = 0x20,
  125                 .refresh = lm_refresh_volt,
  126                 .rfact = RFACT_NONE
  127         },
  128         {
  129                 .desc = "VCore B",
  130                 .type = ENVSYS_SVOLTS_DC,
  131                 .bank = 0,
  132                 .reg = 0x21,
  133                 .refresh = lm_refresh_volt,
  134                 .rfact = RFACT_NONE
  135         },
  136         {
  137                 .desc = "+3.3V",
  138                 .type = ENVSYS_SVOLTS_DC,
  139                 .bank = 0,
  140                 .reg = 0x22,
  141                 .refresh = lm_refresh_volt,
  142                 .rfact = RFACT_NONE
  143         },
  144         {
  145                 .desc = "+5V",
  146                 .type = ENVSYS_SVOLTS_DC,
  147                 .bank = 0,
  148                 .reg = 0x23,
  149                 .refresh = lm_refresh_volt,
  150                 .rfact = RFACT(68, 100)
  151         },
  152         {
  153                 .desc = "+12V",
  154                 .type = ENVSYS_SVOLTS_DC,
  155                 .bank = 0,
  156                 .reg = 0x24,
  157                 .refresh = lm_refresh_volt,
  158                 .rfact = RFACT(30, 10)
  159         },
  160         {
  161                 .desc = "-12V",
  162                 .type = ENVSYS_SVOLTS_DC,
  163                 .bank = 0,
  164                 .reg = 0x25,
  165                 .refresh = lm_refresh_volt,
  166                 .rfact = NRFACT(240, 60)
  167         },
  168         {
  169                 .desc = "-5V",
  170                 .type = ENVSYS_SVOLTS_DC,
  171                 .bank = 0,
  172                 .reg = 0x26,
  173                 .refresh = lm_refresh_volt,
  174                 .rfact = NRFACT(100, 60)
  175         },
  176         
  177         /* Temperature */
  178         {
  179                 .desc = "Temp0",
  180                 .type = ENVSYS_STEMP,
  181                 .bank = 0,
  182                 .reg = 0x27,
  183                 .refresh = lm_refresh_temp,
  184                 .rfact = 0
  185         },
  186 
  187         /* Fans */
  188         {
  189                 .desc = "Fan0",
  190                 .type = ENVSYS_SFANRPM,
  191                 .bank = 0,
  192                 .reg = 0x28,
  193                 .refresh = lm_refresh_fanrpm,
  194                 .rfact = 0
  195         },
  196         {
  197                 .desc = "Fan1",
  198                 .type = ENVSYS_SFANRPM,
  199                 .bank = 0,
  200                 .reg = 0x29,
  201                 .refresh = lm_refresh_fanrpm,
  202                 .rfact = 0
  203         },
  204         {
  205                 .desc = "Fan2",
  206                 .type = ENVSYS_SFANRPM,
  207                 .bank = 0,
  208                 .reg = 0x2a,
  209                 .refresh = lm_refresh_fanrpm,
  210                 .rfact = 0
  211         },
  212 
  213         { .desc = NULL }
  214 };
  215 
  216 /* W83627HF */
  217 static const struct lm_sensor w83627hf_sensors[] = {
  218         /* Voltage */
  219         {
  220                 .desc = "VCore A",
  221                 .type = ENVSYS_SVOLTS_DC,
  222                 .bank = 0,
  223                 .reg = 0x20,
  224                 .refresh = lm_refresh_volt,
  225                 .rfact = RFACT_NONE
  226         },
  227         {
  228                 .desc = "VCore B",
  229                 .type = ENVSYS_SVOLTS_DC,
  230                 .bank = 0,
  231                 .reg = 0x21,
  232                 .refresh = lm_refresh_volt,
  233                 .rfact = RFACT_NONE
  234         },
  235         {
  236                 .desc = "+3.3V",
  237                 .type = ENVSYS_SVOLTS_DC,
  238                 .bank = 0,
  239                 .reg = 0x22,
  240                 .refresh = lm_refresh_volt,
  241                 .rfact = RFACT_NONE
  242         },
  243         {
  244                 .desc = "+5V",
  245                 .type = ENVSYS_SVOLTS_DC,
  246                 .bank = 0,
  247                 .reg = 0x23,
  248                 .refresh = lm_refresh_volt,
  249                 .rfact = RFACT(34, 50)
  250         },
  251         {
  252                 .desc = "+12V",
  253                 .type = ENVSYS_SVOLTS_DC,
  254                 .bank = 0,
  255                 .reg = 0x24,
  256                 .refresh = lm_refresh_volt,
  257                 .rfact = RFACT(28, 10)
  258         },
  259         {
  260                 .desc = "-12V",
  261                 .type = ENVSYS_SVOLTS_DC,
  262                 .bank = 0,
  263                 .reg = 0x25,
  264                 .refresh = wb_refresh_nvolt,
  265                 .rfact = RFACT(232, 56)
  266         },
  267         {
  268                 .desc = "-5V",
  269                 .type = ENVSYS_SVOLTS_DC,
  270                 .bank = 0,
  271                 .reg = 0x26,
  272                 .refresh = wb_refresh_nvolt,
  273                 .rfact = RFACT(120, 56)
  274         },
  275         {
  276                 .desc = "5VSB",
  277                 .type = ENVSYS_SVOLTS_DC,
  278                 .bank = 5,
  279                 .reg = 0x50,
  280                 .refresh = lm_refresh_volt,
  281                 .rfact = RFACT(17, 33)
  282         },
  283         {
  284                 .desc = "VBAT",
  285                 .type = ENVSYS_SVOLTS_DC,
  286                 .bank = 5,
  287                 .reg = 0x51,
  288                 .refresh = lm_refresh_volt,
  289                 .rfact = RFACT_NONE
  290         },
  291 
  292         /* Temperature */
  293         {
  294                 .desc = "Temp0",
  295                 .type = ENVSYS_STEMP,
  296                 .bank = 0,
  297                 .reg = 0x27,
  298                 .refresh = lm_refresh_temp,
  299                 .rfact = 0
  300         },
  301         {
  302                 .desc = "Temp1",
  303                 .type = ENVSYS_STEMP,
  304                 .bank = 1,
  305                 .reg = 0x50,
  306                 .refresh = wb_refresh_temp,
  307                 .rfact = 0
  308         },
  309         {
  310                 .desc = "Temp2",
  311                 .type = ENVSYS_STEMP,
  312                 .bank = 2,
  313                 .reg = 0x50,
  314                 .refresh = wb_refresh_temp,
  315                 .rfact = 0
  316         },
  317 
  318         /* Fans */
  319         {
  320                 .desc = "Fan0",
  321                 .type = ENVSYS_SFANRPM,
  322                 .bank = 0,
  323                 .reg = 0x28,
  324                 .refresh = wb_refresh_fanrpm,
  325                 .rfact = 0
  326         },
  327         {
  328                 .desc = "Fan1",
  329                 .type = ENVSYS_SFANRPM,
  330                 .bank = 0,
  331                 .reg = 0x29,
  332                 .refresh = wb_refresh_fanrpm,
  333                 .rfact = 0
  334         },
  335         {
  336                 .desc = "Fan2",
  337                 .type = ENVSYS_SFANRPM,
  338                 .bank = 0,
  339                 .reg = 0x2a,
  340                 .refresh = wb_refresh_fanrpm,
  341                 .rfact = 0
  342         },
  343 
  344         { .desc = NULL }
  345 };
  346 
  347 /* W8627EHF */
  348 
  349 /*
  350  * The W83627EHF can measure voltages up to 2.048 V instead of the
  351  * traditional 4.096 V.  For measuring positive voltages, this can be
  352  * accounted for by halving the resistor factor.  Negative voltages
  353  * need special treatment, also because the reference voltage is 2.048 V
  354  * instead of the traditional 3.6 V.
  355  */
  356 static const struct lm_sensor w83627ehf_sensors[] = {
  357         /* Voltage */
  358         {
  359                 .desc = "VCore",
  360                 .type = ENVSYS_SVOLTS_DC,
  361                 .bank = 0,
  362                 .reg = 0x20,
  363                 .refresh = lm_refresh_volt,
  364                 .rfact = RFACT_NONE / 2
  365         },
  366         {
  367                 .desc = "+12V",
  368                 .type = ENVSYS_SVOLTS_DC,
  369                 .bank = 0,
  370                 .reg = 0x21,
  371                 .refresh = lm_refresh_volt,
  372                 .rfact = RFACT(56, 10) / 2
  373         },
  374         {
  375                 .desc = "+3.3V",
  376                 .type = ENVSYS_SVOLTS_DC,
  377                 .bank = 0,
  378                 .reg = 0x22,
  379                 .refresh = lm_refresh_volt,
  380                 .rfact = RFACT(34, 34) / 2
  381         },
  382         {
  383                 .desc = "VIN3",
  384                 .type = ENVSYS_SVOLTS_DC,
  385                 .bank = 0,
  386                 .reg = 0x23,
  387                 .refresh = lm_refresh_volt,
  388                 .rfact = RFACT(34, 34) / 2
  389         },
  390         {
  391                 .desc = "-12V",
  392                 .type = ENVSYS_SVOLTS_DC,
  393                 .bank = 0,
  394                 .reg = 0x24,
  395                 .refresh = wb_w83627ehf_refresh_nvolt,
  396                 .rfact = 0
  397         },
  398         {
  399                 .desc = "VIN5",
  400                 .type = ENVSYS_SVOLTS_DC,
  401                 .bank = 0,
  402                 .reg = 0x25,
  403                 .refresh = lm_refresh_volt,
  404                 .rfact = RFACT_NONE / 2
  405         },
  406         {
  407                 .desc = "VIN6",
  408                 .type = ENVSYS_SVOLTS_DC,
  409                 .bank = 0,
  410                 .reg = 0x26,
  411                 .refresh = lm_refresh_volt,
  412                 .rfact = RFACT_NONE / 2
  413         },
  414         {
  415                 .desc = "3.3VSB",
  416                 .type = ENVSYS_SVOLTS_DC,
  417                 .bank = 5,
  418                 .reg = 0x50,
  419                 .refresh = lm_refresh_volt,
  420                 .rfact = RFACT(34, 34) / 2
  421         },
  422         {
  423                 .desc = "VBAT",
  424                 .type = ENVSYS_SVOLTS_DC,
  425                 .bank = 5,
  426                 .reg = 0x51,
  427                 .refresh = lm_refresh_volt,
  428                 .rfact = RFACT_NONE / 2
  429         },
  430         {
  431                 .desc = "VIN8",
  432                 .type = ENVSYS_SVOLTS_DC,
  433                 .bank = 5,
  434                 .reg = 0x52,
  435                 .refresh = lm_refresh_volt,
  436                 .rfact = RFACT_NONE / 2
  437         },
  438 
  439         /* Temperature */
  440         {
  441                 .desc = "Temp0",
  442                 .type = ENVSYS_STEMP,
  443                 .bank = 0,
  444                 .reg = 0x27,
  445                 .refresh = lm_refresh_temp,
  446                 .rfact = 0
  447         },
  448         {
  449                 .desc = "Temp1",
  450                 .type = ENVSYS_STEMP,
  451                 .bank = 1,
  452                 .reg = 0x50,
  453                 .refresh = wb_refresh_temp,
  454                 .rfact = 0
  455         },
  456         {
  457                 .desc = "Temp2",
  458                 .type = ENVSYS_STEMP,
  459                 .bank = 2,
  460                 .reg = 0x50,
  461                 .refresh = wb_refresh_temp,
  462                 .rfact = 0
  463         },
  464 
  465         /* Fans */
  466         {
  467                 .desc = "Fan0",
  468                 .type = ENVSYS_SFANRPM,
  469                 .bank = 0,
  470                 .reg = 0x28,
  471                 .refresh = wb_refresh_fanrpm,
  472                 .rfact = 0
  473         },
  474         {
  475                 .desc = "Fan1",
  476                 .type = ENVSYS_SFANRPM,
  477                 .bank = 0,
  478                 .reg = 0x29,
  479                 .refresh = wb_refresh_fanrpm,
  480                 .rfact = 0
  481         },
  482         {
  483                 .desc = "Fan2",
  484                 .type = ENVSYS_SFANRPM,
  485                 .bank = 0,
  486                 .reg = 0x2a,
  487                 .refresh = wb_refresh_fanrpm,
  488                 .rfact = 0
  489         },
  490 
  491         { .desc = NULL }
  492 };
  493 
  494 /*  W83627DHG */
  495 static const struct lm_sensor w83627dhg_sensors[] = {
  496         /* Voltage */
  497         {
  498                 .desc = "VCore",
  499                 .type = ENVSYS_SVOLTS_DC,
  500                 .bank = 0,
  501                 .reg = 0x20,
  502                 .refresh = lm_refresh_volt,
  503                 .rfact = RFACT_NONE / 2
  504         },
  505         {
  506                 .desc = "+12V",
  507                 .type = ENVSYS_SVOLTS_DC,
  508                 .bank = 0,
  509                 .reg = 0x21,
  510                 .refresh = lm_refresh_volt,
  511                 .rfact = RFACT(56, 10) / 2
  512         },
  513         {
  514                 .desc = "AVCC",
  515                 .type = ENVSYS_SVOLTS_DC,
  516                 .bank = 0,
  517                 .reg = 0x22,
  518                 .refresh = lm_refresh_volt,
  519                 .rfact = RFACT(34, 34) / 2
  520         },
  521         {
  522                 .desc = "+3.3V",
  523                 .type = ENVSYS_SVOLTS_DC,
  524                 .bank = 0,
  525                 .reg = 0x23,
  526                 .refresh = lm_refresh_volt,
  527                 .rfact = RFACT(34, 34) / 2
  528         },
  529         {
  530                 .desc = "-12V",
  531                 .type = ENVSYS_SVOLTS_DC,
  532                 .bank = 0,
  533                 .reg = 0x24,
  534                 .refresh = wb_w83627ehf_refresh_nvolt,
  535                 .rfact = 0
  536         },
  537         {
  538                 .desc = "+5V",
  539                 .type = ENVSYS_SVOLTS_DC,
  540                 .bank = 0,
  541                 .reg = 0x25,
  542                 .refresh = lm_refresh_volt,
  543                 .rfact = 16000
  544         },
  545         {
  546                 .desc = "VIN3",
  547                 .type = ENVSYS_SVOLTS_DC,
  548                 .bank = 0,
  549                 .reg = 0x26,
  550                 .refresh = lm_refresh_volt,
  551                 .rfact = RFACT_NONE
  552         },
  553         {
  554                 .desc = "+3.3VSB",
  555                 .type = ENVSYS_SVOLTS_DC,
  556                 .bank = 5,
  557                 .reg = 0x50,
  558                 .refresh = lm_refresh_volt,
  559                 .rfact = RFACT(34, 34) / 2
  560         },
  561         {
  562                 .desc = "VBAT",
  563                 .type = ENVSYS_SVOLTS_DC,
  564                 .bank = 5,
  565                 .reg = 0x51,
  566                 .refresh = lm_refresh_volt,
  567                 .rfact = RFACT(34, 34) / 2
  568         },
  569 
  570         /* Temperature */
  571         {
  572                 .desc = "MB Temperature",
  573                 .type = ENVSYS_STEMP,
  574                 .bank = 0,
  575                 .reg = 0x27,
  576                 .refresh = lm_refresh_temp,
  577                 .rfact = 0
  578         },
  579         {
  580                 .desc = "CPU Temperature",
  581                 .type = ENVSYS_STEMP,
  582                 .bank = 1,
  583                 .reg = 0x50,
  584                 .refresh = lm_refresh_temp,
  585                 .rfact = 0
  586         },
  587         {
  588                 .desc = "Aux Temp",
  589                 .type = ENVSYS_STEMP,
  590                 .bank = 2,
  591                 .reg = 0x50,
  592                 .refresh = lm_refresh_temp,
  593                 .rfact = 0
  594         },
  595 
  596         /* Fans */
  597         {
  598                 .desc = "System Fan",
  599                 .type = ENVSYS_SFANRPM,
  600                 .bank = 0,
  601                 .reg = 0x28,
  602                 .refresh = wb_refresh_fanrpm,
  603                 .rfact = 0
  604         },
  605         {
  606                 .desc = "CPU Fan",
  607                 .type = ENVSYS_SFANRPM,
  608                 .bank = 0,
  609                 .reg = 0x29,
  610                 .refresh = wb_refresh_fanrpm,
  611                 .rfact = 0
  612         },
  613         {
  614                 .desc = "Aux Fan",
  615                 .type = ENVSYS_SFANRPM,
  616                 .bank = 0,
  617                 .reg = 0x2a,
  618                 .refresh = wb_refresh_fanrpm,
  619                 .rfact = 0
  620         },
  621 
  622         { .desc = NULL }
  623 };
  624 
  625 /* W83637HF */
  626 static const struct lm_sensor w83637hf_sensors[] = {
  627         /* Voltage */
  628         {
  629                 .desc = "VCore",
  630                 .type = ENVSYS_SVOLTS_DC,
  631                 .bank = 0,
  632                 .reg = 0x20,
  633                 .refresh = wb_w83637hf_refresh_vcore,
  634                 .rfact = 0
  635         },
  636         {
  637                 .desc = "+12V",
  638                 .type = ENVSYS_SVOLTS_DC,
  639                 .bank = 0,
  640                 .reg = 0x21,
  641                 .refresh = lm_refresh_volt,
  642                 .rfact = RFACT(28, 10)
  643         },
  644         {
  645                 .desc = "+3.3V",
  646                 .type = ENVSYS_SVOLTS_DC,
  647                 .bank = 0,
  648                 .reg = 0x22,
  649                 .refresh = lm_refresh_volt,
  650                 .rfact = RFACT_NONE
  651         },
  652         {
  653                 .desc = "+5V",
  654                 .type = ENVSYS_SVOLTS_DC,
  655                 .bank = 0,
  656                 .reg = 0x23,
  657                 .refresh = lm_refresh_volt,
  658                 .rfact = RFACT(34, 51)
  659         },
  660         {
  661                 .desc = "-12V",
  662                 .type = ENVSYS_SVOLTS_DC,
  663                 .bank = 0,
  664                 .reg = 0x24,
  665                 .refresh = wb_refresh_nvolt,
  666                 .rfact = RFACT(232, 56)
  667         },
  668         {
  669                 .desc = "5VSB",
  670                 .type = ENVSYS_SVOLTS_DC,
  671                 .bank = 5,
  672                 .reg = 0x50,
  673                 .refresh = lm_refresh_volt,
  674                 .rfact = RFACT(34, 51)
  675         },
  676         {
  677                 .desc = "VBAT",
  678                 .type = ENVSYS_SVOLTS_DC,
  679                 .bank = 5,
  680                 .reg = 0x51,
  681                 .refresh = lm_refresh_volt,
  682                 .rfact = RFACT_NONE
  683         },
  684 
  685         /* Temperature */
  686         {
  687                 .desc = "Temp0",
  688                 .type = ENVSYS_STEMP,
  689                 .bank = 0,
  690                 .reg = 0x27,
  691                 .refresh = lm_refresh_temp,
  692                 .rfact = 0
  693         },
  694         {
  695                 .desc = "Temp1",
  696                 .type = ENVSYS_STEMP,
  697                 .bank = 1,
  698                 .reg = 0x50,
  699                 .refresh = wb_refresh_temp,
  700                 .rfact = 0
  701         },
  702         {
  703                 .desc = "Temp2",
  704                 .type = ENVSYS_STEMP,
  705                 .bank = 2,
  706                 .reg = 0x50,
  707                 .refresh = wb_refresh_temp,
  708                 .rfact = 0
  709         },
  710 
  711         /* Fans */
  712         {
  713                 .desc = "Fan0",
  714                 .type = ENVSYS_SFANRPM,
  715                 .bank = 0,
  716                 .reg = 0x28,
  717                 .refresh = wb_refresh_fanrpm,
  718                 .rfact = 0
  719         },
  720         {
  721                 .desc = "Fan1",
  722                 .type = ENVSYS_SFANRPM,
  723                 .bank = 0,
  724                 .reg = 0x29,
  725                 .refresh = wb_refresh_fanrpm,
  726                 .rfact = 0
  727         },
  728         {
  729                 .desc = "Fan2",
  730                 .type = ENVSYS_SFANRPM,
  731                 .bank = 0,
  732                 .reg = 0x2a,
  733                 .refresh = wb_refresh_fanrpm,
  734                 .rfact = 0
  735         },
  736 
  737         { .desc = NULL }
  738 };
  739 
  740 /* W83697HF */
  741 static const struct lm_sensor w83697hf_sensors[] = {
  742         /* Voltage */
  743         {
  744                 .desc = "VCore",
  745                 .type = ENVSYS_SVOLTS_DC,
  746                 .bank = 0,
  747                 .reg = 0x20,
  748                 .refresh = lm_refresh_volt,
  749                 .rfact = RFACT_NONE
  750         },
  751         {
  752                 .desc = "+3.3V",
  753                 .type = ENVSYS_SVOLTS_DC,
  754                 .bank = 0,
  755                 .reg = 0x22,
  756                 .refresh = lm_refresh_volt,
  757                 .rfact = RFACT_NONE
  758         },
  759         {
  760                 .desc = "+5V",
  761                 .type = ENVSYS_SVOLTS_DC,
  762                 .bank = 0,
  763                 .reg = 0x23,
  764                 .refresh = lm_refresh_volt,
  765                 .rfact = RFACT(34, 50)
  766         },
  767         {
  768                 .desc = "+12V",
  769                 .type = ENVSYS_SVOLTS_DC,
  770                 .bank = 0,
  771                 .reg = 0x24,
  772                 .refresh = lm_refresh_volt,
  773                 .rfact = RFACT(28, 10)
  774         },
  775         {
  776                 .desc = "-12V",
  777                 .type = ENVSYS_SVOLTS_DC,
  778                 .bank = 0,
  779                 .reg = 0x25,
  780                 .refresh = wb_refresh_nvolt,
  781                 .rfact = RFACT(232, 56)
  782         },
  783         {
  784                 .desc = "-5V",
  785                 .type = ENVSYS_SVOLTS_DC,
  786                 .bank = 0,
  787                 .reg = 0x26,
  788                 .refresh = wb_refresh_nvolt,
  789                 .rfact = RFACT(120, 56)
  790         },
  791         {
  792                 .desc = "5VSB",
  793                 .type = ENVSYS_SVOLTS_DC,
  794                 .bank = 5,
  795                 .reg = 0x50,
  796                 .refresh = lm_refresh_volt,
  797                 .rfact = RFACT(17, 33)
  798         },
  799         {
  800                 .desc = "VBAT",
  801                 .type = ENVSYS_SVOLTS_DC,
  802                 .bank = 5,
  803                 .reg = 0x51,
  804                 .refresh = lm_refresh_volt,
  805                 .rfact = RFACT_NONE
  806         },
  807 
  808         /* Temperature */
  809         {
  810                 .desc = "Temp0",
  811                 .type = ENVSYS_STEMP,
  812                 .bank = 0,
  813                 .reg = 0x27,
  814                 .refresh = lm_refresh_temp,
  815                 .rfact = 0
  816         },
  817         {
  818                 .desc = "Temp1",
  819                 .type = ENVSYS_STEMP,
  820                 .bank = 1,
  821                 .reg = 0x50,
  822                 .refresh = wb_refresh_temp,
  823                 .rfact = 0
  824         },
  825 
  826         /* Fans */
  827         {
  828                 .desc = "Fan0",
  829                 .type = ENVSYS_SFANRPM,
  830                 .bank = 0,
  831                 .reg = 0x28,
  832                 .refresh = wb_refresh_fanrpm,
  833                 .rfact = 0
  834         },
  835         {
  836                 .desc = "Fan1",
  837                 .type = ENVSYS_SFANRPM,
  838                 .bank = 0,
  839                 .reg = 0x29,
  840                 .refresh = wb_refresh_fanrpm,
  841                 .rfact = 0
  842         },
  843 
  844         { .desc = NULL }
  845 };
  846 
  847 /* W83781D */
  848 
  849 /*
  850  * The datasheet doesn't mention the (internal) resistors used for the
  851  * +5V, but using the values from the W83782D datasheets seems to
  852  * provide sensible results.
  853  */
  854 static const struct lm_sensor w83781d_sensors[] = {
  855         /* Voltage */
  856         {
  857                 .desc = "VCore A",
  858                 .type = ENVSYS_SVOLTS_DC,
  859                 .bank = 0,
  860                 .reg = 0x20,
  861                 .refresh = lm_refresh_volt,
  862                 .rfact = RFACT_NONE
  863         },
  864         {
  865                 .desc = "VCore B",
  866                 .type = ENVSYS_SVOLTS_DC,
  867                 .bank = 0,
  868                 .reg = 0x21,
  869                 .refresh = lm_refresh_volt,
  870                 .rfact = RFACT_NONE
  871         },
  872         {
  873                 .desc = "+3.3V",
  874                 .type = ENVSYS_SVOLTS_DC,
  875                 .bank = 0,
  876                 .reg = 0x22,
  877                 .refresh = lm_refresh_volt,
  878                 .rfact = RFACT_NONE
  879         },
  880         {
  881                 .desc = "+5V",
  882                 .type = ENVSYS_SVOLTS_DC,
  883                 .bank = 0,
  884                 .reg = 0x23,
  885                 .refresh = lm_refresh_volt,
  886                 .rfact = RFACT(34, 50)
  887         },
  888         {
  889                 .desc = "+12V",
  890                 .type = ENVSYS_SVOLTS_DC,
  891                 .bank = 0,
  892                 .reg = 0x24,
  893                 .refresh = lm_refresh_volt,
  894                 .rfact = RFACT(28, 10)
  895         },
  896         {
  897                 .desc = "-12V",
  898                 .type = ENVSYS_SVOLTS_DC,
  899                 .bank = 0,
  900                 .reg = 0x25,
  901                 .refresh = lm_refresh_volt,
  902                 .rfact = NRFACT(2100, 604)
  903         },
  904         {
  905                 .desc = "-5V",
  906                 .type = ENVSYS_SVOLTS_DC,
  907                 .bank = 0,
  908                 .reg = 0x26,
  909                 .refresh = lm_refresh_volt,
  910                 .rfact = NRFACT(909, 604)
  911         },
  912 
  913         /* Temperature */
  914         {
  915                 .desc = "Temp0",
  916                 .type = ENVSYS_STEMP,
  917                 .bank = 0,
  918                 .reg = 0x27,
  919                 .refresh = lm_refresh_temp,
  920                 .rfact = 0
  921         },
  922         {
  923                 .desc = "Temp1",
  924                 .type = ENVSYS_STEMP,
  925                 .bank = 1,
  926                 .reg = 0x50,
  927                 .refresh = wb_refresh_temp,
  928                 .rfact = 0
  929         },
  930         {
  931                 .desc = "Temp2",
  932                 .type = ENVSYS_STEMP,
  933                 .bank = 2,
  934                 .reg = 0x50,
  935                 .refresh = wb_refresh_temp,
  936                 .rfact = 0
  937         },
  938 
  939         /* Fans */
  940         {
  941                 .desc = "Fan0",
  942                 .type = ENVSYS_SFANRPM,
  943                 .bank = 0,
  944                 .reg = 0x28,
  945                 .refresh = lm_refresh_fanrpm,
  946                 .rfact = 0
  947         },
  948         {
  949                 .desc = "Fan1",
  950                 .type = ENVSYS_SFANRPM,
  951                 .bank = 0,
  952                 .reg = 0x29,
  953                 .refresh = lm_refresh_fanrpm,
  954                 .rfact = 0
  955         },
  956         {
  957                 .desc = "Fan2",
  958                 .type = ENVSYS_SFANRPM,
  959                 .bank = 0,
  960                 .reg = 0x2a,
  961                 .refresh = lm_refresh_fanrpm,
  962                 .rfact = 0
  963         },
  964 
  965         { .desc = NULL }
  966 };
  967 
  968 /* W83782D */
  969 static const struct lm_sensor w83782d_sensors[] = {
  970         /* Voltage */
  971         {
  972                 .desc = "VCore",
  973                 .type = ENVSYS_SVOLTS_DC,
  974                 .bank = 0,
  975                 .reg = 0x20,
  976                 .refresh = lm_refresh_volt,
  977                 .rfact = RFACT_NONE
  978         },
  979         {
  980                 .desc = "VINR0",
  981                 .type = ENVSYS_SVOLTS_DC,
  982                 .bank = 0,
  983                 .reg = 0x21,
  984                 .refresh = lm_refresh_volt,
  985                 .rfact = RFACT_NONE
  986         },
  987         {
  988                 .desc = "+3.3V",
  989                 .type = ENVSYS_SVOLTS_DC,
  990                 .bank = 0,
  991                 .reg = 0x22,
  992                 .refresh = lm_refresh_volt,
  993                 .rfact = RFACT_NONE
  994         },
  995         {
  996                 .desc = "+5V",
  997                 .type = ENVSYS_SVOLTS_DC,
  998                 .bank = 0,
  999                 .reg = 0x23,
 1000                 .refresh = lm_refresh_volt,
 1001                 .rfact = RFACT(34, 50)
 1002         },
 1003         {
 1004                 .desc = "+12V",
 1005                 .type = ENVSYS_SVOLTS_DC,
 1006                 .bank = 0,
 1007                 .reg = 0x24,
 1008                 .refresh = lm_refresh_volt,
 1009                 .rfact = RFACT(28, 10)
 1010         },
 1011         {
 1012                 .desc = "-12V",
 1013                 .type = ENVSYS_SVOLTS_DC,
 1014                 .bank = 0,
 1015                 .reg = 0x25,
 1016                 .refresh = wb_refresh_nvolt,
 1017                 .rfact = RFACT(232, 56)
 1018         },
 1019         {
 1020                 .desc = "-5V",
 1021                 .type = ENVSYS_SVOLTS_DC,
 1022                 .bank = 0,
 1023                 .reg = 0x26,
 1024                 .refresh = wb_refresh_nvolt,
 1025                 .rfact = RFACT(120, 56)
 1026         },
 1027         {
 1028                 .desc = "5VSB",
 1029                 .type = ENVSYS_SVOLTS_DC,
 1030                 .bank = 5,
 1031                 .reg = 0x50,
 1032                 .refresh = lm_refresh_volt,
 1033                 .rfact = RFACT(17, 33)
 1034         },
 1035         {
 1036                 .desc = "VBAT",
 1037                 .type = ENVSYS_SVOLTS_DC,
 1038                 .bank = 5,
 1039                 .reg = 0x51,
 1040                 .refresh = lm_refresh_volt,
 1041                 .rfact = RFACT_NONE
 1042         },
 1043 
 1044         /* Temperature */
 1045         {
 1046                 .desc = "Temp0",
 1047                 .type = ENVSYS_STEMP,
 1048                 .bank = 0,
 1049                 .reg = 0x27,
 1050                 .refresh = lm_refresh_temp,
 1051                 .rfact = 0
 1052         },
 1053         {
 1054                 .desc = "Temp1",
 1055                 .type = ENVSYS_STEMP,
 1056                 .bank = 1,
 1057                 .reg = 0x50,
 1058                 .refresh = wb_refresh_temp,
 1059                 .rfact = 0
 1060         },
 1061         {
 1062                 .desc = "Temp2",
 1063                 .type = ENVSYS_STEMP,
 1064                 .bank = 2,
 1065                 .reg = 0x50,
 1066                 .refresh = wb_refresh_temp,
 1067                 .rfact = 0
 1068         },
 1069 
 1070         /* Fans */
 1071         {
 1072                 .desc = "Fan0",
 1073                 .type = ENVSYS_SFANRPM,
 1074                 .bank = 0,
 1075                 .reg = 0x28,
 1076                 .refresh = wb_refresh_fanrpm,
 1077                 .rfact = 0
 1078         },
 1079         {
 1080                 .desc = "Fan1",
 1081                 .type = ENVSYS_SFANRPM,
 1082                 .bank = 0,
 1083                 .reg = 0x29,
 1084                 .refresh = wb_refresh_fanrpm,
 1085                 .rfact = 0
 1086         },
 1087         {
 1088                 .desc = "Fan2",
 1089                 .type = ENVSYS_SFANRPM,
 1090                 .bank = 0,
 1091                 .reg = 0x2a,
 1092                 .refresh = wb_refresh_fanrpm,
 1093                 .rfact = 0
 1094         },
 1095 
 1096         { .desc = NULL }
 1097 };
 1098 
 1099 /* W83783S */
 1100 static const struct lm_sensor w83783s_sensors[] = {
 1101         /* Voltage */
 1102         {
 1103                 .desc = "VCore",
 1104                 .type = ENVSYS_SVOLTS_DC,
 1105                 .bank = 0,
 1106                 .reg = 0x20,
 1107                 .refresh = lm_refresh_volt,
 1108                 .rfact = RFACT_NONE
 1109         },
 1110         {
 1111                 .desc = "+3.3V",
 1112                 .type = ENVSYS_SVOLTS_DC,
 1113                 .bank = 0,
 1114                 .reg = 0x22,
 1115                 .refresh = lm_refresh_volt,
 1116                 .rfact = RFACT_NONE
 1117         },
 1118         {
 1119                 .desc = "+5V",
 1120                 .type = ENVSYS_SVOLTS_DC,
 1121                 .bank = 0,
 1122                 .reg = 0x23,
 1123                 .refresh = lm_refresh_volt,
 1124                 .rfact = RFACT(34, 50)
 1125         },
 1126         {
 1127                 .desc = "+12V",
 1128                 .type = ENVSYS_SVOLTS_DC,
 1129                 .bank = 0,
 1130                 .reg = 0x24,
 1131                 .refresh = lm_refresh_volt,
 1132                 .rfact = RFACT(28, 10)
 1133         },
 1134         {
 1135                 .desc = "-12V",
 1136                 .type = ENVSYS_SVOLTS_DC,
 1137                 .bank = 0,
 1138                 .reg = 0x25,
 1139                 .refresh = wb_refresh_nvolt,
 1140                 .rfact = RFACT(232, 56)
 1141         },
 1142         {
 1143                 .desc = "-5V",
 1144                 .type = ENVSYS_SVOLTS_DC,
 1145                 .bank = 0,
 1146                 .reg = 0x26,
 1147                 .refresh = wb_refresh_nvolt,
 1148                 .rfact = RFACT(120, 56)
 1149         },
 1150 
 1151         /* Temperature */
 1152         {
 1153                 .desc = "Temp0",
 1154                 .type = ENVSYS_STEMP,
 1155                 .bank = 0,
 1156                 .reg = 0x27,
 1157                 .refresh = lm_refresh_temp,
 1158                 .rfact = 0
 1159         },
 1160         {
 1161                 .desc = "Temp1",
 1162                 .type = ENVSYS_STEMP,
 1163                 .bank = 1,
 1164                 .reg = 0x50,
 1165                 .refresh = wb_refresh_temp,
 1166                 .rfact = 0
 1167         },
 1168 
 1169         /* Fans */
 1170         {
 1171                 .desc = "Fan0",
 1172                 .type = ENVSYS_SFANRPM,
 1173                 .bank = 0,
 1174                 .reg = 0x28,
 1175                 .refresh = wb_refresh_fanrpm,
 1176                 .rfact = 0
 1177         },
 1178         {
 1179                 .desc = "Fan1",
 1180                 .type = ENVSYS_SFANRPM,
 1181                 .bank = 0,
 1182                 .reg = 0x29,
 1183                 .refresh = wb_refresh_fanrpm,
 1184                 .rfact = 0
 1185         },
 1186         {
 1187                 .desc = "Fan2",
 1188                 .type = ENVSYS_SFANRPM,
 1189                 .bank = 0,
 1190                 .reg = 0x2a,
 1191                 .refresh = wb_refresh_fanrpm,
 1192                 .rfact = 0
 1193         },
 1194 
 1195         { .desc = NULL }
 1196 };
 1197 
 1198 /* W83791D */
 1199 static const struct lm_sensor w83791d_sensors[] = {
 1200         /* Voltage */
 1201         {
 1202                 .desc = "VCore",
 1203                 .type = ENVSYS_SVOLTS_DC,
 1204                 .bank = 0,
 1205                 .reg = 0x20,
 1206                 .refresh = lm_refresh_volt,
 1207                 .rfact = 10000
 1208         },
 1209         {
 1210                 .desc = "VINR0",
 1211                 .type = ENVSYS_SVOLTS_DC,
 1212                 .bank = 0,
 1213                 .reg = 0x21,
 1214                 .refresh = lm_refresh_volt,
 1215                 .rfact = 10000
 1216         },
 1217         {
 1218                 .desc = "+3.3V",
 1219                 .type = ENVSYS_SVOLTS_DC,
 1220                 .bank = 0,
 1221                 .reg = 0x22,
 1222                 .refresh = lm_refresh_volt,
 1223                 .rfact = 10000
 1224         },
 1225         {
 1226                 .desc = "+5V",
 1227                 .type = ENVSYS_SVOLTS_DC,
 1228                 .bank = 0,
 1229                 .reg = 0x23,
 1230                 .refresh = lm_refresh_volt,
 1231                 .rfact = RFACT(34, 50)
 1232         },
 1233         {
 1234                 .desc = "+12V",
 1235                 .type = ENVSYS_SVOLTS_DC,
 1236                 .bank = 0,
 1237                 .reg = 0x24,
 1238                 .refresh = lm_refresh_volt,
 1239                 .rfact = RFACT(28, 10)
 1240         },
 1241         {
 1242                 .desc = "-12V",
 1243                 .type = ENVSYS_SVOLTS_DC,
 1244                 .bank = 0,
 1245                 .reg = 0x25,
 1246                 .refresh = wb_refresh_nvolt,
 1247                 .rfact = RFACT(232, 56)
 1248         },
 1249         {
 1250                 .desc = "-5V",
 1251                 .type = ENVSYS_SVOLTS_DC,
 1252                 .bank = 0,
 1253                 .reg = 0x26,
 1254                 .refresh = wb_refresh_nvolt,
 1255                 .rfact = RFACT(120, 56)
 1256         },
 1257         {
 1258                 .desc = "5VSB",
 1259                 .type = ENVSYS_SVOLTS_DC,
 1260                 .bank = 0,
 1261                 .reg = 0xb0,
 1262                 .refresh = lm_refresh_volt,
 1263                 .rfact = RFACT(17, 33)
 1264         },
 1265         {
 1266                 .desc = "VBAT",
 1267                 .type = ENVSYS_SVOLTS_DC,
 1268                 .bank = 0,
 1269                 .reg = 0xb1,
 1270                 .refresh = lm_refresh_volt,
 1271                 .rfact = RFACT_NONE
 1272         },
 1273         {
 1274                 .desc = "VINR1",
 1275                 .type = ENVSYS_SVOLTS_DC,
 1276                 .bank = 0,
 1277                 .reg = 0xb2,
 1278                 .refresh = lm_refresh_volt,
 1279                 .rfact = RFACT_NONE
 1280         },
 1281 
 1282         /* Temperature */
 1283         {
 1284                 .desc = "Temp0",
 1285                 .type = ENVSYS_STEMP,
 1286                 .bank = 0,
 1287                 .reg = 0x27,
 1288                 .refresh = lm_refresh_temp,
 1289                 .rfact = 0
 1290         },
 1291         {
 1292                 .desc = "Temp1",
 1293                 .type = ENVSYS_STEMP,
 1294                 .bank = 0,
 1295                 .reg = 0xc0,
 1296                 .refresh = wb_refresh_temp,
 1297                 .rfact = 0
 1298         },
 1299         {
 1300                 .desc = "Temp2",
 1301                 .type = ENVSYS_STEMP,
 1302                 .bank = 0,
 1303                 .reg = 0xc8,
 1304                 .refresh = wb_refresh_temp,
 1305                 .rfact = 0
 1306         },
 1307 
 1308         /* Fans */
 1309         {
 1310                 .desc = "Fan0",
 1311                 .type = ENVSYS_SFANRPM,
 1312                 .bank = 0,
 1313                 .reg = 0x28,
 1314                 .refresh = wb_refresh_fanrpm,
 1315                 .rfact = 0
 1316         },
 1317         {
 1318                 .desc = "Fan1",
 1319                 .type = ENVSYS_SFANRPM,
 1320                 .bank = 0,
 1321                 .reg = 0x29,
 1322                 .refresh = wb_refresh_fanrpm,
 1323                 .rfact = 0
 1324         },
 1325         {
 1326                 .desc = "Fan2",
 1327                 .type = ENVSYS_SFANRPM,
 1328                 .bank = 0,
 1329                 .reg = 0x2a,
 1330                 .refresh = wb_refresh_fanrpm,
 1331                 .rfact = 0
 1332         },
 1333         {
 1334                 .desc = "Fan3",
 1335                 .type = ENVSYS_SFANRPM,
 1336                 .bank = 0,
 1337                 .reg = 0xba,
 1338                 .refresh = wb_refresh_fanrpm,
 1339                 .rfact = 0
 1340         },
 1341         {
 1342                 .desc = "Fan4",
 1343                 .type = ENVSYS_SFANRPM,
 1344                 .bank = 0,
 1345                 .reg = 0xbb,
 1346                 .refresh = wb_refresh_fanrpm,
 1347                 .rfact = 0
 1348         },
 1349 
 1350         { .desc = NULL }
 1351 };
 1352 
 1353 /* W83792D */
 1354 static const struct lm_sensor w83792d_sensors[] = {
 1355         /* Voltage */
 1356         {
 1357                 .desc = "VCore A",
 1358                 .type = ENVSYS_SVOLTS_DC,
 1359                 .bank = 0,
 1360                 .reg = 0x20,
 1361                 .refresh = lm_refresh_volt,
 1362                 .rfact = RFACT_NONE
 1363         },
 1364         {
 1365                 .desc = "VCore B",
 1366                 .type = ENVSYS_SVOLTS_DC,
 1367                 .bank = 0,
 1368                 .reg = 0x21,
 1369                 .refresh = lm_refresh_volt,
 1370                 .rfact = RFACT_NONE
 1371         },
 1372         {
 1373                 .desc = "+3.3V",
 1374                 .type = ENVSYS_SVOLTS_DC,
 1375                 .bank = 0,
 1376                 .reg = 0x22,
 1377                 .refresh = lm_refresh_volt,
 1378                 .rfact = RFACT_NONE
 1379         },
 1380         {
 1381                 .desc = "-5V",
 1382                 .type = ENVSYS_SVOLTS_DC,
 1383                 .bank = 0,
 1384                 .reg = 0x23,
 1385                 .refresh = wb_refresh_nvolt,
 1386                 .rfact = RFACT(120, 56)
 1387         },
 1388         {
 1389                 .desc = "+12V",
 1390                 .type = ENVSYS_SVOLTS_DC,
 1391                 .bank = 0,
 1392                 .reg = 0x24,
 1393                 .refresh = lm_refresh_volt,
 1394                 .rfact = RFACT(28, 10)
 1395         },
 1396         {
 1397                 .desc = "-12V",
 1398                 .type = ENVSYS_SVOLTS_DC,
 1399                 .bank = 0,
 1400                 .reg = 0x25,
 1401                 .refresh = wb_refresh_nvolt,
 1402                 .rfact = RFACT(232, 56)
 1403         },
 1404         {
 1405                 .desc = "+5V",
 1406                 .type = ENVSYS_SVOLTS_DC,
 1407                 .bank = 0,
 1408                 .reg = 0x26,
 1409                 .refresh = lm_refresh_volt,
 1410                 .rfact = RFACT(34, 50)
 1411         },
 1412         {
 1413                 .desc = "5VSB",
 1414                 .type = ENVSYS_SVOLTS_DC,
 1415                 .bank = 0,
 1416                 .reg = 0xb0,
 1417                 .refresh = lm_refresh_volt,
 1418                 .rfact = RFACT(17, 33)
 1419         },
 1420         {
 1421                 .desc = "VBAT",
 1422                 .type = ENVSYS_SVOLTS_DC,
 1423                 .bank = 0,
 1424                 .reg = 0xb1,
 1425                 .refresh = lm_refresh_volt,
 1426                 .rfact = RFACT_NONE
 1427         },
 1428 
 1429         /* Temperature */
 1430         {
 1431                 .desc = "Temp0",
 1432                 .type = ENVSYS_STEMP,
 1433                 .bank = 0,
 1434                 .reg = 0x27,
 1435                 .refresh = lm_refresh_temp,
 1436                 .rfact = 0
 1437         },
 1438         {
 1439                 .desc = "Temp1",
 1440                 .type = ENVSYS_STEMP,
 1441                 .bank = 0,
 1442                 .reg = 0xc0,
 1443                 .refresh = wb_refresh_temp,
 1444                 .rfact = 0
 1445         },
 1446         {
 1447                 .desc = "Temp2",
 1448                 .type = ENVSYS_STEMP,
 1449                 .bank = 0,
 1450                 .reg = 0xc8,
 1451                 .refresh = wb_refresh_temp,
 1452                 .rfact = 0
 1453         },
 1454 
 1455         /* Fans */
 1456         {
 1457                 .desc = "Fan0",
 1458                 .type = ENVSYS_SFANRPM,
 1459                 .bank = 0,
 1460                 .reg = 0x28,
 1461                 .refresh = wb_w83792d_refresh_fanrpm,
 1462                 .rfact = 0
 1463         },
 1464         {
 1465                 .desc = "Fan1",
 1466                 .type = ENVSYS_SFANRPM,
 1467                 .bank = 0,
 1468                 .reg = 0x29,
 1469                 .refresh = wb_w83792d_refresh_fanrpm,
 1470                 .rfact = 0
 1471         },
 1472         {
 1473                 .desc = "Fan2",
 1474                 .type = ENVSYS_SFANRPM,
 1475                 .bank = 0,
 1476                 .reg = 0x2a,
 1477                 .refresh = wb_w83792d_refresh_fanrpm,
 1478                 .rfact = 0
 1479         },
 1480         {
 1481                 .desc = "Fan3",
 1482                 .type = ENVSYS_SFANRPM,
 1483                 .bank = 0,
 1484                 .reg = 0xb8,
 1485                 .refresh = wb_w83792d_refresh_fanrpm,
 1486                 .rfact = 0
 1487         },
 1488         {
 1489                 .desc = "Fan4",
 1490                 .type = ENVSYS_SFANRPM,
 1491                 .bank = 0,
 1492                 .reg = 0xb9,
 1493                 .refresh = wb_w83792d_refresh_fanrpm,
 1494                 .rfact = 0
 1495         },
 1496         {
 1497                 .desc = "Fan5",
 1498                 .type = ENVSYS_SFANRPM,
 1499                 .bank = 0,
 1500                 .reg = 0xba,
 1501                 .refresh = wb_w83792d_refresh_fanrpm,
 1502                 .rfact = 0
 1503         },
 1504         {
 1505                 .desc = "Fan6",
 1506                 .type = ENVSYS_SFANRPM,
 1507                 .bank = 0,
 1508                 .reg = 0xbe,
 1509                 .refresh = wb_w83792d_refresh_fanrpm,
 1510                 .rfact = 0
 1511         },
 1512 
 1513         { .desc = NULL }
 1514 };
 1515 
 1516 /* AS99127F */
 1517 static const struct lm_sensor as99127f_sensors[] = {
 1518         /* Voltage */
 1519         {
 1520                 .desc = "VCore A",
 1521                 .type = ENVSYS_SVOLTS_DC,
 1522                 .bank = 0,
 1523                 .reg = 0x20,
 1524                 .refresh = lm_refresh_volt,
 1525                 .rfact = RFACT_NONE
 1526         },
 1527         {
 1528                 .desc = "VCore B",
 1529                 .type = ENVSYS_SVOLTS_DC,
 1530                 .bank = 0,
 1531                 .reg = 0x21,
 1532                 .refresh = lm_refresh_volt,
 1533                 .rfact = RFACT_NONE
 1534         },
 1535         {
 1536                 .desc = "+3.3V",
 1537                 .type = ENVSYS_SVOLTS_DC,
 1538                 .bank = 0,
 1539                 .reg = 0x22,
 1540                 .refresh = lm_refresh_volt,
 1541                 .rfact = RFACT_NONE
 1542         },
 1543         {
 1544                 .desc = "+5V",
 1545                 .type = ENVSYS_SVOLTS_DC,
 1546                 .bank = 0,
 1547                 .reg = 0x23,
 1548                 .refresh = lm_refresh_volt,
 1549                 .rfact = RFACT(34, 50)
 1550         },
 1551         {
 1552                 .desc = "+12V",
 1553                 .type = ENVSYS_SVOLTS_DC,
 1554                 .bank = 0,
 1555                 .reg = 0x24,
 1556                 .refresh = lm_refresh_volt,
 1557                 .rfact = RFACT(28, 10)
 1558         },
 1559         {
 1560                 .desc = "-12V",
 1561                 .type = ENVSYS_SVOLTS_DC,
 1562                 .bank = 0,
 1563                 .reg = 0x25,
 1564                 .refresh = wb_refresh_nvolt,
 1565                 .rfact = RFACT(232, 56)
 1566         },
 1567         {
 1568                 .desc = "-5V",
 1569                 .type = ENVSYS_SVOLTS_DC,
 1570                 .bank = 0,
 1571                 .reg = 0x26,
 1572                 .refresh = wb_refresh_nvolt,
 1573                 .rfact = RFACT(120, 56)
 1574         },
 1575 
 1576         /* Temperature */
 1577         {
 1578                 .desc = "Temp0",
 1579                 .type = ENVSYS_STEMP,
 1580                 .bank = 0,
 1581                 .reg = 0x27,
 1582                 .refresh = lm_refresh_temp,
 1583                 .rfact = 0
 1584         },
 1585         {
 1586                 .desc = "Temp1",
 1587                 .type = ENVSYS_STEMP,
 1588                 .bank = 1,
 1589                 .reg = 0x50,
 1590                 .refresh = as_refresh_temp,
 1591                 .rfact = 0
 1592         },
 1593         {
 1594                 .desc = "Temp2",
 1595                 .type = ENVSYS_STEMP,
 1596                 .bank = 2,
 1597                 .reg = 0x50,
 1598                 .refresh = as_refresh_temp,
 1599                 .rfact = 0
 1600         },
 1601 
 1602         /* Fans */
 1603         {
 1604                 .desc = "Fan0",
 1605                 .type = ENVSYS_SFANRPM,
 1606                 .bank = 0,
 1607                 .reg = 0x28,
 1608                 .refresh = lm_refresh_fanrpm,
 1609                 .rfact = 0
 1610         },
 1611         {
 1612                 .desc = "Fan1",
 1613                 .type = ENVSYS_SFANRPM,
 1614                 .bank = 0,
 1615                 .reg = 0x29,
 1616                 .refresh = lm_refresh_fanrpm,
 1617                 .rfact = 0
 1618         },
 1619         {
 1620                 .desc = "Fan2",
 1621                 .type = ENVSYS_SFANRPM,
 1622                 .bank = 0,
 1623                 .reg = 0x2a,
 1624                 .refresh = lm_refresh_fanrpm,
 1625                 .rfact = 0
 1626         },
 1627 
 1628         { .desc = NULL }
 1629 };
 1630 
 1631 /* NCT6776F */
 1632 static const struct lm_sensor nct6776f_sensors[] = {
 1633         /* Voltage */
 1634         {
 1635                 .desc = "VCore",
 1636                 .type = ENVSYS_SVOLTS_DC,
 1637                 .bank = 0,
 1638                 .reg = 0x20,
 1639                 .refresh = lm_refresh_volt,
 1640                 .rfact = RFACT_NONE / 2
 1641         },
 1642         {
 1643                 .desc = "+12V",
 1644                 .type = ENVSYS_SVOLTS_DC,
 1645                 .bank = 0,
 1646                 .reg = 0x21,
 1647                 .refresh = lm_refresh_volt,
 1648                 .rfact = RFACT(56, 10) / 2
 1649         },
 1650         {
 1651                 .desc = "AVCC",
 1652                 .type = ENVSYS_SVOLTS_DC,
 1653                 .bank = 0,
 1654                 .reg = 0x22,
 1655                 .refresh = lm_refresh_volt,
 1656                 .rfact = RFACT(34, 34) / 2
 1657         },
 1658         {
 1659                 .desc = "+3.3V",
 1660                 .type = ENVSYS_SVOLTS_DC,
 1661                 .bank = 0,
 1662                 .reg = 0x23,
 1663                 .refresh = lm_refresh_volt,
 1664                 .rfact = RFACT(34, 34) / 2
 1665         },
 1666         {
 1667                 .desc = "-12V",
 1668                 .type = ENVSYS_SVOLTS_DC,
 1669                 .bank = 0,
 1670                 .reg = 0x24,
 1671                 .refresh = wb_w83627ehf_refresh_nvolt,
 1672                 .rfact = 0
 1673         },
 1674         {
 1675                 .desc = "+5V",
 1676                 .type = ENVSYS_SVOLTS_DC,
 1677                 .bank = 0,
 1678                 .reg = 0x25,
 1679                 .refresh = lm_refresh_volt,
 1680                 .rfact = 16000
 1681         },
 1682         {
 1683                 .desc = "VIN3",
 1684                 .type = ENVSYS_SVOLTS_DC,
 1685                 .bank = 0,
 1686                 .reg = 0x26,
 1687                 .refresh = lm_refresh_volt,
 1688                 .rfact = RFACT_NONE
 1689         },
 1690         {
 1691                 .desc = "+3.3VSB",
 1692                 .type = ENVSYS_SVOLTS_DC,
 1693                 .bank = 5,
 1694                 .reg = 0x50,
 1695                 .refresh = lm_refresh_volt,
 1696                 .rfact = RFACT(34, 34) / 2
 1697         },
 1698         {
 1699                 .desc = "VBAT",
 1700                 .type = ENVSYS_SVOLTS_DC,
 1701                 .bank = 5,
 1702                 .reg = 0x51,
 1703                 .refresh = lm_refresh_volt,
 1704                 .rfact = RFACT(34, 34) / 2
 1705         },
 1706 
 1707         /* Temperature */
 1708         {
 1709                 .desc = "MB Temperature",
 1710                 .type = ENVSYS_STEMP,
 1711                 .bank = 0,
 1712                 .reg = 0x27,
 1713                 .refresh = lm_refresh_temp,
 1714                 .rfact = 0
 1715         },
 1716         {
 1717                 .desc = "CPU Temperature",
 1718                 .type = ENVSYS_STEMP,
 1719                 .bank = 1,
 1720                 .reg = 0x50,
 1721                 .refresh = wb_refresh_temp,
 1722                 .rfact = 0
 1723         },
 1724         {
 1725                 .desc = "Aux Temp",
 1726                 .type = ENVSYS_STEMP,
 1727                 .bank = 2,
 1728                 .reg = 0x50,
 1729                 .refresh = wb_refresh_temp,
 1730                 .rfact = 0
 1731         },
 1732 
 1733         /* Fans */
 1734         {
 1735                 .desc = "System Fan",
 1736                 .type = ENVSYS_SFANRPM,
 1737                 .bank = 6,
 1738                 .reg = 0x56,
 1739                 .refresh = wb_nct6776f_refresh_fanrpm,
 1740                 .rfact = 0
 1741         },
 1742         {
 1743                 .desc = "CPU Fan",
 1744                 .type = ENVSYS_SFANRPM,
 1745                 .bank = 6,
 1746                 .reg = 0x58,
 1747                 .refresh = wb_nct6776f_refresh_fanrpm,
 1748                 .rfact = 0
 1749         },
 1750         {
 1751                 .desc = "Aux Fan0",
 1752                 .type = ENVSYS_SFANRPM,
 1753                 .bank = 6,
 1754                 .reg = 0x5a,
 1755                 .refresh = wb_nct6776f_refresh_fanrpm,
 1756                 .rfact = 0
 1757         },
 1758         {
 1759                 .desc = "Aux Fan1",
 1760                 .type = ENVSYS_SFANRPM,
 1761                 .bank = 6,
 1762                 .reg = 0x5c,
 1763                 .refresh = wb_nct6776f_refresh_fanrpm,
 1764                 .rfact = 0
 1765         },
 1766 
 1767         {
 1768                 .desc = "Aux Fan2",
 1769                 .type = ENVSYS_SFANRPM,
 1770                 .bank = 6,
 1771                 .reg = 0x5e,
 1772                 .refresh = wb_nct6776f_refresh_fanrpm,
 1773                 .rfact = 0
 1774         },
 1775 
 1776         { .desc = NULL }
 1777 };
 1778 
 1779 /* NCT610[246]D */
 1780 static const struct lm_sensor nct6102d_sensors[] = {
 1781         /* Voltage */
 1782         {
 1783                 .desc = "VCore",
 1784                 .type = ENVSYS_SVOLTS_DC,
 1785                 .bank = 0,
 1786                 .reg = 0x00,
 1787                 .refresh = lm_refresh_volt,
 1788                 .rfact = RFACT_NONE
 1789         },
 1790         {
 1791                 .desc = "VIN0",
 1792                 .type = ENVSYS_SVOLTS_DC,
 1793                 .bank = 0,
 1794                 .reg = 0x01,
 1795                 .refresh = lm_refresh_volt,
 1796                 .rfact = RFACT_NONE
 1797         },
 1798         {
 1799                 .desc = "AVCC",
 1800                 .type = ENVSYS_SVOLTS_DC,
 1801                 .bank = 0,
 1802                 .reg = 0x02,
 1803                 .refresh = lm_refresh_volt,
 1804                 .rfact = RFACT(34, 34) / 2
 1805         },
 1806         {
 1807                 .desc = "3VCC",
 1808                 .type = ENVSYS_SVOLTS_DC,
 1809                 .bank = 0,
 1810                 .reg = 0x03,
 1811                 .refresh = lm_refresh_volt,
 1812                 .rfact = RFACT(34, 34) / 2
 1813         },
 1814         {
 1815                 .desc = "VIN1",
 1816                 .type = ENVSYS_SVOLTS_DC,
 1817                 .bank = 0,
 1818                 .reg = 0x04,
 1819                 .refresh = lm_refresh_volt,
 1820                 .rfact = RFACT_NONE
 1821         },
 1822         {
 1823                 .desc = "VIN2",
 1824                 .type = ENVSYS_SVOLTS_DC,
 1825                 .bank = 0,
 1826                 .reg = 0x05,
 1827                 .refresh = lm_refresh_volt,
 1828                 .rfact = RFACT(34, 34) / 2
 1829         },
 1830         {
 1831                 .desc = "+3.3VSB",
 1832                 .type = ENVSYS_SVOLTS_DC,
 1833                 .bank = 0,
 1834                 .reg = 0x07,
 1835                 .refresh = lm_refresh_volt,
 1836                 .rfact = RFACT(34, 34) / 2
 1837         },
 1838         {
 1839                 .desc = "VBAT",
 1840                 .type = ENVSYS_SVOLTS_DC,
 1841                 .bank = 0,
 1842                 .reg = 0x08,
 1843                 .refresh = lm_refresh_volt,
 1844                 .rfact = RFACT(34, 34) / 2
 1845         },
 1846         {
 1847                 .desc = "VTT",
 1848                 .type = ENVSYS_SVOLTS_DC,
 1849                 .bank = 0,
 1850                 .reg = 0x09,
 1851                 .refresh = lm_refresh_volt,
 1852                 .rfact = RFACT_NONE
 1853         },
 1854 
 1855         /* Temperature */
 1856         {
 1857                 .desc = "MB Temperature",
 1858                 .type = ENVSYS_STEMP,
 1859                 .bank = 0,
 1860                 .reg = 0x18,
 1861                 .refresh = lm_refresh_temp,
 1862                 .rfact = 0
 1863         },
 1864         {
 1865                 .desc = "CPU Temperature",
 1866                 .type = ENVSYS_STEMP,
 1867                 .bank = 0,
 1868                 .reg = 0x19,
 1869                 .refresh = lm_refresh_temp,
 1870                 .rfact = 0
 1871         },
 1872         {
 1873                 .desc = "Aux Temp",
 1874                 .type = ENVSYS_STEMP,
 1875                 .bank = 0,
 1876                 .reg = 0x1a,
 1877                 .refresh = lm_refresh_temp,
 1878                 .rfact = 0
 1879         },
 1880 
 1881         /* Fans */
 1882         {
 1883                 .desc = "System Fan",
 1884                 .type = ENVSYS_SFANRPM,
 1885                 .bank = 0,
 1886                 .reg = 0x30,
 1887                 .refresh = wb_nct6776f_refresh_fanrpm,
 1888                 .rfact = 0
 1889         },
 1890         {
 1891                 .desc = "CPU Fan",
 1892                 .type = ENVSYS_SFANRPM,
 1893                 .bank = 0,
 1894                 .reg = 0x32,
 1895                 .refresh = wb_nct6776f_refresh_fanrpm,
 1896                 .rfact = 0
 1897         },
 1898         {
 1899                 .desc = "Aux Fan",
 1900                 .type = ENVSYS_SFANRPM,
 1901                 .bank = 0,
 1902                 .reg = 0x34,
 1903                 .refresh = wb_nct6776f_refresh_fanrpm,
 1904                 .rfact = 0
 1905         },
 1906 
 1907         { .desc = NULL }
 1908 };
 1909 
 1910 /* NCT6779D */
 1911 static const struct lm_sensor nct6779d_sensors[] = {
 1912         /* Voltage */
 1913         {
 1914                 .desc = "VCore",
 1915                 .type = ENVSYS_SVOLTS_DC,
 1916                 .bank = 4,
 1917                 .reg = 0x80,
 1918                 .refresh = lm_refresh_volt,
 1919                 .rfact = RFACT_NONE / 2
 1920         },
 1921         {
 1922                 .desc = "VIN1",
 1923                 .type = ENVSYS_SVOLTS_DC,
 1924                 .bank = 4,
 1925                 .reg = 0x81,
 1926                 .refresh = lm_refresh_volt,
 1927                 .rfact = RFACT(56, 10) / 2
 1928         },
 1929         {
 1930                 .desc = "AVCC",
 1931                 .type = ENVSYS_SVOLTS_DC,
 1932                 .bank = 4,
 1933                 .reg = 0x82,
 1934                 .refresh = lm_refresh_volt,
 1935                 .rfact = RFACT(34, 34) / 2
 1936         },
 1937         {
 1938                 .desc = "+3.3V",
 1939                 .type = ENVSYS_SVOLTS_DC,
 1940                 .bank = 4,
 1941                 .reg = 0x83,
 1942                 .refresh = lm_refresh_volt,
 1943                 .rfact = RFACT(34, 34) / 2
 1944         },
 1945         {
 1946                 .desc = "VIN0",
 1947                 .type = ENVSYS_SVOLTS_DC,
 1948                 .bank = 4,
 1949                 .reg = 0x84,
 1950                 .refresh = lm_refresh_volt,
 1951                 .rfact = RFACT(48600, 10000)
 1952         },
 1953         {
 1954                 .desc = "VIN8",
 1955                 .type = ENVSYS_SVOLTS_DC,
 1956                 .bank = 4,
 1957                 .reg = 0x85,
 1958                 .refresh = lm_refresh_volt,
 1959                 .rfact = RFACT_NONE / 2
 1960         },
 1961         {
 1962                 .desc = "VIN4",
 1963                 .type = ENVSYS_SVOLTS_DC,
 1964                 .bank = 4,
 1965                 .reg = 0x86,
 1966                 .refresh = lm_refresh_volt,
 1967                 .rfact = RFACT_NONE
 1968         },
 1969         {
 1970                 .desc = "+3.3VSB",
 1971                 .type = ENVSYS_SVOLTS_DC,
 1972                 .bank = 4,
 1973                 .reg = 0x87,
 1974                 .refresh = lm_refresh_volt,
 1975                 .rfact = RFACT(34, 34) / 2
 1976         },
 1977         {
 1978                 .desc = "VBAT",
 1979                 .type = ENVSYS_SVOLTS_DC,
 1980                 .bank = 4,
 1981                 .reg = 0x88,
 1982                 .refresh = lm_refresh_volt,
 1983                 .rfact = RFACT_NONE
 1984         },
 1985         {
 1986                 .desc = "VTT",
 1987                 .type = ENVSYS_SVOLTS_DC,
 1988                 .bank = 4,
 1989                 .reg = 0x89,
 1990                 .refresh = lm_refresh_volt,
 1991                 .rfact = RFACT_NONE
 1992         },
 1993         {
 1994                 .desc = "VIN5",
 1995                 .type = ENVSYS_SVOLTS_DC,
 1996                 .bank = 4,
 1997                 .reg = 0x8a,
 1998                 .refresh = lm_refresh_volt,
 1999                 .rfact = RFACT_NONE
 2000         },
 2001         {
 2002                 .desc = "VIN6",
 2003                 .type = ENVSYS_SVOLTS_DC,
 2004                 .bank = 4,
 2005                 .reg = 0x8b,
 2006                 .refresh = lm_refresh_volt,
 2007                 .rfact = RFACT_NONE
 2008         },
 2009         {
 2010                 .desc = "VIN2",
 2011                 .type = ENVSYS_SVOLTS_DC,
 2012                 .bank = 4,
 2013                 .reg = 0x8c,
 2014                 .refresh = lm_refresh_volt,
 2015                 .rfact = RFACT_NONE
 2016         },
 2017         {
 2018                 .desc = "VIN3",
 2019                 .type = ENVSYS_SVOLTS_DC,
 2020                 .bank = 4,
 2021                 .reg = 0x8d,
 2022                 .refresh = lm_refresh_volt,
 2023                 .rfact = RFACT(14414, 10000)
 2024         },
 2025         {
 2026                 .desc = "VIN7",
 2027                 .type = ENVSYS_SVOLTS_DC,
 2028                 .bank = 4,
 2029                 .reg = 0x8e,
 2030                 .refresh = lm_refresh_volt,
 2031                 .rfact = RFACT_NONE / 2
 2032         },
 2033 
 2034         /* Temperature */
 2035         {
 2036                 .desc = "MB Temperature",
 2037                 .type = ENVSYS_STEMP,
 2038                 .bank = 4,
 2039                 .reg = 0x90,
 2040                 .refresh = lm_refresh_temp,
 2041                 .rfact = 0
 2042         },
 2043         {
 2044                 .desc = "CPU Temperature",
 2045                 .type = ENVSYS_STEMP,
 2046                 .bank = 4,
 2047                 .reg = 0x91,
 2048                 .refresh = wb_refresh_temp,
 2049                 .rfact = 0
 2050         },
 2051         {
 2052                 .desc = "Aux Temp0",
 2053                 .type = ENVSYS_STEMP,
 2054                 .bank = 4,
 2055                 .reg = 0x92,
 2056                 .refresh = wb_refresh_temp,
 2057                 .rfact = 0
 2058         },
 2059         {
 2060                 .desc = "Aux Temp1",
 2061                 .type = ENVSYS_STEMP,
 2062                 .bank = 4,
 2063                 .reg = 0x93,
 2064                 .refresh = wb_refresh_temp,
 2065                 .rfact = 0
 2066         },
 2067         {
 2068                 .desc = "Aux Temp2",
 2069                 .type = ENVSYS_STEMP,
 2070                 .bank = 4,
 2071                 .reg = 0x94,
 2072                 .refresh = wb_refresh_temp,
 2073                 .rfact = 0
 2074         },
 2075         {
 2076                 .desc = "Aux Temp3",
 2077                 .type = ENVSYS_STEMP,
 2078                 .bank = 4,
 2079                 .reg = 0x95,
 2080                 .refresh = wb_refresh_temp,
 2081                 .rfact = 0
 2082         },
 2083 
 2084         /* Fans */
 2085         {
 2086                 .desc = "System Fan",
 2087                 .type = ENVSYS_SFANRPM,
 2088                 .bank = 4,
 2089                 .reg = 0xc0,
 2090                 .refresh = wb_nct6776f_refresh_fanrpm,
 2091                 .rfact = 0
 2092         },
 2093         {
 2094                 .desc = "CPU Fan",
 2095                 .type = ENVSYS_SFANRPM,
 2096                 .bank = 4,
 2097                 .reg = 0xc2,
 2098                 .refresh = wb_nct6776f_refresh_fanrpm,
 2099                 .rfact = 0
 2100         },
 2101         {
 2102                 .desc = "Aux Fan0",
 2103                 .type = ENVSYS_SFANRPM,
 2104                 .bank = 4,
 2105                 .reg = 0xc4,
 2106                 .refresh = wb_nct6776f_refresh_fanrpm,
 2107                 .rfact = 0
 2108         },
 2109         {
 2110                 .desc = "Aux Fan1",
 2111                 .type = ENVSYS_SFANRPM,
 2112                 .bank = 4,
 2113                 .reg = 0xc6,
 2114                 .refresh = wb_nct6776f_refresh_fanrpm,
 2115                 .rfact = 0
 2116         },
 2117         {
 2118                 .desc = "Aux Fan2",
 2119                 .type = ENVSYS_SFANRPM,
 2120                 .bank = 4,
 2121                 .reg = 0xc8,
 2122                 .refresh = wb_nct6776f_refresh_fanrpm,
 2123                 .rfact = 0
 2124         },
 2125 
 2126         { .desc = NULL }
 2127 };
 2128 
 2129 static const struct wb_product wb_products[] = {
 2130     { WB_CHIPID_W83627HF,   "W83627HF", w83627hf_sensors, NULL },
 2131     { WB_CHIPID_W83627THF,  "W83627THF",w83637hf_sensors, NULL },
 2132     { WB_CHIPID_W83627EHF_A,"W83627EHF-A",w83627ehf_sensors,NULL },
 2133     { WB_CHIPID_W83627EHF,  "W83627EHF",w83627ehf_sensors,NULL },
 2134     { WB_CHIPID_W83627DHG,  NULL,       NULL,   NULL },
 2135     { WB_CHIPID_W83637HF,   "W83637HF", w83637hf_sensors, NULL },
 2136     { WB_CHIPID_W83697HF,   "W83697HF", w83697hf_sensors, NULL },
 2137     { WB_CHIPID_W83781D,    "W83781D",  w83781d_sensors,  NULL },
 2138     { WB_CHIPID_W83781D_2,  "W83781D",  w83781d_sensors,  NULL },
 2139     { WB_CHIPID_W83782D,    "W83782D",  w83782d_sensors,  NULL },
 2140     { WB_CHIPID_W83783S,    "W83783S",  w83783s_sensors,  NULL },
 2141     { WB_CHIPID_W83791D,    "W83791D",  w83791d_sensors,  NULL },
 2142     { WB_CHIPID_W83791SD,   "W83791SD", NULL,             NULL },
 2143     { WB_CHIPID_W83792D,    "W83792D",  w83792d_sensors,  NULL },
 2144     { WB_CHIPID_AS99127F,   NULL,       NULL,  NULL },
 2145     { 0, NULL, NULL, NULL }
 2146 };
 2147 
 2148 static const struct wb_product wbsio_products[] = {
 2149     { WBSIO_ID_W83627DHG,   "W83627DHG",w83627dhg_sensors,NULL },
 2150     { WBSIO_ID_NCT6775F,    "NCT6775F", nct6776f_sensors, NULL },
 2151     { WBSIO_ID_NCT6776F,    "NCT6776F", nct6776f_sensors, NULL },
 2152     { WBSIO_ID_NCT5104D,    "NCT5104D or 610[246]D",nct6102d_sensors,NULL },
 2153     { WBSIO_ID_NCT6779D,    "NCT6779D", nct6779d_sensors, NULL },
 2154     { WBSIO_ID_NCT6791D,    "NCT6791D", nct6779d_sensors, NULL },
 2155     { WBSIO_ID_NCT6792D,    "NCT6792D", nct6779d_sensors, NULL },
 2156     { WBSIO_ID_NCT6793D,    "NCT6793D", nct6779d_sensors, NULL },
 2157     { WBSIO_ID_NCT6795D,    "NCT6795D", nct6779d_sensors, NULL },
 2158     { WBSIO_ID_NCT6796D,    "NCT6796D", nct6779d_sensors, NULL },
 2159     { WBSIO_ID_NCT6797D,    "NCT6797D", nct6779d_sensors, NULL },
 2160     { WBSIO_ID_NCT6798D,    "NCT6798D", nct6779d_sensors, NULL },
 2161     { WBSIO_ID_NCT6799D,    "NCT6799D", nct6779d_sensors, NULL },
 2162     { 0, NULL, NULL, NULL }
 2163 };
 2164 
 2165 static const struct wb_product as99127f_products[] = {
 2166     { WB_VENDID_ASUS,       "AS99127F", w83781d_sensors,  NULL },
 2167     { WB_VENDID_WINBOND,    "AS99127F rev 2",as99127f_sensors,NULL },
 2168     { 0, NULL, NULL, NULL }
 2169 };
 2170 
 2171 static void
 2172 lm_generic_banksel(struct lm_softc *lmsc, uint8_t bank)
 2173 {
 2174         (*lmsc->lm_writereg)(lmsc, WB_BANKSEL, bank);
 2175 }
 2176 
 2177 /*
 2178  * bus independent match
 2179  *
 2180  * prerequisites:  lmsc contains valid lm_{read,write}reg() routines
 2181  * and associated bus access data is present in attachment's softc
 2182  */
 2183 int
 2184 lm_match(struct lm_softc *lmsc)
 2185 {
 2186         uint8_t cr;
 2187         int i, rv;
 2188 
 2189         /* Perform LM78 reset */
 2190         /*(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x80); */
 2191 
 2192         cr = (*lmsc->lm_readreg)(lmsc, LMD_CONFIG);
 2193 
 2194         /* XXX - spec says *only* 0x08! */
 2195         if ((cr != 0x08) && (cr != 0x01) && (cr != 0x03) && (cr != 0x06))
 2196                 return 0;
 2197 
 2198         DPRINTF(("%s: 0x80 check: cr = %x\n", __func__, cr));
 2199 
 2200         for (i = 0; i < __arraycount(lm_chips); i++)
 2201                 if ((rv = lm_chips[i].chip_match(lmsc)) != 0)
 2202                         return rv;
 2203 
 2204         return 0;
 2205 }
 2206 
 2207 int
 2208 nslm_match(struct lm_softc *sc)
 2209 {
 2210         uint8_t chipid;
 2211 
 2212         /* See if we have an LM78/LM78J/LM79 or LM81 */
 2213         chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK;
 2214         switch(chipid) {
 2215         case LM_ID_LM78:
 2216         case LM_ID_LM78J:
 2217         case LM_ID_LM79:
 2218         case LM_ID_LM81:
 2219                 break;
 2220         default:
 2221                 return 0;
 2222         }
 2223         DPRINTF(("%s: chipid %x\n", __func__, chipid));
 2224         return 1;
 2225 }
 2226 
 2227 void
 2228 lm_attach(struct lm_softc *lmsc)
 2229 {
 2230         uint32_t i;
 2231         int rv;
 2232 
 2233         for (i = 0; i < __arraycount(lm_chips); i++) {
 2234                 if (lm_chips[i].chip_match(lmsc) != 0) {
 2235                         if (lm_chips[i].chip_attach(lmsc) == 0)
 2236                                 break;
 2237                         else
 2238                                 return;
 2239                 }
 2240         }
 2241 
 2242         /* Start the monitoring loop */
 2243         (*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01);
 2244 
 2245         lmsc->sc_sme = sysmon_envsys_create();
 2246         /* Initialize sensors */
 2247         for (i = 0; i < lmsc->numsensors; i++) {
 2248                 lmsc->sensors[i].state = ENVSYS_SINVALID;
 2249                 if ((rv = sysmon_envsys_sensor_attach(lmsc->sc_sme,
 2250                             &lmsc->sensors[i])) != 0) {
 2251                         sysmon_envsys_destroy(lmsc->sc_sme);
 2252                         lmsc->sc_sme = NULL;
 2253                         aprint_error_dev(lmsc->sc_dev,
 2254                             "sysmon_envsys_sensor_attach() returned %d\n", rv);
 2255                         return;
 2256                 }
 2257         }
 2258 
 2259         /*
 2260          * Setup the callout to refresh sensor data every 2 seconds.
 2261          */
 2262         callout_init(&lmsc->sc_callout, 0);
 2263         callout_setfunc(&lmsc->sc_callout, lm_refresh, lmsc);
 2264         callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO);
 2265 
 2266         /*
 2267          * Hook into the System Monitor.
 2268          */
 2269         lmsc->sc_sme->sme_name = device_xname(lmsc->sc_dev);
 2270         lmsc->sc_sme->sme_flags = SME_DISABLE_REFRESH;
 2271 
 2272         if (sysmon_envsys_register(lmsc->sc_sme)) {
 2273                 aprint_error_dev(lmsc->sc_dev,
 2274                     "unable to register with sysmon\n");
 2275                 sysmon_envsys_destroy(lmsc->sc_sme);
 2276                 lmsc->sc_sme = NULL;
 2277         }
 2278         if (!pmf_device_register(lmsc->sc_dev, NULL, NULL))
 2279                 aprint_error_dev(lmsc->sc_dev,
 2280                     "couldn't establish power handler\n");
 2281 }
 2282 
 2283 /*
 2284  * Stop, destroy the callout and unregister the driver with the
 2285  * sysmon_envsys(9) framework.
 2286  */
 2287 void
 2288 lm_detach(struct lm_softc *lmsc)
 2289 {
 2290         callout_halt(&lmsc->sc_callout, NULL);
 2291         callout_destroy(&lmsc->sc_callout);
 2292 
 2293         if (lmsc->sc_sme != NULL)
 2294                 sysmon_envsys_unregister(lmsc->sc_sme);
 2295         pmf_device_deregister(lmsc->sc_dev);
 2296 }
 2297 
 2298 static void
 2299 lm_refresh(void *arg)
 2300 {
 2301         struct lm_softc *lmsc = arg;
 2302 
 2303         lmsc->refresh_sensor_data(lmsc);
 2304         callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO);
 2305 }
 2306 
 2307 static int
 2308 nslm_attach(struct lm_softc *sc)
 2309 {
 2310         const char *model = NULL;
 2311         uint8_t chipid;
 2312 
 2313         /* See if we have an LM78/LM78J/LM79 or LM81 */
 2314         chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK;
 2315         switch(chipid) {
 2316         case LM_ID_LM78:
 2317                 model = "LM78";
 2318                 break;
 2319         case LM_ID_LM78J:
 2320                 model = "LM78J";
 2321                 break;
 2322         case LM_ID_LM79:
 2323                 model = "LM79";
 2324                 break;
 2325         case LM_ID_LM81:
 2326                 model = "LM81";
 2327                 break;
 2328         default:
 2329                 return -1;
 2330         }
 2331 
 2332         aprint_naive("\n");
 2333         aprint_normal("\n");
 2334         aprint_normal_dev(sc->sc_dev,
 2335             "National Semiconductor %s Hardware monitor\n", model);
 2336 
 2337         lm_setup_sensors(sc, lm78_sensors);
 2338         sc->refresh_sensor_data = lm_refresh_sensor_data;
 2339         return 0;
 2340 }
 2341 
 2342 static int
 2343 def_match(struct lm_softc *sc)
 2344 {
 2345 
 2346         return 1;
 2347 }
 2348 
 2349 static int
 2350 def_attach(struct lm_softc *sc)
 2351 {
 2352         uint8_t chipid;
 2353 
 2354         chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK;
 2355         aprint_naive("\n");
 2356         aprint_normal("\n");
 2357         aprint_error_dev(sc->sc_dev, "Unknown chip (ID 0x%02x)\n", chipid);
 2358 
 2359         lm_setup_sensors(sc, lm78_sensors);
 2360         sc->refresh_sensor_data = lm_refresh_sensor_data;
 2361         return 0;
 2362 }
 2363 
 2364 static void
 2365 wb_temp_diode_type(struct lm_softc *sc, int diode_type)
 2366 {
 2367         uint8_t regval, banksel;
 2368 
 2369         banksel = (*sc->lm_readreg)(sc, WB_BANKSEL);
 2370         switch (diode_type) {
 2371             case 1:     /* Switch to Pentium-II diode mode */
 2372                 lm_generic_banksel(sc, WB_BANKSEL_B0);
 2373                 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
 2374                 regval |= 0x0e;
 2375                 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval);
 2376                 regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1);
 2377                 regval |= 0x70;
 2378                 (*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0);
 2379                 lm_generic_banksel(sc, banksel);
 2380                 aprint_verbose_dev(sc->sc_dev, "Pentium-II diode temp sensors\n");
 2381                 break;
 2382             case 2:     /* Switch to 2N3904 mode */
 2383                 lm_generic_banksel(sc, WB_BANKSEL_B0);
 2384                 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
 2385                 regval |= 0xe;
 2386                 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval);
 2387                 regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1);
 2388                 regval &= ~0x70;
 2389                 (*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0);
 2390                 lm_generic_banksel(sc, banksel);
 2391                 aprint_verbose_dev(sc->sc_dev, "2N3904 bipolar temp sensors\n");
 2392                 break;
 2393             case 4:     /* Switch to generic thermistor mode */
 2394                 lm_generic_banksel(sc, WB_BANKSEL_B0);
 2395                 regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
 2396                 regval &= ~0xe;
 2397                 (*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval);
 2398                 lm_generic_banksel(sc, banksel);
 2399                 aprint_verbose_dev(sc->sc_dev, "Thermistor temp sensors\n");
 2400                 break;
 2401             case 0:     /* Unspecified - use default */
 2402                 aprint_verbose_dev(sc->sc_dev, "Using default temp sensors\n");
 2403                 break;
 2404             default:
 2405                 aprint_error_dev(sc->sc_dev,
 2406                                  "Ignoring invalid temp sensor mode %d\n",
 2407                                  diode_type);
 2408                 break;
 2409         }
 2410 }
 2411 
 2412 static const struct wb_product *
 2413 wb_lookup(struct lm_softc *sc, const struct wb_product *products, uint16_t id)
 2414 {
 2415         const struct wb_product *prod = products;
 2416         int i = 0;
 2417 
 2418         while (prod[i].id != 0) {
 2419                 if (prod[i].id != id) {
 2420                         i++;
 2421                         continue;
 2422                 }
 2423                 if (prod[i].str == NULL) {
 2424                         if (products == wb_products) {
 2425                                 if (id == WB_CHIPID_W83627DHG) {
 2426                                         /*
 2427                                          *  Lookup wbsio_products
 2428                                          * with WBSIO_ID.
 2429                                          */
 2430                                         return wb_lookup(sc, wbsio_products,
 2431                                             sc->sioid);
 2432                                 } else if (id == WB_CHIPID_AS99127F) {
 2433                                         /*
 2434                                          *  Lookup as99127f_products
 2435                                          * with WB_VENDID.
 2436                                          */
 2437                                         return wb_lookup(sc, as99127f_products,
 2438                                             wb_read_vendorid(sc));
 2439                                 } else
 2440                                         return NULL; /* not occur */
 2441                         }
 2442                         return NULL; /* not occur */
 2443                 }
 2444                 return &prod[i];
 2445         }
 2446 
 2447         /* Not found */
 2448         return NULL;
 2449 }
 2450 
 2451 static uint16_t
 2452 wb_read_vendorid(struct lm_softc *sc)
 2453 {
 2454         uint16_t vendid;
 2455         uint8_t vendidreg;
 2456         uint8_t banksel;
 2457 
 2458         /* Save bank */
 2459         banksel = (*sc->lm_readreg)(sc, WB_BANKSEL);
 2460 
 2461         /* Check default vendor ID register first */
 2462         vendidreg = WB_VENDID;
 2463 
 2464 retry:
 2465         /* Read vendor ID */
 2466         lm_generic_banksel(sc, WB_BANKSEL_HBAC);
 2467         vendid = (*sc->lm_readreg)(sc, vendidreg) << 8;
 2468         lm_generic_banksel(sc, 0);
 2469         vendid |= (*sc->lm_readreg)(sc, vendidreg);
 2470 
 2471         if ((vendidreg == WB_VENDID)
 2472             &&  (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)) {
 2473                 /* If it failed, try NCT6102 vendor ID register */
 2474                 vendidreg = WB_NCT6102_VENDID;
 2475                 goto retry;
 2476         } else if ((vendidreg == WB_NCT6102_VENDID)
 2477             && (vendid != WB_VENDID_WINBOND))
 2478                 vendid = 0; /* XXX */
 2479         
 2480         /* Restore bank */
 2481         lm_generic_banksel(sc, banksel);
 2482 
 2483         return vendid;
 2484 }
 2485 
 2486 static uint8_t
 2487 wb_read_chipid(struct lm_softc *sc)
 2488 {
 2489         const struct wb_product *prod;
 2490         uint8_t chipidreg, chipid, banksel;
 2491 
 2492         /* Save bank */
 2493         banksel = (*sc->lm_readreg)(sc, WB_BANKSEL);
 2494 
 2495         /* Check default vendor ID register first */
 2496         chipidreg = WB_BANK0_CHIPID;
 2497         lm_generic_banksel(sc, WB_BANKSEL_B0);
 2498 
 2499 retry:
 2500         (void)(*sc->lm_readreg)(sc, LMD_CHIPID);
 2501         chipid = (*sc->lm_readreg)(sc, chipidreg);
 2502         prod = wb_lookup(sc, wb_products, chipid);
 2503         if (prod == NULL) {
 2504                 if (chipidreg == WB_BANK0_CHIPID) {
 2505                         chipidreg = WB_BANK0_NCT6102_CHIPID;
 2506                         goto retry;
 2507                 } else
 2508                         chipid = 0;
 2509         }
 2510         /* Restore bank */
 2511         lm_generic_banksel(sc, banksel);
 2512 
 2513         return chipid;
 2514 }
 2515 
 2516 static int
 2517 wb_match(struct lm_softc *sc)
 2518 {
 2519         const struct wb_product *prod;
 2520         uint16_t vendid;
 2521         uint8_t chipid;
 2522 
 2523         /* Read vendor ID */
 2524         vendid = wb_read_vendorid(sc);
 2525         DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid));
 2526         if ((vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS))
 2527                 return 0;
 2528 
 2529         /* Read device/chip ID */
 2530         chipid = wb_read_chipid(sc);
 2531         DPRINTF(("%s: winbond chip id 0x%x\n", __func__, chipid));
 2532         prod = wb_lookup(sc, wb_products, chipid);
 2533 
 2534         if (prod == NULL) {
 2535                 if (vendid == WB_VENDID_WINBOND)
 2536                         return 1; /* Generic match */
 2537                 else
 2538                         return 0;
 2539         }
 2540         DPRINTF(("%s: chipid %02x, sioid = %04x\n", __func__, chipid,
 2541                 sc->sioid));
 2542 
 2543         return 10; /* found */
 2544 }
 2545 
 2546 static int
 2547 wb_attach(struct lm_softc *sc)
 2548 {
 2549         device_t dev = sc->sc_dev;
 2550         const struct wb_product *prod;
 2551         const char *model = NULL;
 2552         const char *vendor = "Winbond";
 2553         const struct lm_sensor *sensors;
 2554         uint16_t vendid;
 2555         uint8_t banksel;
 2556         int cf_flags;
 2557 
 2558         aprint_naive("\n");
 2559         aprint_normal("\n");
 2560         /* Read device/chip ID */
 2561         sc->chipid = wb_read_chipid(sc);
 2562         DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid));
 2563 
 2564         if ((prod = wb_lookup(sc, wb_products, sc->chipid)) != NULL) {
 2565                 model = prod->str;
 2566                 switch (model[0]) {
 2567                 case 'W':
 2568                         vendor = "Winbond";
 2569                         break;
 2570                 case 'A':
 2571                         vendor = "ASUS";
 2572                         break;
 2573                 case 'N':
 2574                         vendor = "Nuvoton";
 2575                         break;
 2576                 default:
 2577                         aprint_error_dev(dev, "Unknown model (%s)\n", model);
 2578                         return -1;
 2579                 }
 2580                 sensors = prod->sensors;
 2581                 sc->refresh_sensor_data = wb_refresh_sensor_data;
 2582                 if (prod->extattach != NULL)
 2583                         prod->extattach(sc);
 2584         } else {
 2585                 vendid = wb_read_vendorid(sc);
 2586                 if (vendid == WB_VENDID_WINBOND) {
 2587                         vendor = "Winbond";
 2588                         model = "unknown-model";
 2589 
 2590                         /* Handle as a standard LM78. */
 2591                         sensors = lm78_sensors;
 2592                         sc->refresh_sensor_data = lm_refresh_sensor_data;
 2593                 } else {
 2594                         aprint_error_dev(dev, "Unknown chip (ID %02x)\n",
 2595                             sc->chipid);
 2596                         return -1;
 2597                 }
 2598         }
 2599         
 2600         cf_flags = device_cfdata(dev)->cf_flags;
 2601 
 2602         if (sensors != NULL) {
 2603                 lm_setup_sensors(sc, sensors);
 2604 
 2605                 /* XXX Is this correct? Check all datasheets. */
 2606                 switch (sc->chipid) {
 2607                 case WB_CHIPID_W83627EHF_A:
 2608                 case WB_CHIPID_W83781D:
 2609                 case WB_CHIPID_W83781D_2:
 2610                 case WB_CHIPID_W83791SD:
 2611                 case WB_CHIPID_W83792D:
 2612                 case WB_CHIPID_AS99127F:
 2613                         break;
 2614                 default:
 2615                         wb_temp_diode_type(sc, cf_flags);
 2616                         break;
 2617                 }
 2618         }
 2619 
 2620         /* XXX Is this correct? Check all datasheets. */
 2621         banksel = (*sc->lm_readreg)(sc, WB_BANKSEL);
 2622         switch(sc->chipid) {
 2623         case WB_CHIPID_W83627THF:
 2624                 lm_generic_banksel(sc, WB_BANKSEL_B0);
 2625                 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9)
 2626                         sc->vrm9 = 1;
 2627                 lm_generic_banksel(sc, banksel);
 2628                 break;
 2629         case WB_CHIPID_W83637HF:
 2630                 lm_generic_banksel(sc, WB_BANKSEL_B0);
 2631                 if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9)
 2632                         sc->vrm9 = 1;
 2633                 lm_generic_banksel(sc, banksel);
 2634                 break;
 2635         default:
 2636                 break;
 2637         }
 2638 
 2639         aprint_normal_dev(dev, "%s %s Hardware monitor\n", vendor, model);
 2640 
 2641         return 0;
 2642 }
 2643 
 2644 static void
 2645 lm_setup_sensors(struct lm_softc *sc, const struct lm_sensor *sensors)
 2646 {
 2647         int i;
 2648 
 2649         for (i = 0; sensors[i].desc; i++) {
 2650                 sc->sensors[i].units = sensors[i].type;
 2651                 if (sc->sensors[i].units == ENVSYS_SVOLTS_DC)
 2652                         sc->sensors[i].flags = ENVSYS_FCHANGERFACT;
 2653                 strlcpy(sc->sensors[i].desc, sensors[i].desc,
 2654                     sizeof(sc->sensors[i].desc));
 2655                 sc->numsensors++;
 2656         }
 2657         sc->lm_sensors = sensors;
 2658 }
 2659 
 2660 static void
 2661 lm_refresh_sensor_data(struct lm_softc *sc)
 2662 {
 2663         int i;
 2664 
 2665         for (i = 0; i < sc->numsensors; i++)
 2666                 sc->lm_sensors[i].refresh(sc, i);
 2667 }
 2668 
 2669 static void
 2670 lm_refresh_volt(struct lm_softc *sc, int n)
 2671 {
 2672         int data;
 2673 
 2674         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2675         if (data == 0xff) {
 2676                 sc->sensors[n].state = ENVSYS_SINVALID;
 2677         } else {
 2678                 sc->sensors[n].value_cur = (data << 4);
 2679                 if (sc->sensors[n].rfact) {
 2680                         sc->sensors[n].value_cur *= sc->sensors[n].rfact;
 2681                         sc->sensors[n].value_cur /= 10;
 2682                 } else {
 2683                         sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact;
 2684                         sc->sensors[n].value_cur /= 10;
 2685                         sc->sensors[n].rfact = sc->lm_sensors[n].rfact;
 2686                 }
 2687                 sc->sensors[n].state = ENVSYS_SVALID;
 2688         }
 2689 
 2690         DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
 2691             __func__, n, data, sc->sensors[n].value_cur));
 2692 }
 2693 
 2694 static void
 2695 lm_refresh_temp(struct lm_softc *sc, int n)
 2696 {
 2697         int data;
 2698 
 2699         /*
 2700          * The data sheet suggests that the range of the temperature
 2701          * sensor is between -55 degC and +125 degC.
 2702          */
 2703         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2704         if (data > 0x7d && data < 0xc9)
 2705                 sc->sensors[n].state = ENVSYS_SINVALID;
 2706         else {
 2707                 if (data & 0x80)
 2708                         data -= 0x100;
 2709                 sc->sensors[n].state = ENVSYS_SVALID;
 2710                 sc->sensors[n].value_cur = data * 1000000 + 273150000;
 2711         }
 2712         DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
 2713             __func__, n, data, sc->sensors[n].value_cur));
 2714 }
 2715 
 2716 static void
 2717 lm_refresh_fanrpm(struct lm_softc *sc, int n)
 2718 {
 2719         int data, divisor = 1;
 2720 
 2721         /*
 2722          * We might get more accurate fan readings by adjusting the
 2723          * divisor, but that might interfere with APM or other SMM
 2724          * BIOS code reading the fan speeds.
 2725          */
 2726 
 2727         /* FAN3 has a fixed fan divisor. */
 2728         if (sc->lm_sensors[n].reg == LMD_FAN1 ||
 2729             sc->lm_sensors[n].reg == LMD_FAN2) {
 2730                 data = (*sc->lm_readreg)(sc, LMD_VIDFAN);
 2731                 if (sc->lm_sensors[n].reg == LMD_FAN1)
 2732                         divisor = (data >> 4) & 0x03;
 2733                 else
 2734                         divisor = (data >> 6) & 0x03;
 2735         }
 2736 
 2737         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2738         if (data == 0xff || data == 0x00)
 2739                 sc->sensors[n].state = ENVSYS_SINVALID;
 2740         else {
 2741                 sc->sensors[n].state = ENVSYS_SVALID;
 2742                 sc->sensors[n].value_cur = 1350000 / (data << divisor);
 2743         }
 2744         DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
 2745             __func__, n, data, sc->sensors[n].value_cur));
 2746 }
 2747 
 2748 static void
 2749 wb_refresh_sensor_data(struct lm_softc *sc)
 2750 {
 2751         uint8_t banksel, bank;
 2752         int i;
 2753 
 2754         /*
 2755          * Properly save and restore bank selection register.
 2756          */
 2757         banksel = bank = sc->lm_readreg(sc, WB_BANKSEL);
 2758         for (i = 0; i < sc->numsensors; i++) {
 2759                 if (bank != sc->lm_sensors[i].bank) {
 2760                         bank = sc->lm_sensors[i].bank;
 2761                         lm_generic_banksel(sc, bank);
 2762                 }
 2763                 sc->lm_sensors[i].refresh(sc, i);
 2764         }
 2765         lm_generic_banksel(sc, banksel);
 2766 }
 2767 
 2768 static void
 2769 wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n)
 2770 {
 2771         int data;
 2772 
 2773         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2774         /*
 2775          * Depending on the voltage detection method,
 2776          * one of the following formulas is used:
 2777          *      VRM8 method: value = raw * 0.016V
 2778          *      VRM9 method: value = raw * 0.00488V + 0.70V
 2779          */
 2780         if (sc->vrm9)
 2781                 sc->sensors[n].value_cur = (data * 4880) + 700000;
 2782         else
 2783                 sc->sensors[n].value_cur = (data * 16000);
 2784         sc->sensors[n].state = ENVSYS_SVALID;
 2785         DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
 2786            __func__, n, data, sc->sensors[n].value_cur));
 2787 }
 2788 
 2789 static void
 2790 wb_refresh_nvolt(struct lm_softc *sc, int n)
 2791 {
 2792         int data;
 2793 
 2794         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2795         sc->sensors[n].value_cur = ((data << 4) - WB_VREF);
 2796         if (sc->sensors[n].rfact)
 2797                 sc->sensors[n].value_cur *= sc->sensors[n].rfact;
 2798         else
 2799                 sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact;
 2800 
 2801         sc->sensors[n].value_cur /= 10;
 2802         sc->sensors[n].value_cur += WB_VREF * 1000;
 2803         sc->sensors[n].state = ENVSYS_SVALID;
 2804         DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
 2805              __func__, n , data, sc->sensors[n].value_cur));
 2806 }
 2807 
 2808 static void
 2809 wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n)
 2810 {
 2811         int data;
 2812 
 2813         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2814         sc->sensors[n].value_cur = ((data << 3) - WB_W83627EHF_VREF);
 2815         if (sc->sensors[n].rfact)
 2816                 sc->sensors[n].value_cur *= sc->sensors[n].rfact;
 2817         else    
 2818                 sc->sensors[n].value_cur *= RFACT(232, 10);
 2819 
 2820         sc->sensors[n].value_cur /= 10;
 2821         sc->sensors[n].value_cur += WB_W83627EHF_VREF * 1000;
 2822         sc->sensors[n].state = ENVSYS_SVALID;
 2823         DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
 2824             __func__, n , data, sc->sensors[n].value_cur));
 2825 }
 2826 
 2827 static void
 2828 wb_refresh_temp(struct lm_softc *sc, int n)
 2829 {
 2830         int data;
 2831 
 2832         /*
 2833          * The data sheet suggests that the range of the temperature
 2834          * sensor is between -55 degC and +125 degC.  However, values
 2835          * around -48 degC seem to be a very common bogus values.
 2836          * Since such values are unreasonably low, we use -45 degC for
 2837          * the lower limit instead.
 2838          */
 2839         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
 2840         data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
 2841         if (data > 0xfffffff || (data > 0x0fa && data < 0x1a6)) {
 2842                 sc->sensors[n].state = ENVSYS_SINVALID;
 2843         } else {
 2844                 if (data & 0x100)
 2845                         data -= 0x200;
 2846                 sc->sensors[n].state = ENVSYS_SVALID;
 2847                 sc->sensors[n].value_cur = data * 500000 + 273150000;
 2848         }
 2849         DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
 2850             __func__, n , data, sc->sensors[n].value_cur));
 2851 }
 2852 
 2853 static void
 2854 wb_refresh_fanrpm(struct lm_softc *sc, int n)
 2855 {
 2856         int fan, data, divisor = 0;
 2857 
 2858         /* 
 2859          * This is madness; the fan divisor bits are scattered all
 2860          * over the place.
 2861          */
 2862 
 2863         if (sc->lm_sensors[n].reg == LMD_FAN1 ||
 2864             sc->lm_sensors[n].reg == LMD_FAN2 ||
 2865             sc->lm_sensors[n].reg == LMD_FAN3) {
 2866                 data = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
 2867                 fan = (sc->lm_sensors[n].reg - LMD_FAN1);
 2868                 if ((data >> 5) & (1 << fan))
 2869                         divisor |= 0x04;
 2870         }
 2871 
 2872         if (sc->lm_sensors[n].reg == LMD_FAN1 ||
 2873             sc->lm_sensors[n].reg == LMD_FAN2) {
 2874                 data = (*sc->lm_readreg)(sc, LMD_VIDFAN);
 2875                 if (sc->lm_sensors[n].reg == LMD_FAN1)
 2876                         divisor |= (data >> 4) & 0x03;
 2877                 else
 2878                         divisor |= (data >> 6) & 0x03;
 2879         } else if (sc->lm_sensors[n].reg == LMD_FAN3) {
 2880                 data = (*sc->lm_readreg)(sc, WB_PIN);
 2881                 divisor |= (data >> 6) & 0x03;
 2882         } else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 ||
 2883                    sc->lm_sensors[n].reg == WB_BANK0_FAN5) {
 2884                 data = (*sc->lm_readreg)(sc, WB_BANK0_FAN45);
 2885                 if (sc->lm_sensors[n].reg == WB_BANK0_FAN4)
 2886                         divisor |= (data >> 0) & 0x07;
 2887                 else
 2888                         divisor |= (data >> 4) & 0x07;
 2889         }
 2890 
 2891         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2892         if (data >= 0xff || data == 0x00)
 2893                 sc->sensors[n].state = ENVSYS_SINVALID;
 2894         else {
 2895                 sc->sensors[n].state = ENVSYS_SVALID;
 2896                 sc->sensors[n].value_cur = 1350000 / (data << divisor);
 2897         }
 2898         DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
 2899             __func__, n , data, sc->sensors[n].value_cur));
 2900 }
 2901 
 2902 static void
 2903 wb_nct6776f_refresh_fanrpm(struct lm_softc *sc, int n)
 2904 {
 2905         int datah, datal;
 2906 
 2907         datah = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2908         datal = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1);
 2909 
 2910         if ((datah == 0xff) || (datah == 0)) {
 2911                 sc->sensors[n].state = ENVSYS_SINVALID;
 2912         } else {
 2913                 sc->sensors[n].state = ENVSYS_SVALID;
 2914                 sc->sensors[n].value_cur = (datah << 8) | datal;
 2915         }
 2916 }
 2917 
 2918 static void
 2919 wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n)
 2920 {
 2921         int shift, data, divisor = 1;
 2922         uint8_t reg;
 2923 
 2924         shift = 0;
 2925 
 2926         switch (sc->lm_sensors[n].reg) {
 2927         case 0x28:
 2928                 reg = 0x47; shift = 0;
 2929                 break;
 2930         case 0x29:
 2931                 reg = 0x47; shift = 4;
 2932                 break;
 2933         case 0x2a:
 2934                 reg = 0x5b; shift = 0;
 2935                 break;
 2936         case 0xb8:
 2937                 reg = 0x5b; shift = 4;
 2938                 break;
 2939         case 0xb9:
 2940                 reg = 0x5c; shift = 0;
 2941                 break;
 2942         case 0xba:
 2943                 reg = 0x5c; shift = 4;
 2944                 break;
 2945         case 0xbe:
 2946                 reg = 0x9e; shift = 0;
 2947                 break;
 2948         default:
 2949                 reg = 0;
 2950                 break;
 2951         }
 2952 
 2953         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
 2954         if (data == 0xff || data == 0x00)
 2955                 sc->sensors[n].state = ENVSYS_SINVALID;
 2956         else {
 2957                 if (reg != 0)
 2958                         divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7;
 2959                 sc->sensors[n].state = ENVSYS_SVALID;
 2960                 sc->sensors[n].value_cur = 1350000 / (data << divisor);
 2961         }
 2962         DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
 2963             __func__, n , data, sc->sensors[n].value_cur));
 2964 }
 2965 
 2966 static void
 2967 as_refresh_temp(struct lm_softc *sc, int n)
 2968 {
 2969         int data;
 2970 
 2971         /*
 2972          * It seems a shorted temperature diode produces an all-ones
 2973          * bit pattern.
 2974          */
 2975         data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
 2976         data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
 2977         if (data == 0x1ff)
 2978                 sc->sensors[n].state = ENVSYS_SINVALID;
 2979         else {
 2980                 if (data & 0x100)
 2981                         data -= 0x200;
 2982                 sc->sensors[n].state = ENVSYS_SVALID;
 2983                 sc->sensors[n].value_cur = data * 500000 + 273150000;
 2984         }
 2985         DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
 2986             __func__, n, data, sc->sensors[n].value_cur));
 2987 }
 2988 
 2989 MODULE(MODULE_CLASS_DRIVER, lm, "sysmon_envsys");
 2990 
 2991 static int
 2992 lm_modcmd(modcmd_t cmd, void *opaque)
 2993 {
 2994         switch (cmd) {
 2995         case MODULE_CMD_INIT:
 2996         case MODULE_CMD_FINI:
 2997                 return 0;
 2998         default:
 2999                 return ENOTTY;
 3000         }
 3001 }

Cache object: 2f7a63661adfa55e8ba6d803af2b6574


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