xref: /netbsd-src/sys/dev/ic/nslm7x.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
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 }
2194