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