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