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