xref: /linux/drivers/hwmon/abituguru3.c (revision b43ab901d671e3e3cad425ea5e9a3c74e266dcdd)
1 /*
2     abituguru3.c
3 
4     Copyright (c) 2006-2008 Hans de Goede <hdegoede@redhat.com>
5     Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk>
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 /*
22     This driver supports the sensor part of revision 3 of the custom Abit uGuru
23     chip found on newer Abit uGuru motherboards. Note: because of lack of specs
24     only reading the sensors and their settings is supported.
25 */
26 
27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28 
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/jiffies.h>
33 #include <linux/mutex.h>
34 #include <linux/err.h>
35 #include <linux/delay.h>
36 #include <linux/platform_device.h>
37 #include <linux/hwmon.h>
38 #include <linux/hwmon-sysfs.h>
39 #include <linux/dmi.h>
40 #include <linux/io.h>
41 
42 /* uGuru3 bank addresses */
43 #define ABIT_UGURU3_SETTINGS_BANK		0x01
44 #define ABIT_UGURU3_SENSORS_BANK		0x08
45 #define ABIT_UGURU3_MISC_BANK			0x09
46 #define ABIT_UGURU3_ALARMS_START		0x1E
47 #define ABIT_UGURU3_SETTINGS_START		0x24
48 #define ABIT_UGURU3_VALUES_START		0x80
49 #define ABIT_UGURU3_BOARD_ID			0x0A
50 /* uGuru3 sensor bank flags */			     /* Alarm if: */
51 #define ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE	0x01 /*  temp over warn */
52 #define ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE	0x02 /*  volt over max */
53 #define ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE	0x04 /*  volt under min */
54 #define ABIT_UGURU3_TEMP_HIGH_ALARM_FLAG	0x10 /* temp is over warn */
55 #define ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG	0x20 /* volt is over max */
56 #define ABIT_UGURU3_VOLT_LOW_ALARM_FLAG		0x40 /* volt is under min */
57 #define ABIT_UGURU3_FAN_LOW_ALARM_ENABLE	0x01 /*   fan under min */
58 #define ABIT_UGURU3_BEEP_ENABLE			0x08 /* beep if alarm */
59 #define ABIT_UGURU3_SHUTDOWN_ENABLE		0x80 /* shutdown if alarm */
60 /* sensor types */
61 #define ABIT_UGURU3_IN_SENSOR			0
62 #define ABIT_UGURU3_TEMP_SENSOR			1
63 #define ABIT_UGURU3_FAN_SENSOR			2
64 
65 /* Timeouts / Retries, if these turn out to need a lot of fiddling we could
66    convert them to params. Determined by trial and error. I assume this is
67    cpu-speed independent, since the ISA-bus and not the CPU should be the
68    bottleneck. */
69 #define ABIT_UGURU3_WAIT_TIMEOUT		250
70 /* Normally the 0xAC at the end of synchronize() is reported after the
71    first read, but sometimes not and we need to poll */
72 #define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT		5
73 /* utility macros */
74 #define ABIT_UGURU3_NAME			"abituguru3"
75 #define ABIT_UGURU3_DEBUG(format, arg...)	\
76 	if (verbose)				\
77 		printk(KERN_DEBUG ABIT_UGURU3_NAME ": "	format , ## arg)
78 
79 /* Macros to help calculate the sysfs_names array length */
80 #define ABIT_UGURU3_MAX_NO_SENSORS 26
81 /* sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0,
82    in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0 */
83 #define ABIT_UGURU3_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11)
84 /* sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0,
85    temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0,
86    temp??_label\0 */
87 #define ABIT_UGURU3_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16 + 13)
88 /* sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0,
89    fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0 */
90 #define ABIT_UGURU3_FAN_NAMES_LENGTH (12 + 10 + 12 + 19 + 11 + 15 + 12)
91 /* Worst case scenario 16 in sensors (longest names_length) and the rest
92    temp sensors (second longest names_length). */
93 #define ABIT_UGURU3_SYSFS_NAMES_LENGTH (16 * ABIT_UGURU3_IN_NAMES_LENGTH + \
94 	(ABIT_UGURU3_MAX_NO_SENSORS - 16) * ABIT_UGURU3_TEMP_NAMES_LENGTH)
95 
96 /* All the macros below are named identical to the openguru2 program
97    reverse engineered by Louis Kruger, hence the names might not be 100%
98    logical. I could come up with better names, but I prefer keeping the names
99    identical so that this driver can be compared with his work more easily. */
100 /* Two i/o-ports are used by uGuru */
101 #define ABIT_UGURU3_BASE			0x00E0
102 #define ABIT_UGURU3_CMD				0x00
103 #define ABIT_UGURU3_DATA			0x04
104 #define ABIT_UGURU3_REGION_LENGTH		5
105 /* The wait_xxx functions return this on success and the last contents
106    of the DATA register (0-255) on failure. */
107 #define ABIT_UGURU3_SUCCESS			-1
108 /* uGuru status flags */
109 #define ABIT_UGURU3_STATUS_READY_FOR_READ	0x01
110 #define ABIT_UGURU3_STATUS_BUSY			0x02
111 
112 
113 /* Structures */
114 struct abituguru3_sensor_info {
115 	const char* name;
116 	int port;
117 	int type;
118 	int multiplier;
119 	int divisor;
120 	int offset;
121 };
122 
123 /* Avoid use of flexible array members */
124 #define ABIT_UGURU3_MAX_DMI_NAMES 2
125 
126 struct abituguru3_motherboard_info {
127 	u16 id;
128 	const char *dmi_name[ABIT_UGURU3_MAX_DMI_NAMES + 1];
129 	/* + 1 -> end of sensors indicated by a sensor with name == NULL */
130 	struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1];
131 };
132 
133 /* For the Abit uGuru, we need to keep some data in memory.
134    The structure is dynamically allocated, at the same time when a new
135    abituguru3 device is allocated. */
136 struct abituguru3_data {
137 	struct device *hwmon_dev;	/* hwmon registered device */
138 	struct mutex update_lock;	/* protect access to data and uGuru */
139 	unsigned short addr;		/* uguru base address */
140 	char valid;			/* !=0 if following fields are valid */
141 	unsigned long last_updated;	/* In jiffies */
142 
143 	/* For convenience the sysfs attr and their names are generated
144 	   automatically. We have max 10 entries per sensor (for in sensors) */
145 	struct sensor_device_attribute_2 sysfs_attr[ABIT_UGURU3_MAX_NO_SENSORS
146 		* 10];
147 
148 	/* Buffer to store the dynamically generated sysfs names */
149 	char sysfs_names[ABIT_UGURU3_SYSFS_NAMES_LENGTH];
150 
151 	/* Pointer to the sensors info for the detected motherboard */
152 	const struct abituguru3_sensor_info *sensors;
153 
154 	/* The abituguru3 supports up to 48 sensors, and thus has registers
155 	   sets for 48 sensors, for convienence reasons / simplicity of the
156 	   code we always read and store all registers for all 48 sensors */
157 
158 	/* Alarms for all 48 sensors (1 bit per sensor) */
159 	u8 alarms[48/8];
160 
161 	/* Value of all 48 sensors */
162 	u8 value[48];
163 
164 	/* Settings of all 48 sensors, note in and temp sensors (the first 32
165 	   sensors) have 3 bytes of settings, while fans only have 2 bytes,
166 	   for convenience we use 3 bytes for all sensors */
167 	u8 settings[48][3];
168 };
169 
170 
171 /* Constants */
172 static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
173 	{ 0x000C, { NULL } /* Unknown, need DMI string */, {
174 		{ "CPU Core",		 0, 0, 10, 1, 0 },
175 		{ "DDR",		 1, 0, 10, 1, 0 },
176 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
177 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
178 		{ "MCH & PCIE 1.5V",	 4, 0, 10, 1, 0 },
179 		{ "MCH 2.5V",		 5, 0, 20, 1, 0 },
180 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
181 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
182 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
183 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
184 		{ "+3.3V",		10, 0, 20, 1, 0 },
185 		{ "5VSB",		11, 0, 30, 1, 0 },
186 		{ "CPU",		24, 1, 1, 1, 0 },
187 		{ "System",		25, 1, 1, 1, 0 },
188 		{ "PWM",		26, 1, 1, 1, 0 },
189 		{ "CPU Fan",		32, 2, 60, 1, 0 },
190 		{ "NB Fan",		33, 2, 60, 1, 0 },
191 		{ "SYS FAN",		34, 2, 60, 1, 0 },
192 		{ "AUX1 Fan",		35, 2, 60, 1, 0 },
193 		{ NULL, 0, 0, 0, 0, 0 } }
194 	},
195 	{ 0x000D, { NULL } /* Abit AW8, need DMI string */, {
196 		{ "CPU Core",		 0, 0, 10, 1, 0 },
197 		{ "DDR",		 1, 0, 10, 1, 0 },
198 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
199 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
200 		{ "MCH & PCIE 1.5V",	 4, 0, 10, 1, 0 },
201 		{ "MCH 2.5V",		 5, 0, 20, 1, 0 },
202 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
203 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
204 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
205 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
206 		{ "+3.3V",		10, 0, 20, 1, 0 },
207 		{ "5VSB",		11, 0, 30, 1, 0 },
208 		{ "CPU",		24, 1, 1, 1, 0 },
209 		{ "System",		25, 1, 1, 1, 0 },
210 		{ "PWM1",		26, 1, 1, 1, 0 },
211 		{ "PWM2",		27, 1, 1, 1, 0 },
212 		{ "PWM3",		28, 1, 1, 1, 0 },
213 		{ "PWM4",		29, 1, 1, 1, 0 },
214 		{ "CPU Fan",		32, 2, 60, 1, 0 },
215 		{ "NB Fan",		33, 2, 60, 1, 0 },
216 		{ "SYS Fan",		34, 2, 60, 1, 0 },
217 		{ "AUX1 Fan",		35, 2, 60, 1, 0 },
218 		{ "AUX2 Fan",		36, 2, 60, 1, 0 },
219 		{ "AUX3 Fan",		37, 2, 60, 1, 0 },
220 		{ "AUX4 Fan",		38, 2, 60, 1, 0 },
221 		{ "AUX5 Fan",		39, 2, 60, 1, 0 },
222 		{ NULL, 0, 0, 0, 0, 0 } }
223 	},
224 	{ 0x000E, { NULL } /* AL-8, need DMI string */, {
225 		{ "CPU Core",		 0, 0, 10, 1, 0 },
226 		{ "DDR",		 1, 0, 10, 1, 0 },
227 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
228 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
229 		{ "MCH & PCIE 1.5V",	 4, 0, 10, 1, 0 },
230 		{ "MCH 2.5V",		 5, 0, 20, 1, 0 },
231 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
232 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
233 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
234 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
235 		{ "+3.3V",		10, 0, 20, 1, 0 },
236 		{ "5VSB",		11, 0, 30, 1, 0 },
237 		{ "CPU",		24, 1, 1, 1, 0 },
238 		{ "System",		25, 1, 1, 1, 0 },
239 		{ "PWM",		26, 1, 1, 1, 0 },
240 		{ "CPU Fan",		32, 2, 60, 1, 0 },
241 		{ "NB Fan",		33, 2, 60, 1, 0 },
242 		{ "SYS Fan",		34, 2, 60, 1, 0 },
243 		{ NULL, 0, 0, 0, 0, 0 } }
244 	},
245 	{ 0x000F, { NULL } /* Unknown, need DMI string */, {
246 
247 		{ "CPU Core",		 0, 0, 10, 1, 0 },
248 		{ "DDR",		 1, 0, 10, 1, 0 },
249 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
250 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
251 		{ "MCH & PCIE 1.5V",	 4, 0, 10, 1, 0 },
252 		{ "MCH 2.5V",		 5, 0, 20, 1, 0 },
253 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
254 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
255 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
256 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
257 		{ "+3.3V",		10, 0, 20, 1, 0 },
258 		{ "5VSB",		11, 0, 30, 1, 0 },
259 		{ "CPU",		24, 1, 1, 1, 0 },
260 		{ "System",		25, 1, 1, 1, 0 },
261 		{ "PWM",		26, 1, 1, 1, 0 },
262 		{ "CPU Fan",		32, 2, 60, 1, 0 },
263 		{ "NB Fan",		33, 2, 60, 1, 0 },
264 		{ "SYS Fan",		34, 2, 60, 1, 0 },
265 		{ NULL, 0, 0, 0, 0, 0 } }
266 	},
267 	{ 0x0010, { NULL } /* Abit NI8 SLI GR, need DMI string */, {
268 		{ "CPU Core",		 0, 0, 10, 1, 0 },
269 		{ "DDR",		 1, 0, 10, 1, 0 },
270 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
271 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
272 		{ "NB 1.4V",		 4, 0, 10, 1, 0 },
273 		{ "SB 1.5V",		 6, 0, 10, 1, 0 },
274 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
275 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
276 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
277 		{ "+3.3V",		10, 0, 20, 1, 0 },
278 		{ "5VSB",		11, 0, 30, 1, 0 },
279 		{ "CPU",		24, 1, 1, 1, 0 },
280 		{ "SYS",		25, 1, 1, 1, 0 },
281 		{ "PWM",		26, 1, 1, 1, 0 },
282 		{ "CPU Fan",		32, 2, 60, 1, 0 },
283 		{ "NB Fan",		33, 2, 60, 1, 0 },
284 		{ "SYS Fan",		34, 2, 60, 1, 0 },
285 		{ "AUX1 Fan",		35, 2, 60, 1, 0 },
286 		{ "OTES1 Fan",		36, 2, 60, 1, 0 },
287 		{ NULL, 0, 0, 0, 0, 0 } }
288 	},
289 	{ 0x0011, { "AT8 32X", NULL }, {
290 		{ "CPU Core",		 0, 0, 10, 1, 0 },
291 		{ "DDR",		 1, 0, 20, 1, 0 },
292 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
293 		{ "CPU VDDA 2.5V",	 6, 0, 20, 1, 0 },
294 		{ "NB 1.8V",		 4, 0, 10, 1, 0 },
295 		{ "NB 1.8V Dual",	 5, 0, 10, 1, 0 },
296 		{ "HTV 1.2",		 3, 0, 10, 1, 0 },
297 		{ "PCIE 1.2V",		12, 0, 10, 1, 0 },
298 		{ "NB 1.2V",		13, 0, 10, 1, 0 },
299 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
300 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
301 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
302 		{ "+3.3V",		10, 0, 20, 1, 0 },
303 		{ "5VSB",		11, 0, 30, 1, 0 },
304 		{ "CPU",		24, 1, 1, 1, 0 },
305 		{ "NB",			25, 1, 1, 1, 0 },
306 		{ "System",		26, 1, 1, 1, 0 },
307 		{ "PWM",		27, 1, 1, 1, 0 },
308 		{ "CPU Fan",		32, 2, 60, 1, 0 },
309 		{ "NB Fan",		33, 2, 60, 1, 0 },
310 		{ "SYS Fan",		34, 2, 60, 1, 0 },
311 		{ "AUX1 Fan",		35, 2, 60, 1, 0 },
312 		{ "AUX2 Fan",		36, 2, 60, 1, 0 },
313 		{ "AUX3 Fan",		37, 2, 60, 1, 0 },
314 		{ NULL, 0, 0, 0, 0, 0 } }
315 	},
316 	{ 0x0012, { NULL } /* Abit AN8 32X, need DMI string */, {
317 		{ "CPU Core",		 0, 0, 10, 1, 0 },
318 		{ "DDR",		 1, 0, 20, 1, 0 },
319 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
320 		{ "HyperTransport",	 3, 0, 10, 1, 0 },
321 		{ "CPU VDDA 2.5V",	 5, 0, 20, 1, 0 },
322 		{ "NB",			 4, 0, 10, 1, 0 },
323 		{ "SB",			 6, 0, 10, 1, 0 },
324 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
325 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
326 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
327 		{ "+3.3V",		10, 0, 20, 1, 0 },
328 		{ "5VSB",		11, 0, 30, 1, 0 },
329 		{ "CPU",		24, 1, 1, 1, 0 },
330 		{ "SYS",		25, 1, 1, 1, 0 },
331 		{ "PWM",		26, 1, 1, 1, 0 },
332 		{ "CPU Fan",		32, 2, 60, 1, 0 },
333 		{ "NB Fan",		33, 2, 60, 1, 0 },
334 		{ "SYS Fan",		34, 2, 60, 1, 0 },
335 		{ "AUX1 Fan",		36, 2, 60, 1, 0 },
336 		{ NULL, 0, 0, 0, 0, 0 } }
337 	},
338 	{ 0x0013, { NULL } /* Abit AW8D, need DMI string */, {
339 		{ "CPU Core",		 0, 0, 10, 1, 0 },
340 		{ "DDR",		 1, 0, 10, 1, 0 },
341 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
342 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
343 		{ "MCH & PCIE 1.5V",	 4, 0, 10, 1, 0 },
344 		{ "MCH 2.5V",		 5, 0, 20, 1, 0 },
345 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
346 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
347 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
348 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
349 		{ "+3.3V",		10, 0, 20, 1, 0 },
350 		{ "5VSB",		11, 0, 30, 1, 0 },
351 		{ "CPU",		24, 1, 1, 1, 0 },
352 		{ "System",		25, 1, 1, 1, 0 },
353 		{ "PWM1",		26, 1, 1, 1, 0 },
354 		{ "PWM2",		27, 1, 1, 1, 0 },
355 		{ "PWM3",		28, 1, 1, 1, 0 },
356 		{ "PWM4",		29, 1, 1, 1, 0 },
357 		{ "CPU Fan",		32, 2, 60, 1, 0 },
358 		{ "NB Fan",		33, 2, 60, 1, 0 },
359 		{ "SYS Fan",		34, 2, 60, 1, 0 },
360 		{ "AUX1 Fan",		35, 2, 60, 1, 0 },
361 		{ "AUX2 Fan",		36, 2, 60, 1, 0 },
362 		{ "AUX3 Fan",		37, 2, 60, 1, 0 },
363 		{ "AUX4 Fan",		38, 2, 60, 1, 0 },
364 		{ "AUX5 Fan",		39, 2, 60, 1, 0 },
365 		{ NULL, 0, 0, 0, 0, 0 } }
366 	},
367 	{ 0x0014, { "AB9", "AB9 Pro", NULL }, {
368 		{ "CPU Core",		 0, 0, 10, 1, 0 },
369 		{ "DDR",		 1, 0, 10, 1, 0 },
370 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
371 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
372 		{ "MCH & PCIE 1.5V",	 4, 0, 10, 1, 0 },
373 		{ "MCH 2.5V",		 5, 0, 20, 1, 0 },
374 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
375 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
376 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
377 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
378 		{ "+3.3V",		10, 0, 20, 1, 0 },
379 		{ "5VSB",		11, 0, 30, 1, 0 },
380 		{ "CPU",		24, 1, 1, 1, 0 },
381 		{ "System",		25, 1, 1, 1, 0 },
382 		{ "PWM",		26, 1, 1, 1, 0 },
383 		{ "CPU Fan",		32, 2, 60, 1, 0 },
384 		{ "NB Fan",		33, 2, 60, 1, 0 },
385 		{ "SYS Fan",		34, 2, 60, 1, 0 },
386 		{ NULL, 0, 0, 0, 0, 0 } }
387 	},
388 	{ 0x0015, { NULL } /* Unknown, need DMI string */, {
389 		{ "CPU Core",		 0, 0, 10, 1, 0 },
390 		{ "DDR",		 1, 0, 20, 1, 0 },
391 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
392 		{ "HyperTransport",	 3, 0, 10, 1, 0 },
393 		{ "CPU VDDA 2.5V",	 5, 0, 20, 1, 0 },
394 		{ "NB",			 4, 0, 10, 1, 0 },
395 		{ "SB",			 6, 0, 10, 1, 0 },
396 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
397 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
398 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
399 		{ "+3.3V",		10, 0, 20, 1, 0 },
400 		{ "5VSB",		11, 0, 30, 1, 0 },
401 		{ "CPU",		24, 1, 1, 1, 0 },
402 		{ "SYS",		25, 1, 1, 1, 0 },
403 		{ "PWM",		26, 1, 1, 1, 0 },
404 		{ "CPU Fan",		32, 2, 60, 1, 0 },
405 		{ "NB Fan",		33, 2, 60, 1, 0 },
406 		{ "SYS Fan",		34, 2, 60, 1, 0 },
407 		{ "AUX1 Fan",		33, 2, 60, 1, 0 },
408 		{ "AUX2 Fan",		35, 2, 60, 1, 0 },
409 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
410 		{ NULL, 0, 0, 0, 0, 0 } }
411 	},
412 	{ 0x0016, { "AW9D-MAX", NULL }, {
413 		{ "CPU Core",		 0, 0, 10, 1, 0 },
414 		{ "DDR2",		 1, 0, 20, 1, 0 },
415 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
416 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
417 		{ "MCH & PCIE 1.5V",	 4, 0, 10, 1, 0 },
418 		{ "MCH 2.5V",		 5, 0, 20, 1, 0 },
419 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
420 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
421 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
422 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
423 		{ "+3.3V",		10, 0, 20, 1, 0 },
424 		{ "5VSB",		11, 0, 30, 1, 0 },
425 		{ "CPU",		24, 1, 1, 1, 0 },
426 		{ "System",		25, 1, 1, 1, 0 },
427 		{ "PWM1",		26, 1, 1, 1, 0 },
428 		{ "PWM2",		27, 1, 1, 1, 0 },
429 		{ "PWM3",		28, 1, 1, 1, 0 },
430 		{ "PWM4",		29, 1, 1, 1, 0 },
431 		{ "CPU Fan",		32, 2, 60, 1, 0 },
432 		{ "NB Fan",		33, 2, 60, 1, 0 },
433 		{ "SYS Fan",		34, 2, 60, 1, 0 },
434 		{ "AUX1 Fan",		35, 2, 60, 1, 0 },
435 		{ "AUX2 Fan",		36, 2, 60, 1, 0 },
436 		{ "AUX3 Fan",		37, 2, 60, 1, 0 },
437 		{ "OTES1 Fan",		38, 2, 60, 1, 0 },
438 		{ NULL, 0, 0, 0, 0, 0 } }
439 	},
440 	{ 0x0017, { NULL } /* Unknown, need DMI string */, {
441 		{ "CPU Core",		 0, 0, 10, 1, 0 },
442 		{ "DDR2",		 1, 0, 20, 1, 0 },
443 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
444 		{ "HyperTransport",	 3, 0, 10, 1, 0 },
445 		{ "CPU VDDA 2.5V",	 6, 0, 20, 1, 0 },
446 		{ "NB 1.8V",		 4, 0, 10, 1, 0 },
447 		{ "NB 1.2V ",		13, 0, 10, 1, 0 },
448 		{ "SB 1.2V",		 5, 0, 10, 1, 0 },
449 		{ "PCIE 1.2V",		12, 0, 10, 1, 0 },
450 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
451 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
452 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
453 		{ "ATX +3.3V",		10, 0, 20, 1, 0 },
454 		{ "ATX 5VSB",		11, 0, 30, 1, 0 },
455 		{ "CPU",		24, 1, 1, 1, 0 },
456 		{ "System",		26, 1, 1, 1, 0 },
457 		{ "PWM",		27, 1, 1, 1, 0 },
458 		{ "CPU FAN",		32, 2, 60, 1, 0 },
459 		{ "SYS FAN",		34, 2, 60, 1, 0 },
460 		{ "AUX1 FAN",		35, 2, 60, 1, 0 },
461 		{ "AUX2 FAN",		36, 2, 60, 1, 0 },
462 		{ "AUX3 FAN",		37, 2, 60, 1, 0 },
463 		{ NULL, 0, 0, 0, 0, 0 } }
464 	},
465 	{ 0x0018, { "AB9 QuadGT", NULL }, {
466 		{ "CPU Core",		 0, 0, 10, 1, 0 },
467 		{ "DDR2",		 1, 0, 20, 1, 0 },
468 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
469 		{ "CPU VTT",		 3, 0, 10, 1, 0 },
470 		{ "MCH 1.25V",		 4, 0, 10, 1, 0 },
471 		{ "ICHIO 1.5V",		 5, 0, 10, 1, 0 },
472 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
473 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
474 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
475 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
476 		{ "+3.3V",		10, 0, 20, 1, 0 },
477 		{ "5VSB",		11, 0, 30, 1, 0 },
478 		{ "CPU",		24, 1, 1, 1, 0 },
479 		{ "System",		25, 1, 1, 1, 0 },
480 		{ "PWM Phase1",		26, 1, 1, 1, 0 },
481 		{ "PWM Phase2",		27, 1, 1, 1, 0 },
482 		{ "PWM Phase3",		28, 1, 1, 1, 0 },
483 		{ "PWM Phase4",		29, 1, 1, 1, 0 },
484 		{ "PWM Phase5",		30, 1, 1, 1, 0 },
485 		{ "CPU Fan",		32, 2, 60, 1, 0 },
486 		{ "SYS Fan",		34, 2, 60, 1, 0 },
487 		{ "AUX1 Fan",		33, 2, 60, 1, 0 },
488 		{ "AUX2 Fan",		35, 2, 60, 1, 0 },
489 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
490 		{ NULL, 0, 0, 0, 0, 0 } }
491 	},
492 	{ 0x0019, { "IN9 32X MAX", NULL }, {
493 		{ "CPU Core",		 7, 0, 10, 1, 0 },
494 		{ "DDR2",		13, 0, 20, 1, 0 },
495 		{ "DDR2 VTT",		14, 0, 10, 1, 0 },
496 		{ "CPU VTT",		 3, 0, 20, 1, 0 },
497 		{ "NB 1.2V",		 4, 0, 10, 1, 0 },
498 		{ "SB 1.5V",		 6, 0, 10, 1, 0 },
499 		{ "HyperTransport",	 5, 0, 10, 1, 0 },
500 		{ "ATX +12V (24-Pin)",	12, 0, 60, 1, 0 },
501 		{ "ATX +12V (4-pin)",	 8, 0, 60, 1, 0 },
502 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
503 		{ "ATX +3.3V",		10, 0, 20, 1, 0 },
504 		{ "ATX 5VSB",		11, 0, 30, 1, 0 },
505 		{ "CPU",		24, 1, 1, 1, 0 },
506 		{ "System",		25, 1, 1, 1, 0 },
507 		{ "PWM Phase1",		26, 1, 1, 1, 0 },
508 		{ "PWM Phase2",		27, 1, 1, 1, 0 },
509 		{ "PWM Phase3",		28, 1, 1, 1, 0 },
510 		{ "PWM Phase4",		29, 1, 1, 1, 0 },
511 		{ "PWM Phase5",		30, 1, 1, 1, 0 },
512 		{ "CPU FAN",		32, 2, 60, 1, 0 },
513 		{ "SYS FAN",		34, 2, 60, 1, 0 },
514 		{ "AUX1 FAN",		33, 2, 60, 1, 0 },
515 		{ "AUX2 FAN",		35, 2, 60, 1, 0 },
516 		{ "AUX3 FAN",		36, 2, 60, 1, 0 },
517 		{ NULL, 0, 0, 0, 0, 0 } }
518 	},
519 	{ 0x001A, { "IP35 Pro", "IP35 Pro XE", NULL }, {
520 		{ "CPU Core",		 0, 0, 10, 1, 0 },
521 		{ "DDR2",		 1, 0, 20, 1, 0 },
522 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
523 		{ "CPU VTT 1.2V",	 3, 0, 10, 1, 0 },
524 		{ "MCH 1.25V",		 4, 0, 10, 1, 0 },
525 		{ "ICHIO 1.5V",		 5, 0, 10, 1, 0 },
526 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
527 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
528 		{ "ATX +12V (8-pin)",	 8, 0, 60, 1, 0 },
529 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
530 		{ "+3.3V",		10, 0, 20, 1, 0 },
531 		{ "5VSB",		11, 0, 30, 1, 0 },
532 		{ "CPU",		24, 1, 1, 1, 0 },
533 		{ "System",		25, 1, 1, 1, 0 },
534 		{ "PWM",		26, 1, 1, 1, 0 },
535 		{ "PWM Phase2",		27, 1, 1, 1, 0 },
536 		{ "PWM Phase3",		28, 1, 1, 1, 0 },
537 		{ "PWM Phase4",		29, 1, 1, 1, 0 },
538 		{ "PWM Phase5",		30, 1, 1, 1, 0 },
539 		{ "CPU Fan",		32, 2, 60, 1, 0 },
540 		{ "SYS Fan",		34, 2, 60, 1, 0 },
541 		{ "AUX1 Fan",		33, 2, 60, 1, 0 },
542 		{ "AUX2 Fan",		35, 2, 60, 1, 0 },
543 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
544 		{ "AUX4 Fan",		37, 2, 60, 1, 0 },
545 		{ NULL, 0, 0, 0, 0, 0 } }
546 	},
547 	{ 0x001B, { NULL } /* Unknown, need DMI string */, {
548 		{ "CPU Core",		 0, 0, 10, 1, 0 },
549 		{ "DDR3",		 1, 0, 20, 1, 0 },
550 		{ "DDR3 VTT",		 2, 0, 10, 1, 0 },
551 		{ "CPU VTT",		 3, 0, 10, 1, 0 },
552 		{ "MCH 1.25V",		 4, 0, 10, 1, 0 },
553 		{ "ICHIO 1.5V",		 5, 0, 10, 1, 0 },
554 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
555 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
556 		{ "ATX +12V (8-pin)",	 8, 0, 60, 1, 0 },
557 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
558 		{ "+3.3V",		10, 0, 20, 1, 0 },
559 		{ "5VSB",		11, 0, 30, 1, 0 },
560 		{ "CPU",		24, 1, 1, 1, 0 },
561 		{ "System",		25, 1, 1, 1, 0 },
562 		{ "PWM Phase1",		26, 1, 1, 1, 0 },
563 		{ "PWM Phase2",		27, 1, 1, 1, 0 },
564 		{ "PWM Phase3",		28, 1, 1, 1, 0 },
565 		{ "PWM Phase4",		29, 1, 1, 1, 0 },
566 		{ "PWM Phase5",		30, 1, 1, 1, 0 },
567 		{ "CPU Fan",		32, 2, 60, 1, 0 },
568 		{ "SYS Fan",		34, 2, 60, 1, 0 },
569 		{ "AUX1 Fan",		33, 2, 60, 1, 0 },
570 		{ "AUX2 Fan",		35, 2, 60, 1, 0 },
571 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
572 		{ NULL, 0, 0, 0, 0, 0 } }
573 	},
574 	{ 0x001C, { "IX38 QuadGT", NULL }, {
575 		{ "CPU Core",		 0, 0, 10, 1, 0 },
576 		{ "DDR2",		 1, 0, 20, 1, 0 },
577 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
578 		{ "CPU VTT",		 3, 0, 10, 1, 0 },
579 		{ "MCH 1.25V",		 4, 0, 10, 1, 0 },
580 		{ "ICHIO 1.5V",		 5, 0, 10, 1, 0 },
581 		{ "ICH 1.05V",		 6, 0, 10, 1, 0 },
582 		{ "ATX +12V (24-Pin)",	 7, 0, 60, 1, 0 },
583 		{ "ATX +12V (8-pin)",	 8, 0, 60, 1, 0 },
584 		{ "ATX +5V",		 9, 0, 30, 1, 0 },
585 		{ "+3.3V",		10, 0, 20, 1, 0 },
586 		{ "5VSB",		11, 0, 30, 1, 0 },
587 		{ "CPU",		24, 1, 1, 1, 0 },
588 		{ "System",		25, 1, 1, 1, 0 },
589 		{ "PWM Phase1",		26, 1, 1, 1, 0 },
590 		{ "PWM Phase2",		27, 1, 1, 1, 0 },
591 		{ "PWM Phase3",		28, 1, 1, 1, 0 },
592 		{ "PWM Phase4",		29, 1, 1, 1, 0 },
593 		{ "PWM Phase5",		30, 1, 1, 1, 0 },
594 		{ "CPU Fan",		32, 2, 60, 1, 0 },
595 		{ "SYS Fan",		34, 2, 60, 1, 0 },
596 		{ "AUX1 Fan",		33, 2, 60, 1, 0 },
597 		{ "AUX2 Fan",		35, 2, 60, 1, 0 },
598 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
599 		{ NULL, 0, 0, 0, 0, 0 } }
600 	},
601 	{ 0x0000, { NULL }, { { NULL, 0, 0, 0, 0, 0 } } }
602 };
603 
604 
605 /* Insmod parameters */
606 static bool force;
607 module_param(force, bool, 0);
608 MODULE_PARM_DESC(force, "Set to one to force detection.");
609 /* Default verbose is 1, since this driver is still in the testing phase */
610 static bool verbose = 1;
611 module_param(verbose, bool, 0644);
612 MODULE_PARM_DESC(verbose, "Enable/disable verbose error reporting");
613 
614 static const char *never_happen = "This should never happen.";
615 static const char *report_this =
616 	"Please report this to the abituguru3 maintainer (see MAINTAINERS)";
617 
618 /* wait while the uguru is busy (usually after a write) */
619 static int abituguru3_wait_while_busy(struct abituguru3_data *data)
620 {
621 	u8 x;
622 	int timeout = ABIT_UGURU3_WAIT_TIMEOUT;
623 
624 	while ((x = inb_p(data->addr + ABIT_UGURU3_DATA)) &
625 			ABIT_UGURU3_STATUS_BUSY) {
626 		timeout--;
627 		if (timeout == 0)
628 			return x;
629 		/* sleep a bit before our last try, to give the uGuru3 one
630 		   last chance to respond. */
631 		if (timeout == 1)
632 			msleep(1);
633 	}
634 	return ABIT_UGURU3_SUCCESS;
635 }
636 
637 /* wait till uguru is ready to be read */
638 static int abituguru3_wait_for_read(struct abituguru3_data *data)
639 {
640 	u8 x;
641 	int timeout = ABIT_UGURU3_WAIT_TIMEOUT;
642 
643 	while (!((x = inb_p(data->addr + ABIT_UGURU3_DATA)) &
644 			ABIT_UGURU3_STATUS_READY_FOR_READ)) {
645 		timeout--;
646 		if (timeout == 0)
647 			return x;
648 		/* sleep a bit before our last try, to give the uGuru3 one
649 		   last chance to respond. */
650 		if (timeout == 1)
651 			msleep(1);
652 	}
653 	return ABIT_UGURU3_SUCCESS;
654 }
655 
656 /* This synchronizes us with the uGuru3's protocol state machine, this
657    must be done before each command. */
658 static int abituguru3_synchronize(struct abituguru3_data *data)
659 {
660 	int x, timeout = ABIT_UGURU3_SYNCHRONIZE_TIMEOUT;
661 
662 	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
663 		ABIT_UGURU3_DEBUG("synchronize timeout during initial busy "
664 			"wait, status: 0x%02x\n", x);
665 		return -EIO;
666 	}
667 
668 	outb(0x20, data->addr + ABIT_UGURU3_DATA);
669 	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
670 		ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x20, "
671 			"status: 0x%02x\n", x);
672 		return -EIO;
673 	}
674 
675 	outb(0x10, data->addr + ABIT_UGURU3_CMD);
676 	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
677 		ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x10, "
678 			"status: 0x%02x\n", x);
679 		return -EIO;
680 	}
681 
682 	outb(0x00, data->addr + ABIT_UGURU3_CMD);
683 	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
684 		ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x00, "
685 			"status: 0x%02x\n", x);
686 		return -EIO;
687 	}
688 
689 	if ((x = abituguru3_wait_for_read(data)) != ABIT_UGURU3_SUCCESS) {
690 		ABIT_UGURU3_DEBUG("synchronize timeout waiting for read, "
691 			"status: 0x%02x\n", x);
692 		return -EIO;
693 	}
694 
695 	while ((x = inb(data->addr + ABIT_UGURU3_CMD)) != 0xAC) {
696 		timeout--;
697 		if (timeout == 0) {
698 			ABIT_UGURU3_DEBUG("synchronize timeout cmd does not "
699 				"hold 0xAC after synchronize, cmd: 0x%02x\n",
700 				x);
701 			return -EIO;
702 		}
703 		msleep(1);
704 	}
705 	return 0;
706 }
707 
708 /* Read count bytes from sensor sensor_addr in bank bank_addr and store the
709    result in buf */
710 static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
711 	u8 count, u8 *buf)
712 {
713 	int i, x;
714 
715 	if ((x = abituguru3_synchronize(data)))
716 		return x;
717 
718 	outb(0x1A, data->addr + ABIT_UGURU3_DATA);
719 	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
720 		ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
721 			"sending 0x1A, status: 0x%02x\n", (unsigned int)bank,
722 			(unsigned int)offset, x);
723 		return -EIO;
724 	}
725 
726 	outb(bank, data->addr + ABIT_UGURU3_CMD);
727 	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
728 		ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
729 			"sending the bank, status: 0x%02x\n",
730 			(unsigned int)bank, (unsigned int)offset, x);
731 		return -EIO;
732 	}
733 
734 	outb(offset, data->addr + ABIT_UGURU3_CMD);
735 	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
736 		ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
737 			"sending the offset, status: 0x%02x\n",
738 			(unsigned int)bank, (unsigned int)offset, x);
739 		return -EIO;
740 	}
741 
742 	outb(count, data->addr + ABIT_UGURU3_CMD);
743 	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
744 		ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
745 			"sending the count, status: 0x%02x\n",
746 			(unsigned int)bank, (unsigned int)offset, x);
747 		return -EIO;
748 	}
749 
750 	for (i = 0; i < count; i++) {
751 		if ((x = abituguru3_wait_for_read(data)) !=
752 				ABIT_UGURU3_SUCCESS) {
753 			ABIT_UGURU3_DEBUG("timeout reading byte %d from "
754 				"0x%02x:0x%02x, status: 0x%02x\n", i,
755 				(unsigned int)bank, (unsigned int)offset, x);
756 			break;
757 		}
758 		buf[i] = inb(data->addr + ABIT_UGURU3_CMD);
759 	}
760 	return i;
761 }
762 
763 /* Sensor settings are stored 1 byte per offset with the bytes
764    placed add consecutive offsets. */
765 static int abituguru3_read_increment_offset(struct abituguru3_data *data,
766 					    u8 bank, u8 offset, u8 count,
767 					    u8 *buf, int offset_count)
768 {
769 	int i, x;
770 
771 	for (i = 0; i < offset_count; i++)
772 		if ((x = abituguru3_read(data, bank, offset + i, count,
773 				buf + i * count)) != count) {
774 			if (x < 0)
775 				return x;
776 			return i * count + x;
777 		}
778 
779 	return i * count;
780 }
781 
782 /* Following are the sysfs callback functions. These functions expect:
783    sensor_device_attribute_2->index:   index into the data->sensors array
784    sensor_device_attribute_2->nr:      register offset, bitmask or NA. */
785 static struct abituguru3_data *abituguru3_update_device(struct device *dev);
786 
787 static ssize_t show_value(struct device *dev,
788 	struct device_attribute *devattr, char *buf)
789 {
790 	int value;
791 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
792 	struct abituguru3_data *data = abituguru3_update_device(dev);
793 	const struct abituguru3_sensor_info *sensor;
794 
795 	if (!data)
796 		return -EIO;
797 
798 	sensor = &data->sensors[attr->index];
799 
800 	/* are we reading a setting, or is this a normal read? */
801 	if (attr->nr)
802 		value = data->settings[sensor->port][attr->nr];
803 	else
804 		value = data->value[sensor->port];
805 
806 	/* convert the value */
807 	value = (value * sensor->multiplier) / sensor->divisor +
808 		sensor->offset;
809 
810 	/* alternatively we could update the sensors settings struct for this,
811 	   but then its contents would differ from the windows sw ini files */
812 	if (sensor->type == ABIT_UGURU3_TEMP_SENSOR)
813 		value *= 1000;
814 
815 	return sprintf(buf, "%d\n", value);
816 }
817 
818 static ssize_t show_alarm(struct device *dev,
819 	struct device_attribute *devattr, char *buf)
820 {
821 	int port;
822 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
823 	struct abituguru3_data *data = abituguru3_update_device(dev);
824 
825 	if (!data)
826 		return -EIO;
827 
828 	port = data->sensors[attr->index].port;
829 
830 	/* See if the alarm bit for this sensor is set and if a bitmask is
831 	   given in attr->nr also check if the alarm matches the type of alarm
832 	   we're looking for (for volt it can be either low or high). The type
833 	   is stored in a few readonly bits in the settings of the sensor. */
834 	if ((data->alarms[port / 8] & (0x01 << (port % 8))) &&
835 			(!attr->nr || (data->settings[port][0] & attr->nr)))
836 		return sprintf(buf, "1\n");
837 	else
838 		return sprintf(buf, "0\n");
839 }
840 
841 static ssize_t show_mask(struct device *dev,
842 	struct device_attribute *devattr, char *buf)
843 {
844 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
845 	struct abituguru3_data *data = dev_get_drvdata(dev);
846 
847 	if (data->settings[data->sensors[attr->index].port][0] & attr->nr)
848 		return sprintf(buf, "1\n");
849 	else
850 		return sprintf(buf, "0\n");
851 }
852 
853 static ssize_t show_label(struct device *dev,
854 	struct device_attribute *devattr, char *buf)
855 {
856 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
857 	struct abituguru3_data *data = dev_get_drvdata(dev);
858 
859 	return sprintf(buf, "%s\n", data->sensors[attr->index].name);
860 }
861 
862 static ssize_t show_name(struct device *dev,
863 	struct device_attribute *devattr, char *buf)
864 {
865 	return sprintf(buf, "%s\n", ABIT_UGURU3_NAME);
866 }
867 
868 /* Sysfs attr templates, the real entries are generated automatically. */
869 static const
870 struct sensor_device_attribute_2 abituguru3_sysfs_templ[3][10] = { {
871 	SENSOR_ATTR_2(in%d_input, 0444, show_value, NULL, 0, 0),
872 	SENSOR_ATTR_2(in%d_min, 0444, show_value, NULL, 1, 0),
873 	SENSOR_ATTR_2(in%d_max, 0444, show_value, NULL, 2, 0),
874 	SENSOR_ATTR_2(in%d_min_alarm, 0444, show_alarm, NULL,
875 		ABIT_UGURU3_VOLT_LOW_ALARM_FLAG, 0),
876 	SENSOR_ATTR_2(in%d_max_alarm, 0444, show_alarm, NULL,
877 		ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG, 0),
878 	SENSOR_ATTR_2(in%d_beep, 0444, show_mask, NULL,
879 		ABIT_UGURU3_BEEP_ENABLE, 0),
880 	SENSOR_ATTR_2(in%d_shutdown, 0444, show_mask, NULL,
881 		ABIT_UGURU3_SHUTDOWN_ENABLE, 0),
882 	SENSOR_ATTR_2(in%d_min_alarm_enable, 0444, show_mask, NULL,
883 		ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE, 0),
884 	SENSOR_ATTR_2(in%d_max_alarm_enable, 0444, show_mask, NULL,
885 		ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE, 0),
886 	SENSOR_ATTR_2(in%d_label, 0444, show_label, NULL, 0, 0)
887 	}, {
888 	SENSOR_ATTR_2(temp%d_input, 0444, show_value, NULL, 0, 0),
889 	SENSOR_ATTR_2(temp%d_max, 0444, show_value, NULL, 1, 0),
890 	SENSOR_ATTR_2(temp%d_crit, 0444, show_value, NULL, 2, 0),
891 	SENSOR_ATTR_2(temp%d_alarm, 0444, show_alarm, NULL, 0, 0),
892 	SENSOR_ATTR_2(temp%d_beep, 0444, show_mask, NULL,
893 		ABIT_UGURU3_BEEP_ENABLE, 0),
894 	SENSOR_ATTR_2(temp%d_shutdown, 0444, show_mask, NULL,
895 		ABIT_UGURU3_SHUTDOWN_ENABLE, 0),
896 	SENSOR_ATTR_2(temp%d_alarm_enable, 0444, show_mask, NULL,
897 		ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE, 0),
898 	SENSOR_ATTR_2(temp%d_label, 0444, show_label, NULL, 0, 0)
899 	}, {
900 	SENSOR_ATTR_2(fan%d_input, 0444, show_value, NULL, 0, 0),
901 	SENSOR_ATTR_2(fan%d_min, 0444, show_value, NULL, 1, 0),
902 	SENSOR_ATTR_2(fan%d_alarm, 0444, show_alarm, NULL, 0, 0),
903 	SENSOR_ATTR_2(fan%d_beep, 0444, show_mask, NULL,
904 		ABIT_UGURU3_BEEP_ENABLE, 0),
905 	SENSOR_ATTR_2(fan%d_shutdown, 0444, show_mask, NULL,
906 		ABIT_UGURU3_SHUTDOWN_ENABLE, 0),
907 	SENSOR_ATTR_2(fan%d_alarm_enable, 0444, show_mask, NULL,
908 		ABIT_UGURU3_FAN_LOW_ALARM_ENABLE, 0),
909 	SENSOR_ATTR_2(fan%d_label, 0444, show_label, NULL, 0, 0)
910 } };
911 
912 static struct sensor_device_attribute_2 abituguru3_sysfs_attr[] = {
913 	SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0),
914 };
915 
916 static int __devinit abituguru3_probe(struct platform_device *pdev)
917 {
918 	const int no_sysfs_attr[3] = { 10, 8, 7 };
919 	int sensor_index[3] = { 0, 1, 1 };
920 	struct abituguru3_data *data;
921 	int i, j, type, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV;
922 	char *sysfs_filename;
923 	u8 buf[2];
924 	u16 id;
925 
926 	if (!(data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL)))
927 		return -ENOMEM;
928 
929 	data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
930 	mutex_init(&data->update_lock);
931 	platform_set_drvdata(pdev, data);
932 
933 	/* Read the motherboard ID */
934 	if ((i = abituguru3_read(data, ABIT_UGURU3_MISC_BANK,
935 			ABIT_UGURU3_BOARD_ID, 2, buf)) != 2) {
936 		goto abituguru3_probe_error;
937 	}
938 
939 	/* Completely read the uGuru to see if one really is there */
940 	if (!abituguru3_update_device(&pdev->dev))
941 		goto abituguru3_probe_error;
942 
943 	/* lookup the ID in our motherboard table */
944 	id = ((u16)buf[0] << 8) | (u16)buf[1];
945 	for (i = 0; abituguru3_motherboards[i].id; i++)
946 		if (abituguru3_motherboards[i].id == id)
947 			break;
948 	if (!abituguru3_motherboards[i].id) {
949 		pr_err("error unknown motherboard ID: %04X. %s\n",
950 		       (unsigned int)id, report_this);
951 		goto abituguru3_probe_error;
952 	}
953 	data->sensors = abituguru3_motherboards[i].sensors;
954 
955 	pr_info("found Abit uGuru3, motherboard ID: %04X\n", (unsigned int)id);
956 
957 	/* Fill the sysfs attr array */
958 	sysfs_attr_i = 0;
959 	sysfs_filename = data->sysfs_names;
960 	sysfs_names_free = ABIT_UGURU3_SYSFS_NAMES_LENGTH;
961 	for (i = 0; data->sensors[i].name; i++) {
962 		/* Fail safe check, this should never happen! */
963 		if (i >= ABIT_UGURU3_MAX_NO_SENSORS) {
964 			pr_err("Fatal error motherboard has more sensors then ABIT_UGURU3_MAX_NO_SENSORS. %s %s\n",
965 			       never_happen, report_this);
966 			res = -ENAMETOOLONG;
967 			goto abituguru3_probe_error;
968 		}
969 		type = data->sensors[i].type;
970 		for (j = 0; j < no_sysfs_attr[type]; j++) {
971 			used = snprintf(sysfs_filename, sysfs_names_free,
972 				abituguru3_sysfs_templ[type][j].dev_attr.attr.
973 				name, sensor_index[type]) + 1;
974 			data->sysfs_attr[sysfs_attr_i] =
975 				abituguru3_sysfs_templ[type][j];
976 			data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name =
977 				sysfs_filename;
978 			data->sysfs_attr[sysfs_attr_i].index = i;
979 			sysfs_filename += used;
980 			sysfs_names_free -= used;
981 			sysfs_attr_i++;
982 		}
983 		sensor_index[type]++;
984 	}
985 	/* Fail safe check, this should never happen! */
986 	if (sysfs_names_free < 0) {
987 		pr_err("Fatal error ran out of space for sysfs attr names. %s %s\n",
988 		       never_happen, report_this);
989 		res = -ENAMETOOLONG;
990 		goto abituguru3_probe_error;
991 	}
992 
993 	/* Register sysfs hooks */
994 	for (i = 0; i < sysfs_attr_i; i++)
995 		if (device_create_file(&pdev->dev,
996 				&data->sysfs_attr[i].dev_attr))
997 			goto abituguru3_probe_error;
998 	for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++)
999 		if (device_create_file(&pdev->dev,
1000 				&abituguru3_sysfs_attr[i].dev_attr))
1001 			goto abituguru3_probe_error;
1002 
1003 	data->hwmon_dev = hwmon_device_register(&pdev->dev);
1004 	if (IS_ERR(data->hwmon_dev)) {
1005 		res = PTR_ERR(data->hwmon_dev);
1006 		goto abituguru3_probe_error;
1007 	}
1008 
1009 	return 0; /* success */
1010 
1011 abituguru3_probe_error:
1012 	for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
1013 		device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
1014 	for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++)
1015 		device_remove_file(&pdev->dev,
1016 			&abituguru3_sysfs_attr[i].dev_attr);
1017 	kfree(data);
1018 	return res;
1019 }
1020 
1021 static int __devexit abituguru3_remove(struct platform_device *pdev)
1022 {
1023 	int i;
1024 	struct abituguru3_data *data = platform_get_drvdata(pdev);
1025 
1026 	platform_set_drvdata(pdev, NULL);
1027 	hwmon_device_unregister(data->hwmon_dev);
1028 	for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
1029 		device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
1030 	for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++)
1031 		device_remove_file(&pdev->dev,
1032 			&abituguru3_sysfs_attr[i].dev_attr);
1033 	kfree(data);
1034 
1035 	return 0;
1036 }
1037 
1038 static struct abituguru3_data *abituguru3_update_device(struct device *dev)
1039 {
1040 	int i;
1041 	struct abituguru3_data *data = dev_get_drvdata(dev);
1042 
1043 	mutex_lock(&data->update_lock);
1044 	if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
1045 		/* Clear data->valid while updating */
1046 		data->valid = 0;
1047 		/* Read alarms */
1048 		if (abituguru3_read_increment_offset(data,
1049 				ABIT_UGURU3_SETTINGS_BANK,
1050 				ABIT_UGURU3_ALARMS_START,
1051 				1, data->alarms, 48/8) != (48/8))
1052 			goto LEAVE_UPDATE;
1053 		/* Read in and temp sensors (3 byte settings / sensor) */
1054 		for (i = 0; i < 32; i++) {
1055 			if (abituguru3_read(data, ABIT_UGURU3_SENSORS_BANK,
1056 					ABIT_UGURU3_VALUES_START + i,
1057 					1, &data->value[i]) != 1)
1058 				goto LEAVE_UPDATE;
1059 			if (abituguru3_read_increment_offset(data,
1060 					ABIT_UGURU3_SETTINGS_BANK,
1061 					ABIT_UGURU3_SETTINGS_START + i * 3,
1062 					1,
1063 					data->settings[i], 3) != 3)
1064 				goto LEAVE_UPDATE;
1065 		}
1066 		/* Read temp sensors (2 byte settings / sensor) */
1067 		for (i = 0; i < 16; i++) {
1068 			if (abituguru3_read(data, ABIT_UGURU3_SENSORS_BANK,
1069 					ABIT_UGURU3_VALUES_START + 32 + i,
1070 					1, &data->value[32 + i]) != 1)
1071 				goto LEAVE_UPDATE;
1072 			if (abituguru3_read_increment_offset(data,
1073 					ABIT_UGURU3_SETTINGS_BANK,
1074 					ABIT_UGURU3_SETTINGS_START + 32 * 3 +
1075 						i * 2, 1,
1076 					data->settings[32 + i], 2) != 2)
1077 				goto LEAVE_UPDATE;
1078 		}
1079 		data->last_updated = jiffies;
1080 		data->valid = 1;
1081 	}
1082 LEAVE_UPDATE:
1083 	mutex_unlock(&data->update_lock);
1084 	if (data->valid)
1085 		return data;
1086 	else
1087 		return NULL;
1088 }
1089 
1090 #ifdef CONFIG_PM
1091 static int abituguru3_suspend(struct platform_device *pdev, pm_message_t state)
1092 {
1093 	struct abituguru3_data *data = platform_get_drvdata(pdev);
1094 	/* make sure all communications with the uguru3 are done and no new
1095 	   ones are started */
1096 	mutex_lock(&data->update_lock);
1097 	return 0;
1098 }
1099 
1100 static int abituguru3_resume(struct platform_device *pdev)
1101 {
1102 	struct abituguru3_data *data = platform_get_drvdata(pdev);
1103 	mutex_unlock(&data->update_lock);
1104 	return 0;
1105 }
1106 #else
1107 #define abituguru3_suspend	NULL
1108 #define abituguru3_resume	NULL
1109 #endif /* CONFIG_PM */
1110 
1111 static struct platform_driver abituguru3_driver = {
1112 	.driver = {
1113 		.owner	= THIS_MODULE,
1114 		.name	= ABIT_UGURU3_NAME,
1115 	},
1116 	.probe	= abituguru3_probe,
1117 	.remove	= __devexit_p(abituguru3_remove),
1118 	.suspend = abituguru3_suspend,
1119 	.resume = abituguru3_resume
1120 };
1121 
1122 static int __init abituguru3_dmi_detect(void)
1123 {
1124 	const char *board_vendor, *board_name;
1125 	int i, err = (force) ? 1 : -ENODEV;
1126 	const char *const *dmi_name;
1127 	size_t sublen;
1128 
1129 	board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1130 	if (!board_vendor || strcmp(board_vendor, "http://www.abit.com.tw/"))
1131 		return err;
1132 
1133 	board_name = dmi_get_system_info(DMI_BOARD_NAME);
1134 	if (!board_name)
1135 		return err;
1136 
1137 	/* At the moment, we don't care about the part of the vendor
1138 	 * DMI string contained in brackets. Truncate the string at
1139 	 * the first occurrence of a bracket. Trim any trailing space
1140 	 * from the substring.
1141 	 */
1142 	sublen = strcspn(board_name, "(");
1143 	while (sublen > 0 && board_name[sublen - 1] == ' ')
1144 		sublen--;
1145 
1146 	for (i = 0; abituguru3_motherboards[i].id; i++) {
1147 		dmi_name = abituguru3_motherboards[i].dmi_name;
1148 		for ( ; *dmi_name; dmi_name++) {
1149 			if (strlen(*dmi_name) != sublen)
1150 				continue;
1151 			if (!strncasecmp(board_name, *dmi_name, sublen))
1152 				return 0;
1153 		}
1154 	}
1155 
1156 	/* No match found */
1157 	return 1;
1158 }
1159 
1160 /* FIXME: Manual detection should die eventually; we need to collect stable
1161  *        DMI model names first before we can rely entirely on CONFIG_DMI.
1162  */
1163 
1164 static int __init abituguru3_detect(void)
1165 {
1166 	/* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
1167 	   0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
1168 	   or 0x55 at CMD instead, why is unknown. */
1169 	u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA);
1170 	u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD);
1171 	if (((data_val == 0x00) || (data_val == 0x08)) &&
1172 			((cmd_val == 0xAC) || (cmd_val == 0x05) ||
1173 			 (cmd_val == 0x55)))
1174 		return 0;
1175 
1176 	ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = "
1177 		"0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val);
1178 
1179 	if (force) {
1180 		pr_info("Assuming Abit uGuru3 is present because of \"force\" parameter\n");
1181 		return 0;
1182 	}
1183 
1184 	/* No uGuru3 found */
1185 	return -ENODEV;
1186 }
1187 
1188 static struct platform_device *abituguru3_pdev;
1189 
1190 static int __init abituguru3_init(void)
1191 {
1192 	struct resource res = { .flags = IORESOURCE_IO };
1193 	int err;
1194 
1195 	/* Attempt DMI detection first */
1196 	err = abituguru3_dmi_detect();
1197 	if (err < 0)
1198 		return err;
1199 
1200 	/* Fall back to manual detection if there was no exact
1201 	 * board name match, or force was specified.
1202 	 */
1203 	if (err > 0) {
1204 		err = abituguru3_detect();
1205 		if (err)
1206 			return err;
1207 
1208 		pr_warn("this motherboard was not detected using DMI. "
1209 			"Please send the output of \"dmidecode\" to the abituguru3 maintainer (see MAINTAINERS)\n");
1210 	}
1211 
1212 	err = platform_driver_register(&abituguru3_driver);
1213 	if (err)
1214 		goto exit;
1215 
1216 	abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME,
1217 						ABIT_UGURU3_BASE);
1218 	if (!abituguru3_pdev) {
1219 		pr_err("Device allocation failed\n");
1220 		err = -ENOMEM;
1221 		goto exit_driver_unregister;
1222 	}
1223 
1224 	res.start = ABIT_UGURU3_BASE;
1225 	res.end = ABIT_UGURU3_BASE + ABIT_UGURU3_REGION_LENGTH - 1;
1226 	res.name = ABIT_UGURU3_NAME;
1227 
1228 	err = platform_device_add_resources(abituguru3_pdev, &res, 1);
1229 	if (err) {
1230 		pr_err("Device resource addition failed (%d)\n", err);
1231 		goto exit_device_put;
1232 	}
1233 
1234 	err = platform_device_add(abituguru3_pdev);
1235 	if (err) {
1236 		pr_err("Device addition failed (%d)\n", err);
1237 		goto exit_device_put;
1238 	}
1239 
1240 	return 0;
1241 
1242 exit_device_put:
1243 	platform_device_put(abituguru3_pdev);
1244 exit_driver_unregister:
1245 	platform_driver_unregister(&abituguru3_driver);
1246 exit:
1247 	return err;
1248 }
1249 
1250 static void __exit abituguru3_exit(void)
1251 {
1252 	platform_device_unregister(abituguru3_pdev);
1253 	platform_driver_unregister(&abituguru3_driver);
1254 }
1255 
1256 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
1257 MODULE_DESCRIPTION("Abit uGuru3 Sensor device");
1258 MODULE_LICENSE("GPL");
1259 
1260 module_init(abituguru3_init);
1261 module_exit(abituguru3_exit);
1262