Linux Audio

Check our new training course

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