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