1f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* 21bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * abituguru.c Copyright (c) 2005-2006 Hans de Goede <hdegoede@redhat.com> 31bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * 41bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * This program is free software; you can redistribute it and/or modify 51bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * it under the terms of the GNU General Public License as published by 61bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * the Free Software Foundation; either version 2 of the License, or 71bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * (at your option) any later version. 81bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * 91bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * This program is distributed in the hope that it will be useful, 101bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 111bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 121bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * GNU General Public License for more details. 131bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * 141bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * You should have received a copy of the GNU General Public License 151bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * along with this program; if not, write to the Free Software 161bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 171bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 18f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* 191bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * This driver supports the sensor part of the first and second revision of 201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because 211bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * of lack of specs the CPU/RAM voltage & frequency control is not supported! 221bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 2328ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches 2428ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2528ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches 26f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/module.h> 27f6a570333e554b48ad589e7137c77c57809eee81Al Viro#include <linux/sched.h> 28f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/init.h> 29f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/slab.h> 30f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/jiffies.h> 31f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/mutex.h> 32f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/err.h> 33faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede#include <linux/delay.h> 34f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/platform_device.h> 35f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/hwmon.h> 36f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#include <linux/hwmon-sysfs.h> 37c182f5bbfb399b1fa2ad65107b3caf9c1c69435eHans de Goede#include <linux/dmi.h> 386055fae8aceee41471edfd1876e5617d16e028feH Hartley Sweeten#include <linux/io.h> 39f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 40f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Banks */ 41f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_ALARM_BANK 0x20 /* 1x 3 bytes */ 42f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_SENSOR_BANK1 0x21 /* 16x volt and temp */ 43f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_FAN_PWM 0x24 /* 3x 5 bytes */ 44f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_SENSOR_BANK2 0x26 /* fans */ 45a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede/* max nr of sensors in bank1, a bank1 sensor can be in, temp or nc */ 46a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede#define ABIT_UGURU_MAX_BANK1_SENSORS 16 471bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 481bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Warning if you increase one of the 2 MAX defines below to 10 or higher you 491bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * should adjust the belonging _NAMES_LENGTH macro for the 2 digit number! 501bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 51f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* max nr of sensors in bank2, currently mb's with max 6 fans are known */ 52f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_MAX_BANK2_SENSORS 6 53f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* max nr of pwm outputs, currently mb's with max 5 pwm outputs are known */ 54f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_MAX_PWMS 5 55f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* uGuru sensor bank 1 flags */ /* Alarm if: */ 56f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE 0x01 /* temp over warn */ 57f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE 0x02 /* volt over max */ 58f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_VOLT_LOW_ALARM_ENABLE 0x04 /* volt under min */ 59f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_TEMP_HIGH_ALARM_FLAG 0x10 /* temp is over warn */ 60f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_VOLT_HIGH_ALARM_FLAG 0x20 /* volt is over max */ 61f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_VOLT_LOW_ALARM_FLAG 0x40 /* volt is under min */ 62f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* uGuru sensor bank 2 flags */ /* Alarm if: */ 63f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_FAN_LOW_ALARM_ENABLE 0x01 /* fan under min */ 64f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* uGuru sensor bank common flags */ 65f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_BEEP_ENABLE 0x08 /* beep if alarm */ 66f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_SHUTDOWN_ENABLE 0x80 /* shutdown if alarm */ 67f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* uGuru fan PWM (speed control) flags */ 68f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_FAN_PWM_ENABLE 0x80 /* enable speed control */ 69f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Values used for conversion */ 70f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_FAN_MAX 15300 /* RPM */ 71f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Bank1 sensor types */ 72f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_IN_SENSOR 0 73f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_TEMP_SENSOR 1 74f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_NC 2 751bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 761bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * In many cases we need to wait for the uGuru to reach a certain status, most 771bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * of the time it will reach this status within 30 - 90 ISA reads, and thus we 781bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * can best busy wait. This define gives the total amount of reads to try. 791bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 80faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede#define ABIT_UGURU_WAIT_TIMEOUT 125 811bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 821bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * However sometimes older versions of the uGuru seem to be distracted and they 831bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * do not respond for a long time. To handle this we sleep before each of the 841bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * last ABIT_UGURU_WAIT_TIMEOUT_SLEEP tries. 851bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 86faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede#define ABIT_UGURU_WAIT_TIMEOUT_SLEEP 5 871bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 881bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Normally all expected status in abituguru_ready, are reported after the 891bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * first read, but sometimes not and we need to poll. 901bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 91faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede#define ABIT_UGURU_READY_TIMEOUT 5 92f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */ 93f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_MAX_RETRIES 3 94f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_RETRY_DELAY (HZ/5) 95a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede/* Maximum 2 timeouts in abituguru_update_device, iow 3 in a row is an error */ 96f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_MAX_TIMEOUTS 2 97a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede/* utility macros */ 98a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede#define ABIT_UGURU_NAME "abituguru" 99a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede#define ABIT_UGURU_DEBUG(level, format, arg...) \ 100a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede if (level <= verbose) \ 101a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede printk(KERN_DEBUG ABIT_UGURU_NAME ": " format , ## arg) 102a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede/* Macros to help calculate the sysfs_names array length */ 1031bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 1041bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0, 1051bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0 1061bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 107a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede#define ABITUGURU_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14) 1081bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 1091bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sum of strlen of: temp??_input\0, temp??_max\0, temp??_crit\0, 1101bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0 1111bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 112a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede#define ABITUGURU_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16) 1131bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 1141bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sum of strlen of: fan?_input\0, fan?_min\0, fan?_alarm\0, 1151bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * fan?_alarm_enable\0, fan?_beep\0, fan?_shutdown\0 1161bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 117a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede#define ABITUGURU_FAN_NAMES_LENGTH (11 + 9 + 11 + 18 + 10 + 14) 1181bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 1191bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sum of strlen of: pwm?_enable\0, pwm?_auto_channels_temp\0, 1201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * pwm?_auto_point{1,2}_pwm\0, pwm?_auto_point{1,2}_temp\0 1211bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 122a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede#define ABITUGURU_PWM_NAMES_LENGTH (12 + 24 + 2 * 21 + 2 * 22) 123a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede/* IN_NAMES_LENGTH > TEMP_NAMES_LENGTH so assume all bank1 sensors are in */ 124a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede#define ABITUGURU_SYSFS_NAMES_LENGTH ( \ 125a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_BANK1_SENSORS * ABITUGURU_IN_NAMES_LENGTH + \ 126a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_BANK2_SENSORS * ABITUGURU_FAN_NAMES_LENGTH + \ 127a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_PWMS * ABITUGURU_PWM_NAMES_LENGTH) 128a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede 1291bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 1301bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * All the macros below are named identical to the oguru and oguru2 programs 1311bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * reverse engineered by Olle Sandberg, hence the names might not be 100% 1321bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * logical. I could come up with better names, but I prefer keeping the names 1331bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * identical so that this driver can be compared with his work more easily. 1341bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 135f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Two i/o-ports are used by uGuru */ 136f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_BASE 0x00E0 137f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Used to tell uGuru what to read and to read the actual data */ 138f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_CMD 0x00 139f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Mostly used to check if uGuru is busy */ 140f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_DATA 0x04 141f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_REGION_LENGTH 5 142f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* uGuru status' */ 143f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_STATUS_WRITE 0x00 /* Ready to be written */ 144f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_STATUS_READ 0x01 /* Ready to be read */ 145f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_STATUS_INPUT 0x08 /* More input */ 146f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede#define ABIT_UGURU_STATUS_READY 0x09 /* Ready to be written */ 147f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 148f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Constants */ 149f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* in (Volt) sensors go up to 3494 mV, temp to 255000 millidegrees Celsius */ 150f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const int abituguru_bank1_max_value[2] = { 3494, 255000 }; 1511bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 1521bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Min / Max allowed values for sensor2 (fan) alarm threshold, these values 1531bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * correspond to 300-3000 RPM 1541bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 155f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const u8 abituguru_bank2_min_threshold = 5; 156f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const u8 abituguru_bank2_max_threshold = 50; 1571bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 1581bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Register 0 is a bitfield, 1 and 2 are pwm settings (255 = 100%), 3 and 4 1591bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * are temperature trip points. 1601bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 161f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const int abituguru_pwm_settings_multiplier[5] = { 0, 1, 1, 1000, 1000 }; 1621bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 1631bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Min / Max allowed values for pwm_settings. Note: pwm1 (CPU fan) is a 1641bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * special case the minium allowed pwm% setting for this is 30% (77) on 1651bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * some MB's this special case is handled in the code! 1661bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 167f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const u8 abituguru_pwm_min[5] = { 0, 170, 170, 25, 25 }; 168f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 }; 169f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 170f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 171f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Insmod parameters */ 17290ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool force; 173f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedemodule_param(force, bool, 0); 174f2b84bbcebfdbe4855bab532909eef6621999f9fHans de GoedeMODULE_PARM_DESC(force, "Set to one to force detection."); 1759b2ad1298232a4016a407261bd6811294b09ba97Hans de Goedestatic int bank1_types[ABIT_UGURU_MAX_BANK1_SENSORS] = { -1, -1, -1, -1, -1, 1769b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; 1779b2ad1298232a4016a407261bd6811294b09ba97Hans de Goedemodule_param_array(bank1_types, int, NULL, 0); 1789b2ad1298232a4016a407261bd6811294b09ba97Hans de GoedeMODULE_PARM_DESC(bank1_types, "Bank1 sensortype autodetection override:\n" 1799b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede " -1 autodetect\n" 1809b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede " 0 volt sensor\n" 1819b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede " 1 temp sensor\n" 1829b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede " 2 not connected"); 183f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int fan_sensors; 184f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedemodule_param(fan_sensors, int, 0); 185f2b84bbcebfdbe4855bab532909eef6621999f9fHans de GoedeMODULE_PARM_DESC(fan_sensors, "Number of fan sensors on the uGuru " 186f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "(0 = autodetect)"); 187f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int pwms; 188f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedemodule_param(pwms, int, 0); 189f2b84bbcebfdbe4855bab532909eef6621999f9fHans de GoedeMODULE_PARM_DESC(pwms, "Number of PWMs on the uGuru " 190f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "(0 = autodetect)"); 191f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 192f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Default verbose is 2, since this driver is still in the testing phase */ 193f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int verbose = 2; 194f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedemodule_param(verbose, int, 0644); 195f2b84bbcebfdbe4855bab532909eef6621999f9fHans de GoedeMODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n" 196f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede " 0 normal output\n" 197f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede " 1 + verbose error reporting\n" 198f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede " 2 + sensors type probing info\n" 199f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede " 3 + retryable error reporting"); 200f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 201f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 2021bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 2031bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * For the Abit uGuru, we need to keep some data in memory. 2041bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * The structure is dynamically allocated, at the same time when a new 2051bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * abituguru device is allocated. 2061bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 207f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestruct abituguru_data { 2081beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones struct device *hwmon_dev; /* hwmon registered device */ 209f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct mutex update_lock; /* protect access to data and uGuru */ 210f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede unsigned long last_updated; /* In jiffies */ 211f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede unsigned short addr; /* uguru base address */ 212f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede char uguru_ready; /* is the uguru in ready state? */ 2131bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck unsigned char update_timeouts; /* 2141bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * number of update timeouts since last 2151bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * successful update 2161bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 2171bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 2181bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 2191bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * The sysfs attr and their names are generated automatically, for bank1 2201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * we cannot use a predefined array because we don't know beforehand 2211bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * of a sensor is a volt or a temp sensor, for bank2 and the pwms its 2221bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * easier todo things the same way. For in sensors we have 9 (temp 7) 2231bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sysfs entries per sensor, for bank2 and pwms 6. 2241bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 225a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede struct sensor_device_attribute_2 sysfs_attr[ 226a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_BANK1_SENSORS * 9 + 227f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_MAX_BANK2_SENSORS * 6 + ABIT_UGURU_MAX_PWMS * 6]; 228a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede /* Buffer to store the dynamically generated sysfs names */ 229a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede char sysfs_names[ABITUGURU_SYSFS_NAMES_LENGTH]; 230f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 231f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Bank 1 data */ 232a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede /* number of and addresses of [0] in, [1] temp sensors */ 233a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede u8 bank1_sensors[2]; 234a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede u8 bank1_address[2][ABIT_UGURU_MAX_BANK1_SENSORS]; 235a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede u8 bank1_value[ABIT_UGURU_MAX_BANK1_SENSORS]; 2361bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 2371bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * This array holds 3 entries per sensor for the bank 1 sensor settings 2381bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * (flags, min, max for voltage / flags, warn, shutdown for temp). 2391bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 240a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede u8 bank1_settings[ABIT_UGURU_MAX_BANK1_SENSORS][3]; 2411bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 2421bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Maximum value for each sensor used for scaling in mV/millidegrees 2431bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Celsius. 2441bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 245a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede int bank1_max_value[ABIT_UGURU_MAX_BANK1_SENSORS]; 246f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 247f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Bank 2 data, ABIT_UGURU_MAX_BANK2_SENSORS entries for bank2 */ 248f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 bank2_sensors; /* actual number of bank2 sensors found */ 249f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 bank2_value[ABIT_UGURU_MAX_BANK2_SENSORS]; 250f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 bank2_settings[ABIT_UGURU_MAX_BANK2_SENSORS][2]; /* flags, min */ 251f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 252f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Alarms 2 bytes for bank1, 1 byte for bank2 */ 253f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 alarms[3]; 254f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 255f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Fan PWM (speed control) 5 bytes per PWM */ 256f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 pwms; /* actual number of pwms found */ 257f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 pwm_settings[ABIT_UGURU_MAX_PWMS][5]; 258f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede}; 259f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 26028ebfa13f97265e415fbe19795500a6d922a6c86Joe Perchesstatic const char *never_happen = "This should never happen."; 26128ebfa13f97265e415fbe19795500a6d922a6c86Joe Perchesstatic const char *report_this = 26228ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches "Please report this to the abituguru maintainer (see MAINTAINERS)"; 26328ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches 264f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* wait till the uguru is in the specified state */ 265f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int abituguru_wait(struct abituguru_data *data, u8 state) 266f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 267f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int timeout = ABIT_UGURU_WAIT_TIMEOUT; 268f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 269f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede while (inb_p(data->addr + ABIT_UGURU_DATA) != state) { 270f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede timeout--; 271f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (timeout == 0) 272f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EBUSY; 2731bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 2741bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sleep a bit before our last few tries, see the comment on 2751bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * this where ABIT_UGURU_WAIT_TIMEOUT_SLEEP is defined. 2761bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 277faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede if (timeout <= ABIT_UGURU_WAIT_TIMEOUT_SLEEP) 278faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede msleep(0); 279f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 280f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return 0; 281f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 282f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 283f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Put the uguru in ready for input state */ 284f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int abituguru_ready(struct abituguru_data *data) 285f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 286f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int timeout = ABIT_UGURU_READY_TIMEOUT; 287f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 288f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->uguru_ready) 289f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return 0; 290f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 291f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Reset? / Prepare for next read/write cycle */ 292f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede outb(0x00, data->addr + ABIT_UGURU_DATA); 293f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 294f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Wait till the uguru is ready */ 295f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_wait(data, ABIT_UGURU_STATUS_READY)) { 296f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(1, 297f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "timeout exceeded waiting for ready state\n"); 298f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 299f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 300f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 301f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Cmd port MUST be read now and should contain 0xAC */ 302f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) { 303f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede timeout--; 304f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (timeout == 0) { 305f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(1, 306f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "CMD reg does not hold 0xAC after ready command\n"); 307f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 308f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 309faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede msleep(0); 310f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 311f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 3121bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 3131bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * After this the ABIT_UGURU_DATA port should contain 3141bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * ABIT_UGURU_STATUS_INPUT 3151bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 316f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede timeout = ABIT_UGURU_READY_TIMEOUT; 317f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede while (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) { 318f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede timeout--; 319f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (timeout == 0) { 320f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(1, 321f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "state != more input after ready command\n"); 322f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 323f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 324faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede msleep(0); 325f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 326f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 327f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->uguru_ready = 1; 328f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return 0; 329f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 330f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 3311bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 3321bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Send the bank and then sensor address to the uGuru for the next read/write 3331bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * cycle. This function gets called as the first part of a read/write by 3341bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * abituguru_read and abituguru_write. This function should never be 3351bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * called by any other function. 3361bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 337f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int abituguru_send_address(struct abituguru_data *data, 338f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 bank_addr, u8 sensor_addr, int retries) 339f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 3401bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 3411bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * assume the caller does error handling itself if it has not requested 3421bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * any retries, and thus be quiet. 3431bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 344f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int report_errors = retries; 345f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 346f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (;;) { 3471bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 3481bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Make sure the uguru is ready and then send the bank address, 3491bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * after this the uguru is no longer "ready". 3501bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 351f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_ready(data) != 0) 352f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 353f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede outb(bank_addr, data->addr + ABIT_UGURU_DATA); 354f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->uguru_ready = 0; 355f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 3561bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 3571bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Wait till the uguru is ABIT_UGURU_STATUS_INPUT state again 3581bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * and send the sensor addr 3591bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 360f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_wait(data, ABIT_UGURU_STATUS_INPUT)) { 361f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (retries) { 362f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(3, "timeout exceeded " 363f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "waiting for more input state, %d " 364f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "tries remaining\n", retries); 365f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede set_current_state(TASK_UNINTERRUPTIBLE); 366f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede schedule_timeout(ABIT_UGURU_RETRY_DELAY); 367f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede retries--; 368f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede continue; 369f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 370f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (report_errors) 371f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(1, "timeout exceeded " 372f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "waiting for more input state " 373f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "(bank: %d)\n", (int)bank_addr); 374f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EBUSY; 375f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 376f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede outb(sensor_addr, data->addr + ABIT_UGURU_CMD); 377f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return 0; 378f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 379f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 380f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 3811bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 3821bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Read count bytes from sensor sensor_addr in bank bank_addr and store the 3831bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * result in buf, retry the send address part of the read retries times. 3841bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 385f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int abituguru_read(struct abituguru_data *data, 386f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 bank_addr, u8 sensor_addr, u8 *buf, int count, int retries) 387f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 388f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int i; 389f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 390f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Send the address */ 391f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede i = abituguru_send_address(data, bank_addr, sensor_addr, retries); 392f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (i) 393f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return i; 394f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 395f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* And read the data */ 396f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < count; i++) { 397f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) { 398faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede ABIT_UGURU_DEBUG(retries ? 1 : 3, 399faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede "timeout exceeded waiting for " 400f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "read state (bank: %d, sensor: %d)\n", 401f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)bank_addr, (int)sensor_addr); 402f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 403f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 404f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede buf[i] = inb(data->addr + ABIT_UGURU_CMD); 405f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 406f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 407f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Last put the chip back in ready state */ 408f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_ready(data); 409f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 410f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return i; 411f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 412f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 4131bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 4141bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Write count bytes from buf to sensor sensor_addr in bank bank_addr, the send 4151bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * address part of the write is always retried ABIT_UGURU_MAX_RETRIES times. 4161bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 417f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int abituguru_write(struct abituguru_data *data, 418f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 bank_addr, u8 sensor_addr, u8 *buf, int count) 419f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 4201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 4211bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * We use the ready timeout as we have to wait for 0xAC just like the 4221bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * ready function 4231bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 424faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede int i, timeout = ABIT_UGURU_READY_TIMEOUT; 425f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 426f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Send the address */ 427f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede i = abituguru_send_address(data, bank_addr, sensor_addr, 428f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_MAX_RETRIES); 429f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (i) 430f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return i; 431f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 432f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* And write the data */ 433f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < count; i++) { 434f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_wait(data, ABIT_UGURU_STATUS_WRITE)) { 435f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for " 436f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "write state (bank: %d, sensor: %d)\n", 437f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)bank_addr, (int)sensor_addr); 438f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 439f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 440f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede outb(buf[i], data->addr + ABIT_UGURU_CMD); 441f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 442f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 4431bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 4441bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Now we need to wait till the chip is ready to be read again, 4451bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * so that we can read 0xAC as confirmation that our write has 4461bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * succeeded. 4471bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 448f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) { 449f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for read state " 450f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "after write (bank: %d, sensor: %d)\n", (int)bank_addr, 451f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)sensor_addr); 452f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 453f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 454f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 455f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Cmd port MUST be read now and should contain 0xAC */ 456faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) { 457faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede timeout--; 458faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede if (timeout == 0) { 459faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after " 460faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede "write (bank: %d, sensor: %d)\n", 461faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede (int)bank_addr, (int)sensor_addr); 462faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede return -EIO; 463faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede } 464faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede msleep(0); 465f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 466f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 467f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Last put the chip back in ready state */ 468f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_ready(data); 469f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 470f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return i; 471f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 472f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 4731bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 4741bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Detect sensor type. Temp and Volt sensors are enabled with 4751bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * different masks and will ignore enable masks not meant for them. 4761bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * This enables us to test what kind of sensor we're dealing with. 4771bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * By setting the alarm thresholds so that we will always get an 4781bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * alarm for sensor type X and then enabling the sensor as sensor type 4791bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * X, if we then get an alarm it is a sensor of type X. 4801bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 481f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int __devinit 482f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedeabituguru_detect_bank1_sensor_type(struct abituguru_data *data, 483f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 sensor_addr) 484f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 485e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede u8 val, test_flag, buf[3]; 486faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede int i, ret = -ENODEV; /* error is the most common used retval :| */ 487f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 4889b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede /* If overriden by the user return the user selected type */ 4899b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede if (bank1_types[sensor_addr] >= ABIT_UGURU_IN_SENSOR && 4909b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede bank1_types[sensor_addr] <= ABIT_UGURU_NC) { 4919b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede ABIT_UGURU_DEBUG(2, "assuming sensor type %d for bank1 sensor " 4929b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede "%d because of \"bank1_types\" module param\n", 4939b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede bank1_types[sensor_addr], (int)sensor_addr); 4949b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede return bank1_types[sensor_addr]; 4959b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede } 4969b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede 497f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* First read the sensor and the current settings */ 498f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, sensor_addr, &val, 499f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1, ABIT_UGURU_MAX_RETRIES) != 1) 500a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede return -ENODEV; 501f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 502f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Test val is sane / usable for sensor type detection. */ 503e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede if ((val < 10u) || (val > 250u)) { 50428ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches pr_warn("bank1-sensor: %d reading (%d) too close to limits, " 505f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "unable to determine sensor type, skipping sensor\n", 506f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)sensor_addr, (int)val); 5071bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 5081bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * assume no sensor is there for sensors for which we can't 5091bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * determine the sensor type because their reading is too close 5101bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * to their limits, this usually means no sensor is there. 5111bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 512f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ABIT_UGURU_NC; 513f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 514f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 515f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr); 5161bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 5171bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Volt sensor test, enable volt low alarm, set min value ridicously 5181bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * high, or vica versa if the reading is very high. If its a volt 5191bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sensor this should always give us an alarm. 5201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 521e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede if (val <= 240u) { 522e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE; 523e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede buf[1] = 245; 524e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede buf[2] = 250; 525e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede test_flag = ABIT_UGURU_VOLT_LOW_ALARM_FLAG; 526e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede } else { 527e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede buf[0] = ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE; 528e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede buf[1] = 5; 529e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede buf[2] = 10; 530e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede test_flag = ABIT_UGURU_VOLT_HIGH_ALARM_FLAG; 531e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede } 532e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede 533f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, 534f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede buf, 3) != 3) 535faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede goto abituguru_detect_bank1_sensor_type_exit; 5361bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 5371bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Now we need 20 ms to give the uguru time to read the sensors 5381bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * and raise a voltage alarm 5391bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 540f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede set_current_state(TASK_UNINTERRUPTIBLE); 541f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede schedule_timeout(HZ/50); 542f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Check for alarm and check the alarm is a volt low alarm. */ 543f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, 544f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_MAX_RETRIES) != 3) 545faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede goto abituguru_detect_bank1_sensor_type_exit; 546f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { 547f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, 548f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede sensor_addr, buf, 3, 549f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_MAX_RETRIES) != 3) 550faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede goto abituguru_detect_bank1_sensor_type_exit; 551e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede if (buf[0] & test_flag) { 552f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " found volt sensor\n"); 553faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede ret = ABIT_UGURU_IN_SENSOR; 554faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede goto abituguru_detect_bank1_sensor_type_exit; 555f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } else 556f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " alarm raised during volt " 557e432dc811bfb6b3d3ad618d99bd8d58132fec316Hans de Goede "sensor test, but volt range flag not set\n"); 558f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } else 559f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " alarm not raised during volt sensor " 560f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "test\n"); 561f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 5621bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 5631bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Temp sensor test, enable sensor as a temp sensor, set beep value 5641bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * ridicously low (but not too low, otherwise uguru ignores it). 5651bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * If its a temp sensor this should always give us an alarm. 5661bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 567f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede buf[0] = ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE; 568f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede buf[1] = 5; 569f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede buf[2] = 10; 570f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, 571f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede buf, 3) != 3) 572faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede goto abituguru_detect_bank1_sensor_type_exit; 5731bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 5741bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Now we need 50 ms to give the uguru time to read the sensors 5751bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * and raise a temp alarm 5761bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 577f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede set_current_state(TASK_UNINTERRUPTIBLE); 578f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede schedule_timeout(HZ/20); 579f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Check for alarm and check the alarm is a temp high alarm. */ 580f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, 581f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_MAX_RETRIES) != 3) 582faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede goto abituguru_detect_bank1_sensor_type_exit; 583f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { 584f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, 585f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede sensor_addr, buf, 3, 586f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_MAX_RETRIES) != 3) 587faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede goto abituguru_detect_bank1_sensor_type_exit; 588f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (buf[0] & ABIT_UGURU_TEMP_HIGH_ALARM_FLAG) { 589f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " found temp sensor\n"); 590faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede ret = ABIT_UGURU_TEMP_SENSOR; 591faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede goto abituguru_detect_bank1_sensor_type_exit; 592f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } else 593f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " alarm raised during temp " 594f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "sensor test, but temp high flag not set\n"); 595f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } else 596f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " alarm not raised during temp sensor " 597f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "test\n"); 598f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 599faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede ret = ABIT_UGURU_NC; 600faf9b616325430422fa13fead88ca7843eb249d6Hans de Goedeabituguru_detect_bank1_sensor_type_exit: 6011bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 6021bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Restore original settings, failing here is really BAD, it has been 6031bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * reported that some BIOS-es hang when entering the uGuru menu with 6041bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * invalid settings present in the uGuru, so we try this 3 times. 6051bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 606faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede for (i = 0; i < 3; i++) 607faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, 608faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede sensor_addr, data->bank1_settings[sensor_addr], 609faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede 3) == 3) 610faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede break; 611faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede if (i == 3) { 61228ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches pr_err("Fatal error could not restore original settings. %s %s\n", 61328ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches never_happen, report_this); 614a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede return -ENODEV; 615faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede } 616f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ret; 617f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 618f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 6191bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 6201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * These functions try to find out how many sensors there are in bank2 and how 6211bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * many pwms there are. The purpose of this is to make sure that we don't give 6221bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * the user the possibility to change settings for non-existent sensors / pwm. 6231bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * The uGuru will happily read / write whatever memory happens to be after the 6241bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * memory storing the PWM settings when reading/writing to a PWM which is not 6251bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * there. Notice even if we detect a PWM which doesn't exist we normally won't 6261bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * write to it, unless the user tries to change the settings. 6271bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * 6281bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Although the uGuru allows reading (settings) from non existing bank2 6291bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sensors, my version of the uGuru does seem to stop writing to them, the 6301bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * write function above aborts in this case with: 6311bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * "CMD reg does not hold 0xAC after write" 6321bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * 6331bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Notice these 2 tests are non destructive iow read-only tests, otherwise 6341bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * they would defeat their purpose. Although for the bank2_sensors detection a 6351bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * read/write test would be feasible because of the reaction above, I've 6361bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * however opted to stay on the safe side. 6371bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 638f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic void __devinit 639f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedeabituguru_detect_no_bank2_sensors(struct abituguru_data *data) 640f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 641f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int i; 642f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 6439b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede if (fan_sensors > 0 && fan_sensors <= ABIT_UGURU_MAX_BANK2_SENSORS) { 644f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_sensors = fan_sensors; 645f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, "assuming %d fan sensors because of " 646f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "\"fan_sensors\" module param\n", 647f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->bank2_sensors); 648f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return; 649f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 650f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 651f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, "detecting number of fan sensors\n"); 652f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) { 6531bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 6541bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * 0x89 are the known used bits: 6551bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * -0x80 enable shutdown 6561bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * -0x08 enable beep 6571bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * -0x01 enable alarm 6581bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * All other bits should be 0, but on some motherboards 6591bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * 0x40 (bit 6) is also high for some of the fans?? 6601bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 661b7c066044f4355d9fbe1ac45e03303b78d21e8d4Hans de Goede if (data->bank2_settings[i][0] & ~0xC9) { 662f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " 663f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "to be a fan sensor: settings[0] = %02X\n", 664f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede i, (unsigned int)data->bank2_settings[i][0]); 665f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 666f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 667f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 668f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* check if the threshold is within the allowed range */ 669f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->bank2_settings[i][1] < 670f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_bank2_min_threshold) { 671f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " 672f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "to be a fan sensor: the threshold (%d) is " 673f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "below the minimum (%d)\n", i, 674f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->bank2_settings[i][1], 675f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)abituguru_bank2_min_threshold); 676f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 677f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 678f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->bank2_settings[i][1] > 679f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_bank2_max_threshold) { 680f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " bank2 sensor %d does not seem " 681f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "to be a fan sensor: the threshold (%d) is " 682f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "above the maximum (%d)\n", i, 683f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->bank2_settings[i][1], 684f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)abituguru_bank2_max_threshold); 685f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 686f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 687f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 688f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 689f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_sensors = i; 690f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " found: %d fan sensors\n", 691f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->bank2_sensors); 692f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 693f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 694f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic void __devinit 695f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedeabituguru_detect_no_pwms(struct abituguru_data *data) 696f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 697f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int i, j; 698f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 6999b2ad1298232a4016a407261bd6811294b09ba97Hans de Goede if (pwms > 0 && pwms <= ABIT_UGURU_MAX_PWMS) { 700f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->pwms = pwms; 701f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, "assuming %d PWM outputs because of " 702f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "\"pwms\" module param\n", (int)data->pwms); 703f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return; 704f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 705f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 706f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, "detecting number of PWM outputs\n"); 707f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) { 7081bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 7091bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * 0x80 is the enable bit and the low 7101bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * nibble is which temp sensor to use, 7111bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * the other bits should be 0 7121bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 713f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->pwm_settings[i][0] & ~0x8F) { 714f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " 715f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "to be a pwm channel: settings[0] = %02X\n", 716f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede i, (unsigned int)data->pwm_settings[i][0]); 717f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 718f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 719f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 7201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 7211bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * the low nibble must correspond to one of the temp sensors 7221bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * we've found 7231bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 724f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (j = 0; j < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]; 725f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede j++) { 726f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][j] == 727f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (data->pwm_settings[i][0] & 0x0F)) 728f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 729f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 730f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (j == data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) { 731f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " 732f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "to be a pwm channel: %d is not a valid temp " 733f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "sensor address\n", i, 734f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->pwm_settings[i][0] & 0x0F); 735f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 736f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 737f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 738f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* check if all other settings are within the allowed range */ 739f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (j = 1; j < 5; j++) { 740f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 min; 741f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* special case pwm1 min pwm% */ 742f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if ((i == 0) && ((j == 1) || (j == 2))) 743f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede min = 77; 744f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 745f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede min = abituguru_pwm_min[j]; 746f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->pwm_settings[i][j] < min) { 747f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " pwm channel %d does " 748f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "not seem to be a pwm channel: " 749f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "setting %d (%d) is below the minimum " 750f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "value (%d)\n", i, j, 751f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->pwm_settings[i][j], 752f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)min); 753f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto abituguru_detect_no_pwms_exit; 754f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 755f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->pwm_settings[i][j] > abituguru_pwm_max[j]) { 756f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " pwm channel %d does " 757f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "not seem to be a pwm channel: " 758f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "setting %d (%d) is above the maximum " 759f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "value (%d)\n", i, j, 760f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->pwm_settings[i][j], 761f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)abituguru_pwm_max[j]); 762f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto abituguru_detect_no_pwms_exit; 763f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 764f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 765f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 766f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* check that min temp < max temp and min pwm < max pwm */ 767f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->pwm_settings[i][1] >= data->pwm_settings[i][2]) { 768f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " 769f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "to be a pwm channel: min pwm (%d) >= " 770f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "max pwm (%d)\n", i, 771f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->pwm_settings[i][1], 772f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->pwm_settings[i][2]); 773f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 774f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 775f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->pwm_settings[i][3] >= data->pwm_settings[i][4]) { 776f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " pwm channel %d does not seem " 777f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "to be a pwm channel: min temp (%d) >= " 778f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "max temp (%d)\n", i, 779f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->pwm_settings[i][3], 780f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->pwm_settings[i][4]); 781f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede break; 782f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 783f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 784f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 785f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedeabituguru_detect_no_pwms_exit: 786f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->pwms = i; 787f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, " found: %d PWM outputs\n", (int)data->pwms); 788f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 789f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 7901bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck/* 7911bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Following are the sysfs callback functions. These functions expect: 7921bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sensor_device_attribute_2->index: sensor address/offset in the bank 7931bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * sensor_device_attribute_2->nr: register offset, bitmask or NA. 7941bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 795f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic struct abituguru_data *abituguru_update_device(struct device *dev); 796f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 797f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_bank1_value(struct device *dev, 798f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 799f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 800f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 801f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = abituguru_update_device(dev); 802f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (!data) 803f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 804f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "%d\n", (data->bank1_value[attr->index] * 805f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_max_value[attr->index] + 128) / 255); 806f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 807f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 808f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_bank1_setting(struct device *dev, 809f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 810f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 811f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 812f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 813f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "%d\n", 814f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (data->bank1_settings[attr->index][attr->nr] * 815f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_max_value[attr->index] + 128) / 255); 816f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 817f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 818f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_bank2_value(struct device *dev, 819f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 820f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 821f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 822f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = abituguru_update_device(dev); 823f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (!data) 824f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 825f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "%d\n", (data->bank2_value[attr->index] * 826f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_FAN_MAX + 128) / 255); 827f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 828f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 829f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_bank2_setting(struct device *dev, 830f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 831f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 832f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 833f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 834f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "%d\n", 835f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (data->bank2_settings[attr->index][attr->nr] * 836f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_FAN_MAX + 128) / 255); 837f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 838f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 839f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t store_bank1_setting(struct device *dev, struct device_attribute 840f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede *devattr, const char *buf, size_t count) 841f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 842f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 843f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 8441bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck unsigned long val; 8451bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ssize_t ret; 8461bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 8471bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = kstrtoul(buf, 10, &val); 8481bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (ret) 8491bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return ret; 8501bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 8511bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = count; 8521bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck val = (val * 255 + data->bank1_max_value[attr->index] / 2) / 853f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_max_value[attr->index]; 8541bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (val > 255) 8551bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return -EINVAL; 856f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 857f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_lock(&data->update_lock); 858f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->bank1_settings[attr->index][attr->nr] != val) { 859f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 orig_val = data->bank1_settings[attr->index][attr->nr]; 860f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_settings[attr->index][attr->nr] = val; 861f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, 862f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede attr->index, data->bank1_settings[attr->index], 863f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 3) <= attr->nr) { 864f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_settings[attr->index][attr->nr] = orig_val; 865f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ret = -EIO; 866f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 867f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 868f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_unlock(&data->update_lock); 869f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ret; 870f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 871f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 872f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t store_bank2_setting(struct device *dev, struct device_attribute 873f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede *devattr, const char *buf, size_t count) 874f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 875f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 876f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 8771bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck unsigned long val; 8781bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ssize_t ret; 8791bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 8801bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = kstrtoul(buf, 10, &val); 8811bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (ret) 8821bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return ret; 8831bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 8841bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = count; 8851bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck val = (val * 255 + ABIT_UGURU_FAN_MAX / 2) / ABIT_UGURU_FAN_MAX; 886f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 887f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* this check can be done before taking the lock */ 8881bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (val < abituguru_bank2_min_threshold || 8891bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck val > abituguru_bank2_max_threshold) 890f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EINVAL; 891f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 892f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_lock(&data->update_lock); 893f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->bank2_settings[attr->index][attr->nr] != val) { 894f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 orig_val = data->bank2_settings[attr->index][attr->nr]; 895f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_settings[attr->index][attr->nr] = val; 896f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK2 + 2, 897f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede attr->index, data->bank2_settings[attr->index], 898f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 2) <= attr->nr) { 899f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_settings[attr->index][attr->nr] = orig_val; 900f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ret = -EIO; 901f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 902f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 903f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_unlock(&data->update_lock); 904f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ret; 905f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 906f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 907f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_bank1_alarm(struct device *dev, 908f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 909f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 910f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 911f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = abituguru_update_device(dev); 912f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (!data) 913f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 9141bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 9151bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * See if the alarm bit for this sensor is set, and if the 9161bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * alarm matches the type of alarm we're looking for (for volt 9171bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * it can be either low or high). The type is stored in a few 9181bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * readonly bits in the settings part of the relevant sensor. 9191bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * The bitmask of the type is passed to us in attr->nr. 9201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 921f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if ((data->alarms[attr->index / 8] & (0x01 << (attr->index % 8))) && 922f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (data->bank1_settings[attr->index][0] & attr->nr)) 923f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "1\n"); 924f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 925f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "0\n"); 926f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 927f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 928f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_bank2_alarm(struct device *dev, 929f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 930f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 931f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 932f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = abituguru_update_device(dev); 933f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (!data) 934f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EIO; 935f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->alarms[2] & (0x01 << attr->index)) 936f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "1\n"); 937f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 938f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "0\n"); 939f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 940f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 941f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_bank1_mask(struct device *dev, 942f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 943f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 944f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 945f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 946f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->bank1_settings[attr->index][0] & attr->nr) 947f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "1\n"); 948f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 949f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "0\n"); 950f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 951f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 952f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_bank2_mask(struct device *dev, 953f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 954f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 955f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 956f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 957f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->bank2_settings[attr->index][0] & attr->nr) 958f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "1\n"); 959f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 960f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "0\n"); 961f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 962f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 963f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t store_bank1_mask(struct device *dev, 964f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, const char *buf, size_t count) 965f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 966f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 967f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 9681bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ssize_t ret; 969f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 orig_val; 9701bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck unsigned long mask; 9711bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 9721bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = kstrtoul(buf, 10, &mask); 9731bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (ret) 9741bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return ret; 975f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 9761bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = count; 977f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_lock(&data->update_lock); 978f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede orig_val = data->bank1_settings[attr->index][0]; 979f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 980f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (mask) 981f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_settings[attr->index][0] |= attr->nr; 982f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 983f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_settings[attr->index][0] &= ~attr->nr; 984f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 985f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if ((data->bank1_settings[attr->index][0] != orig_val) && 986f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (abituguru_write(data, 987f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_SENSOR_BANK1 + 2, attr->index, 988f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_settings[attr->index], 3) < 1)) { 989f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_settings[attr->index][0] = orig_val; 990f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ret = -EIO; 991f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 992f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_unlock(&data->update_lock); 993f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ret; 994f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 995f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 996f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t store_bank2_mask(struct device *dev, 997f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, const char *buf, size_t count) 998f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 999f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 1000f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 10011bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ssize_t ret; 1002f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 orig_val; 10031bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck unsigned long mask; 1004f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 10051bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = kstrtoul(buf, 10, &mask); 10061bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (ret) 10071bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return ret; 10081bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 10091bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = count; 1010f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_lock(&data->update_lock); 1011f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede orig_val = data->bank2_settings[attr->index][0]; 1012f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1013f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (mask) 1014f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_settings[attr->index][0] |= attr->nr; 1015f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 1016f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_settings[attr->index][0] &= ~attr->nr; 1017f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1018f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if ((data->bank2_settings[attr->index][0] != orig_val) && 1019f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (abituguru_write(data, 1020f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_SENSOR_BANK2 + 2, attr->index, 1021f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_settings[attr->index], 2) < 1)) { 1022f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_settings[attr->index][0] = orig_val; 1023f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ret = -EIO; 1024f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1025f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_unlock(&data->update_lock); 1026f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ret; 1027f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1028f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1029f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Fan PWM (speed control) */ 1030f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_pwm_setting(struct device *dev, 1031f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 1032f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1033f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 1034f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 1035f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "%d\n", data->pwm_settings[attr->index][attr->nr] * 1036f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_pwm_settings_multiplier[attr->nr]); 1037f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1038f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1039f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t store_pwm_setting(struct device *dev, struct device_attribute 1040f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede *devattr, const char *buf, size_t count) 1041f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1042f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 1043f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 10441bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck u8 min; 10451bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck unsigned long val; 10461bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ssize_t ret; 10471bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 10481bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = kstrtoul(buf, 10, &val); 10491bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (ret) 10501bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return ret; 10511bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 10521bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = count; 10531bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck val = (val + abituguru_pwm_settings_multiplier[attr->nr] / 2) / 10541bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck abituguru_pwm_settings_multiplier[attr->nr]; 1055f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1056f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* special case pwm1 min pwm% */ 1057f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if ((attr->index == 0) && ((attr->nr == 1) || (attr->nr == 2))) 1058f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede min = 77; 1059f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 1060f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede min = abituguru_pwm_min[attr->nr]; 1061f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1062f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* this check can be done before taking the lock */ 10631bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (val < min || val > abituguru_pwm_max[attr->nr]) 1064f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -EINVAL; 1065f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1066f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_lock(&data->update_lock); 1067f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* this check needs to be done after taking the lock */ 1068f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if ((attr->nr & 1) && 1069f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (val >= data->pwm_settings[attr->index][attr->nr + 1])) 1070f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ret = -EINVAL; 1071f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else if (!(attr->nr & 1) && 1072f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (val <= data->pwm_settings[attr->index][attr->nr - 1])) 1073f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ret = -EINVAL; 1074f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else if (data->pwm_settings[attr->index][attr->nr] != val) { 1075f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 orig_val = data->pwm_settings[attr->index][attr->nr]; 1076f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->pwm_settings[attr->index][attr->nr] = val; 1077f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, 1078f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede attr->index, data->pwm_settings[attr->index], 1079f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 5) <= attr->nr) { 1080f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->pwm_settings[attr->index][attr->nr] = 1081f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede orig_val; 1082f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ret = -EIO; 1083f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1084f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1085f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_unlock(&data->update_lock); 1086f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ret; 1087f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1088f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1089f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_pwm_sensor(struct device *dev, 1090f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 1091f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1092f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 1093f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 1094f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int i; 10951bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 10961bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * We need to walk to the temp sensor addresses to find what 10971bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * the userspace id of the configured temp sensor is. 10981bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 1099f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]; i++) 1100f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][i] == 1101f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (data->pwm_settings[attr->index][0] & 0x0F)) 1102f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "%d\n", i+1); 1103f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1104f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -ENXIO; 1105f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1106f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1107f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t store_pwm_sensor(struct device *dev, struct device_attribute 1108f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede *devattr, const char *buf, size_t count) 1109f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1110f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 1111f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 11121bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ssize_t ret; 11131bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck unsigned long val; 11141bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck u8 orig_val; 11151bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck u8 address; 11161bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 11171bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = kstrtoul(buf, 10, &val); 11181bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (ret) 11191bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return ret; 1120f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 11211bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (val == 0 || val > data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) 11221bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return -EINVAL; 11231bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 11241bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck val -= 1; 11251bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = count; 1126f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_lock(&data->update_lock); 11271bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck orig_val = data->pwm_settings[attr->index][0]; 11281bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck address = data->bank1_address[ABIT_UGURU_TEMP_SENSOR][val]; 11291bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck data->pwm_settings[attr->index][0] &= 0xF0; 11301bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck data->pwm_settings[attr->index][0] |= address; 11311bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (data->pwm_settings[attr->index][0] != orig_val) { 11321bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, attr->index, 11331bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck data->pwm_settings[attr->index], 5) < 1) { 11341bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck data->pwm_settings[attr->index][0] = orig_val; 11351bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = -EIO; 1136f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1137f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1138f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_unlock(&data->update_lock); 1139f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ret; 1140f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1141f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1142f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_pwm_enable(struct device *dev, 1143f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 1144f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1145f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 1146f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 1147f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int res = 0; 1148f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->pwm_settings[attr->index][0] & ABIT_UGURU_FAN_PWM_ENABLE) 1149f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede res = 2; 1150f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "%d\n", res); 1151f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1152f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1153f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t store_pwm_enable(struct device *dev, struct device_attribute 1154f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede *devattr, const char *buf, size_t count) 1155f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1156f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); 1157f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 11581bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck u8 orig_val; 11591bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ssize_t ret; 11601bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck unsigned long user_val; 11611bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck 11621bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = kstrtoul(buf, 10, &user_val); 11631bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (ret) 11641bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck return ret; 1165f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 11661bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = count; 1167f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_lock(&data->update_lock); 1168f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede orig_val = data->pwm_settings[attr->index][0]; 1169f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede switch (user_val) { 11701bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck case 0: 11711bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck data->pwm_settings[attr->index][0] &= 11721bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ~ABIT_UGURU_FAN_PWM_ENABLE; 11731bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck break; 11741bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck case 2: 11751bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck data->pwm_settings[attr->index][0] |= ABIT_UGURU_FAN_PWM_ENABLE; 11761bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck break; 11771bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck default: 11781bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck ret = -EINVAL; 1179f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1180f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if ((data->pwm_settings[attr->index][0] != orig_val) && 1181f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, 1182f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede attr->index, data->pwm_settings[attr->index], 1183f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 5) < 1)) { 1184f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->pwm_settings[attr->index][0] = orig_val; 1185f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ret = -EIO; 1186f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1187f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_unlock(&data->update_lock); 1188f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ret; 1189f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1190f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1191f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic ssize_t show_name(struct device *dev, 1192f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct device_attribute *devattr, char *buf) 1193f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1194f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return sprintf(buf, "%s\n", ABIT_UGURU_NAME); 1195f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1196f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1197f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede/* Sysfs attr templates, the real entries are generated automatically. */ 1198f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const 1199f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestruct sensor_device_attribute_2 abituguru_sysfs_bank1_templ[2][9] = { 1200f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede { 1201f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_input, 0444, show_bank1_value, NULL, 0, 0), 1202f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_min, 0644, show_bank1_setting, 1203f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_setting, 1, 0), 1204f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_min_alarm, 0444, show_bank1_alarm, NULL, 1205f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_VOLT_LOW_ALARM_FLAG, 0), 1206f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_max, 0644, show_bank1_setting, 1207f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_setting, 2, 0), 1208f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_max_alarm, 0444, show_bank1_alarm, NULL, 1209f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_VOLT_HIGH_ALARM_FLAG, 0), 1210f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_beep, 0644, show_bank1_mask, 1211f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_mask, ABIT_UGURU_BEEP_ENABLE, 0), 1212f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_shutdown, 0644, show_bank1_mask, 1213f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), 1214f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_min_alarm_enable, 0644, show_bank1_mask, 1215f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_mask, ABIT_UGURU_VOLT_LOW_ALARM_ENABLE, 0), 1216f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(in%d_max_alarm_enable, 0644, show_bank1_mask, 1217f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_mask, ABIT_UGURU_VOLT_HIGH_ALARM_ENABLE, 0), 1218f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede }, { 1219f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(temp%d_input, 0444, show_bank1_value, NULL, 0, 0), 1220f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(temp%d_alarm, 0444, show_bank1_alarm, NULL, 1221f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_TEMP_HIGH_ALARM_FLAG, 0), 1222f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(temp%d_max, 0644, show_bank1_setting, 1223f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_setting, 1, 0), 1224f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(temp%d_crit, 0644, show_bank1_setting, 1225f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_setting, 2, 0), 1226f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(temp%d_beep, 0644, show_bank1_mask, 1227f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_mask, ABIT_UGURU_BEEP_ENABLE, 0), 1228f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(temp%d_shutdown, 0644, show_bank1_mask, 1229f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), 1230f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(temp%d_alarm_enable, 0644, show_bank1_mask, 1231f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank1_mask, ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE, 0), 1232f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1233f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede}; 1234f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1235f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const struct sensor_device_attribute_2 abituguru_sysfs_fan_templ[6] = { 1236f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(fan%d_input, 0444, show_bank2_value, NULL, 0, 0), 1237f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(fan%d_alarm, 0444, show_bank2_alarm, NULL, 0, 0), 1238f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(fan%d_min, 0644, show_bank2_setting, 1239f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank2_setting, 1, 0), 1240f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(fan%d_beep, 0644, show_bank2_mask, 1241f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank2_mask, ABIT_UGURU_BEEP_ENABLE, 0), 1242f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(fan%d_shutdown, 0644, show_bank2_mask, 1243f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank2_mask, ABIT_UGURU_SHUTDOWN_ENABLE, 0), 1244f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(fan%d_alarm_enable, 0644, show_bank2_mask, 1245f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_bank2_mask, ABIT_UGURU_FAN_LOW_ALARM_ENABLE, 0), 1246f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede}; 1247f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1248f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic const struct sensor_device_attribute_2 abituguru_sysfs_pwm_templ[6] = { 1249f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(pwm%d_enable, 0644, show_pwm_enable, 1250f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_pwm_enable, 0, 0), 1251f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(pwm%d_auto_channels_temp, 0644, show_pwm_sensor, 1252f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_pwm_sensor, 0, 0), 1253f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(pwm%d_auto_point1_pwm, 0644, show_pwm_setting, 1254f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_pwm_setting, 1, 0), 1255f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(pwm%d_auto_point2_pwm, 0644, show_pwm_setting, 1256f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_pwm_setting, 2, 0), 1257f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(pwm%d_auto_point1_temp, 0644, show_pwm_setting, 1258f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_pwm_setting, 3, 0), 1259f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(pwm%d_auto_point2_temp, 0644, show_pwm_setting, 1260f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede store_pwm_setting, 4, 0), 1261f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede}; 1262f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1263a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goedestatic struct sensor_device_attribute_2 abituguru_sysfs_attr[] = { 1264f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0), 1265f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede}; 1266f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1267f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int __devinit abituguru_probe(struct platform_device *pdev) 1268f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1269f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data; 1270a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede int i, j, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV; 1271f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede char *sysfs_filename; 1272f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 12731bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 12741bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * El weirdo probe order, to keep the sysfs order identical to the 12751bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * BIOS and window-appliction listing order. 12761bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 1277a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede const u8 probe_order[ABIT_UGURU_MAX_BANK1_SENSORS] = { 1278a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede 0x00, 0x01, 0x03, 0x04, 0x0A, 0x08, 0x0E, 0x02, 1279a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede 0x09, 0x06, 0x05, 0x0B, 0x0F, 0x0D, 0x07, 0x0C }; 1280f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 12811bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL); 12821bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (!data) 1283f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -ENOMEM; 1284f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1285f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; 1286f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_init(&data->update_lock); 1287f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede platform_set_drvdata(pdev, data); 1288f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1289f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* See if the uGuru is ready */ 1290f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (inb_p(data->addr + ABIT_UGURU_DATA) == ABIT_UGURU_STATUS_INPUT) 1291f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->uguru_ready = 1; 1292f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 12931bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 12941bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Completely read the uGuru this has 2 purposes: 12951bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * - testread / see if one really is there. 12961bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * - make an in memory copy of all the uguru settings for future use. 12971bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 1298f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, 1299a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede data->alarms, 3, ABIT_UGURU_MAX_RETRIES) != 3) 1300a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede goto abituguru_probe_error; 1301f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1302a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { 1303f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, i, 1304f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede &data->bank1_value[i], 1, 1305a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_RETRIES) != 1) 1306a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede goto abituguru_probe_error; 1307f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1+1, i, 1308f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_settings[i], 3, 1309a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_RETRIES) != 3) 1310a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede goto abituguru_probe_error; 1311f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 13121bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 13131bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Note: We don't know how many bank2 sensors / pwms there really are, 13141bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * but in order to "detect" this we need to read the maximum amount 13151bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * anyways. If we read sensors/pwms not there we'll just read crap 13161bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * this can't hurt. We need the detection because we don't want 13171bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * unwanted writes, which will hurt! 13181bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 1319f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) { 1320f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i, 1321f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede &data->bank2_value[i], 1, 1322a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_RETRIES) != 1) 1323a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede goto abituguru_probe_error; 1324f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2+1, i, 1325f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank2_settings[i], 2, 1326a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_RETRIES) != 2) 1327a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede goto abituguru_probe_error; 1328f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1329f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) { 1330f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (abituguru_read(data, ABIT_UGURU_FAN_PWM, i, 1331f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->pwm_settings[i], 5, 1332a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede ABIT_UGURU_MAX_RETRIES) != 5) 1333a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede goto abituguru_probe_error; 1334f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1335f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->last_updated = jiffies; 1336f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1337f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Detect sensor types and fill the sysfs attr for bank1 */ 1338a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_attr_i = 0; 1339a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_filename = data->sysfs_names; 1340a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_names_free = ABITUGURU_SYSFS_NAMES_LENGTH; 1341a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { 1342f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede res = abituguru_detect_bank1_sensor_type(data, probe_order[i]); 1343a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede if (res < 0) 1344a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede goto abituguru_probe_error; 1345f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (res == ABIT_UGURU_NC) 1346f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede continue; 1347f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1348a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede /* res 1 (temp) sensors have 7 sysfs entries, 0 (in) 9 */ 1349f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (j = 0; j < (res ? 7 : 9); j++) { 1350a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede used = snprintf(sysfs_filename, sysfs_names_free, 1351a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede abituguru_sysfs_bank1_templ[res][j].dev_attr. 1352a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede attr.name, data->bank1_sensors[res] + res) 1353a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede + 1; 1354f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i] = 1355f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_sysfs_bank1_templ[res][j]; 1356f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = 1357f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede sysfs_filename; 1358f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i].index = probe_order[i]; 1359a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_filename += used; 1360a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_names_free -= used; 1361f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede sysfs_attr_i++; 1362f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1363f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_max_value[probe_order[i]] = 1364f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_bank1_max_value[res]; 1365f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_address[res][data->bank1_sensors[res]] = 1366f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede probe_order[i]; 1367f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->bank1_sensors[res]++; 1368f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1369f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Detect number of sensors and fill the sysfs attr for bank2 (fans) */ 1370f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_detect_no_bank2_sensors(data); 1371f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < data->bank2_sensors; i++) { 1372a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede for (j = 0; j < ARRAY_SIZE(abituguru_sysfs_fan_templ); j++) { 1373a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede used = snprintf(sysfs_filename, sysfs_names_free, 1374a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede abituguru_sysfs_fan_templ[j].dev_attr.attr.name, 1375a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede i + 1) + 1; 1376f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i] = 1377f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_sysfs_fan_templ[j]; 1378f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = 1379f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede sysfs_filename; 1380f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i].index = i; 1381a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_filename += used; 1382a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_names_free -= used; 1383f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede sysfs_attr_i++; 1384f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1385f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1386f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Detect number of sensors and fill the sysfs attr for pwms */ 1387f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_detect_no_pwms(data); 1388f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < data->pwms; i++) { 1389a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede for (j = 0; j < ARRAY_SIZE(abituguru_sysfs_pwm_templ); j++) { 1390a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede used = snprintf(sysfs_filename, sysfs_names_free, 1391a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede abituguru_sysfs_pwm_templ[j].dev_attr.attr.name, 1392a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede i + 1) + 1; 1393f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i] = 1394f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_sysfs_pwm_templ[j]; 1395f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name = 1396f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede sysfs_filename; 1397f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->sysfs_attr[sysfs_attr_i].index = i; 1398a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_filename += used; 1399a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede sysfs_names_free -= used; 1400f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede sysfs_attr_i++; 1401f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1402f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1403a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede /* Fail safe check, this should never happen! */ 1404a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede if (sysfs_names_free < 0) { 140528ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches pr_err("Fatal error ran out of space for sysfs attr names. %s %s", 140628ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches never_happen, report_this); 1407a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede res = -ENAMETOOLONG; 1408a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede goto abituguru_probe_error; 1409f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 141028ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches pr_info("found Abit uGuru\n"); 1411f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1412f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Register sysfs hooks */ 1413f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede for (i = 0; i < sysfs_attr_i; i++) 1414bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede if (device_create_file(&pdev->dev, 1415bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede &data->sysfs_attr[i].dev_attr)) 1416bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede goto abituguru_probe_error; 1417a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) 1418bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede if (device_create_file(&pdev->dev, 1419bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede &abituguru_sysfs_attr[i].dev_attr)) 1420bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede goto abituguru_probe_error; 1421f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 14221beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones data->hwmon_dev = hwmon_device_register(&pdev->dev); 14231beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones if (!IS_ERR(data->hwmon_dev)) 1424bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede return 0; /* success */ 1425a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede 14261beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones res = PTR_ERR(data->hwmon_dev); 1427a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goedeabituguru_probe_error: 1428bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) 1429bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); 1430bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) 1431bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede device_remove_file(&pdev->dev, 1432bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede &abituguru_sysfs_attr[i].dev_attr); 143304a6217df28e3004ba4e76eb0a356a30f72c564fJean Delvare platform_set_drvdata(pdev, NULL); 1434a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede kfree(data); 1435a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede return res; 1436f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1437f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1438f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int __devexit abituguru_remove(struct platform_device *pdev) 1439f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1440bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede int i; 1441f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = platform_get_drvdata(pdev); 1442f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 14431beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones hwmon_device_unregister(data->hwmon_dev); 1444bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) 1445bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); 1446bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) 1447bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede device_remove_file(&pdev->dev, 1448bc8f0a26855d8fac68040d462ec3cc13884e98e5Hans de Goede &abituguru_sysfs_attr[i].dev_attr); 144904a6217df28e3004ba4e76eb0a356a30f72c564fJean Delvare platform_set_drvdata(pdev, NULL); 1450f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede kfree(data); 1451f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1452f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return 0; 1453f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1454f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1455f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic struct abituguru_data *abituguru_update_device(struct device *dev) 1456f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1457f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int i, err; 1458f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct abituguru_data *data = dev_get_drvdata(dev); 1459f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* fake a complete successful read if no update necessary. */ 1460f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede char success = 1; 1461f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1462f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_lock(&data->update_lock); 1463f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (time_after(jiffies, data->last_updated + HZ)) { 1464f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede success = 0; 14651bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, 14661bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck data->alarms, 3, 0); 14671bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (err != 3) 1468f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto LEAVE_UPDATE; 1469a2392e0b907b9633c31be14ee75bb39fce348b01Hans de Goede for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) { 14701bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, 14711bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck i, &data->bank1_value[i], 1, 0); 14721bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (err != 1) 1473f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto LEAVE_UPDATE; 14741bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, 14751bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck i, data->bank1_settings[i], 3, 0); 14761bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (err != 3) 1477f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto LEAVE_UPDATE; 1478f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 14791bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck for (i = 0; i < data->bank2_sensors; i++) { 14801bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i, 14811bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck &data->bank2_value[i], 1, 0); 14821bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck if (err != 1) 1483f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto LEAVE_UPDATE; 14841bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck } 1485f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* success! */ 1486f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede success = 1; 1487f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->update_timeouts = 0; 1488f2b84bbcebfdbe4855bab532909eef6621999f9fHans de GoedeLEAVE_UPDATE: 1489f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* handle timeout condition */ 1490faf9b616325430422fa13fead88ca7843eb249d6Hans de Goede if (!success && (err == -EBUSY || err >= 0)) { 1491f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* No overflow please */ 1492f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->update_timeouts < 255u) 1493f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->update_timeouts++; 1494f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (data->update_timeouts <= ABIT_UGURU_MAX_TIMEOUTS) { 1495f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(3, "timeout exceeded, will " 1496f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "try again next update\n"); 1497f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* Just a timeout, fake a successful read */ 1498f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede success = 1; 1499f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } else 1500f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(1, "timeout exceeded %d " 1501f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "times waiting for more input state\n", 1502f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede (int)data->update_timeouts); 1503f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1504f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* On success set last_updated */ 1505f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (success) 1506f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede data->last_updated = jiffies; 1507f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1508f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede mutex_unlock(&data->update_lock); 1509f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1510f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (success) 1511f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return data; 1512f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede else 1513f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return NULL; 1514f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1515f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1516360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede#ifdef CONFIG_PM 1517360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goedestatic int abituguru_suspend(struct platform_device *pdev, pm_message_t state) 1518360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede{ 1519360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede struct abituguru_data *data = platform_get_drvdata(pdev); 15201bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 15211bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * make sure all communications with the uguru are done and no new 15221bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * ones are started 15231bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 1524360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede mutex_lock(&data->update_lock); 1525360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede return 0; 1526360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede} 1527360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede 1528360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goedestatic int abituguru_resume(struct platform_device *pdev) 1529360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede{ 1530360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede struct abituguru_data *data = platform_get_drvdata(pdev); 1531360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede /* See if the uGuru is still ready */ 1532360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede if (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) 1533360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede data->uguru_ready = 0; 1534360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede mutex_unlock(&data->update_lock); 1535360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede return 0; 1536360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede} 1537360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede#else 1538360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede#define abituguru_suspend NULL 1539360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede#define abituguru_resume NULL 1540360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede#endif /* CONFIG_PM */ 1541360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede 1542f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic struct platform_driver abituguru_driver = { 1543f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede .driver = { 1544f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede .owner = THIS_MODULE, 1545f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede .name = ABIT_UGURU_NAME, 1546f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede }, 1547360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede .probe = abituguru_probe, 1548360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede .remove = __devexit_p(abituguru_remove), 1549360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede .suspend = abituguru_suspend, 1550360b9ab220aedaf346380fc2344729d9acc3b075Hans de Goede .resume = abituguru_resume, 1551f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede}; 1552f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1553f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int __init abituguru_detect(void) 1554f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 15551bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck /* 15561bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * See if there is an uguru there. After a reboot uGuru will hold 0x00 15571bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * at DATA and 0xAC, when this driver has already been loaded once 15581bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * DATA will hold 0x08. For most uGuru's CMD will hold 0xAC in either 15591bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * scenario but some will hold 0x00. 15601bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * Some uGuru's initially hold 0x09 at DATA and will only hold 0x08 15611bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck * after reading CMD first, so CMD must be read first! 15621bd385d67946391dd3ed80654e36adbb634f0be6Guenter Roeck */ 1563f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 cmd_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_CMD); 1564f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede u8 data_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_DATA); 1565f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (((data_val == 0x00) || (data_val == 0x08)) && 1566f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ((cmd_val == 0x00) || (cmd_val == 0xAC))) 1567f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ABIT_UGURU_BASE; 1568f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1569f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede ABIT_UGURU_DEBUG(2, "no Abit uGuru found, data = 0x%02X, cmd = " 1570f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); 1571f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1572f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (force) { 157328ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches pr_info("Assuming Abit uGuru is present because of \"force\" parameter\n"); 1574f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return ABIT_UGURU_BASE; 1575f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1576f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1577f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede /* No uGuru found */ 1578f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return -ENODEV; 1579f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1580f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1581f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic struct platform_device *abituguru_pdev; 1582f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1583f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic int __init abituguru_init(void) 1584f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1585f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede int address, err; 1586f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede struct resource res = { .flags = IORESOURCE_IO }; 15871855256c497ecfefc730df6032243f26855ce52cJeff Garzik const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); 1588c182f5bbfb399b1fa2ad65107b3caf9c1c69435eHans de Goede 1589c182f5bbfb399b1fa2ad65107b3caf9c1c69435eHans de Goede /* safety check, refuse to load on non Abit motherboards */ 1590c182f5bbfb399b1fa2ad65107b3caf9c1c69435eHans de Goede if (!force && (!board_vendor || 1591c182f5bbfb399b1fa2ad65107b3caf9c1c69435eHans de Goede strcmp(board_vendor, "http://www.abit.com.tw/"))) 1592c182f5bbfb399b1fa2ad65107b3caf9c1c69435eHans de Goede return -ENODEV; 1593c182f5bbfb399b1fa2ad65107b3caf9c1c69435eHans de Goede 1594f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede address = abituguru_detect(); 1595f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (address < 0) 1596f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return address; 1597f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1598f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede err = platform_driver_register(&abituguru_driver); 1599f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (err) 1600f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto exit; 1601f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1602f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede abituguru_pdev = platform_device_alloc(ABIT_UGURU_NAME, address); 1603f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (!abituguru_pdev) { 160428ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches pr_err("Device allocation failed\n"); 1605f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede err = -ENOMEM; 1606f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto exit_driver_unregister; 1607f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1608f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1609f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede res.start = address; 1610f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede res.end = address + ABIT_UGURU_REGION_LENGTH - 1; 1611f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede res.name = ABIT_UGURU_NAME; 1612f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1613f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede err = platform_device_add_resources(abituguru_pdev, &res, 1); 1614f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (err) { 161528ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches pr_err("Device resource addition failed (%d)\n", err); 1616f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto exit_device_put; 1617f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1618f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1619f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede err = platform_device_add(abituguru_pdev); 1620f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede if (err) { 162128ebfa13f97265e415fbe19795500a6d922a6c86Joe Perches pr_err("Device addition failed (%d)\n", err); 1622f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede goto exit_device_put; 1623f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede } 1624f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1625f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return 0; 1626f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1627f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedeexit_device_put: 1628f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede platform_device_put(abituguru_pdev); 1629f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedeexit_driver_unregister: 1630f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede platform_driver_unregister(&abituguru_driver); 1631f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedeexit: 1632f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede return err; 1633f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1634f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1635f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedestatic void __exit abituguru_exit(void) 1636f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede{ 1637f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede platform_device_unregister(abituguru_pdev); 1638f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede platform_driver_unregister(&abituguru_driver); 1639f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede} 1640f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 164193d0cc588345a9de304285781e010e298f74e06eHans de GoedeMODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 1642f2b84bbcebfdbe4855bab532909eef6621999f9fHans de GoedeMODULE_DESCRIPTION("Abit uGuru Sensor device"); 1643f2b84bbcebfdbe4855bab532909eef6621999f9fHans de GoedeMODULE_LICENSE("GPL"); 1644f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goede 1645f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedemodule_init(abituguru_init); 1646f2b84bbcebfdbe4855bab532909eef6621999f9fHans de Goedemodule_exit(abituguru_exit); 1647