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