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