1 /* $NetBSD: nslm7x.c,v 1.48 2008/10/12 13:17:28 pgoyette Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: nslm7x.c,v 1.48 2008/10/12 13:17:28 pgoyette Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
39 #include <sys/device.h>
45 #include <dev/isa/isareg.h>
46 #include <dev/isa/isavar.h>
48 #include <dev/sysmon/sysmonvar.h>
50 #include <dev/ic/nslm7xvar.h>
55 #define DPRINTF(x) do { printf x; } while (0)
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.
67 #define RFACT_NONE 10000
68 #define RFACT(x, y) (RFACT_NONE * ((x) + (y)) / (y))
69 #define NRFACT(x, y) (-RFACT_NONE * (x) / (y))
71 #define LM_REFRESH_TIMO (2 * hz) /* 2 seconds */
73 static int lm_match(struct lm_softc
*);
74 static int wb_match(struct lm_softc
*);
75 static int def_match(struct lm_softc
*);
77 static void lm_refresh(void *);
79 static void lm_generic_banksel(struct lm_softc
*, int);
80 static void lm_setup_sensors(struct lm_softc
*, struct lm_sensor
*);
81 static void lm_refresh_sensor_data(struct lm_softc
*);
82 static void lm_refresh_volt(struct lm_softc
*, int);
83 static void lm_refresh_temp(struct lm_softc
*, int);
84 static void lm_refresh_fanrpm(struct lm_softc
*, int);
86 static void wb_refresh_sensor_data(struct lm_softc
*);
87 static void wb_w83637hf_refresh_vcore(struct lm_softc
*, int);
88 static void wb_refresh_nvolt(struct lm_softc
*, int);
89 static void wb_w83627ehf_refresh_nvolt(struct lm_softc
*, int);
90 static void wb_refresh_temp(struct lm_softc
*, int);
91 static void wb_refresh_fanrpm(struct lm_softc
*, int);
92 static void wb_w83792d_refresh_fanrpm(struct lm_softc
*, int);
94 static void as_refresh_temp(struct lm_softc
*, int);
97 int (*chip_match
)(struct lm_softc
*);
100 static struct lm_chip lm_chips
[] = {
103 { def_match
} /* Must be last */
107 static struct lm_sensor lm78_sensors
[] = {
111 .type
= ENVSYS_SVOLTS_DC
,
114 .refresh
= lm_refresh_volt
,
119 .type
= ENVSYS_SVOLTS_DC
,
122 .refresh
= lm_refresh_volt
,
127 .type
= ENVSYS_SVOLTS_DC
,
130 .refresh
= lm_refresh_volt
,
135 .type
= ENVSYS_SVOLTS_DC
,
138 .refresh
= lm_refresh_volt
,
139 .rfact
= RFACT(68, 100)
143 .type
= ENVSYS_SVOLTS_DC
,
146 .refresh
= lm_refresh_volt
,
147 .rfact
= RFACT(30, 10)
151 .type
= ENVSYS_SVOLTS_DC
,
154 .refresh
= lm_refresh_volt
,
155 .rfact
= NRFACT(240, 60)
159 .type
= ENVSYS_SVOLTS_DC
,
162 .refresh
= lm_refresh_volt
,
163 .rfact
= NRFACT(100, 60)
169 .type
= ENVSYS_STEMP
,
172 .refresh
= lm_refresh_temp
,
179 .type
= ENVSYS_SFANRPM
,
182 .refresh
= lm_refresh_fanrpm
,
187 .type
= ENVSYS_SFANRPM
,
190 .refresh
= lm_refresh_fanrpm
,
195 .type
= ENVSYS_SFANRPM
,
198 .refresh
= lm_refresh_fanrpm
,
206 static struct lm_sensor w83627hf_sensors
[] = {
210 .type
= ENVSYS_SVOLTS_DC
,
213 .refresh
= lm_refresh_volt
,
218 .type
= ENVSYS_SVOLTS_DC
,
221 .refresh
= lm_refresh_volt
,
226 .type
= ENVSYS_SVOLTS_DC
,
229 .refresh
= lm_refresh_volt
,
234 .type
= ENVSYS_SVOLTS_DC
,
237 .refresh
= lm_refresh_volt
,
238 .rfact
= RFACT(34, 50)
242 .type
= ENVSYS_SVOLTS_DC
,
245 .refresh
= lm_refresh_volt
,
246 .rfact
= RFACT(28, 10)
250 .type
= ENVSYS_SVOLTS_DC
,
253 .refresh
= wb_refresh_nvolt
,
254 .rfact
= RFACT(232, 56)
258 .type
= ENVSYS_SVOLTS_DC
,
261 .refresh
= wb_refresh_nvolt
,
262 .rfact
= RFACT(120, 56)
266 .type
= ENVSYS_SVOLTS_DC
,
269 .refresh
= lm_refresh_volt
,
270 .rfact
= RFACT(17, 33)
274 .type
= ENVSYS_SVOLTS_DC
,
277 .refresh
= lm_refresh_volt
,
284 .type
= ENVSYS_STEMP
,
287 .refresh
= lm_refresh_temp
,
292 .type
= ENVSYS_STEMP
,
295 .refresh
= wb_refresh_temp
,
300 .type
= ENVSYS_STEMP
,
303 .refresh
= wb_refresh_temp
,
310 .type
= ENVSYS_SFANRPM
,
313 .refresh
= wb_refresh_fanrpm
,
318 .type
= ENVSYS_SFANRPM
,
321 .refresh
= wb_refresh_fanrpm
,
326 .type
= ENVSYS_SFANRPM
,
329 .refresh
= wb_refresh_fanrpm
,
339 * The W83627EHF can measure voltages up to 2.048 V instead of the
340 * traditional 4.096 V. For measuring positive voltages, this can be
341 * accounted for by halving the resistor factor. Negative voltages
342 * need special treatment, also because the reference voltage is 2.048 V
343 * instead of the traditional 3.6 V.
345 static struct lm_sensor w83627ehf_sensors
[] = {
349 .type
= ENVSYS_SVOLTS_DC
,
352 .refresh
= lm_refresh_volt
,
353 .rfact
= RFACT_NONE
/ 2
357 .type
= ENVSYS_SVOLTS_DC
,
360 .refresh
= lm_refresh_volt
,
361 .rfact
= RFACT(56, 10) / 2
365 .type
= ENVSYS_SVOLTS_DC
,
368 .refresh
= lm_refresh_volt
,
369 .rfact
= RFACT(34, 34) / 2
373 .type
= ENVSYS_SVOLTS_DC
,
376 .refresh
= lm_refresh_volt
,
377 .rfact
= RFACT(34, 34) / 2
381 .type
= ENVSYS_SVOLTS_DC
,
384 .refresh
= wb_w83627ehf_refresh_nvolt
,
389 .type
= ENVSYS_SVOLTS_DC
,
392 .refresh
= lm_refresh_volt
,
393 .rfact
= RFACT_NONE
/ 2
397 .type
= ENVSYS_SVOLTS_DC
,
400 .refresh
= lm_refresh_volt
,
401 .rfact
= RFACT_NONE
/ 2
405 .type
= ENVSYS_SVOLTS_DC
,
408 .refresh
= lm_refresh_volt
,
409 .rfact
= RFACT(34, 34) / 2
413 .type
= ENVSYS_SVOLTS_DC
,
416 .refresh
= lm_refresh_volt
,
417 .rfact
= RFACT_NONE
/ 2
421 .type
= ENVSYS_SVOLTS_DC
,
424 .refresh
= lm_refresh_volt
,
425 .rfact
= RFACT_NONE
/ 2
431 .type
= ENVSYS_STEMP
,
434 .refresh
= lm_refresh_temp
,
439 .type
= ENVSYS_STEMP
,
442 .refresh
= wb_refresh_temp
,
447 .type
= ENVSYS_STEMP
,
450 .refresh
= wb_refresh_temp
,
457 .type
= ENVSYS_SFANRPM
,
460 .refresh
= wb_refresh_fanrpm
,
465 .type
= ENVSYS_SFANRPM
,
468 .refresh
= wb_refresh_fanrpm
,
473 .type
= ENVSYS_SFANRPM
,
476 .refresh
= wb_refresh_fanrpm
,
484 static struct lm_sensor w83627dhg_sensors
[] = {
488 .type
= ENVSYS_SVOLTS_DC
,
491 .refresh
= lm_refresh_volt
,
492 .rfact
= RFACT_NONE
/ 2
496 .type
= ENVSYS_SVOLTS_DC
,
499 .refresh
= lm_refresh_volt
,
500 .rfact
= RFACT(56, 10) / 2
504 .type
= ENVSYS_SVOLTS_DC
,
507 .refresh
= lm_refresh_volt
,
508 .rfact
= RFACT(34, 34) / 2
512 .type
= ENVSYS_SVOLTS_DC
,
515 .refresh
= lm_refresh_volt
,
516 .rfact
= RFACT(34, 34) / 2
520 .type
= ENVSYS_SVOLTS_DC
,
523 .refresh
= wb_w83627ehf_refresh_nvolt
,
528 .type
= ENVSYS_SVOLTS_DC
,
531 .refresh
= lm_refresh_volt
,
536 .type
= ENVSYS_SVOLTS_DC
,
539 .refresh
= lm_refresh_volt
,
544 .type
= ENVSYS_SVOLTS_DC
,
547 .refresh
= lm_refresh_volt
,
548 .rfact
= RFACT(34, 34) / 2
552 .type
= ENVSYS_SVOLTS_DC
,
555 .refresh
= lm_refresh_volt
,
556 .rfact
= RFACT(34, 34) / 2
561 .desc
= "MB Temperature",
562 .type
= ENVSYS_STEMP
,
565 .refresh
= lm_refresh_temp
,
569 .desc
= "CPU Temperature",
570 .type
= ENVSYS_STEMP
,
573 .refresh
= lm_refresh_temp
,
578 .type
= ENVSYS_STEMP
,
581 .refresh
= lm_refresh_temp
,
587 .desc
= "System Fan",
588 .type
= ENVSYS_SFANRPM
,
591 .refresh
= wb_refresh_fanrpm
,
596 .type
= ENVSYS_SFANRPM
,
599 .refresh
= wb_refresh_fanrpm
,
604 .type
= ENVSYS_SFANRPM
,
607 .refresh
= wb_refresh_fanrpm
,
615 static struct lm_sensor w83637hf_sensors
[] = {
619 .type
= ENVSYS_SVOLTS_DC
,
622 .refresh
= wb_w83637hf_refresh_vcore
,
627 .type
= ENVSYS_SVOLTS_DC
,
630 .refresh
= lm_refresh_volt
,
631 .rfact
= RFACT(28, 10)
635 .type
= ENVSYS_SVOLTS_DC
,
638 .refresh
= lm_refresh_volt
,
643 .type
= ENVSYS_SVOLTS_DC
,
646 .refresh
= lm_refresh_volt
,
647 .rfact
= RFACT(34, 51)
651 .type
= ENVSYS_SVOLTS_DC
,
654 .refresh
= wb_refresh_nvolt
,
655 .rfact
= RFACT(232, 56)
659 .type
= ENVSYS_SVOLTS_DC
,
662 .refresh
= lm_refresh_volt
,
663 .rfact
= RFACT(34, 51)
667 .type
= ENVSYS_SVOLTS_DC
,
670 .refresh
= lm_refresh_volt
,
677 .type
= ENVSYS_STEMP
,
680 .refresh
= lm_refresh_temp
,
685 .type
= ENVSYS_STEMP
,
688 .refresh
= wb_refresh_temp
,
693 .type
= ENVSYS_STEMP
,
696 .refresh
= wb_refresh_temp
,
703 .type
= ENVSYS_SFANRPM
,
706 .refresh
= wb_refresh_fanrpm
,
711 .type
= ENVSYS_SFANRPM
,
714 .refresh
= wb_refresh_fanrpm
,
719 .type
= ENVSYS_SFANRPM
,
722 .refresh
= wb_refresh_fanrpm
,
730 static struct lm_sensor w83697hf_sensors
[] = {
734 .type
= ENVSYS_SVOLTS_DC
,
737 .refresh
= lm_refresh_volt
,
742 .type
= ENVSYS_SVOLTS_DC
,
745 .refresh
= lm_refresh_volt
,
750 .type
= ENVSYS_SVOLTS_DC
,
753 .refresh
= lm_refresh_volt
,
754 .rfact
= RFACT(34, 50)
758 .type
= ENVSYS_SVOLTS_DC
,
761 .refresh
= lm_refresh_volt
,
762 .rfact
= RFACT(28, 10)
766 .type
= ENVSYS_SVOLTS_DC
,
769 .refresh
= wb_refresh_nvolt
,
770 .rfact
= RFACT(232, 56)
774 .type
= ENVSYS_SVOLTS_DC
,
777 .refresh
= wb_refresh_nvolt
,
778 .rfact
= RFACT(120, 56)
782 .type
= ENVSYS_SVOLTS_DC
,
785 .refresh
= lm_refresh_volt
,
786 .rfact
= RFACT(17, 33)
790 .type
= ENVSYS_SVOLTS_DC
,
793 .refresh
= lm_refresh_volt
,
800 .type
= ENVSYS_STEMP
,
803 .refresh
= lm_refresh_temp
,
808 .type
= ENVSYS_STEMP
,
811 .refresh
= wb_refresh_temp
,
818 .type
= ENVSYS_SFANRPM
,
821 .refresh
= wb_refresh_fanrpm
,
826 .type
= ENVSYS_SFANRPM
,
829 .refresh
= wb_refresh_fanrpm
,
839 * The datasheet doesn't mention the (internal) resistors used for the
840 * +5V, but using the values from the W83782D datasheets seems to
841 * provide sensible results.
843 static struct lm_sensor w83781d_sensors
[] = {
847 .type
= ENVSYS_SVOLTS_DC
,
850 .refresh
= lm_refresh_volt
,
855 .type
= ENVSYS_SVOLTS_DC
,
858 .refresh
= lm_refresh_volt
,
863 .type
= ENVSYS_SVOLTS_DC
,
866 .refresh
= lm_refresh_volt
,
871 .type
= ENVSYS_SVOLTS_DC
,
874 .refresh
= lm_refresh_volt
,
875 .rfact
= RFACT(34, 50)
879 .type
= ENVSYS_SVOLTS_DC
,
882 .refresh
= lm_refresh_volt
,
883 .rfact
= RFACT(28, 10)
887 .type
= ENVSYS_SVOLTS_DC
,
890 .refresh
= lm_refresh_volt
,
891 .rfact
= NRFACT(2100, 604)
895 .type
= ENVSYS_SVOLTS_DC
,
898 .refresh
= lm_refresh_volt
,
899 .rfact
= NRFACT(909, 604)
905 .type
= ENVSYS_STEMP
,
908 .refresh
= lm_refresh_temp
,
913 .type
= ENVSYS_STEMP
,
916 .refresh
= wb_refresh_temp
,
921 .type
= ENVSYS_STEMP
,
924 .refresh
= wb_refresh_temp
,
931 .type
= ENVSYS_SFANRPM
,
934 .refresh
= lm_refresh_fanrpm
,
939 .type
= ENVSYS_SFANRPM
,
942 .refresh
= lm_refresh_fanrpm
,
947 .type
= ENVSYS_SFANRPM
,
950 .refresh
= lm_refresh_fanrpm
,
958 static struct lm_sensor w83782d_sensors
[] = {
962 .type
= ENVSYS_SVOLTS_DC
,
965 .refresh
= lm_refresh_volt
,
970 .type
= ENVSYS_SVOLTS_DC
,
973 .refresh
= lm_refresh_volt
,
978 .type
= ENVSYS_SVOLTS_DC
,
981 .refresh
= lm_refresh_volt
,
986 .type
= ENVSYS_SVOLTS_DC
,
989 .refresh
= lm_refresh_volt
,
990 .rfact
= RFACT(34, 50)
994 .type
= ENVSYS_SVOLTS_DC
,
997 .refresh
= lm_refresh_volt
,
998 .rfact
= RFACT(28, 10)
1002 .type
= ENVSYS_SVOLTS_DC
,
1005 .refresh
= wb_refresh_nvolt
,
1006 .rfact
= RFACT(232, 56)
1010 .type
= ENVSYS_SVOLTS_DC
,
1013 .refresh
= wb_refresh_nvolt
,
1014 .rfact
= RFACT(120, 56)
1018 .type
= ENVSYS_SVOLTS_DC
,
1021 .refresh
= lm_refresh_volt
,
1022 .rfact
= RFACT(17, 33)
1026 .type
= ENVSYS_SVOLTS_DC
,
1029 .refresh
= lm_refresh_volt
,
1036 .type
= ENVSYS_STEMP
,
1039 .refresh
= lm_refresh_temp
,
1044 .type
= ENVSYS_STEMP
,
1047 .refresh
= wb_refresh_temp
,
1052 .type
= ENVSYS_STEMP
,
1055 .refresh
= wb_refresh_temp
,
1062 .type
= ENVSYS_SFANRPM
,
1065 .refresh
= wb_refresh_fanrpm
,
1070 .type
= ENVSYS_SFANRPM
,
1073 .refresh
= wb_refresh_fanrpm
,
1078 .type
= ENVSYS_SFANRPM
,
1081 .refresh
= wb_refresh_fanrpm
,
1089 static struct lm_sensor w83783s_sensors
[] = {
1093 .type
= ENVSYS_SVOLTS_DC
,
1096 .refresh
= lm_refresh_volt
,
1101 .type
= ENVSYS_SVOLTS_DC
,
1104 .refresh
= lm_refresh_volt
,
1109 .type
= ENVSYS_SVOLTS_DC
,
1112 .refresh
= lm_refresh_volt
,
1113 .rfact
= RFACT(34, 50)
1117 .type
= ENVSYS_SVOLTS_DC
,
1120 .refresh
= lm_refresh_volt
,
1121 .rfact
= RFACT(28, 10)
1125 .type
= ENVSYS_SVOLTS_DC
,
1128 .refresh
= wb_refresh_nvolt
,
1129 .rfact
= RFACT(232, 56)
1133 .type
= ENVSYS_SVOLTS_DC
,
1136 .refresh
= wb_refresh_nvolt
,
1137 .rfact
= RFACT(120, 56)
1143 .type
= ENVSYS_STEMP
,
1146 .refresh
= lm_refresh_temp
,
1151 .type
= ENVSYS_STEMP
,
1154 .refresh
= wb_refresh_temp
,
1161 .type
= ENVSYS_SFANRPM
,
1164 .refresh
= wb_refresh_fanrpm
,
1169 .type
= ENVSYS_SFANRPM
,
1172 .refresh
= wb_refresh_fanrpm
,
1177 .type
= ENVSYS_SFANRPM
,
1180 .refresh
= wb_refresh_fanrpm
,
1188 static struct lm_sensor w83791d_sensors
[] = {
1192 .type
= ENVSYS_SVOLTS_DC
,
1195 .refresh
= lm_refresh_volt
,
1200 .type
= ENVSYS_SVOLTS_DC
,
1203 .refresh
= lm_refresh_volt
,
1208 .type
= ENVSYS_SVOLTS_DC
,
1211 .refresh
= lm_refresh_volt
,
1216 .type
= ENVSYS_SVOLTS_DC
,
1219 .refresh
= lm_refresh_volt
,
1220 .rfact
= RFACT(34, 50)
1224 .type
= ENVSYS_SVOLTS_DC
,
1227 .refresh
= lm_refresh_volt
,
1228 .rfact
= RFACT(28, 10)
1232 .type
= ENVSYS_SVOLTS_DC
,
1235 .refresh
= wb_refresh_nvolt
,
1236 .rfact
= RFACT(232, 56)
1240 .type
= ENVSYS_SVOLTS_DC
,
1243 .refresh
= wb_refresh_nvolt
,
1244 .rfact
= RFACT(120, 56)
1248 .type
= ENVSYS_SVOLTS_DC
,
1251 .refresh
= lm_refresh_volt
,
1252 .rfact
= RFACT(17, 33)
1256 .type
= ENVSYS_SVOLTS_DC
,
1259 .refresh
= lm_refresh_volt
,
1264 .type
= ENVSYS_SVOLTS_DC
,
1267 .refresh
= lm_refresh_volt
,
1274 .type
= ENVSYS_STEMP
,
1277 .refresh
= lm_refresh_temp
,
1282 .type
= ENVSYS_STEMP
,
1285 .refresh
= wb_refresh_temp
,
1290 .type
= ENVSYS_STEMP
,
1293 .refresh
= wb_refresh_temp
,
1300 .type
= ENVSYS_SFANRPM
,
1303 .refresh
= wb_refresh_fanrpm
,
1308 .type
= ENVSYS_SFANRPM
,
1311 .refresh
= wb_refresh_fanrpm
,
1316 .type
= ENVSYS_SFANRPM
,
1319 .refresh
= wb_refresh_fanrpm
,
1324 .type
= ENVSYS_SFANRPM
,
1327 .refresh
= wb_refresh_fanrpm
,
1332 .type
= ENVSYS_SFANRPM
,
1335 .refresh
= wb_refresh_fanrpm
,
1343 static struct lm_sensor w83792d_sensors
[] = {
1347 .type
= ENVSYS_SVOLTS_DC
,
1350 .refresh
= lm_refresh_volt
,
1355 .type
= ENVSYS_SVOLTS_DC
,
1358 .refresh
= lm_refresh_volt
,
1363 .type
= ENVSYS_SVOLTS_DC
,
1366 .refresh
= lm_refresh_volt
,
1371 .type
= ENVSYS_SVOLTS_DC
,
1374 .refresh
= wb_refresh_nvolt
,
1375 .rfact
= RFACT(120, 56)
1379 .type
= ENVSYS_SVOLTS_DC
,
1382 .refresh
= lm_refresh_volt
,
1383 .rfact
= RFACT(28, 10)
1387 .type
= ENVSYS_SVOLTS_DC
,
1390 .refresh
= wb_refresh_nvolt
,
1391 .rfact
= RFACT(232, 56)
1395 .type
= ENVSYS_SVOLTS_DC
,
1398 .refresh
= lm_refresh_volt
,
1399 .rfact
= RFACT(34, 50)
1403 .type
= ENVSYS_SVOLTS_DC
,
1406 .refresh
= lm_refresh_volt
,
1407 .rfact
= RFACT(17, 33)
1411 .type
= ENVSYS_SVOLTS_DC
,
1414 .refresh
= lm_refresh_volt
,
1421 .type
= ENVSYS_STEMP
,
1424 .refresh
= lm_refresh_temp
,
1429 .type
= ENVSYS_STEMP
,
1432 .refresh
= wb_refresh_temp
,
1437 .type
= ENVSYS_STEMP
,
1440 .refresh
= wb_refresh_temp
,
1447 .type
= ENVSYS_SFANRPM
,
1450 .refresh
= wb_w83792d_refresh_fanrpm
,
1455 .type
= ENVSYS_SFANRPM
,
1458 .refresh
= wb_w83792d_refresh_fanrpm
,
1463 .type
= ENVSYS_SFANRPM
,
1466 .refresh
= wb_w83792d_refresh_fanrpm
,
1471 .type
= ENVSYS_SFANRPM
,
1474 .refresh
= wb_w83792d_refresh_fanrpm
,
1479 .type
= ENVSYS_SFANRPM
,
1482 .refresh
= wb_w83792d_refresh_fanrpm
,
1487 .type
= ENVSYS_SFANRPM
,
1490 .refresh
= wb_w83792d_refresh_fanrpm
,
1495 .type
= ENVSYS_SFANRPM
,
1498 .refresh
= wb_w83792d_refresh_fanrpm
,
1506 static struct lm_sensor as99127f_sensors
[] = {
1510 .type
= ENVSYS_SVOLTS_DC
,
1513 .refresh
= lm_refresh_volt
,
1518 .type
= ENVSYS_SVOLTS_DC
,
1521 .refresh
= lm_refresh_volt
,
1526 .type
= ENVSYS_SVOLTS_DC
,
1529 .refresh
= lm_refresh_volt
,
1534 .type
= ENVSYS_SVOLTS_DC
,
1537 .refresh
= lm_refresh_volt
,
1538 .rfact
= RFACT(34, 50)
1542 .type
= ENVSYS_SVOLTS_DC
,
1545 .refresh
= lm_refresh_volt
,
1546 .rfact
= RFACT(28, 10)
1550 .type
= ENVSYS_SVOLTS_DC
,
1553 .refresh
= wb_refresh_nvolt
,
1554 .rfact
= RFACT(232, 56)
1558 .type
= ENVSYS_SVOLTS_DC
,
1561 .refresh
= wb_refresh_nvolt
,
1562 .rfact
= RFACT(120, 56)
1568 .type
= ENVSYS_STEMP
,
1571 .refresh
= lm_refresh_temp
,
1576 .type
= ENVSYS_STEMP
,
1579 .refresh
= as_refresh_temp
,
1584 .type
= ENVSYS_STEMP
,
1587 .refresh
= as_refresh_temp
,
1594 .type
= ENVSYS_SFANRPM
,
1597 .refresh
= lm_refresh_fanrpm
,
1602 .type
= ENVSYS_SFANRPM
,
1605 .refresh
= lm_refresh_fanrpm
,
1610 .type
= ENVSYS_SFANRPM
,
1613 .refresh
= lm_refresh_fanrpm
,
1621 lm_generic_banksel(struct lm_softc
*lmsc
, int bank
)
1623 (*lmsc
->lm_writereg
)(lmsc
, WB_BANKSEL
, bank
);
1627 * bus independent probe
1629 * prerequisites: lmsc contains valid lm_{read,write}reg() routines
1630 * and associated bus access data is present in attachment's softc
1633 lm_probe(struct lm_softc
*lmsc
)
1638 /* Perform LM78 reset */
1639 /*(*lmsc->lm_writereg)(lmsc, LMD_CONFIG, 0x80); */
1641 cr
= (*lmsc
->lm_readreg
)(lmsc
, LMD_CONFIG
);
1643 /* XXX - spec says *only* 0x08! */
1644 if ((cr
== 0x08) || (cr
== 0x01) || (cr
== 0x03) || (cr
== 0x06))
1649 DPRINTF(("%s: rv = %d, cr = %x\n", __func__
, rv
, cr
));
1655 lm_attach(struct lm_softc
*lmsc
)
1659 for (i
= 0; i
< __arraycount(lm_chips
); i
++)
1660 if (lm_chips
[i
].chip_match(lmsc
))
1663 /* Start the monitoring loop */
1664 (*lmsc
->lm_writereg
)(lmsc
, LMD_CONFIG
, 0x01);
1666 lmsc
->sc_sme
= sysmon_envsys_create();
1667 /* Initialize sensors */
1668 for (i
= 0; i
< lmsc
->numsensors
; i
++) {
1669 if (sysmon_envsys_sensor_attach(lmsc
->sc_sme
,
1670 &lmsc
->sensors
[i
])) {
1671 sysmon_envsys_destroy(lmsc
->sc_sme
);
1677 * Setup the callout to refresh sensor data every 2 seconds.
1679 callout_init(&lmsc
->sc_callout
, 0);
1680 callout_setfunc(&lmsc
->sc_callout
, lm_refresh
, lmsc
);
1681 callout_schedule(&lmsc
->sc_callout
, LM_REFRESH_TIMO
);
1684 * Hook into the System Monitor.
1686 lmsc
->sc_sme
->sme_name
= device_xname(lmsc
->sc_dev
);
1687 lmsc
->sc_sme
->sme_flags
= SME_DISABLE_REFRESH
;
1689 if (sysmon_envsys_register(lmsc
->sc_sme
)) {
1690 aprint_error_dev(lmsc
->sc_dev
,
1691 "unable to register with sysmon\n");
1692 sysmon_envsys_destroy(lmsc
->sc_sme
);
1697 * Stop, destroy the callout and unregister the driver with the
1698 * sysmon_envsys(9) framework.
1701 lm_detach(struct lm_softc
*lmsc
)
1703 callout_stop(&lmsc
->sc_callout
);
1704 callout_destroy(&lmsc
->sc_callout
);
1705 sysmon_envsys_unregister(lmsc
->sc_sme
);
1709 lm_refresh(void *arg
)
1711 struct lm_softc
*lmsc
= arg
;
1713 lmsc
->refresh_sensor_data(lmsc
);
1714 callout_schedule(&lmsc
->sc_callout
, LM_REFRESH_TIMO
);
1718 lm_match(struct lm_softc
*sc
)
1720 const char *model
= NULL
;
1723 /* See if we have an LM78/LM78J/LM79 or LM81 */
1724 chipid
= (*sc
->lm_readreg
)(sc
, LMD_CHIPID
) & LM_ID_MASK
;
1742 aprint_normal("\n");
1743 aprint_normal_dev(sc
->sc_dev
,
1744 "National Semiconductor %s Hardware monitor\n", model
);
1746 lm_setup_sensors(sc
, lm78_sensors
);
1747 sc
->refresh_sensor_data
= lm_refresh_sensor_data
;
1752 def_match(struct lm_softc
*sc
)
1756 chipid
= (*sc
->lm_readreg
)(sc
, LMD_CHIPID
) & LM_ID_MASK
;
1757 aprint_normal("\n");
1758 aprint_error_dev(sc
->sc_dev
, "Unknown chip (ID %d)\n", chipid
);
1760 lm_setup_sensors(sc
, lm78_sensors
);
1761 sc
->refresh_sensor_data
= lm_refresh_sensor_data
;
1766 wb_match(struct lm_softc
*sc
)
1768 const char *model
= NULL
;
1769 int banksel
, vendid
, devid
;
1771 aprint_normal("\n");
1772 /* Read vendor ID */
1773 banksel
= (*sc
->lm_readreg
)(sc
, WB_BANKSEL
);
1774 lm_generic_banksel(sc
, WB_BANKSEL_HBAC
);
1775 vendid
= (*sc
->lm_readreg
)(sc
, WB_VENDID
) << 8;
1776 lm_generic_banksel(sc
, 0);
1777 vendid
|= (*sc
->lm_readreg
)(sc
, WB_VENDID
);
1778 DPRINTF(("%s: winbond vend id 0x%x\n", __func__
, vendid
));
1779 if (vendid
!= WB_VENDID_WINBOND
&& vendid
!= WB_VENDID_ASUS
)
1782 /* Read device/chip ID */
1783 lm_generic_banksel(sc
, WB_BANKSEL_B0
);
1784 devid
= (*sc
->lm_readreg
)(sc
, LMD_CHIPID
);
1785 sc
->chipid
= (*sc
->lm_readreg
)(sc
, WB_BANK0_CHIPID
);
1786 lm_generic_banksel(sc
, banksel
);
1787 DPRINTF(("%s: winbond chip id 0x%x\n", __func__
, sc
->chipid
));
1789 switch(sc
->chipid
) {
1790 case WB_CHIPID_W83627HF
:
1792 lm_setup_sensors(sc
, w83627hf_sensors
);
1794 case WB_CHIPID_W83627THF
:
1795 model
= "W83627THF";
1796 lm_setup_sensors(sc
, w83637hf_sensors
);
1798 case WB_CHIPID_W83627EHF_A
:
1799 model
= "W83627EHF-A";
1800 lm_setup_sensors(sc
, w83627ehf_sensors
);
1802 case WB_CHIPID_W83627EHF
:
1803 model
= "W83627EHF";
1804 lm_setup_sensors(sc
, w83627ehf_sensors
);
1806 case WB_CHIPID_W83627DHG
:
1807 model
= "W83627DHG";
1808 lm_setup_sensors(sc
, w83627dhg_sensors
);
1810 case WB_CHIPID_W83637HF
:
1812 lm_generic_banksel(sc
, WB_BANKSEL_B0
);
1813 if ((*sc
->lm_readreg
)(sc
, WB_BANK0_CONFIG
) & WB_CONFIG_VMR9
)
1815 lm_generic_banksel(sc
, banksel
);
1816 lm_setup_sensors(sc
, w83637hf_sensors
);
1818 case WB_CHIPID_W83697HF
:
1820 lm_setup_sensors(sc
, w83697hf_sensors
);
1822 case WB_CHIPID_W83781D
:
1823 case WB_CHIPID_W83781D_2
:
1825 lm_setup_sensors(sc
, w83781d_sensors
);
1827 case WB_CHIPID_W83782D
:
1829 lm_setup_sensors(sc
, w83782d_sensors
);
1831 case WB_CHIPID_W83783S
:
1833 lm_setup_sensors(sc
, w83783s_sensors
);
1835 case WB_CHIPID_W83791D
:
1837 lm_setup_sensors(sc
, w83791d_sensors
);
1839 case WB_CHIPID_W83791SD
:
1842 case WB_CHIPID_W83792D
:
1844 lm_setup_sensors(sc
, w83792d_sensors
);
1846 case WB_CHIPID_AS99127F
:
1847 if (vendid
== WB_VENDID_ASUS
) {
1849 lm_setup_sensors(sc
, w83781d_sensors
);
1851 model
= "AS99127F rev 2";
1852 lm_setup_sensors(sc
, as99127f_sensors
);
1856 aprint_normal_dev(sc
->sc_dev
,
1857 "unknown Winbond chip (ID 0x%x)\n", sc
->chipid
);
1858 /* Handle as a standard LM78. */
1859 lm_setup_sensors(sc
, lm78_sensors
);
1860 sc
->refresh_sensor_data
= lm_refresh_sensor_data
;
1864 aprint_normal_dev(sc
->sc_dev
, "Winbond %s Hardware monitor\n", model
);
1866 sc
->refresh_sensor_data
= wb_refresh_sensor_data
;
1871 lm_setup_sensors(struct lm_softc
*sc
, struct lm_sensor
*sensors
)
1875 for (i
= 0; sensors
[i
].desc
; i
++) {
1876 sc
->sensors
[i
].units
= sensors
[i
].type
;
1877 strlcpy(sc
->sensors
[i
].desc
, sensors
[i
].desc
,
1878 sizeof(sc
->sensors
[i
].desc
));
1881 sc
->lm_sensors
= sensors
;
1885 lm_refresh_sensor_data(struct lm_softc
*sc
)
1889 for (i
= 0; i
< sc
->numsensors
; i
++)
1890 sc
->lm_sensors
[i
].refresh(sc
, i
);
1894 lm_refresh_volt(struct lm_softc
*sc
, int n
)
1898 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
);
1900 sc
->sensors
[n
].state
= ENVSYS_SINVALID
;
1902 sc
->sensors
[n
].flags
= ENVSYS_FCHANGERFACT
;
1903 sc
->sensors
[n
].value_cur
= (data
<< 4);
1904 if (sc
->sensors
[n
].rfact
) {
1905 sc
->sensors
[n
].value_cur
*= sc
->sensors
[n
].rfact
;
1906 sc
->sensors
[n
].value_cur
/= 10;
1908 sc
->sensors
[n
].value_cur
*= sc
->lm_sensors
[n
].rfact
;
1909 sc
->sensors
[n
].value_cur
/= 10;
1910 sc
->sensors
[n
].rfact
= sc
->lm_sensors
[n
].rfact
;
1912 sc
->sensors
[n
].state
= ENVSYS_SVALID
;
1915 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
1916 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
1920 lm_refresh_temp(struct lm_softc
*sc
, int n
)
1925 * The data sheet suggests that the range of the temperature
1926 * sensor is between -55 degC and +125 degC.
1928 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
);
1929 if (data
> 0x7d && data
< 0xc9)
1930 sc
->sensors
[n
].state
= ENVSYS_SINVALID
;
1934 sc
->sensors
[n
].state
= ENVSYS_SVALID
;
1935 sc
->sensors
[n
].value_cur
= data
* 1000000 + 273150000;
1937 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
1938 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
1942 lm_refresh_fanrpm(struct lm_softc
*sc
, int n
)
1944 int data
, divisor
= 1;
1947 * We might get more accurate fan readings by adjusting the
1948 * divisor, but that might interfere with APM or other SMM
1949 * BIOS code reading the fan speeds.
1952 /* FAN3 has a fixed fan divisor. */
1953 if (sc
->lm_sensors
[n
].reg
== LMD_FAN1
||
1954 sc
->lm_sensors
[n
].reg
== LMD_FAN2
) {
1955 data
= (*sc
->lm_readreg
)(sc
, LMD_VIDFAN
);
1956 if (sc
->lm_sensors
[n
].reg
== LMD_FAN1
)
1957 divisor
= (data
>> 4) & 0x03;
1959 divisor
= (data
>> 6) & 0x03;
1962 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
);
1963 if (data
== 0xff || data
== 0x00)
1964 sc
->sensors
[n
].state
= ENVSYS_SINVALID
;
1966 sc
->sensors
[n
].state
= ENVSYS_SVALID
;
1967 sc
->sensors
[n
].value_cur
= 1350000 / (data
<< divisor
);
1969 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
1970 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
1974 wb_refresh_sensor_data(struct lm_softc
*sc
)
1976 int banksel
, bank
, i
;
1979 * Properly save and restore bank selection register.
1981 banksel
= bank
= sc
->lm_readreg(sc
, WB_BANKSEL
);
1982 for (i
= 0; i
< sc
->numsensors
; i
++) {
1983 if (bank
!= sc
->lm_sensors
[i
].bank
) {
1984 bank
= sc
->lm_sensors
[i
].bank
;
1985 lm_generic_banksel(sc
, bank
);
1987 sc
->lm_sensors
[i
].refresh(sc
, i
);
1989 lm_generic_banksel(sc
, banksel
);
1993 wb_w83637hf_refresh_vcore(struct lm_softc
*sc
, int n
)
1997 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
);
1999 * Depending on the voltage detection method,
2000 * one of the following formulas is used:
2001 * VRM8 method: value = raw * 0.016V
2002 * VRM9 method: value = raw * 0.00488V + 0.70V
2005 sc
->sensors
[n
].value_cur
= (data
* 4880) + 700000;
2007 sc
->sensors
[n
].value_cur
= (data
* 16000);
2008 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
2009 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
2013 wb_refresh_nvolt(struct lm_softc
*sc
, int n
)
2017 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
);
2018 sc
->sensors
[n
].flags
= ENVSYS_FCHANGERFACT
;
2019 sc
->sensors
[n
].value_cur
= ((data
<< 4) - WB_VREF
);
2020 if (sc
->sensors
[n
].rfact
)
2021 sc
->sensors
[n
].value_cur
*= sc
->sensors
[n
].rfact
;
2023 sc
->sensors
[n
].value_cur
*= sc
->lm_sensors
[n
].rfact
;
2025 sc
->sensors
[n
].value_cur
/= 10;
2026 sc
->sensors
[n
].value_cur
+= WB_VREF
* 1000;
2027 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
2028 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
2032 wb_w83627ehf_refresh_nvolt(struct lm_softc
*sc
, int n
)
2036 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
);
2037 sc
->sensors
[n
].value_cur
= ((data
<< 3) - WB_W83627EHF_VREF
);
2038 sc
->sensors
[n
].flags
= ENVSYS_FCHANGERFACT
;
2039 if (sc
->sensors
[n
].rfact
)
2040 sc
->sensors
[n
].value_cur
*= sc
->sensors
[n
].rfact
;
2042 sc
->sensors
[n
].value_cur
*= RFACT(232, 10);
2044 sc
->sensors
[n
].value_cur
/= 10;
2045 sc
->sensors
[n
].value_cur
+= WB_W83627EHF_VREF
* 1000;
2046 DPRINTF(("%s: volt[%d] data=0x%x value_cur=%d\n",
2047 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
2051 wb_refresh_temp(struct lm_softc
*sc
, int n
)
2056 * The data sheet suggests that the range of the temperature
2057 * sensor is between -55 degC and +125 degC. However, values
2058 * around -48 degC seem to be a very common bogus values.
2059 * Since such values are unreasonably low, we use -45 degC for
2060 * the lower limit instead.
2062 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
) << 1;
2063 data
+= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
+ 1) >> 7;
2064 if (data
> 0xfffffff || (data
> 0x0fa && data
< 0x1a6)) {
2065 sc
->sensors
[n
].state
= ENVSYS_SINVALID
;
2069 sc
->sensors
[n
].state
= ENVSYS_SVALID
;
2070 sc
->sensors
[n
].value_cur
= data
* 500000 + 273150000;
2072 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
2073 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
2077 wb_refresh_fanrpm(struct lm_softc
*sc
, int n
)
2079 int fan
, data
, divisor
= 0;
2082 * This is madness; the fan divisor bits are scattered all
2086 if (sc
->lm_sensors
[n
].reg
== LMD_FAN1
||
2087 sc
->lm_sensors
[n
].reg
== LMD_FAN2
||
2088 sc
->lm_sensors
[n
].reg
== LMD_FAN3
) {
2089 data
= (*sc
->lm_readreg
)(sc
, WB_BANK0_VBAT
);
2090 fan
= (sc
->lm_sensors
[n
].reg
- LMD_FAN1
);
2091 if ((data
>> 5) & (1 << fan
))
2095 if (sc
->lm_sensors
[n
].reg
== LMD_FAN1
||
2096 sc
->lm_sensors
[n
].reg
== LMD_FAN2
) {
2097 data
= (*sc
->lm_readreg
)(sc
, LMD_VIDFAN
);
2098 if (sc
->lm_sensors
[n
].reg
== LMD_FAN1
)
2099 divisor
|= (data
>> 4) & 0x03;
2101 divisor
|= (data
>> 6) & 0x03;
2102 } else if (sc
->lm_sensors
[n
].reg
== LMD_FAN3
) {
2103 data
= (*sc
->lm_readreg
)(sc
, WB_PIN
);
2104 divisor
|= (data
>> 6) & 0x03;
2105 } else if (sc
->lm_sensors
[n
].reg
== WB_BANK0_FAN4
||
2106 sc
->lm_sensors
[n
].reg
== WB_BANK0_FAN5
) {
2107 data
= (*sc
->lm_readreg
)(sc
, WB_BANK0_FAN45
);
2108 if (sc
->lm_sensors
[n
].reg
== WB_BANK0_FAN4
)
2109 divisor
|= (data
>> 0) & 0x07;
2111 divisor
|= (data
>> 4) & 0x07;
2114 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
);
2115 if (data
>= 0xff || data
== 0x00)
2116 sc
->sensors
[n
].state
= ENVSYS_SINVALID
;
2118 sc
->sensors
[n
].state
= ENVSYS_SVALID
;
2119 sc
->sensors
[n
].value_cur
= 1350000 / (data
<< divisor
);
2121 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
2122 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
2126 wb_w83792d_refresh_fanrpm(struct lm_softc
*sc
, int n
)
2128 int reg
, shift
, data
, divisor
= 1;
2132 switch (sc
->lm_sensors
[n
].reg
) {
2134 reg
= 0x47; shift
= 0;
2137 reg
= 0x47; shift
= 4;
2140 reg
= 0x5b; shift
= 0;
2143 reg
= 0x5b; shift
= 4;
2146 reg
= 0x5c; shift
= 0;
2149 reg
= 0x5c; shift
= 4;
2152 reg
= 0x9e; shift
= 0;
2159 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
);
2160 if (data
== 0xff || data
== 0x00)
2161 sc
->sensors
[n
].state
= ENVSYS_SINVALID
;
2164 divisor
= ((*sc
->lm_readreg
)(sc
, reg
) >> shift
) & 0x7;
2165 sc
->sensors
[n
].state
= ENVSYS_SVALID
;
2166 sc
->sensors
[n
].value_cur
= 1350000 / (data
<< divisor
);
2168 DPRINTF(("%s: fan[%d] data=0x%x value_cur=%d\n",
2169 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));
2173 as_refresh_temp(struct lm_softc
*sc
, int n
)
2178 * It seems a shorted temperature diode produces an all-ones
2181 data
= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
) << 1;
2182 data
+= (*sc
->lm_readreg
)(sc
, sc
->lm_sensors
[n
].reg
+ 1) >> 7;
2184 sc
->sensors
[n
].state
= ENVSYS_SINVALID
;
2188 sc
->sensors
[n
].state
= ENVSYS_SVALID
;
2189 sc
->sensors
[n
].value_cur
= data
* 500000 + 273150000;
2191 DPRINTF(("%s: temp[%d] data=0x%x value_cur=%d\n",
2192 __func__
, n
, data
, sc
->sensors
[n
].value_cur
));