xref: /dragonfly/sys/dev/powermng/uguru/uguru.c (revision d4ef6694)
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, -1))
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 	sensordev_deinstall(&sc->sc_sensordev);
895 	sensor_task_unregister(sc);
896 
897 	return bus_release_resource(dev, SYS_RES_IOPORT,
898 	    sc->sc_iorid, sc->sc_iores);
899 }
900 
901 static void
902 uguru_refresh(void *arg)
903 {
904 	struct uguru_softc *sc = (struct uguru_softc *)arg;
905 	int i;
906 
907 	for (i = 0; i < sc->sc_numsensors; i++)
908 		sc->uguru_sensors[i].refresh(sc, i);
909 }
910 
911 static void
912 uguru_refresh_temp(struct uguru_softc *sc, int n)
913 {
914 	struct ksensor *sensor = &sc->sc_sensors[n];
915 	int status = SENSOR_S_OK;
916 	int ret;
917 
918 	ret = sc->read(sc, n);
919 	if (sc->cs.reading == 0x00) {
920 		sensor->flags |= SENSOR_FINVALID;
921 		sensor->value = 0;
922 		return;
923 	}
924 	sensor->flags &= ~SENSOR_FINVALID;
925 	sensor->value = sc->cs.reading * 1000000 + 273150000;
926 
927 	if (ret)
928 		status = SENSOR_S_UNSPEC;
929 	else {
930 		if (sc->cs.reading >= sc->cs.lower)
931 			status = SENSOR_S_WARN;
932 		if (sc->cs.reading >= sc->cs.upper)
933 			status = SENSOR_S_CRIT;
934 	}
935 	sensor->status = status;
936 }
937 
938 static void
939 uguru_refresh_volt(struct uguru_softc *sc, int n)
940 {
941 	int status = SENSOR_S_OK;
942 
943 	if (sc->read(sc, n))
944 		status = SENSOR_S_UNSPEC;
945 	else
946 		if (sc->cs.reading <= sc->cs.lower ||
947 		    sc->cs.reading >= sc->cs.upper)
948 			status = SENSOR_S_CRIT;
949 
950 	sc->sc_sensors[n].value =
951 	    sc->cs.reading * sc->uguru_sensors[n].rfact;
952 	sc->sc_sensors[n].status = status;
953 }
954 
955 static void
956 uguru_refresh_fan(struct uguru_softc *sc, int n)
957 {
958 	struct ksensor *sensor = &sc->sc_sensors[n];
959 	int ret;
960 
961 	ret = sc->read(sc, n);
962 	if (sc->cs.reading == 0x00) {
963 		sensor->flags |= SENSOR_FINVALID;
964 		sensor->value = 0;
965 		return;
966 	}
967 	sensor->flags &= ~SENSOR_FINVALID;
968 	sensor->value = sc->cs.reading * 60;
969 
970 	if (ret)
971 		sensor->status = SENSOR_S_UNSPEC;
972 	else
973 		if (sc->cs.reading <= sc->cs.lower)
974 			sensor->status = SENSOR_S_CRIT;
975 		else
976 			sensor->status = SENSOR_S_OK;
977 }
978 
979 static int
980 uguru_read_sensor(struct uguru_softc *sc, int n)
981 {
982 	struct ksensor *sensor = &sc->sc_sensors[n];
983 	bus_space_tag_t iot = sc->sc_iot;
984 	bus_space_handle_t ioh = sc->sc_ioh;
985 	uint8_t reg = sc->uguru_sensors[n].reg;
986 	uint8_t idx, data[3];
987 	uint8_t val = 0x00;
988 	int count, ret = 0;
989 
990 	if (sensor->type == SENSOR_FANRPM)
991 		idx = UGURU_FAN_DATA;
992 	else
993 		idx = UGURU_ITM_DATA;
994 
995 	/* sensor value */
996 	if (uguru_write_multi(iot, ioh, idx, &reg, sizeof(reg)) ||
997 	    uguru_read_multi(iot, ioh, &val, sizeof(val)))
998 		++ret;
999 
1000 	/* sensor status */
1001 	bzero(&data, sizeof(data));
1002 	count = sensor->type == SENSOR_FANRPM ? 2 : 3;
1003 
1004 	if (uguru_write_multi(iot, ioh, idx + 1, &reg, sizeof(reg)) ||
1005 	    uguru_read_multi(iot, ioh, &data, count))
1006 		++ret;
1007 
1008 	/* fill in current sensor structure */
1009 	sc->cs.reading = val;
1010 /*	sc->cs.flags = data[0]; */
1011 	sc->cs.lower = data[1];
1012 	sc->cs.upper = data[2];
1013 
1014 	DPRINTF(50, "0x%.2x: 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
1015 	    idx, reg, val, data[0], data[1], data[2]);
1016 
1017 	return (ret);
1018 }
1019 
1020 static int
1021 uguru_ac5_read_sensor(struct uguru_softc *sc, int n)
1022 {
1023 	uint16_t reg;
1024 	uint8_t val = 0x00;
1025 	int ret = 1;
1026 
1027 	reg = sc->uguru_sensors[n].reg | 0x0880;
1028 	if (uguru_ac5_read(sc->sc_iot, sc->sc_ioh, reg, &val, sizeof(val)))
1029 		++ret;
1030 
1031 	sc->cs.reading = val;
1032 	return (ret);
1033 }
1034 
1035 static int
1036 uguru_ac5_read(bus_space_tag_t iot, bus_space_handle_t ioh,
1037     uint16_t reg, void *data, int count)
1038 {
1039 	uint8_t buf[3];
1040 
1041 	buf[0] = reg >> 8;
1042 	buf[1] = reg & 0xff;
1043 	buf[2] = count;
1044 
1045 	if (!uguru_write_multi(iot, ioh, 0x1a, &buf, sizeof(buf)) &&
1046 	    !uguru_read_multi(iot, ioh, data, count))
1047 		return 0;
1048 
1049 	DPRINTF(0, "uguru_ac5_read: timeout 0x%.2x 0x%.2x 0x%.2x\n",
1050 	    buf[0], buf[1], buf[2]);
1051 
1052 	return 1;
1053 }
1054 
1055 static int
1056 uguru_write_multi(bus_space_tag_t iot, bus_space_handle_t ioh,
1057     uint8_t idx, void *data, int count)
1058 {
1059 	uint8_t *inbuf = data;
1060 	int i, ntries;
1061 
1062 	UGURU_WRITE(iot, ioh, UGURU_INDEX, idx);
1063 
1064 	for (i = 0; i < count; ++i) {
1065 		/*
1066 		 * wait for non-busy status before write
1067 		 * to the data port.
1068 		 */
1069 		ntries = 0;
1070 		while (UGURU_READ(iot, ioh, UGURU_INDEX) >> 1 & 1) {
1071 			if (++ntries > 65)
1072 				goto timeout;
1073 			DELAY(5);
1074 		}
1075 		/* dummy read to flush the internal buffer */
1076 		if (i == 0)
1077 			UGURU_READ(iot, ioh, UGURU_DATA);
1078 
1079 		UGURU_WRITE(iot, ioh, UGURU_DATA, *inbuf++);
1080 	}
1081 	return 0;
1082 
1083 timeout:
1084 	DPRINTF(0, "uguru_write_multi: timeout 0x%.2x\n", idx);
1085 	return 1;
1086 }
1087 
1088 static int
1089 uguru_read_multi(bus_space_tag_t iot, bus_space_handle_t ioh,
1090     void *data, int count)
1091 {
1092 	uint8_t *outbuf = data;
1093 	int i, ntries;
1094 
1095 	for (i = 0; i < count; ++i) {
1096 		/*
1097 		 * wait for valid status before read
1098 		 * from the data port.
1099 		 */
1100 		ntries = 0;
1101 		while (!(UGURU_READ(iot, ioh, UGURU_INDEX) & 1)) {
1102 			if (++ntries > 40) {
1103 				DPRINTF(0, "uguru_read_multi: timeout\n");
1104 				return 1;
1105 			}
1106 			DELAY(35);
1107 		}
1108 		*outbuf++ = UGURU_READ(iot, ioh, UGURU_DATA);
1109 	}
1110 	return 0;
1111 }
1112