Merge branch 'master' of ssh://crater.dragonflybsd.org/repository/git/dragonfly
[dragonfly.git] / sys / dev / powermng / uguru / uguru.c
1 /*      $OpenBSD: uguru.c,v 1.4 2010/06/03 17:48:24 deraadt Exp $       */
2
3 /*
4  * Copyright (c) 2010 Mikko Tolmunen <oskari@sefirosu.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include <sys/param.h>
20 #include <sys/bus.h>
21 #include <sys/device.h>
22 #include <sys/rman.h>
23 #include <sys/sensors.h>
24 #include <sys/systm.h>
25
26 #include <bus/isa/isareg.h>
27 #include <bus/isa/isavar.h>
28
29 #ifdef UGURU_DEBUG
30 int     uguru_dbg = 0;
31 #define DPRINTF(lvl, fmt...)    \
32         if (uguru_dbg >= lvl)   \
33                 kprintf(fmt);
34 #else
35 #define DPRINTF(lvl, fmt...)
36 #endif
37
38 #define UGURU_READ(iot, ioh, reg)       \
39     bus_space_read_1((iot), (ioh), (reg))
40 #define UGURU_WRITE(iot, ioh, reg, val) \
41     bus_space_write_1((iot), (ioh), (reg), (val))
42
43 #define UGURU_DATA              0x00    /* configuration data register */
44 #define UGURU_INDEX             0x04    /* configuration index register */
45 #define UGURU_IOSIZE            0x08
46
47 #define UGURU_DUMMY             0x00    /* dummy zero bit */
48 #define UGURU_ITM_DATA          0x21    /* temp/volt readings */
49 #define UGURU_ITM_CTRL          0x22    /* temp/volt settings */
50 #define UGURU_FAN_DATA          0x26    /* fan readings */
51 #define UGURU_FAN_CTRL          0x27    /* fan settings */
52 #define UGURU_PRODID            0x44    /* product ID */
53
54 #define UGURU_VENDID_ABIT       0x147b  /* ABIT */
55 #define UGURU_DEVID1            0x2003  /* AC2003 */
56 #define UGURU_DEVID2            0x2005  /* AC2005 */
57
58 #define ABIT_SYSID_KV01         0x0301
59 #define ABIT_SYSID_AI01         0x0302
60 #define ABIT_SYSID_AN01         0x0303
61 #define ABIT_SYSID_AA01         0x0304
62 #define ABIT_SYSID_AG01         0x0305
63 #define ABIT_SYSID_AV01         0x0306
64 #define ABIT_SYSID_KVP1         0x0307
65 #define ABIT_SYSID_AS01         0x0308
66 #define ABIT_SYSID_AX01         0x0309
67 #define ABIT_SYSID_M401         0x030a
68 #define ABIT_SYSID_AN02         0x030b
69 #define ABIT_SYSID_AU01         0x050c
70 #define ABIT_SYSID_AW01         0x050d
71 #define ABIT_SYSID_AL01         0x050e
72 #define ABIT_SYSID_BL01         0x050f
73 #define ABIT_SYSID_NI01         0x0510
74 #define ABIT_SYSID_AT01         0x0511
75 #define ABIT_SYSID_AN03         0x0512
76 #define ABIT_SYSID_AW02         0x0513
77 #define ABIT_SYSID_AB01         0x0514
78 #define ABIT_SYSID_AN04         0x0515
79 #define ABIT_SYSID_AW03         0x0516
80 #define ABIT_SYSID_AT02         0x0517
81 #define ABIT_SYSID_AB02         0x0518
82 #define ABIT_SYSID_IN01         0x0519
83 #define ABIT_SYSID_IP01         0x051a
84 #define ABIT_SYSID_IX01         0x051b
85 #define ABIT_SYSID_IX02         0x051c
86
87 #define UGURU_INTERVAL          5
88 #define UGURU_MAX_SENSORS       27
89
90 #define RFACT_NONE              13700
91 #define RFACT_NONE2             10000
92 #define RFACT(x, y)             (RFACT_NONE * ((x) + (y)) / (y))
93 #define RFACT2(x, y)            (RFACT_NONE2 * ((x) + (y)) / (y))
94
95 struct uguru_softc {
96         struct device           *sc_dev;
97
98         struct resource         *sc_iores;
99         int                      sc_iorid;
100
101         bus_space_tag_t          sc_iot;
102         bus_space_handle_t       sc_ioh;
103
104         struct ksensor           sc_sensors[UGURU_MAX_SENSORS];
105         struct ksensordev        sc_sensordev;
106         int                      sc_numsensors;
107         struct uguru_sensor     *uguru_sensors;
108         struct {
109                 uint8_t          reading;
110 /*              uint8_t          flags; */
111                 uint8_t          lower;
112                 uint8_t          upper;
113         } cs;
114         int                     (*read)(struct uguru_softc *, int);
115 };
116
117 struct uguru_sensor {
118         char                    *desc;
119         enum sensor_type         type;
120         void                    (*refresh)(struct uguru_softc *, int);
121         uint8_t                  reg;
122         int                      rfact;
123 };
124
125 static void      uguru_refresh_temp(struct uguru_softc *, int);
126 static void      uguru_refresh_volt(struct uguru_softc *, int);
127 static void      uguru_refresh_fan(struct uguru_softc *, int);
128
129 #define UGURU_R_TEMP    uguru_refresh_temp
130 #define UGURU_R_VOLT    uguru_refresh_volt
131 #define UGURU_R_FAN     uguru_refresh_fan
132
133 struct uguru_sensor abitkv_sensors[] = {
134         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x00 },
135         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x01 },
136         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x0f },
137
138         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE },
139         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT(100, 402) },
140         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT(442, 560) },
141         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT(2800, 887) },
142         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT(442, 560) },
143         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE },
144         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT_NONE },
145
146         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x00 },
147         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x01 },
148         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x02 },
149         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x03 },
150         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x04 },
151
152         { NULL }
153 };
154
155 struct uguru_sensor abitaa_sensors[] = {
156         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x00 },
157         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x01 },
158         { "PWM1", SENSOR_TEMP, UGURU_R_TEMP, 0x0f },
159         { "PWM2", SENSOR_TEMP, UGURU_R_TEMP, 0x0c },
160
161         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE },
162         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT(100, 402) },
163         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT(442, 560) },
164         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT(2800, 888) },
165         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT(442, 560) },
166         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE },
167         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT_NONE },
168         { "FSBVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0e, RFACT_NONE },
169         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE },
170         { "NB +2.5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT_NONE },
171
172         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x00 },
173         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x01 },
174         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x02 },
175         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x03 },
176         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x04 },
177
178         { NULL }
179 };
180
181 struct uguru_sensor abitav_sensors[] = {
182         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x00 },
183         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x01 },
184         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x0f },
185
186         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE },
187         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT(100, 402) },
188         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT(442, 560) },
189         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT(442, 560) },
190         { "+3.3VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0d, RFACT(100, 402) },
191         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE },
192         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT_NONE },
193         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT_NONE },
194         { "SB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0e, RFACT_NONE },
195         { "HTV", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE },
196         { "AGP", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT_NONE },
197
198         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x00 },
199         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x01 },
200         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x02 },
201         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x03 },
202         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x04 },
203
204         { NULL }
205 };
206
207 struct uguru_sensor abitas_sensors[] = {
208         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x00 },
209         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x01 },
210         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x0f },
211
212         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE },
213         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT(100, 402) },
214         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT(442, 560) },
215         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT(2800, 884) },
216         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT(442, 560) },
217         { "+3.3VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0d, RFACT(100, 402) },
218         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE },
219         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT_NONE },
220         { "FSBVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0e, RFACT_NONE },
221         { "NB/AGP", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE },
222         { "GMCH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT_NONE },
223
224         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x00 },
225         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x01 },
226         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x02 },
227         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x03 },
228         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x04 },
229
230         { NULL }
231 };
232
233 struct uguru_sensor abitax_sensors[] = {
234         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x00 },
235         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x01 },
236         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x0f },
237
238         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE },
239         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT(100, 402) },
240         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT(442, 560) },
241         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0d, RFACT(2800, 888) },
242         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT(442, 560) },
243         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE },
244         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT_NONE },
245         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT_NONE },
246         { "SB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0e, RFACT_NONE },
247         { "HTV", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE },
248
249         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x00 },
250         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x01 },
251         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x02 },
252         { "AUX", SENSOR_FANRPM, UGURU_R_FAN, 0x03 },
253
254         { NULL }
255 };
256
257 struct uguru_sensor abitm4_sensors[] = {
258         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x00 },
259         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x01 },
260         { "PWM1", SENSOR_TEMP, UGURU_R_TEMP, 0x02 },
261         { "PWM2", SENSOR_TEMP, UGURU_R_TEMP, 0x03 },
262         { "PWM3", SENSOR_TEMP, UGURU_R_TEMP, 0x04 },
263         { "PWM4", SENSOR_TEMP, UGURU_R_TEMP, 0x05 },
264
265         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT_NONE },
266         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x13, RFACT(100, 402) },
267         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x12, RFACT(442, 560) },
268         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x11, RFACT(2800, 884) },
269         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x10, RFACT(442, 560) },
270         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT_NONE },
271         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT_NONE },
272         { "FSBVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0d, RFACT_NONE },
273         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT_NONE },
274         { "NB +2.5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0c, RFACT_NONE },
275
276         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x00 },
277         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x01 },
278         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x02 },
279         { "OTES1", SENSOR_FANRPM, UGURU_R_FAN, 0x03 },
280         { "OTES2", SENSOR_FANRPM, UGURU_R_FAN, 0x04 },
281
282         { NULL }
283 };
284
285 struct uguru_sensor abitan_sensors[] = {
286         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x00 },
287         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x01 },
288         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x0f },
289
290         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE },
291         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT(100, 402) },
292         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT(442, 560) },
293         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0d, RFACT(2800, 844) },
294         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT(442, 560) },
295         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE },
296         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT_NONE },
297         { "CPUVDDA", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0e, RFACT_NONE },
298         { "HTV", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE },
299         { "MCP", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT_NONE },
300         { "MCP SB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT_NONE },
301
302         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x00 },
303         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x01 },
304         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x02 },
305         { "AUX", SENSOR_FANRPM, UGURU_R_FAN, 0x05 },
306         { "OTES1", SENSOR_FANRPM, UGURU_R_FAN, 0x04 },
307         { "OTES2", SENSOR_FANRPM, UGURU_R_FAN, 0x03 },
308
309         { NULL }
310 };
311
312 struct uguru_sensor abital_sensors[] = {
313         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
314         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
315         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
316
317         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
318         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
319         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
320         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
321         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
322         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
323         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT_NONE2 },
324         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
325         { "CPUVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
326         { "MCH/PCIE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
327         { "MCH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT2(34, 34) },
328         { "ICH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
329
330         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
331         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
332         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
333         { "AUX", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
334
335         { NULL }
336 };
337
338 struct uguru_sensor abitaw_sensors[] = {
339         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
340         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
341         { "PWM1", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
342         { "PWM2", SENSOR_TEMP, UGURU_R_TEMP, 0x1b },
343         { "PWM3", SENSOR_TEMP, UGURU_R_TEMP, 0x1c },
344         { "PWM4", SENSOR_TEMP, UGURU_R_TEMP, 0x1d },
345
346         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
347         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
348         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
349         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
350         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
351         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
352         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT_NONE2 },
353         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
354         { "CPUVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
355         { "MCH/PCIE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
356         { "MCH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT2(34, 34) },
357         { "ICH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
358
359         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
360         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
361         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
362         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
363         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
364         { "AUX3", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
365         { "AUX4", SENSOR_FANRPM, UGURU_R_FAN, 0x26 },
366         { "AUX5", SENSOR_FANRPM, UGURU_R_FAN, 0x27 },
367
368         { NULL }
369 };
370
371 struct uguru_sensor abitni_sensors[] = {
372         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
373         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
374         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
375
376         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
377         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
378         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
379         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
380         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
381         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
382         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT_NONE2 },
383         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
384         { "CPUVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
385         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
386         { "SB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
387
388         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
389         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
390         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
391         { "AUX", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
392         { "OTES1", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
393         { "OTES2", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
394
395         { NULL }
396 };
397
398 struct uguru_sensor abitat_sensors[] = {
399         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
400         { "NB", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
401         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
402         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x1b },
403
404         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
405         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
406         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
407         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
408         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
409         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
410         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT2(34, 34) },
411         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
412         { "CPUVDDA", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT2(34, 34) },
413         { "PCIE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0c, RFACT_NONE2 },
414         { "HTV", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
415         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0d, RFACT_NONE2 },
416         { "NB +1.8V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
417         { "NB +1.8V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT_NONE2 },
418
419         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
420         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
421         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
422         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
423         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
424         { "AUX3", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
425
426         { NULL }
427 };
428
429 struct uguru_sensor abitan2_sensors[] = {
430         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
431         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
432         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
433
434         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
435         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
436         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
437         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
438         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
439         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
440         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT2(34, 34) },
441         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
442         { "CPUVDDA", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT2(34, 34) },
443         { "HTV", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
444         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
445         { "SB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
446
447         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
448         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
449         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
450         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
451         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
452
453         { NULL }
454 };
455
456 struct uguru_sensor abitab_sensors[] = {
457         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
458         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
459         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
460
461         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
462         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
463         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
464         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
465         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
466         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
467         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT_NONE2 },
468         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
469         { "CPUVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
470         { "ICHIO", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT_NONE2 },
471         { "ICH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
472         { "MCH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
473
474         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
475         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
476         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
477         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
478         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
479         { "AUX3", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
480
481         { NULL }
482 };
483
484 struct uguru_sensor abitan3_sensors[] = {
485         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
486         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
487         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
488
489         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
490         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
491         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
492         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
493         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
494         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
495         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT2(34, 34) },
496         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
497         { "CPUVDDA", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT2(34, 34) },
498         { "HTV", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
499         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
500         { "NB/PCIE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0e, RFACT_NONE2 },
501         { "SB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
502
503         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
504         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
505         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
506         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
507         { "AUX3", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
508         { "AUX4", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
509
510         { NULL }
511 };
512
513 struct uguru_sensor abitaw2_sensors[] = {
514         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
515         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
516         { "PWM1", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
517         { "PWM2", SENSOR_TEMP, UGURU_R_TEMP, 0x1b },
518         { "PWM3", SENSOR_TEMP, UGURU_R_TEMP, 0x1c },
519         { "PWM4", SENSOR_TEMP, UGURU_R_TEMP, 0x1d },
520
521         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
522         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
523         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
524         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
525         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
526         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
527         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT2(34, 34) },
528         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
529         { "CPUVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
530         { "MCH/PCIE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
531         { "MCH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT2(34, 34) },
532         { "ICH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
533
534         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
535         { "NB", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
536         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
537         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
538         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
539         { "AUX3", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
540         { "OTES1", SENSOR_FANRPM, UGURU_R_FAN, 0x26 },
541         { "OTES2", SENSOR_FANRPM, UGURU_R_FAN, 0x27 },
542
543         { NULL }
544 };
545
546 struct uguru_sensor abitat2_sensors[] = {
547         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
548         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
549         { "PWM", SENSOR_TEMP, UGURU_R_TEMP, 0x1b },
550
551         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
552         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
553         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
554         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
555         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
556         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
557         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT2(34, 34) },
558         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
559         { "CPUVDDA", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT2(34, 34) },
560         { "PCIE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0c, RFACT_NONE2 },
561         { "HTV", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
562         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0d, RFACT_NONE2 },
563         { "NB +1.8V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
564         { "SB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT_NONE2 },
565
566         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
567         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
568         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
569         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
570         { "AUX3", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
571         { "AUX4", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
572
573         { NULL }
574 };
575
576 struct uguru_sensor abitab2_sensors[] = {
577         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
578         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
579         { "PWM1", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
580         { "PWM2", SENSOR_TEMP, UGURU_R_TEMP, 0x1b },
581         { "PWM3", SENSOR_TEMP, UGURU_R_TEMP, 0x1c },
582         { "PWM4", SENSOR_TEMP, UGURU_R_TEMP, 0x1d },
583         { "PWM5", SENSOR_TEMP, UGURU_R_TEMP, 0x1e },
584
585         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x00, RFACT_NONE2 },
586         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
587         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
588         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT2(50, 10) },
589         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
590         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
591         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x01, RFACT2(34, 34) },
592         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x02, RFACT_NONE2 },
593         { "CPUVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
594         { "ICHIO", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT_NONE2 },
595         { "ICH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
596         { "MCH", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
597
598         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
599         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
600         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
601         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
602         { "AUX3", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
603         { "AUX4", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
604
605         { NULL }
606 };
607
608 struct uguru_sensor abitin_sensors[] = {
609         { "CPU", SENSOR_TEMP, UGURU_R_TEMP, 0x18 },
610         { "SYS", SENSOR_TEMP, UGURU_R_TEMP, 0x19 },
611         { "PWM1", SENSOR_TEMP, UGURU_R_TEMP, 0x1a },
612         { "PWM2", SENSOR_TEMP, UGURU_R_TEMP, 0x1b },
613         { "PWM3", SENSOR_TEMP, UGURU_R_TEMP, 0x1c },
614         { "PWM4", SENSOR_TEMP, UGURU_R_TEMP, 0x1d },
615         { "PWM5", SENSOR_TEMP, UGURU_R_TEMP, 0x1e },
616
617         { "VCORE", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x07, RFACT_NONE2 },
618         { "+3.3V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0a, RFACT2(34, 34) },
619         { "+5V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x09, RFACT2(120, 60) },
620         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0c, RFACT2(50, 10) },
621         { "+12V", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x08, RFACT2(50, 10) },
622         { "+5VSB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0b, RFACT2(120, 60) },
623         { "DDR", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0d, RFACT2(34, 34) },
624         { "DDRVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x0e, RFACT_NONE2 },
625         { "CPUVTT", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x03, RFACT_NONE2 },
626         { "HTV", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x05, RFACT_NONE2 },
627         { "NB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x04, RFACT_NONE2 },
628         { "SB", SENSOR_VOLTS_DC, UGURU_R_VOLT, 0x06, RFACT_NONE2 },
629
630         { "CPU", SENSOR_FANRPM, UGURU_R_FAN, 0x20 },
631         { "SYS", SENSOR_FANRPM, UGURU_R_FAN, 0x22 },
632         { "AUX1", SENSOR_FANRPM, UGURU_R_FAN, 0x21 },
633         { "AUX2", SENSOR_FANRPM, UGURU_R_FAN, 0x23 },
634         { "AUX3", SENSOR_FANRPM, UGURU_R_FAN, 0x24 },
635         { "AUX4", SENSOR_FANRPM, UGURU_R_FAN, 0x25 },
636
637         { NULL }
638 };
639
640 static void      uguru_identify(driver_t *driver, struct device *parent);
641 static int       uguru_match(struct device *);
642 static int       uguru_attach(struct device *);
643 static int       uguru_detach(struct device *dev);
644 static void      uguru_refresh(void *);
645 static int       uguru_read_sensor(struct uguru_softc *, int);
646 static int       uguru_ac5_read_sensor(struct uguru_softc *, int);
647 static int       uguru_ac5_read(bus_space_tag_t, bus_space_handle_t,
648                      uint16_t, void *, int);
649 static int       uguru_write_multi(bus_space_tag_t, bus_space_handle_t,
650                      uint8_t, void *, int);
651 static int       uguru_read_multi(bus_space_tag_t, bus_space_handle_t, void *,
652                      int);
653
654 static device_method_t uguru_methods[] = {
655         DEVMETHOD(device_identify,      uguru_identify),
656         DEVMETHOD(device_probe,         uguru_match),
657         DEVMETHOD(device_attach,        uguru_attach),
658         DEVMETHOD(device_detach,        uguru_detach),
659
660         { NULL, NULL}
661 };
662
663 static driver_t uguru_driver = {
664         "uguru",
665         uguru_methods,
666         sizeof(struct uguru_softc)
667 };
668
669 static devclass_t uguru_devclass;
670
671 DRIVER_MODULE(uguru, isa, uguru_driver, uguru_devclass, NULL, NULL);
672
673 static void
674 uguru_identify(driver_t *driver, struct device *parent)
675 {
676 #ifdef KLD_MODULE
677         struct device *child;
678         const int port = 0xe0;
679
680         child = device_find_child(parent, driver->name, 0);
681         if (child == NULL)
682                 child = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP,
683                     driver->name, 0);
684         if (bus_set_resource(child, SYS_RES_IOPORT, 0, port, UGURU_IOSIZE))
685                 kprintf("%s: cannot set resource for child\n", __func__);
686 #endif
687 }
688
689 static int
690 uguru_match(struct device *dev)
691 {
692         struct resource *iores;
693         int iorid = 0;
694         bus_space_tag_t iot;
695         bus_space_handle_t ioh;
696         uint8_t data[9];
697         uint16_t vendid, devid;
698         int ret = 1;
699
700         iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &iorid,
701             0ul, ~0ul, 8, RF_ACTIVE);
702         if (iores == NULL)
703                 return ENXIO;
704         iot = rman_get_bustag(iores);
705         ioh = rman_get_bushandle(iores);
706
707         UGURU_WRITE(iot, ioh, UGURU_INDEX, UGURU_PRODID);
708         if (!uguru_read_multi(iot, ioh, &data, sizeof(data)) ||
709             !uguru_ac5_read(iot, ioh, 0x0904, &data, sizeof(data))) {
710                 vendid = data[0] << 8 | data[1];
711                 devid = data[2] << 8 | data[3];
712
713                 if (vendid == UGURU_VENDID_ABIT &&
714                     (devid == UGURU_DEVID1 ||
715                      devid == UGURU_DEVID2)) {
716                         ret = 0;
717                 }
718         }
719         bus_release_resource(dev, SYS_RES_IOPORT, iorid, iores);
720         return (ret);
721 }
722
723 static int
724 uguru_attach(struct device *dev)
725 {
726         struct uguru_softc *sc = device_get_softc(dev);
727         struct uguru_sensor *sensors;
728         uint8_t data[9];
729         uint16_t vendid, devid, sysid;
730         int i;
731         const char *desc = NULL;
732         char fulldesc[64];
733
734         sc->sc_dev = dev;
735         sc->sc_iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_iorid,
736             0ul, ~0ul, 8, RF_ACTIVE);
737         if (sc->sc_iores == NULL) {
738                 device_printf(dev, "can't map i/o space\n");
739                 return ENXIO;
740         }
741         sc->sc_iot = rman_get_bustag(sc->sc_iores);
742         sc->sc_ioh = rman_get_bushandle(sc->sc_iores);
743
744         UGURU_WRITE(sc->sc_iot, sc->sc_ioh, UGURU_INDEX, UGURU_PRODID);
745         if (!uguru_read_multi(sc->sc_iot, sc->sc_ioh, &data, sizeof(data))) {
746                 sc->read = uguru_read_sensor;
747                 goto done;
748         }
749
750         /* AC2005 product ID */
751         if (!uguru_ac5_read(sc->sc_iot, sc->sc_ioh,
752             0x0904, &data, sizeof(data))) {
753                 sc->read = uguru_ac5_read_sensor;
754                 goto done;
755         }
756
757         return ENXIO;
758
759 done:
760         DPRINTF(5, ": %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x",
761             data[0], data[1], data[2], data[3], data[4],
762             data[5], data[6], data[7], data[8]);
763
764         vendid = data[0] << 8 | data[1];
765         devid = data[2] << 8 | data[3];
766         sysid = data[3] << 8 | data[7];
767
768         if (vendid != UGURU_VENDID_ABIT ||
769             (devid != UGURU_DEVID1 &&
770              devid != UGURU_DEVID2)) {
771                 device_printf(dev, "attach failed\n");
772                 return ENXIO;
773         }
774
775         switch(sysid) {
776         case ABIT_SYSID_KV01:
777         case ABIT_SYSID_AI01:
778         case ABIT_SYSID_AN01:
779                 desc = "KV1";
780                 sensors = abitkv_sensors;
781                 break;
782         case ABIT_SYSID_AA01:
783         case ABIT_SYSID_AG01:
784                 desc = "AA1";
785                 sensors = abitaa_sensors;
786                 break;
787         case ABIT_SYSID_AV01:
788         case ABIT_SYSID_KVP1:
789                 desc = "AV1";
790                 sensors = abitav_sensors;
791                 break;
792         case ABIT_SYSID_AS01:
793                 desc = "AS1";
794                 sensors = abitas_sensors;
795                 break;
796         case ABIT_SYSID_AX01:
797                 desc = "AX1";
798                 sensors = abitax_sensors;
799                 break;
800         case ABIT_SYSID_M401:
801                 desc = "M41";
802                 sensors = abitm4_sensors;
803                 break;
804         case ABIT_SYSID_AN02:
805                 desc = "AN1";
806                 sensors = abitan_sensors;
807                 break;
808         case ABIT_SYSID_AU01:
809         case ABIT_SYSID_AL01:
810         case ABIT_SYSID_BL01:
811                 desc = "AL1";
812                 sensors = abital_sensors;
813                 break;
814         case ABIT_SYSID_AW01:
815         case ABIT_SYSID_AW02:
816                 desc = "AW1";
817                 sensors = abitaw_sensors;
818                 break;
819         case ABIT_SYSID_NI01:
820                 desc = "NI1";
821                 sensors = abitni_sensors;
822                 break;
823         case ABIT_SYSID_AT01:
824                 desc = "AT1";
825                 sensors = abitat_sensors;
826                 break;
827         case ABIT_SYSID_AN03:
828                 desc = "AN2";
829                 sensors = abitan2_sensors;
830                 break;
831         case ABIT_SYSID_AB01:
832                 desc = "AB1";
833                 sensors = abitab_sensors;
834                 break;
835         case ABIT_SYSID_AN04:
836                 desc = "AN3";
837                 sensors = abitan3_sensors;
838                 break;
839         case ABIT_SYSID_AW03:
840                 desc = "AW2";
841                 sensors = abitaw2_sensors;
842                 break;
843         case ABIT_SYSID_AT02:
844                 desc = "AT2";
845                 sensors = abitat2_sensors;
846                 break;
847         case ABIT_SYSID_AB02:
848         case ABIT_SYSID_IP01:
849         case ABIT_SYSID_IX01:
850         case ABIT_SYSID_IX02:
851                 desc = "AB2";
852                 sensors = abitab2_sensors;
853                 break;
854         case ABIT_SYSID_IN01:
855                 desc = "IN1";
856                 sensors = abitin_sensors;
857                 break;
858         default:
859                 kprintf(" unknown system (ID 0x%.4x)\n", sysid);
860                 return ENXIO;
861         }
862
863         strlcpy(sc->sc_sensordev.xname,
864             device_get_nameunit(sc->sc_dev),
865             sizeof(sc->sc_sensordev.xname));
866
867         for (i = 0; sensors[i].desc != NULL; i++) {
868                 strlcpy(sc->sc_sensors[i].desc,
869                     sensors[i].desc, sizeof(sc->sc_sensors[i].desc));
870                 sc->sc_sensors[i].type = sensors[i].type;
871                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
872                 sc->sc_numsensors++;
873         }
874         sc->uguru_sensors = sensors;
875
876         if (sensor_task_register(sc, uguru_refresh, UGURU_INTERVAL) != 0) {
877                 kprintf("%s: unable to register update task\n",
878                     sc->sc_sensordev.xname);
879                 return ENXIO;
880         }
881         sensordev_install(&sc->sc_sensordev);
882
883         ksnprintf(fulldesc, sizeof(fulldesc),
884             "ABIT AC%x %s I/O port driver", devid, desc);
885         device_set_desc_copy(dev, fulldesc);
886         return 0;
887 }
888
889 static int
890 uguru_detach(struct device *dev)
891 {
892         struct uguru_softc *sc = device_get_softc(dev);
893
894         return bus_release_resource(dev, SYS_RES_IOPORT,
895             sc->sc_iorid, sc->sc_iores);
896 }
897
898 static void
899 uguru_refresh(void *arg)
900 {
901         struct uguru_softc *sc = (struct uguru_softc *)arg;
902         int i;
903
904         for (i = 0; i < sc->sc_numsensors; i++)
905                 sc->uguru_sensors[i].refresh(sc, i);
906 }
907
908 static void
909 uguru_refresh_temp(struct uguru_softc *sc, int n)
910 {
911         struct ksensor *sensor = &sc->sc_sensors[n];
912         int status = SENSOR_S_OK;
913         int ret;
914
915         ret = sc->read(sc, n);
916         if (sc->cs.reading == 0x00) {
917                 sensor->flags |= SENSOR_FINVALID;
918                 sensor->value = 0;
919                 return;
920         }
921         sensor->flags &= ~SENSOR_FINVALID;
922         sensor->value = sc->cs.reading * 1000000 + 273150000;
923
924         if (ret)
925                 status = SENSOR_S_UNSPEC;
926         else {
927                 if (sc->cs.reading >= sc->cs.lower)
928                         status = SENSOR_S_WARN;
929                 if (sc->cs.reading >= sc->cs.upper)
930                         status = SENSOR_S_CRIT;
931         }
932         sensor->status = status;
933 }
934
935 static void
936 uguru_refresh_volt(struct uguru_softc *sc, int n)
937 {
938         int status = SENSOR_S_OK;
939
940         if (sc->read(sc, n))
941                 status = SENSOR_S_UNSPEC;
942         else
943                 if (sc->cs.reading <= sc->cs.lower ||
944                     sc->cs.reading >= sc->cs.upper)
945                         status = SENSOR_S_CRIT;
946
947         sc->sc_sensors[n].value =
948             sc->cs.reading * sc->uguru_sensors[n].rfact;
949         sc->sc_sensors[n].status = status;
950 }
951
952 static void
953 uguru_refresh_fan(struct uguru_softc *sc, int n)
954 {
955         struct ksensor *sensor = &sc->sc_sensors[n];
956         int ret;
957
958         ret = sc->read(sc, n);
959         if (sc->cs.reading == 0x00) {
960                 sensor->flags |= SENSOR_FINVALID;
961                 sensor->value = 0;
962                 return;
963         }
964         sensor->flags &= ~SENSOR_FINVALID;
965         sensor->value = sc->cs.reading * 60;
966
967         if (ret)
968                 sensor->status = SENSOR_S_UNSPEC;
969         else
970                 if (sc->cs.reading <= sc->cs.lower)
971                         sensor->status = SENSOR_S_CRIT;
972                 else
973                         sensor->status = SENSOR_S_OK;
974 }
975
976 static int
977 uguru_read_sensor(struct uguru_softc *sc, int n)
978 {
979         struct ksensor *sensor = &sc->sc_sensors[n];
980         bus_space_tag_t iot = sc->sc_iot;
981         bus_space_handle_t ioh = sc->sc_ioh;
982         uint8_t reg = sc->uguru_sensors[n].reg;
983         uint8_t idx, data[3];
984         uint8_t val = 0x00;
985         int count, ret = 0;
986
987         if (sensor->type == SENSOR_FANRPM)
988                 idx = UGURU_FAN_DATA;
989         else
990                 idx = UGURU_ITM_DATA;
991
992         /* sensor value */
993         if (uguru_write_multi(iot, ioh, idx, &reg, sizeof(reg)) ||
994             uguru_read_multi(iot, ioh, &val, sizeof(val)))
995                 ++ret;
996
997         /* sensor status */
998         bzero(&data, sizeof(data));
999         count = sensor->type == SENSOR_FANRPM ? 2 : 3;
1000
1001         if (uguru_write_multi(iot, ioh, idx + 1, &reg, sizeof(reg)) ||
1002             uguru_read_multi(iot, ioh, &data, count))
1003                 ++ret;
1004
1005         /* fill in current sensor structure */
1006         sc->cs.reading = val;
1007 /*      sc->cs.flags = data[0]; */
1008         sc->cs.lower = data[1];
1009         sc->cs.upper = data[2];
1010
1011         DPRINTF(50, "0x%.2x: 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
1012             idx, reg, val, data[0], data[1], data[2]);
1013
1014         return (ret);
1015 }
1016
1017 static int
1018 uguru_ac5_read_sensor(struct uguru_softc *sc, int n)
1019 {
1020         uint16_t reg;
1021         uint8_t val = 0x00;
1022         int ret = 1;
1023
1024         reg = sc->uguru_sensors[n].reg | 0x0880;
1025         if (uguru_ac5_read(sc->sc_iot, sc->sc_ioh, reg, &val, sizeof(val)))
1026                 ++ret;
1027
1028         sc->cs.reading = val;
1029         return (ret);
1030 }
1031
1032 static int
1033 uguru_ac5_read(bus_space_tag_t iot, bus_space_handle_t ioh,
1034     uint16_t reg, void *data, int count)
1035 {
1036         uint8_t buf[3];
1037
1038         buf[0] = reg >> 8;
1039         buf[1] = reg & 0xff;
1040         buf[2] = count;
1041
1042         if (!uguru_write_multi(iot, ioh, 0x1a, &buf, sizeof(buf)) &&
1043             !uguru_read_multi(iot, ioh, data, count))
1044                 return 0;
1045
1046         DPRINTF(0, "uguru_ac5_read: timeout 0x%.2x 0x%.2x 0x%.2x\n",
1047             buf[0], buf[1], buf[2]);
1048
1049         return 1;
1050 }
1051
1052 static int
1053 uguru_write_multi(bus_space_tag_t iot, bus_space_handle_t ioh,
1054     uint8_t idx, void *data, int count)
1055 {
1056         uint8_t *inbuf = data;
1057         int i, ntries;
1058
1059         UGURU_WRITE(iot, ioh, UGURU_INDEX, idx);
1060
1061         for (i = 0; i < count; ++i) {
1062                 /*
1063                  * wait for non-busy status before write
1064                  * to the data port.
1065                  */
1066                 ntries = 0;
1067                 while (UGURU_READ(iot, ioh, UGURU_INDEX) >> 1 & 1) {
1068                         if (++ntries > 65)
1069                                 goto timeout;
1070                         DELAY(5);
1071                 }
1072                 /* dummy read to flush the internal buffer */
1073                 if (i == 0)
1074                         UGURU_READ(iot, ioh, UGURU_DATA);
1075
1076                 UGURU_WRITE(iot, ioh, UGURU_DATA, *inbuf++);
1077         }
1078         return 0;
1079
1080 timeout:
1081         DPRINTF(0, "uguru_write_multi: timeout 0x%.2x\n", idx);
1082         return 1;
1083 }
1084
1085 static int
1086 uguru_read_multi(bus_space_tag_t iot, bus_space_handle_t ioh,
1087     void *data, int count)
1088 {
1089         uint8_t *outbuf = data;
1090         int i, ntries;
1091
1092         for (i = 0; i < count; ++i) {
1093                 /*
1094                  * wait for valid status before read
1095                  * from the data port.
1096                  */
1097                 ntries = 0;
1098                 while (!(UGURU_READ(iot, ioh, UGURU_INDEX) & 1)) {
1099                         if (++ntries > 40) {
1100                                 DPRINTF(0, "uguru_read_multi: timeout\n");
1101                                 return 1;
1102                         }
1103                         DELAY(35);
1104                 }
1105                 *outbuf++ = UGURU_READ(iot, ioh, UGURU_DATA);
1106         }
1107         return 0;
1108 }