1 /*	$NetBSD: nslm7x.c,v 1.64 2016/06/01 08:06:38 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.64 2016/06/01 08:06:38 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 static void wb_nct6776f_refresh_fanrpm(struct lm_softc *, int);
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 /*  NCT6776F */
1623 static struct lm_sensor nct6776f_sensors[] = {
1624 	/* Voltage */
1625 	{
1626 		.desc = "VCore",
1627 		.type = ENVSYS_SVOLTS_DC,
1628 		.bank = 0,
1629 		.reg = 0x20,
1630 		.refresh = lm_refresh_volt,
1631 		.rfact = RFACT_NONE / 2
1632 	},
1633 	{
1634 		.desc = "+12V",
1635 		.type = ENVSYS_SVOLTS_DC,
1636 		.bank = 0,
1637 		.reg = 0x21,
1638 		.refresh = lm_refresh_volt,
1639 		.rfact = RFACT(56, 10) / 2
1640 	},
1641 	{
1642 		.desc = "AVCC",
1643 		.type = ENVSYS_SVOLTS_DC,
1644 		.bank = 0,
1645 		.reg = 0x22,
1646 		.refresh = lm_refresh_volt,
1647 		.rfact = RFACT(34, 34) / 2
1648 	},
1649 	{
1650 		.desc = "+3.3V",
1651 		.type = ENVSYS_SVOLTS_DC,
1652 		.bank = 0,
1653 		.reg = 0x23,
1654 		.refresh = lm_refresh_volt,
1655 		.rfact = RFACT(34, 34) / 2
1656 	},
1657 	{
1658 		.desc = "-12V",
1659 		.type = ENVSYS_SVOLTS_DC,
1660 		.bank = 0,
1661 		.reg = 0x24,
1662 		.refresh = wb_w83627ehf_refresh_nvolt,
1663 		.rfact = 0
1664 	},
1665 	{
1666 		.desc = "+5V",
1667 		.type = ENVSYS_SVOLTS_DC,
1668 		.bank = 0,
1669 		.reg = 0x25,
1670 		.refresh = lm_refresh_volt,
1671 		.rfact = 16000
1672 	},
1673 	{
1674 		.desc = "VIN3",
1675 		.type = ENVSYS_SVOLTS_DC,
1676 		.bank = 0,
1677 		.reg = 0x26,
1678 		.refresh = lm_refresh_volt,
1679 		.rfact = RFACT_NONE
1680 	},
1681 	{
1682 		.desc = "+3.3VSB",
1683 		.type = ENVSYS_SVOLTS_DC,
1684 		.bank = 5,
1685 		.reg = 0x50,
1686 		.refresh = lm_refresh_volt,
1687 		.rfact = RFACT(34, 34) / 2
1688 	},
1689 	{
1690 		.desc = "VBAT",
1691 		.type = ENVSYS_SVOLTS_DC,
1692 		.bank = 5,
1693 		.reg = 0x51,
1694 		.refresh = lm_refresh_volt,
1695 		.rfact = RFACT(34, 34) / 2
1696 	},
1697 
1698 	/* Temperature */
1699 	{
1700 		.desc = "MB Temperature",
1701 		.type = ENVSYS_STEMP,
1702 		.bank = 0,
1703 		.reg = 0x27,
1704 		.refresh = lm_refresh_temp,
1705 		.rfact = 0
1706 	},
1707 	{
1708 		.desc = "CPU Temperature",
1709 		.type = ENVSYS_STEMP,
1710 		.bank = 1,
1711 		.reg = 0x50,
1712 		.refresh = wb_refresh_temp,
1713 		.rfact = 0
1714 	},
1715 	{
1716 		.desc = "Aux Temp",
1717 		.type = ENVSYS_STEMP,
1718 		.bank = 2,
1719 		.reg = 0x50,
1720 		.refresh = wb_refresh_temp,
1721 		.rfact = 0
1722 	},
1723 
1724 	/* Fans */
1725 	{
1726 		.desc = "System Fan",
1727 		.type = ENVSYS_SFANRPM,
1728 		.bank = 6,
1729 		.reg = 0x56,
1730 		.refresh = wb_nct6776f_refresh_fanrpm,
1731 		.rfact = 0
1732 	},
1733 	{
1734 		.desc = "CPU Fan",
1735 		.type = ENVSYS_SFANRPM,
1736 		.bank = 6,
1737 		.reg = 0x58,
1738 		.refresh = wb_nct6776f_refresh_fanrpm,
1739 		.rfact = 0
1740 	},
1741 	{
1742 		.desc = "Aux Fan0",
1743 		.type = ENVSYS_SFANRPM,
1744 		.bank = 6,
1745 		.reg = 0x5a,
1746 		.refresh = wb_nct6776f_refresh_fanrpm,
1747 		.rfact = 0
1748 	},
1749 	{
1750 		.desc = "Aux Fan1",
1751 		.type = ENVSYS_SFANRPM,
1752 		.bank = 6,
1753 		.reg = 0x5c,
1754 		.refresh = wb_nct6776f_refresh_fanrpm,
1755 		.rfact = 0
1756 	},
1757 
1758 	{
1759 		.desc = "Aux Fan2",
1760 		.type = ENVSYS_SFANRPM,
1761 		.bank = 6,
1762 		.reg = 0x5e,
1763 		.refresh = wb_nct6776f_refresh_fanrpm,
1764 		.rfact = 0
1765 	},
1766 
1767 	{ .desc = NULL }
1768 };
1769 
1770 static void
lm_generic_banksel(struct lm_softc * lmsc,int bank)1771 lm_generic_banksel(struct lm_softc *lmsc, int bank)
1772 {
1773 	(*lmsc->lm_writereg)(lmsc, WB_BANKSEL, bank);
1774 }
1775 
1776 /*
1777  * bus independent probe
1778  *
1779  * prerequisites:  lmsc contains valid lm_{read,write}reg() routines
1780  * and associated bus access data is present in attachment's softc
1781  */
1782 int
lm_probe(struct lm_softc * lmsc)1783 lm_probe(struct lm_softc *lmsc)
1784 {
1785 	uint8_t cr;
1786 	int rv;
1787 
1788 	/* Perform LM78 reset */
1789 	/*(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x80); */
1790 
1791 	cr = (*lmsc->lm_readreg)(lmsc, LMD_CONFIG);
1792 
1793 	/* XXX - spec says *only* 0x08! */
1794 	if ((cr == 0x08) || (cr == 0x01) || (cr == 0x03) || (cr == 0x06))
1795 		rv = 1;
1796 	else
1797 		rv = 0;
1798 
1799 	DPRINTF(("%s: rv = %d, cr = %x\n", __func__, rv, cr));
1800 
1801 	return rv;
1802 }
1803 
1804 void
lm_attach(struct lm_softc * lmsc)1805 lm_attach(struct lm_softc *lmsc)
1806 {
1807 	uint32_t i;
1808 
1809 	for (i = 0; i < __arraycount(lm_chips); i++)
1810 		if (lm_chips[i].chip_match(lmsc))
1811 			break;
1812 
1813 	/* Start the monitoring loop */
1814 	(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x01);
1815 
1816 	lmsc->sc_sme = sysmon_envsys_create();
1817 	/* Initialize sensors */
1818 	for (i = 0; i < lmsc->numsensors; i++) {
1819 		lmsc->sensors[i].state = ENVSYS_SINVALID;
1820 		if (sysmon_envsys_sensor_attach(lmsc->sc_sme,
1821 						&lmsc->sensors[i])) {
1822 			sysmon_envsys_destroy(lmsc->sc_sme);
1823 			return;
1824 		}
1825 	}
1826 
1827 	/*
1828 	 * Setup the callout to refresh sensor data every 2 seconds.
1829 	 */
1830 	callout_init(&lmsc->sc_callout, 0);
1831 	callout_setfunc(&lmsc->sc_callout, lm_refresh, lmsc);
1832 	callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO);
1833 
1834 	/*
1835 	 * Hook into the System Monitor.
1836 	 */
1837 	lmsc->sc_sme->sme_name = device_xname(lmsc->sc_dev);
1838 	lmsc->sc_sme->sme_flags = SME_DISABLE_REFRESH;
1839 
1840 	if (sysmon_envsys_register(lmsc->sc_sme)) {
1841 		aprint_error_dev(lmsc->sc_dev,
1842 		    "unable to register with sysmon\n");
1843 		sysmon_envsys_destroy(lmsc->sc_sme);
1844 	}
1845 }
1846 
1847 /*
1848  * Stop, destroy the callout and unregister the driver with the
1849  * sysmon_envsys(9) framework.
1850  */
1851 void
lm_detach(struct lm_softc * lmsc)1852 lm_detach(struct lm_softc *lmsc)
1853 {
1854 	callout_halt(&lmsc->sc_callout, NULL);
1855 	callout_destroy(&lmsc->sc_callout);
1856 	sysmon_envsys_unregister(lmsc->sc_sme);
1857 }
1858 
1859 static void
lm_refresh(void * arg)1860 lm_refresh(void *arg)
1861 {
1862 	struct lm_softc *lmsc = arg;
1863 
1864 	lmsc->refresh_sensor_data(lmsc);
1865 	callout_schedule(&lmsc->sc_callout, LM_REFRESH_TIMO);
1866 }
1867 
1868 static int
lm_match(struct lm_softc * sc)1869 lm_match(struct lm_softc *sc)
1870 {
1871 	const char *model = NULL;
1872 	int chipid;
1873 
1874 	/* See if we have an LM78/LM78J/LM79 or LM81 */
1875 	chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK;
1876 	switch(chipid) {
1877 	case LM_ID_LM78:
1878 		model = "LM78";
1879 		break;
1880 	case LM_ID_LM78J:
1881 		model = "LM78J";
1882 		break;
1883 	case LM_ID_LM79:
1884 		model = "LM79";
1885 		break;
1886 	case LM_ID_LM81:
1887 		model = "LM81";
1888 		break;
1889 	default:
1890 		return 0;
1891 	}
1892 
1893 	aprint_naive("\n");
1894 	aprint_normal("\n");
1895 	aprint_normal_dev(sc->sc_dev,
1896 	    "National Semiconductor %s Hardware monitor\n", model);
1897 
1898 	lm_setup_sensors(sc, lm78_sensors);
1899 	sc->refresh_sensor_data = lm_refresh_sensor_data;
1900 	return 1;
1901 }
1902 
1903 static int
def_match(struct lm_softc * sc)1904 def_match(struct lm_softc *sc)
1905 {
1906 	int chipid;
1907 
1908 	chipid = (*sc->lm_readreg)(sc, LMD_CHIPID) & LM_ID_MASK;
1909 	aprint_naive("\n");
1910 	aprint_normal("\n");
1911 	aprint_error_dev(sc->sc_dev, "Unknown chip (ID %d)\n", chipid);
1912 
1913 	lm_setup_sensors(sc, lm78_sensors);
1914 	sc->refresh_sensor_data = lm_refresh_sensor_data;
1915 	return 1;
1916 }
1917 
1918 static void
wb_temp_diode_type(struct lm_softc * sc,int diode_type)1919 wb_temp_diode_type(struct lm_softc *sc, int diode_type)
1920 {
1921 	int regval, banksel;
1922 
1923 	banksel = (*sc->lm_readreg)(sc, WB_BANKSEL);
1924 	switch (diode_type) {
1925 	    case 1:	/* Switch to Pentium-II diode mode */
1926 		lm_generic_banksel(sc, WB_BANKSEL_B0);
1927 		regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
1928 		regval |= 0x0e;
1929 		(*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval);
1930 		regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1);
1931 		regval |= 0x70;
1932 		(*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0);
1933 		lm_generic_banksel(sc, banksel);
1934 		aprint_verbose_dev(sc->sc_dev, "Pentium-II diode temp sensors\n");
1935 		break;
1936 	    case 2:	/* Switch to 2N3904 mode */
1937 		lm_generic_banksel(sc, WB_BANKSEL_B0);
1938 		regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
1939 		regval |= 0xe;
1940 		(*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval);
1941 		regval = (*sc->lm_readreg)(sc, WB_BANK0_RESVD1);
1942 		regval &= ~0x70;
1943 		(*sc->lm_writereg)(sc, WB_BANK0_RESVD1, 0x0);
1944 		lm_generic_banksel(sc, banksel);
1945 		aprint_verbose_dev(sc->sc_dev, "2N3904 bipolar temp sensors\n");
1946 		break;
1947 	    case 4:	/* Switch to generic thermistor mode */
1948 		lm_generic_banksel(sc, WB_BANKSEL_B0);
1949 		regval = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
1950 		regval &= ~0xe;
1951 		(*sc->lm_writereg)(sc, WB_BANK0_VBAT, regval);
1952 		lm_generic_banksel(sc, banksel);
1953 		aprint_verbose_dev(sc->sc_dev, "Thermistor temp sensors\n");
1954 		break;
1955 	    case 0:	/* Unspecified - use default */
1956 		aprint_verbose_dev(sc->sc_dev, "Using default temp sensors\n");
1957 		break;
1958 	    default:
1959 		aprint_error_dev(sc->sc_dev,
1960 				 "Ignoring invalid temp sensor mode %d\n",
1961 				 diode_type);
1962 		break;
1963 	}
1964 }
1965 
1966 static int
wb_match(struct lm_softc * sc)1967 wb_match(struct lm_softc *sc)
1968 {
1969 	const char *model = NULL;
1970 	const char *vendor = "Winbond";
1971 	int banksel, vendid, cf_flags;
1972 
1973 	aprint_naive("\n");
1974 	aprint_normal("\n");
1975 	/* Read vendor ID */
1976 	banksel = (*sc->lm_readreg)(sc, WB_BANKSEL);
1977 	lm_generic_banksel(sc, WB_BANKSEL_HBAC);
1978 	vendid = (*sc->lm_readreg)(sc, WB_VENDID) << 8;
1979 	lm_generic_banksel(sc, 0);
1980 	vendid |= (*sc->lm_readreg)(sc, WB_VENDID);
1981 	DPRINTF(("%s: winbond vend id 0x%x\n", __func__, vendid));
1982 	if (vendid != WB_VENDID_WINBOND && vendid != WB_VENDID_ASUS)
1983 		return 0;
1984 
1985 	/* Read device/chip ID */
1986 	lm_generic_banksel(sc, WB_BANKSEL_B0);
1987 	(void)(*sc->lm_readreg)(sc, LMD_CHIPID);
1988 	sc->chipid = (*sc->lm_readreg)(sc, WB_BANK0_CHIPID);
1989 	lm_generic_banksel(sc, banksel);
1990 	cf_flags = device_cfdata(sc->sc_dev)->cf_flags;
1991 	DPRINTF(("%s: winbond chip id 0x%x\n", __func__, sc->chipid));
1992 
1993 	switch(sc->chipid) {
1994 	case WB_CHIPID_W83627HF:
1995 		model = "W83627HF";
1996 		lm_setup_sensors(sc, w83627hf_sensors);
1997 		wb_temp_diode_type(sc, cf_flags);
1998 		break;
1999 	case WB_CHIPID_W83627THF:
2000 		model = "W83627THF";
2001 		lm_generic_banksel(sc, WB_BANKSEL_B0);
2002 		if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9)
2003 			sc->vrm9 = 1;
2004 		lm_generic_banksel(sc, banksel);
2005 		lm_setup_sensors(sc, w83637hf_sensors);
2006 		wb_temp_diode_type(sc, cf_flags);
2007 		break;
2008 	case WB_CHIPID_W83627EHF_A:
2009 		model = "W83627EHF-A";
2010 		lm_setup_sensors(sc, w83627ehf_sensors);
2011 		break;
2012 	case WB_CHIPID_W83627EHF:
2013 		model = "W83627EHF";
2014 		lm_setup_sensors(sc, w83627ehf_sensors);
2015 		wb_temp_diode_type(sc, cf_flags);
2016 		break;
2017 	case WB_CHIPID_W83627DHG:
2018 		if (sc->sioid == WBSIO_ID_NCT6776F) {
2019 			vendor = "Nuvoton";
2020 			model = "NCT6776F";
2021 			lm_setup_sensors(sc, nct6776f_sensors);
2022 		} else {
2023 			model = "W83627DHG";
2024 			lm_setup_sensors(sc, w83627dhg_sensors);
2025 		}
2026 		wb_temp_diode_type(sc, cf_flags);
2027 		break;
2028 	case WB_CHIPID_W83637HF:
2029 		model = "W83637HF";
2030 		lm_generic_banksel(sc, WB_BANKSEL_B0);
2031 		if ((*sc->lm_readreg)(sc, WB_BANK0_CONFIG) & WB_CONFIG_VMR9)
2032 			sc->vrm9 = 1;
2033 		lm_generic_banksel(sc, banksel);
2034 		lm_setup_sensors(sc, w83637hf_sensors);
2035 		wb_temp_diode_type(sc, cf_flags);
2036 		break;
2037 	case WB_CHIPID_W83697HF:
2038 		model = "W83697HF";
2039 		lm_setup_sensors(sc, w83697hf_sensors);
2040 		wb_temp_diode_type(sc, cf_flags);
2041 		break;
2042 	case WB_CHIPID_W83781D:
2043 	case WB_CHIPID_W83781D_2:
2044 		model = "W83781D";
2045 		lm_setup_sensors(sc, w83781d_sensors);
2046 		break;
2047 	case WB_CHIPID_W83782D:
2048 		model = "W83782D";
2049 		lm_setup_sensors(sc, w83782d_sensors);
2050 		wb_temp_diode_type(sc, cf_flags);
2051 		break;
2052 	case WB_CHIPID_W83783S:
2053 		model = "W83783S";
2054 		lm_setup_sensors(sc, w83783s_sensors);
2055 		wb_temp_diode_type(sc, cf_flags);
2056 		break;
2057 	case WB_CHIPID_W83791D:
2058 		model = "W83791D";
2059 		lm_setup_sensors(sc, w83791d_sensors);
2060 		wb_temp_diode_type(sc, cf_flags);
2061 		break;
2062 	case WB_CHIPID_W83791SD:
2063 		model = "W83791SD";
2064 		break;
2065 	case WB_CHIPID_W83792D:
2066 		model = "W83792D";
2067 		lm_setup_sensors(sc, w83792d_sensors);
2068 		break;
2069 	case WB_CHIPID_AS99127F:
2070 		vendor = "ASUS";
2071 		if (vendid == WB_VENDID_ASUS) {
2072 			model = "AS99127F";
2073 			lm_setup_sensors(sc, w83781d_sensors);
2074 		} else {
2075 			model = "AS99127F rev 2";
2076 			lm_setup_sensors(sc, as99127f_sensors);
2077 		}
2078 		break;
2079 	default:
2080 		aprint_normal_dev(sc->sc_dev,
2081 		    "unknown Winbond chip (ID 0x%x)\n", sc->chipid);
2082 		/* Handle as a standard LM78. */
2083 		lm_setup_sensors(sc, lm78_sensors);
2084 		sc->refresh_sensor_data = lm_refresh_sensor_data;
2085 		return 1;
2086 	}
2087 
2088 	aprint_normal_dev(sc->sc_dev, "%s %s Hardware monitor\n", vendor, model);
2089 
2090 	sc->refresh_sensor_data = wb_refresh_sensor_data;
2091 	return 1;
2092 }
2093 
2094 static void
lm_setup_sensors(struct lm_softc * sc,struct lm_sensor * sensors)2095 lm_setup_sensors(struct lm_softc *sc, struct lm_sensor *sensors)
2096 {
2097 	int i;
2098 
2099 	for (i = 0; sensors[i].desc; i++) {
2100 		sc->sensors[i].units = sensors[i].type;
2101 		if (sc->sensors[i].units == ENVSYS_SVOLTS_DC)
2102 			sc->sensors[i].flags = ENVSYS_FCHANGERFACT;
2103 		strlcpy(sc->sensors[i].desc, sensors[i].desc,
2104 		    sizeof(sc->sensors[i].desc));
2105 		sc->numsensors++;
2106 	}
2107 	sc->lm_sensors = sensors;
2108 }
2109 
2110 static void
lm_refresh_sensor_data(struct lm_softc * sc)2111 lm_refresh_sensor_data(struct lm_softc *sc)
2112 {
2113 	int i;
2114 
2115 	for (i = 0; i < sc->numsensors; i++)
2116 		sc->lm_sensors[i].refresh(sc, i);
2117 }
2118 
2119 static void
lm_refresh_volt(struct lm_softc * sc,int n)2120 lm_refresh_volt(struct lm_softc *sc, int n)
2121 {
2122 	int data;
2123 
2124 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2125 	if (data == 0xff) {
2126 		sc->sensors[n].state = ENVSYS_SINVALID;
2127 	} else {
2128 		sc->sensors[n].value_cur = (data << 4);
2129 		if (sc->sensors[n].rfact) {
2130 			sc->sensors[n].value_cur *= sc->sensors[n].rfact;
2131 			sc->sensors[n].value_cur /= 10;
2132 		} else {
2133 			sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact;
2134 			sc->sensors[n].value_cur /= 10;
2135 			sc->sensors[n].rfact = sc->lm_sensors[n].rfact;
2136 		}
2137 		sc->sensors[n].state = ENVSYS_SVALID;
2138 	}
2139 
2140 	DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
2141 	    __func__, n, data, sc->sensors[n].value_cur));
2142 }
2143 
2144 static void
lm_refresh_temp(struct lm_softc * sc,int n)2145 lm_refresh_temp(struct lm_softc *sc, int n)
2146 {
2147 	int data;
2148 
2149 	/*
2150 	 * The data sheet suggests that the range of the temperature
2151 	 * sensor is between -55 degC and +125 degC.
2152 	 */
2153 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2154 	if (data > 0x7d && data < 0xc9)
2155 		sc->sensors[n].state = ENVSYS_SINVALID;
2156 	else {
2157 		if (data & 0x80)
2158 			data -= 0x100;
2159 		sc->sensors[n].state = ENVSYS_SVALID;
2160 		sc->sensors[n].value_cur = data * 1000000 + 273150000;
2161 	}
2162 	DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
2163 	    __func__, n, data, sc->sensors[n].value_cur));
2164 }
2165 
2166 static void
lm_refresh_fanrpm(struct lm_softc * sc,int n)2167 lm_refresh_fanrpm(struct lm_softc *sc, int n)
2168 {
2169 	int data, divisor = 1;
2170 
2171 	/*
2172 	 * We might get more accurate fan readings by adjusting the
2173 	 * divisor, but that might interfere with APM or other SMM
2174 	 * BIOS code reading the fan speeds.
2175 	 */
2176 
2177 	/* FAN3 has a fixed fan divisor. */
2178 	if (sc->lm_sensors[n].reg == LMD_FAN1 ||
2179 	    sc->lm_sensors[n].reg == LMD_FAN2) {
2180 		data = (*sc->lm_readreg)(sc, LMD_VIDFAN);
2181 		if (sc->lm_sensors[n].reg == LMD_FAN1)
2182 			divisor = (data >> 4) & 0x03;
2183 		else
2184 			divisor = (data >> 6) & 0x03;
2185 	}
2186 
2187 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2188 	if (data == 0xff || data == 0x00)
2189 		sc->sensors[n].state = ENVSYS_SINVALID;
2190 	else {
2191 		sc->sensors[n].state = ENVSYS_SVALID;
2192 		sc->sensors[n].value_cur = 1350000 / (data << divisor);
2193 	}
2194 	DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
2195 	    __func__, n, data, sc->sensors[n].value_cur));
2196 }
2197 
2198 static void
wb_refresh_sensor_data(struct lm_softc * sc)2199 wb_refresh_sensor_data(struct lm_softc *sc)
2200 {
2201 	int banksel, bank, i;
2202 
2203 	/*
2204 	 * Properly save and restore bank selection register.
2205 	 */
2206 	banksel = bank = sc->lm_readreg(sc, WB_BANKSEL);
2207 	for (i = 0; i < sc->numsensors; i++) {
2208 		if (bank != sc->lm_sensors[i].bank) {
2209 			bank = sc->lm_sensors[i].bank;
2210 			lm_generic_banksel(sc, bank);
2211 		}
2212 		sc->lm_sensors[i].refresh(sc, i);
2213 	}
2214 	lm_generic_banksel(sc, banksel);
2215 }
2216 
2217 static void
wb_w83637hf_refresh_vcore(struct lm_softc * sc,int n)2218 wb_w83637hf_refresh_vcore(struct lm_softc *sc, int n)
2219 {
2220 	int data;
2221 
2222 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2223 	/*
2224 	 * Depending on the voltage detection method,
2225 	 * one of the following formulas is used:
2226 	 *	VRM8 method: value = raw * 0.016V
2227 	 *	VRM9 method: value = raw * 0.00488V + 0.70V
2228 	 */
2229 	if (sc->vrm9)
2230 		sc->sensors[n].value_cur = (data * 4880) + 700000;
2231 	else
2232 		sc->sensors[n].value_cur = (data * 16000);
2233 	sc->sensors[n].state = ENVSYS_SVALID;
2234 	DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
2235 	   __func__, n, data, sc->sensors[n].value_cur));
2236 }
2237 
2238 static void
wb_refresh_nvolt(struct lm_softc * sc,int n)2239 wb_refresh_nvolt(struct lm_softc *sc, int n)
2240 {
2241 	int data;
2242 
2243 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2244 	sc->sensors[n].value_cur = ((data << 4) - WB_VREF);
2245 	if (sc->sensors[n].rfact)
2246 		sc->sensors[n].value_cur *= sc->sensors[n].rfact;
2247 	else
2248 		sc->sensors[n].value_cur *= sc->lm_sensors[n].rfact;
2249 
2250 	sc->sensors[n].value_cur /= 10;
2251 	sc->sensors[n].value_cur += WB_VREF * 1000;
2252 	sc->sensors[n].state = ENVSYS_SVALID;
2253 	DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
2254 	     __func__, n , data, sc->sensors[n].value_cur));
2255 }
2256 
2257 static void
wb_w83627ehf_refresh_nvolt(struct lm_softc * sc,int n)2258 wb_w83627ehf_refresh_nvolt(struct lm_softc *sc, int n)
2259 {
2260 	int data;
2261 
2262 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2263 	sc->sensors[n].value_cur = ((data << 3) - WB_W83627EHF_VREF);
2264 	if (sc->sensors[n].rfact)
2265 		sc->sensors[n].value_cur *= sc->sensors[n].rfact;
2266 	else
2267 		sc->sensors[n].value_cur *= RFACT(232, 10);
2268 
2269 	sc->sensors[n].value_cur /= 10;
2270 	sc->sensors[n].value_cur += WB_W83627EHF_VREF * 1000;
2271 	sc->sensors[n].state = ENVSYS_SVALID;
2272 	DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
2273 	    __func__, n , data, sc->sensors[n].value_cur));
2274 }
2275 
2276 static void
wb_refresh_temp(struct lm_softc * sc,int n)2277 wb_refresh_temp(struct lm_softc *sc, int n)
2278 {
2279 	int data;
2280 
2281 	/*
2282 	 * The data sheet suggests that the range of the temperature
2283 	 * sensor is between -55 degC and +125 degC.  However, values
2284 	 * around -48 degC seem to be a very common bogus values.
2285 	 * Since such values are unreasonably low, we use -45 degC for
2286 	 * the lower limit instead.
2287 	 */
2288 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
2289 	data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
2290 	if (data > 0xfffffff || (data > 0x0fa && data < 0x1a6)) {
2291 		sc->sensors[n].state = ENVSYS_SINVALID;
2292 	} else {
2293 		if (data & 0x100)
2294 			data -= 0x200;
2295 		sc->sensors[n].state = ENVSYS_SVALID;
2296 		sc->sensors[n].value_cur = data * 500000 + 273150000;
2297 	}
2298 	DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
2299 	    __func__, n , data, sc->sensors[n].value_cur));
2300 }
2301 
2302 static void
wb_refresh_fanrpm(struct lm_softc * sc,int n)2303 wb_refresh_fanrpm(struct lm_softc *sc, int n)
2304 {
2305 	int fan, data, divisor = 0;
2306 
2307 	/*
2308 	 * This is madness; the fan divisor bits are scattered all
2309 	 * over the place.
2310 	 */
2311 
2312 	if (sc->lm_sensors[n].reg == LMD_FAN1 ||
2313 	    sc->lm_sensors[n].reg == LMD_FAN2 ||
2314 	    sc->lm_sensors[n].reg == LMD_FAN3) {
2315 		data = (*sc->lm_readreg)(sc, WB_BANK0_VBAT);
2316 		fan = (sc->lm_sensors[n].reg - LMD_FAN1);
2317 		if ((data >> 5) & (1 << fan))
2318 			divisor |= 0x04;
2319 	}
2320 
2321 	if (sc->lm_sensors[n].reg == LMD_FAN1 ||
2322 	    sc->lm_sensors[n].reg == LMD_FAN2) {
2323 		data = (*sc->lm_readreg)(sc, LMD_VIDFAN);
2324 		if (sc->lm_sensors[n].reg == LMD_FAN1)
2325 			divisor |= (data >> 4) & 0x03;
2326 		else
2327 			divisor |= (data >> 6) & 0x03;
2328 	} else if (sc->lm_sensors[n].reg == LMD_FAN3) {
2329 		data = (*sc->lm_readreg)(sc, WB_PIN);
2330 		divisor |= (data >> 6) & 0x03;
2331 	} else if (sc->lm_sensors[n].reg == WB_BANK0_FAN4 ||
2332 		   sc->lm_sensors[n].reg == WB_BANK0_FAN5) {
2333 		data = (*sc->lm_readreg)(sc, WB_BANK0_FAN45);
2334 		if (sc->lm_sensors[n].reg == WB_BANK0_FAN4)
2335 			divisor |= (data >> 0) & 0x07;
2336 		else
2337 			divisor |= (data >> 4) & 0x07;
2338 	}
2339 
2340 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2341 	if (data >= 0xff || data == 0x00)
2342 		sc->sensors[n].state = ENVSYS_SINVALID;
2343 	else {
2344 		sc->sensors[n].state = ENVSYS_SVALID;
2345 		sc->sensors[n].value_cur = 1350000 / (data << divisor);
2346 	}
2347 	DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
2348 	    __func__, n , data, sc->sensors[n].value_cur));
2349 }
2350 
2351 static void
wb_nct6776f_refresh_fanrpm(struct lm_softc * sc,int n)2352 wb_nct6776f_refresh_fanrpm(struct lm_softc *sc, int n)
2353 {
2354 	int datah, datal;
2355 
2356 	datah = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2357 	datal = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1);
2358 
2359 	if ((datah == 0xff) || (datah == 0)) {
2360 		sc->sensors[n].state = ENVSYS_SINVALID;
2361 	} else {
2362 		sc->sensors[n].state = ENVSYS_SVALID;
2363 		sc->sensors[n].value_cur = (datah << 8) | datal;
2364 	}
2365 }
2366 
2367 static void
wb_w83792d_refresh_fanrpm(struct lm_softc * sc,int n)2368 wb_w83792d_refresh_fanrpm(struct lm_softc *sc, int n)
2369 {
2370 	int reg, shift, data, divisor = 1;
2371 
2372 	shift = 0;
2373 
2374 	switch (sc->lm_sensors[n].reg) {
2375 	case 0x28:
2376 		reg = 0x47; shift = 0;
2377 		break;
2378 	case 0x29:
2379 		reg = 0x47; shift = 4;
2380 		break;
2381 	case 0x2a:
2382 		reg = 0x5b; shift = 0;
2383 		break;
2384 	case 0xb8:
2385 		reg = 0x5b; shift = 4;
2386 		break;
2387 	case 0xb9:
2388 		reg = 0x5c; shift = 0;
2389 		break;
2390 	case 0xba:
2391 		reg = 0x5c; shift = 4;
2392 		break;
2393 	case 0xbe:
2394 		reg = 0x9e; shift = 0;
2395 		break;
2396 	default:
2397 		reg = 0;
2398 		break;
2399 	}
2400 
2401 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg);
2402 	if (data == 0xff || data == 0x00)
2403 		sc->sensors[n].state = ENVSYS_SINVALID;
2404 	else {
2405 		if (reg != 0)
2406 			divisor = ((*sc->lm_readreg)(sc, reg) >> shift) & 0x7;
2407 		sc->sensors[n].state = ENVSYS_SVALID;
2408 		sc->sensors[n].value_cur = 1350000 / (data << divisor);
2409 	}
2410 	DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
2411 	    __func__, n , data, sc->sensors[n].value_cur));
2412 }
2413 
2414 static void
as_refresh_temp(struct lm_softc * sc,int n)2415 as_refresh_temp(struct lm_softc *sc, int n)
2416 {
2417 	int data;
2418 
2419 	/*
2420 	 * It seems a shorted temperature diode produces an all-ones
2421 	 * bit pattern.
2422 	 */
2423 	data = (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg) << 1;
2424 	data += (*sc->lm_readreg)(sc, sc->lm_sensors[n].reg + 1) >> 7;
2425 	if (data == 0x1ff)
2426 		sc->sensors[n].state = ENVSYS_SINVALID;
2427 	else {
2428 		if (data & 0x100)
2429 			data -= 0x200;
2430 		sc->sensors[n].state = ENVSYS_SVALID;
2431 		sc->sensors[n].value_cur = data * 500000 + 273150000;
2432 	}
2433 	DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
2434 	    __func__, n, data, sc->sensors[n].value_cur));
2435 }
2436 
2437 MODULE(MODULE_CLASS_DRIVER, lm, "sysmon_envsys");
2438 
2439 static int
lm_modcmd(modcmd_t cmd,void * opaque)2440 lm_modcmd(modcmd_t cmd, void *opaque)
2441 {
2442 	switch (cmd) {
2443 	case MODULE_CMD_INIT:
2444 	case MODULE_CMD_FINI:
2445 		return 0;
2446 	default:
2447 		return ENOTTY;
2448 	}
2449 }
2450