linux/drivers/hwmon/f71882fg.c
<<
>>
Prefs
   1/***************************************************************************
   2 *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
   3 *   Copyright (C) 2007,2008 by Hans de Goede <hdegoede@redhat.com>        *
   4 *                                                                         *
   5 *   This program is free software; you can redistribute it and/or modify  *
   6 *   it under the terms of the GNU General Public License as published by  *
   7 *   the Free Software Foundation; either version 2 of the License, or     *
   8 *   (at your option) any later version.                                   *
   9 *                                                                         *
  10 *   This program is distributed in the hope that it will be useful,       *
  11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  13 *   GNU General Public License for more details.                          *
  14 *                                                                         *
  15 *   You should have received a copy of the GNU General Public License     *
  16 *   along with this program; if not, write to the                         *
  17 *   Free Software Foundation, Inc.,                                       *
  18 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  19 ***************************************************************************/
  20
  21#include <linux/module.h>
  22#include <linux/init.h>
  23#include <linux/slab.h>
  24#include <linux/jiffies.h>
  25#include <linux/platform_device.h>
  26#include <linux/hwmon.h>
  27#include <linux/hwmon-sysfs.h>
  28#include <linux/err.h>
  29#include <linux/mutex.h>
  30#include <linux/io.h>
  31#include <linux/acpi.h>
  32
  33#define DRVNAME "f71882fg"
  34
  35#define SIO_F71882FG_LD_HWM     0x04    /* Hardware monitor logical device */
  36#define SIO_UNLOCK_KEY          0x87    /* Key to enable Super-I/O */
  37#define SIO_LOCK_KEY            0xAA    /* Key to diasble Super-I/O */
  38
  39#define SIO_REG_LDSEL           0x07    /* Logical device select */
  40#define SIO_REG_DEVID           0x20    /* Device ID (2 bytes) */
  41#define SIO_REG_DEVREV          0x22    /* Device revision */
  42#define SIO_REG_MANID           0x23    /* Fintek ID (2 bytes) */
  43#define SIO_REG_ENABLE          0x30    /* Logical device enable */
  44#define SIO_REG_ADDR            0x60    /* Logical device address (2 bytes) */
  45
  46#define SIO_FINTEK_ID           0x1934  /* Manufacturers ID */
  47#define SIO_F71862_ID           0x0601  /* Chipset ID */
  48#define SIO_F71882_ID           0x0541  /* Chipset ID */
  49#define SIO_F8000_ID            0x0581  /* Chipset ID */
  50
  51#define REGION_LENGTH           8
  52#define ADDR_REG_OFFSET         5
  53#define DATA_REG_OFFSET         6
  54
  55#define F71882FG_REG_PECI               0x0A
  56
  57#define F71882FG_REG_IN_STATUS          0x12 /* f71882fg only */
  58#define F71882FG_REG_IN_BEEP            0x13 /* f71882fg only */
  59#define F71882FG_REG_IN(nr)             (0x20  + (nr))
  60#define F71882FG_REG_IN1_HIGH           0x32 /* f71882fg only */
  61
  62#define F71882FG_REG_FAN(nr)            (0xA0 + (16 * (nr)))
  63#define F71882FG_REG_FAN_TARGET(nr)     (0xA2 + (16 * (nr)))
  64#define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
  65#define F71882FG_REG_FAN_STATUS         0x92
  66#define F71882FG_REG_FAN_BEEP           0x93
  67
  68#define F71882FG_REG_TEMP(nr)           (0x70 + 2 * (nr))
  69#define F71882FG_REG_TEMP_OVT(nr)       (0x80 + 2 * (nr))
  70#define F71882FG_REG_TEMP_HIGH(nr)      (0x81 + 2 * (nr))
  71#define F71882FG_REG_TEMP_STATUS        0x62
  72#define F71882FG_REG_TEMP_BEEP          0x63
  73#define F71882FG_REG_TEMP_HYST(nr)      (0x6C + (nr))
  74#define F71882FG_REG_TEMP_TYPE          0x6B
  75#define F71882FG_REG_TEMP_DIODE_OPEN    0x6F
  76
  77#define F71882FG_REG_PWM(nr)            (0xA3 + (16 * (nr)))
  78#define F71882FG_REG_PWM_TYPE           0x94
  79#define F71882FG_REG_PWM_ENABLE         0x96
  80
  81#define F71882FG_REG_FAN_HYST(nr)       (0x98 + (nr))
  82
  83#define F71882FG_REG_POINT_PWM(pwm, point)      (0xAA + (point) + (16 * (pwm)))
  84#define F71882FG_REG_POINT_TEMP(pwm, point)     (0xA6 + (point) + (16 * (pwm)))
  85#define F71882FG_REG_POINT_MAPPING(nr)          (0xAF + 16 * (nr))
  86
  87#define F71882FG_REG_START              0x01
  88
  89#define FAN_MIN_DETECT                  366 /* Lowest detectable fanspeed */
  90
  91static unsigned short force_id;
  92module_param(force_id, ushort, 0);
  93MODULE_PARM_DESC(force_id, "Override the detected device ID");
  94
  95enum chips { f71862fg, f71882fg, f8000 };
  96
  97static const char *f71882fg_names[] = {
  98        "f71862fg",
  99        "f71882fg",
 100        "f8000",
 101};
 102
 103static struct platform_device *f71882fg_pdev;
 104
 105/* Super-I/O Function prototypes */
 106static inline int superio_inb(int base, int reg);
 107static inline int superio_inw(int base, int reg);
 108static inline void superio_enter(int base);
 109static inline void superio_select(int base, int ld);
 110static inline void superio_exit(int base);
 111
 112struct f71882fg_sio_data {
 113        enum chips type;
 114};
 115
 116struct f71882fg_data {
 117        unsigned short addr;
 118        enum chips type;
 119        struct device *hwmon_dev;
 120
 121        struct mutex update_lock;
 122        char valid;                     /* !=0 if following fields are valid */
 123        unsigned long last_updated;     /* In jiffies */
 124        unsigned long last_limits;      /* In jiffies */
 125
 126        /* Register Values */
 127        u8      in[9];
 128        u8      in1_max;
 129        u8      in_status;
 130        u8      in_beep;
 131        u16     fan[4];
 132        u16     fan_target[4];
 133        u16     fan_full_speed[4];
 134        u8      fan_status;
 135        u8      fan_beep;
 136        /* Note: all models have only 3 temperature channels, but on some
 137           they are addressed as 0-2 and on others as 1-3, so for coding
 138           convenience we reserve space for 4 channels */
 139        u8      temp[4];
 140        u8      temp_ovt[4];
 141        u8      temp_high[4];
 142        u8      temp_hyst[2]; /* 2 hysts stored per reg */
 143        u8      temp_type[4];
 144        u8      temp_status;
 145        u8      temp_beep;
 146        u8      temp_diode_open;
 147        u8      pwm[4];
 148        u8      pwm_enable;
 149        u8      pwm_auto_point_hyst[2];
 150        u8      pwm_auto_point_mapping[4];
 151        u8      pwm_auto_point_pwm[4][5];
 152        u8      pwm_auto_point_temp[4][4];
 153};
 154
 155/* Sysfs in */
 156static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
 157        char *buf);
 158static ssize_t show_in_max(struct device *dev, struct device_attribute
 159        *devattr, char *buf);
 160static ssize_t store_in_max(struct device *dev, struct device_attribute
 161        *devattr, const char *buf, size_t count);
 162static ssize_t show_in_beep(struct device *dev, struct device_attribute
 163        *devattr, char *buf);
 164static ssize_t store_in_beep(struct device *dev, struct device_attribute
 165        *devattr, const char *buf, size_t count);
 166static ssize_t show_in_alarm(struct device *dev, struct device_attribute
 167        *devattr, char *buf);
 168/* Sysfs Fan */
 169static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
 170        char *buf);
 171static ssize_t show_fan_full_speed(struct device *dev,
 172        struct device_attribute *devattr, char *buf);
 173static ssize_t store_fan_full_speed(struct device *dev,
 174        struct device_attribute *devattr, const char *buf, size_t count);
 175static ssize_t show_fan_beep(struct device *dev, struct device_attribute
 176        *devattr, char *buf);
 177static ssize_t store_fan_beep(struct device *dev, struct device_attribute
 178        *devattr, const char *buf, size_t count);
 179static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
 180        *devattr, char *buf);
 181/* Sysfs Temp */
 182static ssize_t show_temp(struct device *dev, struct device_attribute
 183        *devattr, char *buf);
 184static ssize_t show_temp_max(struct device *dev, struct device_attribute
 185        *devattr, char *buf);
 186static ssize_t store_temp_max(struct device *dev, struct device_attribute
 187        *devattr, const char *buf, size_t count);
 188static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
 189        *devattr, char *buf);
 190static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
 191        *devattr, const char *buf, size_t count);
 192static ssize_t show_temp_crit(struct device *dev, struct device_attribute
 193        *devattr, char *buf);
 194static ssize_t store_temp_crit(struct device *dev, struct device_attribute
 195        *devattr, const char *buf, size_t count);
 196static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
 197        *devattr, char *buf);
 198static ssize_t show_temp_type(struct device *dev, struct device_attribute
 199        *devattr, char *buf);
 200static ssize_t show_temp_beep(struct device *dev, struct device_attribute
 201        *devattr, char *buf);
 202static ssize_t store_temp_beep(struct device *dev, struct device_attribute
 203        *devattr, const char *buf, size_t count);
 204static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
 205        *devattr, char *buf);
 206static ssize_t show_temp_fault(struct device *dev, struct device_attribute
 207        *devattr, char *buf);
 208/* PWM and Auto point control */
 209static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
 210        char *buf);
 211static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
 212        const char *buf, size_t count);
 213static ssize_t show_pwm_enable(struct device *dev,
 214        struct device_attribute *devattr, char *buf);
 215static ssize_t store_pwm_enable(struct device *dev,
 216        struct device_attribute *devattr, const char *buf, size_t count);
 217static ssize_t show_pwm_interpolate(struct device *dev,
 218        struct device_attribute *devattr, char *buf);
 219static ssize_t store_pwm_interpolate(struct device *dev,
 220        struct device_attribute *devattr, const char *buf, size_t count);
 221static ssize_t show_pwm_auto_point_channel(struct device *dev,
 222        struct device_attribute *devattr, char *buf);
 223static ssize_t store_pwm_auto_point_channel(struct device *dev,
 224        struct device_attribute *devattr, const char *buf, size_t count);
 225static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
 226        struct device_attribute *devattr, char *buf);
 227static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
 228        struct device_attribute *devattr, const char *buf, size_t count);
 229static ssize_t show_pwm_auto_point_pwm(struct device *dev,
 230        struct device_attribute *devattr, char *buf);
 231static ssize_t store_pwm_auto_point_pwm(struct device *dev,
 232        struct device_attribute *devattr, const char *buf, size_t count);
 233static ssize_t show_pwm_auto_point_temp(struct device *dev,
 234        struct device_attribute *devattr, char *buf);
 235static ssize_t store_pwm_auto_point_temp(struct device *dev,
 236        struct device_attribute *devattr, const char *buf, size_t count);
 237/* Sysfs misc */
 238static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
 239        char *buf);
 240
 241static int __devinit f71882fg_probe(struct platform_device * pdev);
 242static int f71882fg_remove(struct platform_device *pdev);
 243
 244static struct platform_driver f71882fg_driver = {
 245        .driver = {
 246                .owner  = THIS_MODULE,
 247                .name   = DRVNAME,
 248        },
 249        .probe          = f71882fg_probe,
 250        .remove         = __devexit_p(f71882fg_remove),
 251};
 252
 253static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 254
 255/* Temp and in attr common to both the f71862fg and f71882fg */
 256static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
 257        SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 258        SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 259        SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
 260        SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
 261        SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
 262        SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
 263        SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
 264        SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
 265        SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
 266        SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
 267        SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
 268                store_temp_max, 0, 1),
 269        SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
 270                store_temp_max_hyst, 0, 1),
 271        /* Should really be temp1_max_alarm, but older versions did not handle
 272           the max and crit alarms separately and lm_sensors v2 depends on the
 273           presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
 274        SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
 275        SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
 276                store_temp_beep, 0, 1),
 277        SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
 278                store_temp_crit, 0, 1),
 279        SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
 280                0, 1),
 281        SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
 282        SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
 283                store_temp_beep, 0, 5),
 284        SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
 285        SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
 286        SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
 287        SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
 288                store_temp_max, 0, 2),
 289        SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
 290                store_temp_max_hyst, 0, 2),
 291        /* Should be temp2_max_alarm, see temp1_alarm note */
 292        SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
 293        SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
 294                store_temp_beep, 0, 2),
 295        SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
 296                store_temp_crit, 0, 2),
 297        SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
 298                0, 2),
 299        SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
 300        SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
 301                store_temp_beep, 0, 6),
 302        SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
 303        SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 304        SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
 305        SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
 306                store_temp_max, 0, 3),
 307        SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
 308                store_temp_max_hyst, 0, 3),
 309        /* Should be temp3_max_alarm, see temp1_alarm note */
 310        SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
 311        SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
 312                store_temp_beep, 0, 3),
 313        SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
 314                store_temp_crit, 0, 3),
 315        SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
 316                0, 3),
 317        SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
 318        SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
 319                store_temp_beep, 0, 7),
 320        SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
 321        SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
 322};
 323
 324/* Temp and in attr found only on the f71882fg */
 325static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
 326        SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
 327                0, 1),
 328        SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
 329                0, 1),
 330        SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
 331};
 332
 333/* Temp and in attr for the f8000
 334   Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
 335   is used as hysteresis value to clear alarms
 336 */
 337static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
 338        SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 339        SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 340        SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
 341        SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
 342        SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
 343                store_temp_crit, 0, 0),
 344        SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
 345                store_temp_max, 0, 0),
 346        SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
 347        SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
 348        SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
 349                store_temp_crit, 0, 1),
 350        SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
 351                store_temp_max, 0, 1),
 352        SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
 353        SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
 354        SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
 355        SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
 356                store_temp_crit, 0, 2),
 357        SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
 358                store_temp_max, 0, 2),
 359        SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
 360};
 361
 362/* Fan / PWM attr common to all models */
 363static struct sensor_device_attribute_2 fxxxx_fan_attr[] = {
 364        SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
 365        SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
 366                      show_fan_full_speed,
 367                      store_fan_full_speed, 0, 0),
 368        SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
 369        SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
 370        SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
 371                      show_fan_full_speed,
 372                      store_fan_full_speed, 0, 1),
 373        SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
 374        SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
 375        SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
 376                      show_fan_full_speed,
 377                      store_fan_full_speed, 0, 2),
 378        SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
 379
 380        SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
 381        SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 382                      store_pwm_enable, 0, 0),
 383        SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
 384                      show_pwm_interpolate, store_pwm_interpolate, 0, 0),
 385        SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
 386                      show_pwm_auto_point_channel,
 387                      store_pwm_auto_point_channel, 0, 0),
 388
 389        SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
 390        SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 391                      store_pwm_enable, 0, 1),
 392        SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
 393                      show_pwm_interpolate, store_pwm_interpolate, 0, 1),
 394        SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
 395                      show_pwm_auto_point_channel,
 396                      store_pwm_auto_point_channel, 0, 1),
 397
 398        SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
 399                      show_pwm_interpolate, store_pwm_interpolate, 0, 2),
 400        SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
 401                      show_pwm_auto_point_channel,
 402                      store_pwm_auto_point_channel, 0, 2),
 403};
 404
 405/* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the
 406   f71882fg */
 407static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
 408        SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 409                store_fan_beep, 0, 0),
 410        SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 411                store_fan_beep, 0, 1),
 412        SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 413                store_fan_beep, 0, 2),
 414
 415        SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 416                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 417                      1, 0),
 418        SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
 419                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 420                      4, 0),
 421        SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
 422                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 423                      0, 0),
 424        SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
 425                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 426                      3, 0),
 427        SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 428                      show_pwm_auto_point_temp_hyst,
 429                      store_pwm_auto_point_temp_hyst,
 430                      0, 0),
 431        SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
 432                      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
 433
 434        SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 435                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 436                      1, 1),
 437        SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
 438                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 439                      4, 1),
 440        SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
 441                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 442                      0, 1),
 443        SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
 444                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 445                      3, 1),
 446        SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 447                      show_pwm_auto_point_temp_hyst,
 448                      store_pwm_auto_point_temp_hyst,
 449                      0, 1),
 450        SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
 451                      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
 452
 453        SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
 454        SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 455                      store_pwm_enable, 0, 2),
 456        SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 457                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 458                      1, 2),
 459        SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
 460                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 461                      4, 2),
 462        SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
 463                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 464                      0, 2),
 465        SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
 466                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 467                      3, 2),
 468        SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 469                      show_pwm_auto_point_temp_hyst,
 470                      store_pwm_auto_point_temp_hyst,
 471                      0, 2),
 472        SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
 473                      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
 474};
 475
 476/* Fan / PWM attr for the f71882fg */
 477static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
 478        SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 479                store_fan_beep, 0, 0),
 480        SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 481                store_fan_beep, 0, 1),
 482        SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 483                store_fan_beep, 0, 2),
 484        SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
 485        SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
 486                      show_fan_full_speed,
 487                      store_fan_full_speed, 0, 3),
 488        SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 489                store_fan_beep, 0, 3),
 490        SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
 491
 492        SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 493                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 494                      0, 0),
 495        SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
 496                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 497                      1, 0),
 498        SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
 499                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 500                      2, 0),
 501        SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
 502                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 503                      3, 0),
 504        SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
 505                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 506                      4, 0),
 507        SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
 508                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 509                      0, 0),
 510        SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
 511                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 512                      1, 0),
 513        SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
 514                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 515                      2, 0),
 516        SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
 517                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 518                      3, 0),
 519        SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 520                      show_pwm_auto_point_temp_hyst,
 521                      store_pwm_auto_point_temp_hyst,
 522                      0, 0),
 523        SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
 524                      show_pwm_auto_point_temp_hyst, NULL, 1, 0),
 525        SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
 526                      show_pwm_auto_point_temp_hyst, NULL, 2, 0),
 527        SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
 528                      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
 529
 530        SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 531                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 532                      0, 1),
 533        SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
 534                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 535                      1, 1),
 536        SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
 537                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 538                      2, 1),
 539        SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
 540                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 541                      3, 1),
 542        SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
 543                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 544                      4, 1),
 545        SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
 546                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 547                      0, 1),
 548        SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
 549                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 550                      1, 1),
 551        SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
 552                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 553                      2, 1),
 554        SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
 555                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 556                      3, 1),
 557        SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 558                      show_pwm_auto_point_temp_hyst,
 559                      store_pwm_auto_point_temp_hyst,
 560                      0, 1),
 561        SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
 562                      show_pwm_auto_point_temp_hyst, NULL, 1, 1),
 563        SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
 564                      show_pwm_auto_point_temp_hyst, NULL, 2, 1),
 565        SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
 566                      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
 567
 568        SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
 569        SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 570                      store_pwm_enable, 0, 2),
 571        SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 572                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 573                      0, 2),
 574        SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
 575                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 576                      1, 2),
 577        SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
 578                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 579                      2, 2),
 580        SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
 581                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 582                      3, 2),
 583        SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
 584                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 585                      4, 2),
 586        SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
 587                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 588                      0, 2),
 589        SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
 590                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 591                      1, 2),
 592        SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
 593                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 594                      2, 2),
 595        SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
 596                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 597                      3, 2),
 598        SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 599                      show_pwm_auto_point_temp_hyst,
 600                      store_pwm_auto_point_temp_hyst,
 601                      0, 2),
 602        SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
 603                      show_pwm_auto_point_temp_hyst, NULL, 1, 2),
 604        SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
 605                      show_pwm_auto_point_temp_hyst, NULL, 2, 2),
 606        SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
 607                      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
 608
 609        SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
 610        SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
 611                      store_pwm_enable, 0, 3),
 612        SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
 613                      show_pwm_interpolate, store_pwm_interpolate, 0, 3),
 614        SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
 615                      show_pwm_auto_point_channel,
 616                      store_pwm_auto_point_channel, 0, 3),
 617        SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
 618                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 619                      0, 3),
 620        SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
 621                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 622                      1, 3),
 623        SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
 624                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 625                      2, 3),
 626        SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
 627                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 628                      3, 3),
 629        SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
 630                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 631                      4, 3),
 632        SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
 633                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 634                      0, 3),
 635        SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
 636                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 637                      1, 3),
 638        SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
 639                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 640                      2, 3),
 641        SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
 642                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 643                      3, 3),
 644        SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 645                      show_pwm_auto_point_temp_hyst,
 646                      store_pwm_auto_point_temp_hyst,
 647                      0, 3),
 648        SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
 649                      show_pwm_auto_point_temp_hyst, NULL, 1, 3),
 650        SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
 651                      show_pwm_auto_point_temp_hyst, NULL, 2, 3),
 652        SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
 653                      show_pwm_auto_point_temp_hyst, NULL, 3, 3),
 654};
 655
 656/* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm!
 657   Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
 658   F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
 659static struct sensor_device_attribute_2 f8000_fan_attr[] = {
 660        SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
 661
 662        SENSOR_ATTR_2(pwm3, S_IRUGO, show_pwm, NULL, 0, 2),
 663
 664        SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
 665                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 666                      0, 2),
 667        SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
 668                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 669                      1, 2),
 670        SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
 671                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 672                      2, 2),
 673        SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
 674                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 675                      3, 2),
 676        SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
 677                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 678                      4, 2),
 679        SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
 680                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 681                      0, 2),
 682        SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
 683                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 684                      1, 2),
 685        SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
 686                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 687                      2, 2),
 688        SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
 689                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 690                      3, 2),
 691        SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 692                      show_pwm_auto_point_temp_hyst,
 693                      store_pwm_auto_point_temp_hyst,
 694                      0, 2),
 695        SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
 696                      show_pwm_auto_point_temp_hyst, NULL, 1, 2),
 697        SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
 698                      show_pwm_auto_point_temp_hyst, NULL, 2, 2),
 699        SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
 700                      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
 701
 702        SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
 703                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 704                      0, 0),
 705        SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
 706                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 707                      1, 0),
 708        SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
 709                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 710                      2, 0),
 711        SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
 712                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 713                      3, 0),
 714        SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
 715                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 716                      4, 0),
 717        SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
 718                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 719                      0, 0),
 720        SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
 721                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 722                      1, 0),
 723        SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
 724                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 725                      2, 0),
 726        SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
 727                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 728                      3, 0),
 729        SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 730                      show_pwm_auto_point_temp_hyst,
 731                      store_pwm_auto_point_temp_hyst,
 732                      0, 0),
 733        SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
 734                      show_pwm_auto_point_temp_hyst, NULL, 1, 0),
 735        SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
 736                      show_pwm_auto_point_temp_hyst, NULL, 2, 0),
 737        SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
 738                      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
 739
 740        SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
 741                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 742                      0, 1),
 743        SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
 744                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 745                      1, 1),
 746        SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
 747                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 748                      2, 1),
 749        SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
 750                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 751                      3, 1),
 752        SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
 753                      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
 754                      4, 1),
 755        SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
 756                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 757                      0, 1),
 758        SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
 759                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 760                      1, 1),
 761        SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
 762                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 763                      2, 1),
 764        SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
 765                      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
 766                      3, 1),
 767        SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
 768                      show_pwm_auto_point_temp_hyst,
 769                      store_pwm_auto_point_temp_hyst,
 770                      0, 1),
 771        SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
 772                      show_pwm_auto_point_temp_hyst, NULL, 1, 1),
 773        SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
 774                      show_pwm_auto_point_temp_hyst, NULL, 2, 1),
 775        SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
 776                      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
 777};
 778
 779/* Super I/O functions */
 780static inline int superio_inb(int base, int reg)
 781{
 782        outb(reg, base);
 783        return inb(base + 1);
 784}
 785
 786static int superio_inw(int base, int reg)
 787{
 788        int val;
 789        outb(reg++, base);
 790        val = inb(base + 1) << 8;
 791        outb(reg, base);
 792        val |= inb(base + 1);
 793        return val;
 794}
 795
 796static inline void superio_enter(int base)
 797{
 798        /* according to the datasheet the key must be send twice! */
 799        outb( SIO_UNLOCK_KEY, base);
 800        outb( SIO_UNLOCK_KEY, base);
 801}
 802
 803static inline void superio_select( int base, int ld)
 804{
 805        outb(SIO_REG_LDSEL, base);
 806        outb(ld, base + 1);
 807}
 808
 809static inline void superio_exit(int base)
 810{
 811        outb(SIO_LOCK_KEY, base);
 812}
 813
 814static inline int fan_from_reg(u16 reg)
 815{
 816        return reg ? (1500000 / reg) : 0;
 817}
 818
 819static inline u16 fan_to_reg(int fan)
 820{
 821        return fan ? (1500000 / fan) : 0;
 822}
 823
 824static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
 825{
 826        u8 val;
 827
 828        outb(reg, data->addr + ADDR_REG_OFFSET);
 829        val = inb(data->addr + DATA_REG_OFFSET);
 830
 831        return val;
 832}
 833
 834static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
 835{
 836        u16 val;
 837
 838        outb(reg++, data->addr + ADDR_REG_OFFSET);
 839        val = inb(data->addr + DATA_REG_OFFSET) << 8;
 840        outb(reg, data->addr + ADDR_REG_OFFSET);
 841        val |= inb(data->addr + DATA_REG_OFFSET);
 842
 843        return val;
 844}
 845
 846static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
 847{
 848        outb(reg, data->addr + ADDR_REG_OFFSET);
 849        outb(val, data->addr + DATA_REG_OFFSET);
 850}
 851
 852static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
 853{
 854        outb(reg++, data->addr + ADDR_REG_OFFSET);
 855        outb(val >> 8, data->addr + DATA_REG_OFFSET);
 856        outb(reg, data->addr + ADDR_REG_OFFSET);
 857        outb(val & 255, data->addr + DATA_REG_OFFSET);
 858}
 859
 860static struct f71882fg_data *f71882fg_update_device(struct device *dev)
 861{
 862        struct f71882fg_data *data = dev_get_drvdata(dev);
 863        int nr, reg = 0, reg2;
 864        int nr_fans = (data->type == f71882fg) ? 4 : 3;
 865        int nr_ins = (data->type == f8000) ? 3 : 9;
 866        int temp_start = (data->type == f8000) ? 0 : 1;
 867
 868        mutex_lock(&data->update_lock);
 869
 870        /* Update once every 60 seconds */
 871        if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
 872                        !data->valid) {
 873                if (data->type == f71882fg) {
 874                        data->in1_max =
 875                                f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
 876                        data->in_beep =
 877                                f71882fg_read8(data, F71882FG_REG_IN_BEEP);
 878                }
 879
 880                /* Get High & boundary temps*/
 881                for (nr = temp_start; nr < 3 + temp_start; nr++) {
 882                        data->temp_ovt[nr] = f71882fg_read8(data,
 883                                                F71882FG_REG_TEMP_OVT(nr));
 884                        data->temp_high[nr] = f71882fg_read8(data,
 885                                                F71882FG_REG_TEMP_HIGH(nr));
 886                }
 887
 888                if (data->type != f8000) {
 889                        data->fan_beep = f71882fg_read8(data,
 890                                                F71882FG_REG_FAN_BEEP);
 891                        data->temp_beep = f71882fg_read8(data,
 892                                                F71882FG_REG_TEMP_BEEP);
 893                        data->temp_hyst[0] = f71882fg_read8(data,
 894                                                F71882FG_REG_TEMP_HYST(0));
 895                        data->temp_hyst[1] = f71882fg_read8(data,
 896                                                F71882FG_REG_TEMP_HYST(1));
 897                        /* Have to hardcode type, because temp1 is special */
 898                        reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
 899                        data->temp_type[2] = (reg & 0x04) ? 2 : 4;
 900                        data->temp_type[3] = (reg & 0x08) ? 2 : 4;
 901                }
 902                reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
 903                if ((reg2 & 0x03) == 0x01)
 904                        data->temp_type[1] = 6 /* PECI */;
 905                else if ((reg2 & 0x03) == 0x02)
 906                        data->temp_type[1] = 5 /* AMDSI */;
 907                else if (data->type != f8000)
 908                        data->temp_type[1] = (reg & 0x02) ? 2 : 4;
 909                else
 910                        data->temp_type[1] = 2; /* F8000 only supports BJT */
 911
 912                data->pwm_enable = f71882fg_read8(data,
 913                                                  F71882FG_REG_PWM_ENABLE);
 914                data->pwm_auto_point_hyst[0] =
 915                        f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
 916                data->pwm_auto_point_hyst[1] =
 917                        f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
 918
 919                for (nr = 0; nr < nr_fans; nr++) {
 920                        data->pwm_auto_point_mapping[nr] =
 921                            f71882fg_read8(data,
 922                                           F71882FG_REG_POINT_MAPPING(nr));
 923
 924                        if (data->type != f71862fg) {
 925                                int point;
 926                                for (point = 0; point < 5; point++) {
 927                                        data->pwm_auto_point_pwm[nr][point] =
 928                                                f71882fg_read8(data,
 929                                                        F71882FG_REG_POINT_PWM
 930                                                        (nr, point));
 931                                }
 932                                for (point = 0; point < 4; point++) {
 933                                        data->pwm_auto_point_temp[nr][point] =
 934                                                f71882fg_read8(data,
 935                                                        F71882FG_REG_POINT_TEMP
 936                                                        (nr, point));
 937                                }
 938                        } else {
 939                                data->pwm_auto_point_pwm[nr][1] =
 940                                        f71882fg_read8(data,
 941                                                F71882FG_REG_POINT_PWM
 942                                                (nr, 1));
 943                                data->pwm_auto_point_pwm[nr][4] =
 944                                        f71882fg_read8(data,
 945                                                F71882FG_REG_POINT_PWM
 946                                                (nr, 4));
 947                                data->pwm_auto_point_temp[nr][0] =
 948                                        f71882fg_read8(data,
 949                                                F71882FG_REG_POINT_TEMP
 950                                                (nr, 0));
 951                                data->pwm_auto_point_temp[nr][3] =
 952                                        f71882fg_read8(data,
 953                                                F71882FG_REG_POINT_TEMP
 954                                                (nr, 3));
 955                        }
 956                }
 957                data->last_limits = jiffies;
 958        }
 959
 960        /* Update every second */
 961        if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
 962                data->temp_status = f71882fg_read8(data,
 963                                                F71882FG_REG_TEMP_STATUS);
 964                data->temp_diode_open = f71882fg_read8(data,
 965                                                F71882FG_REG_TEMP_DIODE_OPEN);
 966                for (nr = temp_start; nr < 3 + temp_start; nr++)
 967                        data->temp[nr] = f71882fg_read8(data,
 968                                                F71882FG_REG_TEMP(nr));
 969
 970                data->fan_status = f71882fg_read8(data,
 971                                                F71882FG_REG_FAN_STATUS);
 972                for (nr = 0; nr < nr_fans; nr++) {
 973                        data->fan[nr] = f71882fg_read16(data,
 974                                                F71882FG_REG_FAN(nr));
 975                        data->fan_target[nr] =
 976                            f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
 977                        data->fan_full_speed[nr] =
 978                            f71882fg_read16(data,
 979                                            F71882FG_REG_FAN_FULL_SPEED(nr));
 980                        data->pwm[nr] =
 981                            f71882fg_read8(data, F71882FG_REG_PWM(nr));
 982                }
 983
 984                /* The f8000 can monitor 1 more fan, but has no pwm for it */
 985                if (data->type == f8000)
 986                        data->fan[3] = f71882fg_read16(data,
 987                                                F71882FG_REG_FAN(3));
 988                if (data->type == f71882fg)
 989                        data->in_status = f71882fg_read8(data,
 990                                                F71882FG_REG_IN_STATUS);
 991                for (nr = 0; nr < nr_ins; nr++)
 992                        data->in[nr] = f71882fg_read8(data,
 993                                                F71882FG_REG_IN(nr));
 994
 995                data->last_updated = jiffies;
 996                data->valid = 1;
 997        }
 998
 999        mutex_unlock(&data->update_lock);
