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