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