1000
1001        return data;
1002}
1003
1004/* Sysfs Interface */
1005static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
1006        char *buf)
1007{
1008        struct f71882fg_data *data = f71882fg_update_device(dev);
1009        int nr = to_sensor_dev_attr_2(devattr)->index;
1010        int speed = fan_from_reg(data->fan[nr]);
1011
1012        if (speed == FAN_MIN_DETECT)
1013                speed = 0;
1014
1015        return sprintf(buf, "%d\n", speed);
1016}
1017
1018static ssize_t show_fan_full_speed(struct device *dev,
1019                                   struct device_attribute *devattr, char *buf)
1020{
1021        struct f71882fg_data *data = f71882fg_update_device(dev);
1022        int nr = to_sensor_dev_attr_2(devattr)->index;
1023        int speed = fan_from_reg(data->fan_full_speed[nr]);
1024        return sprintf(buf, "%d\n", speed);
1025}
1026
1027static ssize_t store_fan_full_speed(struct device *dev,
1028                                    struct device_attribute *devattr,
1029                                    const char *buf, size_t count)
1030{
1031        struct f71882fg_data *data = dev_get_drvdata(dev);
1032        int nr = to_sensor_dev_attr_2(devattr)->index;
1033        long val = simple_strtol(buf, NULL, 10);
1034
1035        val = SENSORS_LIMIT(val, 23, 1500000);
1036        val = fan_to_reg(val);
1037
1038        mutex_lock(&data->update_lock);
1039        f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
1040        data->fan_full_speed[nr] = val;
1041        mutex_unlock(&data->update_lock);
1042
1043        return count;
1044}
1045
1046static ssize_t show_fan_beep(struct device *dev, struct device_attribute
1047        *devattr, char *buf)
1048{
1049        struct f71882fg_data *data = f71882fg_update_device(dev);
1050        int nr = to_sensor_dev_attr_2(devattr)->index;
1051
1052        if (data->fan_beep & (1 << nr))
1053                return sprintf(buf, "1\n");
1054        else
1055                return sprintf(buf, "0\n");
1056}
1057
1058static ssize_t store_fan_beep(struct device *dev, struct device_attribute
1059        *devattr, const char *buf, size_t count)
1060{
1061        struct f71882fg_data *data = dev_get_drvdata(dev);
1062        int nr = to_sensor_dev_attr_2(devattr)->index;
1063        unsigned long val = simple_strtoul(buf, NULL, 10);
1064
1065        mutex_lock(&data->update_lock);
1066        data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
1067        if (val)
1068                data->fan_beep |= 1 << nr;
1069        else
1070                data->fan_beep &= ~(1 << nr);
1071
1072        f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
1073        mutex_unlock(&data->update_lock);
1074
1075        return count;
1076}
1077
1078static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
1079        *devattr, char *buf)
1080{
1081        struct f71882fg_data *data = f71882fg_update_device(dev);
1082        int nr = to_sensor_dev_attr_2(devattr)->index;
1083
1084        if (data->fan_status & (1 << nr))
1085                return sprintf(buf, "1\n");
1086        else
1087                return sprintf(buf, "0\n");
1088}
1089
1090static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
1091        char *buf)
1092{
1093        struct f71882fg_data *data = f71882fg_update_device(dev);
1094        int nr = to_sensor_dev_attr_2(devattr)->index;
1095
1096        return sprintf(buf, "%d\n", data->in[nr] * 8);
1097}
1098
1099static ssize_t show_in_max(struct device *dev, struct device_attribute
1100        *devattr, char *buf)
1101{
1102        struct f71882fg_data *data = f71882fg_update_device(dev);
1103
1104        return sprintf(buf, "%d\n", data->in1_max * 8);
1105}
1106
1107static ssize_t store_in_max(struct device *dev, struct device_attribute
1108        *devattr, const char *buf, size_t count)
1109{
1110        struct f71882fg_data *data = dev_get_drvdata(dev);
1111        long val = simple_strtol(buf, NULL, 10) / 8;
1112        val = SENSORS_LIMIT(val, 0, 255);
1113
1114        mutex_lock(&data->update_lock);
1115        f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
1116        data->in1_max = val;
1117        mutex_unlock(&data->update_lock);
1118
1119        return count;
1120}
1121
1122static ssize_t show_in_beep(struct device *dev, struct device_attribute
1123        *devattr, char *buf)
1124{
1125        struct f71882fg_data *data = f71882fg_update_device(dev);
1126        int nr = to_sensor_dev_attr_2(devattr)->index;
1127
1128        if (data->in_beep & (1 << nr))
1129                return sprintf(buf, "1\n");
1130        else
1131                return sprintf(buf, "0\n");
1132}
1133
1134static ssize_t store_in_beep(struct device *dev, struct device_attribute
1135        *devattr, const char *buf, size_t count)
1136{
1137        struct f71882fg_data *data = dev_get_drvdata(dev);
1138        int nr = to_sensor_dev_attr_2(devattr)->index;
1139        unsigned long val = simple_strtoul(buf, NULL, 10);
1140
1141        mutex_lock(&data->update_lock);
1142        data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
1143        if (val)
1144                data->in_beep |= 1 << nr;
1145        else
1146                data->in_beep &= ~(1 << nr);
1147
1148        f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
1149        mutex_unlock(&data->update_lock);
1150
1151        return count;
1152}
1153
1154static ssize_t show_in_alarm(struct device *dev, struct device_attribute
1155        *devattr, char *buf)
1156{
1157        struct f71882fg_data *data = f71882fg_update_device(dev);
1158        int nr = to_sensor_dev_attr_2(devattr)->index;
1159
1160        if (data->in_status & (1 << nr))
1161                return sprintf(buf, "1\n");
1162        else
1163                return sprintf(buf, "0\n");
1164}
1165
1166static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1167        char *buf)
1168{
1169        struct f71882fg_data *data = f71882fg_update_device(dev);
1170        int nr = to_sensor_dev_attr_2(devattr)->index;
1171
1172        return sprintf(buf, "%d\n", data->temp[nr] * 1000);
1173}
1174
1175static ssize_t show_temp_max(struct device *dev, struct device_attribute
1176        *devattr, char *buf)
1177{
1178        struct f71882fg_data *data = f71882fg_update_device(dev);
1179        int nr = to_sensor_dev_attr_2(devattr)->index;
1180
1181        return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
1182}
1183
1184static ssize_t store_temp_max(struct device *dev, struct device_attribute
1185        *devattr, const char *buf, size_t count)
1186{
1187        struct f71882fg_data *data = dev_get_drvdata(dev);
1188        int nr = to_sensor_dev_attr_2(devattr)->index;
1189        long val = simple_strtol(buf, NULL, 10) / 1000;
1190        val = SENSORS_LIMIT(val, 0, 255);
1191
1192        mutex_lock(&data->update_lock);
1193        f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
1194        data->temp_high[nr] = val;
1195        mutex_unlock(&data->update_lock);
1196
1197        return count;
1198}
1199
1200static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
1201        *devattr, char *buf)
1202{
1203        struct f71882fg_data *data = f71882fg_update_device(dev);
1204        int nr = to_sensor_dev_attr_2(devattr)->index;
1205        int temp_max_hyst;
1206
1207        mutex_lock(&data->update_lock);
1208        if (nr & 1)
1209                temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
1210        else
1211                temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
1212        temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
1213        mutex_unlock(&data->update_lock);
1214
1215        return sprintf(buf, "%d\n", temp_max_hyst);
1216}
1217
1218static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
1219        *devattr, const char *buf, size_t count)
1220{
1221        struct f71882fg_data *data = dev_get_drvdata(dev);
1222        int nr = to_sensor_dev_attr_2(devattr)->index;
1223        long val = simple_strtol(buf, NULL, 10) / 1000;
1224        ssize_t ret = count;
1225        u8 reg;
1226
1227        mutex_lock(&data->update_lock);
1228
1229        /* convert abs to relative and check */
1230        data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
1231        val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
1232                            data->temp_high[nr]);
1233        val = data->temp_high[nr] - val;
1234
1235        /* convert value to register contents */
1236        reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
1237        if (nr & 1)
1238                reg = (reg & 0x0f) | (val << 4);
1239        else
1240                reg = (reg & 0xf0) | val;
1241        f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
1242        data->temp_hyst[nr / 2] = reg;
1243
1244        mutex_unlock(&data->update_lock);
1245        return ret;
1246}
1247
1248static ssize_t show_temp_crit(struct device *dev, struct device_attribute
1249        *devattr, char *buf)
1250{
1251        struct f71882fg_data *data = f71882fg_update_device(dev);
1252        int nr = to_sensor_dev_attr_2(devattr)->index;
1253
1254        return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
1255}
1256
1257static ssize_t store_temp_crit(struct device *dev, struct device_attribute
1258        *devattr, const char *buf, size_t count)
1259{
1260        struct f71882fg_data *data = dev_get_drvdata(dev);
1261        int nr = to_sensor_dev_attr_2(devattr)->index;
1262        long val = simple_strtol(buf, NULL, 10) / 1000;
1263        val = SENSORS_LIMIT(val, 0, 255);
1264
1265        mutex_lock(&data->update_lock);
1266        f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
1267        data->temp_ovt[nr] = val;
1268        mutex_unlock(&data->update_lock);
1269
1270        return count;
1271}
1272
1273static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
1274        *devattr, char *buf)
1275{
1276        struct f71882fg_data *data = f71882fg_update_device(dev);
1277        int nr = to_sensor_dev_attr_2(devattr)->index;
1278        int temp_crit_hyst;
1279
1280        mutex_lock(&data->update_lock);
1281        if (nr & 1)
1282                temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
1283        else
1284                temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
1285        temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
1286        mutex_unlock(&data->update_lock);
1287
1288        return sprintf(buf, "%d\n", temp_crit_hyst);
1289}
1290
1291static ssize_t show_temp_type(struct device *dev, struct device_attribute
1292        *devattr, char *buf)
1293{
1294        struct f71882fg_data *data = f71882fg_update_device(dev);
1295        int nr = to_sensor_dev_attr_2(devattr)->index;
1296
1297        return sprintf(buf, "%d\n", data->temp_type[nr]);
1298}
1299
1300static ssize_t show_temp_beep(struct device *dev, struct device_attribute
1301        *devattr, char *buf)
1302{
1303        struct f71882fg_data *data = f71882fg_update_device(dev);
1304        int nr = to_sensor_dev_attr_2(devattr)->index;
1305
1306        if (data->temp_beep & (1 << nr))
1307                return sprintf(buf, "1\n");
1308        else
1309                return sprintf(buf, "0\n");
1310}
1311
1312static ssize_t store_temp_beep(struct device *dev, struct device_attribute
1313        *devattr, const char *buf, size_t count)
1314{
1315        struct f71882fg_data *data = dev_get_drvdata(dev);
1316        int nr = to_sensor_dev_attr_2(devattr)->index;
1317        unsigned long val = simple_strtoul(buf, NULL, 10);
1318
1319        mutex_lock(&data->update_lock);
1320        data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
1321        if (val)
1322                data->temp_beep |= 1 << nr;
1323        else
1324                data->temp_beep &= ~(1 << nr);
1325
1326        f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
1327        mutex_unlock(&data->update_lock);
1328
1329        return count;
1330}
1331
1332static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
1333        *devattr, char *buf)
1334{
1335        struct f71882fg_data *data = f71882fg_update_device(dev);
1336        int nr = to_sensor_dev_attr_2(devattr)->index;
1337
1338        if (data->temp_status & (1 << nr))
1339                return sprintf(buf, "1\n");
1340        else
1341                return sprintf(buf, "0\n");
1342}
1343
1344static ssize_t show_temp_fault(struct device *dev, struct device_attribute
1345        *devattr, char *buf)
1346{
1347        struct f71882fg_data *data = f71882fg_update_device(dev);
1348        int nr = to_sensor_dev_attr_2(devattr)->index;
1349
1350        if (data->temp_diode_open & (1 << nr))
1351                return sprintf(buf, "1\n");
1352        else
1353                return sprintf(buf, "0\n");
1354}
1355
1356static ssize_t show_pwm(struct device *dev,
1357                        struct device_attribute *devattr, char *buf)
1358{
1359        struct f71882fg_data *data = f71882fg_update_device(dev);
1360        int val, nr = to_sensor_dev_attr_2(devattr)->index;
1361        mutex_lock(&data->update_lock);
1362        if (data->pwm_enable & (1 << (2 * nr)))
1363                /* PWM mode */
1364                val = data->pwm[nr];
1365        else {
1366                /* RPM mode */
1367                val = 255 * fan_from_reg(data->fan_target[nr])
1368                        / fan_from_reg(data->fan_full_speed[nr]);
1369        }
1370        mutex_unlock(&data->update_lock);
1371        return sprintf(buf, "%d\n", val);
1372}
1373
1374static ssize_t store_pwm(struct device *dev,
1375                         struct device_attribute *devattr, const char *buf,
1376                         size_t count)
1377{
1378        struct f71882fg_data *data = dev_get_drvdata(dev);
1379        int nr = to_sensor_dev_attr_2(devattr)->index;
1380        long val = simple_strtol(buf, NULL, 10);
1381        val = SENSORS_LIMIT(val, 0, 255);
1382
1383        mutex_lock(&data->update_lock);
1384        data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1385        if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1386            (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1387                count = -EROFS;
1388                goto leave;
1389        }
1390        if (data->pwm_enable & (1 << (2 * nr))) {
1391                /* PWM mode */
1392                f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1393                data->pwm[nr] = val;
1394        } else {
1395                /* RPM mode */
1396                int target, full_speed;
1397                full_speed = f71882fg_read16(data,
1398                                             F71882FG_REG_FAN_FULL_SPEED(nr));
1399                target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1400                f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
1401                data->fan_target[nr] = target;
1402                data->fan_full_speed[nr] = full_speed;
1403        }
1404leave:
1405        mutex_unlock(&data->update_lock);
1406
1407        return count;
1408}
1409
1410static ssize_t show_pwm_enable(struct device *dev,
1411                               struct device_attribute *devattr, char *buf)
1412{
1413        int result = 0;
1414        struct f71882fg_data *data = f71882fg_update_device(dev);
1415        int nr = to_sensor_dev_attr_2(devattr)->index;
1416
1417        switch ((data->pwm_enable >> 2 * nr) & 3) {
1418        case 0:
1419        case 1:
1420                result = 2; /* Normal auto mode */
1421                break;
1422        case 2:
1423                result = 1; /* Manual mode */
1424                break;
1425        case 3:
1426                if (data->type == f8000)
1427                        result = 3; /* Thermostat mode */
1428                else
1429                        result = 1; /* Manual mode */
1430                break;
1431        }
1432
1433        return sprintf(buf, "%d\n", result);
1434}
1435
1436static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1437                                *devattr, const char *buf, size_t count)
1438{
1439        struct f71882fg_data *data = dev_get_drvdata(dev);
1440        int nr = to_sensor_dev_attr_2(devattr)->index;
1441        long val = simple_strtol(buf, NULL, 10);
1442
1443        mutex_lock(&data->update_lock);
1444        data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1445        /* Special case for F8000 auto PWM mode / Thermostat mode */
1446        if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1447                switch (val) {
1448                case 2:
1449                        data->pwm_enable &= ~(2 << (2 * nr));
1450                        break;          /* Normal auto mode */
1451                case 3:
1452                        data->pwm_enable |= 2 << (2 * nr);
1453                        break;          /* Thermostat mode */
1454                default:
1455                        count = -EINVAL;
1456                        goto leave;
1457                }
1458        } else {
1459                switch (val) {
1460                case 1:
1461                        data->pwm_enable |= 2 << (2 * nr);
1462                        break;          /* Manual */
1463                case 2:
1464                        data->pwm_enable &= ~(2 << (2 * nr));
1465                        break;          /* Normal auto mode */
1466                default:
1467                        count = -EINVAL;
1468                        goto leave;
1469                }
1470        }
1471        f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1472leave:
1473        mutex_unlock(&data->update_lock);
1474
1475        return count;
1476}
1477
1478static ssize_t show_pwm_auto_point_pwm(struct device *dev,
1479                                       struct device_attribute *devattr,
1480                                       char *buf)
1481{
1482        int result;
1483        struct f71882fg_data *data = f71882fg_update_device(dev);
1484        int pwm = to_sensor_dev_attr_2(devattr)->index;
1485        int point = to_sensor_dev_attr_2(devattr)->nr;
1486
1487        mutex_lock(&data->update_lock);
1488        if (data->pwm_enable & (1 << (2 * pwm))) {
1489                /* PWM mode */
1490                result = data->pwm_auto_point_pwm[pwm][point];
1491        } else {
1492                /* RPM mode */
1493                result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
1494        }
1495        mutex_unlock(&data->update_lock);
1496
1497        return sprintf(buf, "%d\n", result);
1498}
1499
1500static ssize_t store_pwm_auto_point_pwm(struct device *dev,
1501                                        struct device_attribute *devattr,
1502                                        const char *buf, size_t count)
1503{
1504        struct f71882fg_data *data = dev_get_drvdata(dev);
1505        int pwm = to_sensor_dev_attr_2(devattr)->index;
1506        int point = to_sensor_dev_attr_2(devattr)->nr;
1507        long val = simple_strtol(buf, NULL, 10);
1508        val = SENSORS_LIMIT(val, 0, 255);
1509
1510        mutex_lock(&data->update_lock);
1511        data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1512        if (data->pwm_enable & (1 << (2 * pwm))) {
1513                /* PWM mode */
1514        } else {
1515                /* RPM mode */
1516                if (val < 29)   /* Prevent negative numbers */
1517                        val = 255;
1518                else
1519                        val = (255 - val) * 32 / val;
1520        }
1521        f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
1522        data->pwm_auto_point_pwm[pwm][point] = val;
1523        mutex_unlock(&data->update_lock);
1524
1525        return count;
1526}
1527
1528static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
1529                                             struct device_attribute *devattr,
1530                                             char *buf)
1531{
1532        int result = 0;
1533        struct f71882fg_data *data = f71882fg_update_device(dev);
1534        int nr = to_sensor_dev_attr_2(devattr)->index;
1535        int point = to_sensor_dev_attr_2(devattr)->nr;
1536
1537        mutex_lock(&data->update_lock);
1538        if (nr & 1)
1539                result = data->pwm_auto_point_hyst[nr / 2] >> 4;
1540        else
1541                result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
1542        result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
1543        mutex_unlock(&data->update_lock);
1544
1545        return sprintf(buf, "%d\n", result);
1546}
1547
1548static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
1549                                              struct device_attribute *devattr,
1550                                              const char *buf, size_t count)
1551{
1552        struct f71882fg_data *data = dev_get_drvdata(dev);
1553        int nr = to_sensor_dev_attr_2(devattr)->index;
1554        int point = to_sensor_dev_attr_2(devattr)->nr;
1555        long val = simple_strtol(buf, NULL, 10) / 1000;
1556        u8 reg;
1557
1558        mutex_lock(&data->update_lock);
1559        data->pwm_auto_point_temp[nr][point] =
1560                f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
1561        val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
1562                                data->pwm_auto_point_temp[nr][point]);
1563        val = data->pwm_auto_point_temp[nr][point] - val;
1564
1565        reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
1566        if (nr & 1)
1567                reg = (reg & 0x0f) | (val << 4);
1568        else
1569                reg = (reg & 0xf0) | val;
1570
1571        f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
1572        data->pwm_auto_point_hyst[nr / 2] = reg;
1573        mutex_unlock(&data->update_lock);
1574
1575        return count;
1576}
1577
1578static ssize_t show_pwm_interpolate(struct device *dev,
1579                                    struct device_attribute *devattr, char *buf)
1580{
1581        int result;
1582        struct f71882fg_data *data = f71882fg_update_device(dev);
1583        int nr = to_sensor_dev_attr_2(devattr)->index;
1584
1585        result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
1586
1587        return sprintf(buf, "%d\n", result);
1588}
1589
1590static ssize_t store_pwm_interpolate(struct device *dev,
1591                                     struct device_attribute *devattr,
1592                                     const char *buf, size_t count)
1593{
1594        struct f71882fg_data *data = dev_get_drvdata(dev);
1595        int nr = to_sensor_dev_attr_2(devattr)->index;
1596        unsigned long val = simple_strtoul(buf, NULL, 10);
1597
1598        mutex_lock(&data->update_lock);
1599        data->pwm_auto_point_mapping[nr] =
1600                f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1601        if (val)
1602                val = data->pwm_auto_point_mapping[nr] | (1 << 4);
1603        else
1604                val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
1605        f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1606        data->pwm_auto_point_mapping[nr] = val;
1607        mutex_unlock(&data->update_lock);
1608
1609        return count;
1610}
1611
1612static ssize_t show_pwm_auto_point_channel(struct device *dev,
1613                                           struct device_attribute *devattr,
1614                                           char *buf)
1615{
1616        int result;
1617        struct f71882fg_data *data = f71882fg_update_device(dev);
1618        int nr = to_sensor_dev_attr_2(devattr)->index;
1619        int temp_start = (data->type == f8000) ? 0 : 1;
1620
1621        result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - temp_start);
1622
1623        return sprintf(buf, "%d\n", result);
1624}
1625
1626static ssize_t store_pwm_auto_point_channel(struct device *dev,
1627                                            struct device_attribute *devattr,
1628                                            const char *buf, size_t count)
1629{
1630        struct f71882fg_data *data = dev_get_drvdata(dev);
1631        int nr = to_sensor_dev_attr_2(devattr)->index;
1632        int temp_start = (data->type == f8000) ? 0 : 1;
1633        long val = simple_strtol(buf, NULL, 10);
1634
1635        switch (val) {
1636        case 1:
1637                val = 0;
1638                break;
1639        case 2:
1640                val = 1;
1641                break;
1642        case 4:
1643                val = 2;
1644                break;
1645        default:
1646                return -EINVAL;
1647        }
1648        val += temp_start;
1649        mutex_lock(&data->update_lock);
1650        data->pwm_auto_point_mapping[nr] =
1651                f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1652        val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
1653        f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1654        data->pwm_auto_point_mapping[nr] = val;
1655        mutex_unlock(&data->update_lock);
1656
1657        return count;
1658}
1659
1660static ssize_t show_pwm_auto_point_temp(struct device *dev,
1661                                        struct device_attribute *devattr,
1662                                        char *buf)
1663{
1664        int result;
1665        struct f71882fg_data *data = f71882fg_update_device(dev);
1666        int pwm = to_sensor_dev_attr_2(devattr)->index;
1667        int point = to_sensor_dev_attr_2(devattr)->nr;
1668
1669        result = data->pwm_auto_point_temp[pwm][point];
1670        return sprintf(buf, "%d\n", 1000 * result);
1671}
1672
1673static ssize_t store_pwm_auto_point_temp(struct device *dev,
1674                                         struct device_attribute *devattr,
1675                                         const char *buf, size_t count)
1676{
1677        struct f71882fg_data *data = dev_get_drvdata(dev);
1678        int pwm = to_sensor_dev_attr_2(devattr)->index;
1679        int point = to_sensor_dev_attr_2(devattr)->nr;
1680        long val = simple_strtol(buf, NULL, 10) / 1000;
1681        val = SENSORS_LIMIT(val, 0, 255);
1682
1683        mutex_lock(&data->update_lock);
1684        f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
1685        data->pwm_auto_point_temp[pwm][point] = val;
1686        mutex_unlock(&data->update_lock);
1687
1688        return count;
1689}
1690
1691static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
1692        char *buf)
1693{
1694        struct f71882fg_data *data = dev_get_drvdata(dev);
1695        return sprintf(buf, "%s\n", f71882fg_names[data->type]);
1696}
1697
1698static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
1699        struct sensor_device_attribute_2 *attr, int count)
1700{
1701        int err, i;
1702
1703        for (i = 0; i < count; i++) {
1704                err = device_create_file(&pdev->dev, &attr[i].dev_attr);
1705                if (err)
1706                        return err;
1707        }
1708        return 0;
1709}
1710
1711static int __devinit f71882fg_probe(struct platform_device *pdev)
1712{
1713        struct f71882fg_data *data;
1714        struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
1715        int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
1716        u8 start_reg;
1717
1718        data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
1719        if (!data)
1720                return -ENOMEM;
1721
1722        data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1723        data->type = sio_data->type;
1724        mutex_init(&data->update_lock);
1725        platform_set_drvdata(pdev, data);
1726
1727        start_reg = f71882fg_read8(data, F71882FG_REG_START);
1728        if (start_reg & 0x04) {
1729                dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
1730                err = -ENODEV;
1731                goto exit_free;
1732        }
1733        if (!(start_reg & 0x03)) {
1734                dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
1735                err = -ENODEV;
1736                goto exit_free;
1737        }
1738
1739        data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1740        /* If it is a 71862 and the fan / pwm part is enabled sanity check
1741           the pwm settings */
1742        if (data->type == f71862fg && (start_reg & 0x02)) {
1743                if ((data->pwm_enable & 0x15) != 0x15) {
1744                        dev_err(&pdev->dev,
1745                                "Invalid (reserved) pwm settings: 0x%02x\n",
1746                                (unsigned int)data->pwm_enable);
1747                        err = -ENODEV;
1748                        goto exit_free;
1749                }
1750        }
1751
1752        /* Register sysfs interface files */
1753        err = device_create_file(&pdev->dev, &dev_attr_name);
1754        if (err)
1755                goto exit_unregister_sysfs;
1756
1757        if (start_reg & 0x01) {
1758                switch (data->type) {
1759                case f71882fg:
1760                        err = f71882fg_create_sysfs_files(pdev,
1761                                        f71882fg_in_temp_attr,
1762                                        ARRAY_SIZE(f71882fg_in_temp_attr));
1763                        if (err)
1764                                goto exit_unregister_sysfs;
1765                        /* fall through! */
1766                case f71862fg:
1767                        err = f71882fg_create_sysfs_files(pdev,
1768                                        f718x2fg_in_temp_attr,
1769                                        ARRAY_SIZE(f718x2fg_in_temp_attr));
1770                        break;
1771                case f8000:
1772                        err = f71882fg_create_sysfs_files(pdev,
1773                                        f8000_in_temp_attr,
1774                                        ARRAY_SIZE(f8000_in_temp_attr));
1775                        break;
1776                }
1777                if (err)
1778                        goto exit_unregister_sysfs;
1779        }
1780
1781        if (start_reg & 0x02) {
1782                err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
1783                                        ARRAY_SIZE(fxxxx_fan_attr));
1784                if (err)
1785                        goto exit_unregister_sysfs;
1786
1787                switch (data->type) {
1788                case f71862fg:
1789                        err = f71882fg_create_sysfs_files(pdev,
1790                                        f71862fg_fan_attr,
1791                                        ARRAY_SIZE(f71862fg_fan_attr));
1792                        break;
1793                case f71882fg:
1794                        err = f71882fg_create_sysfs_files(pdev,
1795                                        f71882fg_fan_attr,
1796                                        ARRAY_SIZE(f71882fg_fan_attr));
1797                        break;
1798                case f8000:
1799                        err = f71882fg_create_sysfs_files(pdev,
1800                                        f8000_fan_attr,
1801                                        ARRAY_SIZE(f8000_fan_attr));
1802                        break;
1803                }
1804                if (err)
1805                        goto exit_unregister_sysfs;
1806
1807                for (i = 0; i < nr_fans; i++)
1808                        dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
1809                                 (data->pwm_enable & (1 << 2 * i)) ?
1810                                 "duty-cycle" : "RPM");
1811        }
1812
1813        data->hwmon_dev = hwmon_device_register(&pdev->dev);
1814        if (IS_ERR(data->hwmon_dev)) {
1815                err = PTR_ERR(data->hwmon_dev);
1816                data->hwmon_dev = NULL;
1817                goto exit_unregister_sysfs;
1818        }
1819
1820        return 0;
1821
1822exit_unregister_sysfs:
1823        f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
1824        return err; /* f71882fg_remove() also frees our data */
1825exit_free:
1826        kfree(data);
1827        return err;
1828}
1829
1830static int f71882fg_remove(struct platform_device *pdev)
1831{
1832        int i;
1833        struct f71882fg_data *data = platform_get_drvdata(pdev);
1834
1835        platform_set_drvdata(pdev, NULL);
1836        if (data->hwmon_dev)
1837                hwmon_device_unregister(data->hwmon_dev);
1838
1839        /* Note we are not looping over all attr arrays we have as the ones
1840           below are supersets of the ones skipped. */
1841        device_remove_file(&pdev->dev, &dev_attr_name);
1842
1843        for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
1844                device_remove_file(&pdev->dev,
1845                                        &f718x2fg_in_temp_attr[i].dev_attr);
1846
1847        for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
1848                device_remove_file(&pdev->dev,
1849                                        &f71882fg_in_temp_attr[i].dev_attr);
1850
1851        for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++)
1852                device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr);
1853
1854        for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
1855                device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
1856
1857        for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++)
1858                device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr);
1859
1860        kfree(data);
1861
1862        return 0;
1863}
1864
1865static int __init f71882fg_find(int sioaddr, unsigned short *address,
1866        struct f71882fg_sio_data *sio_data)
1867{
1868        int err = -ENODEV;
1869        u16 devid;
1870
1871        superio_enter(sioaddr);
1872
1873        devid = superio_inw(sioaddr, SIO_REG_MANID);
1874        if (devid != SIO_FINTEK_ID) {
1875                pr_debug(DRVNAME ": Not a Fintek device\n");
1876                goto exit;
1877        }
1878
1879        devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
1880        switch (devid) {
1881        case SIO_F71862_ID:
1882                sio_data->type = f71862fg;
1883                break;
1884        case SIO_F71882_ID:
1885                sio_data->type = f71882fg;
1886                break;
1887        case SIO_F8000_ID:
1888                sio_data->type = f8000;
1889                break;
1890        default:
1891                printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
1892                goto exit;
1893        }
1894
1895        superio_select(sioaddr, SIO_F71882FG_LD_HWM);
1896        if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
1897                printk(KERN_WARNING DRVNAME ": Device not activated\n");
1898                goto exit;
1899        }
1900
1901        *address = superio_inw(sioaddr, SIO_REG_ADDR);
1902        if (*address == 0)
1903        {
1904                printk(KERN_WARNING DRVNAME ": Base address not set\n");
1905                goto exit;
1906        }
1907        *address &= ~(REGION_LENGTH - 1);       /* Ignore 3 LSB */
1908
1909        err = 0;
1910        printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
1911                f71882fg_names[sio_data->type], (unsigned int)*address,
1912                (int)superio_inb(sioaddr, SIO_REG_DEVREV));
1913exit:
1914        superio_exit(sioaddr);
1915        return err;
1916}
1917
1918static int __init f71882fg_device_add(unsigned short address,
1919        const struct f71882fg_sio_data *sio_data)
1920{
1921        struct resource res = {
1922                .start  = address,
1923                .end    = address + REGION_LENGTH - 1,
1924                .flags  = IORESOURCE_IO,
1925        };
1926        int err;
1927
1928        f71882fg_pdev = platform_device_alloc(DRVNAME, address);
1929        if (!f71882fg_pdev)
1930                return -ENOMEM;
1931
1932        res.name = f71882fg_pdev->name;
1933        err = acpi_check_resource_conflict(&res);
1934        if (err)
1935                goto exit_device_put;
1936
1937        err = platform_device_add_resources(f71882fg_pdev, &res, 1);
1938        if (err) {
1939                printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
1940                goto exit_device_put;
1941        }
1942
1943        err = platform_device_add_data(f71882fg_pdev, sio_data,
1944                                       sizeof(struct f71882fg_sio_data));
1945        if (err) {
1946                printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
1947                goto exit_device_put;
1948        }
1949
1950        err = platform_device_add(f71882fg_pdev);
1951        if (err) {
1952                printk(KERN_ERR DRVNAME ": Device addition failed\n");
1953                goto exit_device_put;
1954        }
1955
1956        return 0;
1957
1958exit_device_put:
1959        platform_device_put(f71882fg_pdev);
1960
1961        return err;
1962}
1963
1964static int __init f71882fg_init(void)
1965{
1966        int err = -ENODEV;
1967        unsigned short address;
1968        struct f71882fg_sio_data sio_data;
1969
1970        memset(&sio_data, 0, sizeof(sio_data));
1971
1972        if (f71882fg_find(0x2e, &address, &sio_data) &&
1973            f71882fg_find(0x4e, &address, &sio_data))
1974                goto exit;
1975
1976        err = platform_driver_register(&f71882fg_driver);
1977        if (err)
1978                goto exit;
1979
1980        err = f71882fg_device_add(address, &sio_data);
1981        if (err)
1982                goto exit_driver;
1983
1984        return 0;
1985
1986exit_driver:
1987        platform_driver_unregister(&f71882fg_driver);
1988exit:
1989        return err;
1990}
1991
1992static void __exit f71882fg_exit(void)
1993{
1994        platform_device_unregister(f71882fg_pdev);
1995        platform_driver_unregister(&f71882fg_driver);
1996}
1997
1998MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
1999MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
2000MODULE_LICENSE("GPL");
2001
2002module_init(f71882fg_init);
2003module_exit(f71882fg_exit);
2004
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.