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