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

Cache object: c12c0e2b186b68a7c64c280a6a5fce19


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