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