linux/drivers/hwmon/via686a.c
<<
>>
Prefs
   1/*
   2    via686a.c - Part of lm_sensors, Linux kernel modules
   3                for hardware monitoring
   4
   5    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
   6                        Kyösti Mälkki <kmalkki@cc.hut.fi>,
   7                        Mark Studebaker <mdsxyz123@yahoo.com>,
   8                        and Bob Dougherty <bobd@stanford.edu>
   9    (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
  10    <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.)
  11
  12    This program is free software; you can redistribute it and/or modify
  13    it under the terms of the GNU General Public License as published by
  14    the Free Software Foundation; either version 2 of the License, or
  15    (at your option) any later version.
  16
  17    This program is distributed in the hope that it will be useful,
  18    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20    GNU General Public License for more details.
  21
  22    You should have received a copy of the GNU General Public License
  23    along with this program; if not, write to the Free Software
  24    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25*/
  26
  27/*
  28    Supports the Via VT82C686A, VT82C686B south bridges.
  29    Reports all as a 686A.
  30    Warning - only supports a single device.
  31*/
  32
  33#include <linux/module.h>
  34#include <linux/slab.h>
  35#include <linux/pci.h>
  36#include <linux/jiffies.h>
  37#include <linux/platform_device.h>
  38#include <linux/hwmon.h>
  39#include <linux/hwmon-sysfs.h>
  40#include <linux/err.h>
  41#include <linux/init.h>
  42#include <linux/mutex.h>
  43#include <linux/sysfs.h>
  44#include <linux/acpi.h>
  45#include <linux/io.h>
  46
  47
  48/* If force_addr is set to anything different from 0, we forcibly enable
  49   the device at the given address. */
  50static unsigned short force_addr;
  51module_param(force_addr, ushort, 0);
  52MODULE_PARM_DESC(force_addr,
  53                 "Initialize the base address of the sensors");
  54
  55static struct platform_device *pdev;
  56
  57/*
  58   The Via 686a southbridge has a LM78-like chip integrated on the same IC.
  59   This driver is a customized copy of lm78.c
  60*/
  61
  62/* Many VIA686A constants specified below */
  63
  64/* Length of ISA address segment */
  65#define VIA686A_EXTENT          0x80
  66#define VIA686A_BASE_REG        0x70
  67#define VIA686A_ENABLE_REG      0x74
  68
  69/* The VIA686A registers */
  70/* ins numbered 0-4 */
  71#define VIA686A_REG_IN_MAX(nr)  (0x2b + ((nr) * 2))
  72#define VIA686A_REG_IN_MIN(nr)  (0x2c + ((nr) * 2))
  73#define VIA686A_REG_IN(nr)      (0x22 + (nr))
  74
  75/* fans numbered 1-2 */
  76#define VIA686A_REG_FAN_MIN(nr) (0x3a + (nr))
  77#define VIA686A_REG_FAN(nr)     (0x28 + (nr))
  78
  79/* temps numbered 1-3 */
  80static const u8 VIA686A_REG_TEMP[]      = { 0x20, 0x21, 0x1f };
  81static const u8 VIA686A_REG_TEMP_OVER[] = { 0x39, 0x3d, 0x1d };
  82static const u8 VIA686A_REG_TEMP_HYST[] = { 0x3a, 0x3e, 0x1e };
  83/* bits 7-6 */
  84#define VIA686A_REG_TEMP_LOW1   0x4b
  85/* 2 = bits 5-4, 3 = bits 7-6 */
  86#define VIA686A_REG_TEMP_LOW23  0x49
  87
  88#define VIA686A_REG_ALARM1      0x41
  89#define VIA686A_REG_ALARM2      0x42
  90#define VIA686A_REG_FANDIV      0x47
  91#define VIA686A_REG_CONFIG      0x40
  92/* The following register sets temp interrupt mode (bits 1-0 for temp1,
  93 3-2 for temp2, 5-4 for temp3).  Modes are:
  94    00 interrupt stays as long as value is out-of-range
  95    01 interrupt is cleared once register is read (default)
  96    10 comparator mode- like 00, but ignores hysteresis
  97    11 same as 00 */
  98#define VIA686A_REG_TEMP_MODE           0x4b
  99/* We'll just assume that you want to set all 3 simultaneously: */
 100#define VIA686A_TEMP_MODE_MASK          0x3F
 101#define VIA686A_TEMP_MODE_CONTINUOUS    0x00
 102
 103/* Conversions. Limit checking is only done on the TO_REG
 104   variants.
 105
 106********* VOLTAGE CONVERSIONS (Bob Dougherty) ********
 107 From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
 108 voltagefactor[0]=1.25/2628; (2628/1.25=2102.4)   // Vccp
 109 voltagefactor[1]=1.25/2628; (2628/1.25=2102.4)   // +2.5V
 110 voltagefactor[2]=1.67/2628; (2628/1.67=1573.7)   // +3.3V
 111 voltagefactor[3]=2.6/2628;  (2628/2.60=1010.8)   // +5V
 112 voltagefactor[4]=6.3/2628;  (2628/6.30=417.14)   // +12V
 113 in[i]=(data[i+2]*25.0+133)*voltagefactor[i];
 114 That is:
 115 volts = (25*regVal+133)*factor
 116 regVal = (volts/factor-133)/25
 117 (These conversions were contributed by Jonathan Teh Soon Yew
 118 <j.teh@iname.com>) */
 119static inline u8 IN_TO_REG(long val, int inNum)
 120{
 121        /* To avoid floating point, we multiply constants by 10 (100 for +12V).
 122           Rounding is done (120500 is actually 133000 - 12500).
 123           Remember that val is expressed in 0.001V/bit, which is why we divide
 124           by an additional 10000 (100000 for +12V): 1000 for val and 10 (100)
 125           for the constants. */
 126        if (inNum <= 1)
 127                return (u8)
 128                    SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255);
 129        else if (inNum == 2)
 130                return (u8)
 131                    SENSORS_LIMIT((val * 15737 - 1205000) / 250000, 0, 255);
 132        else if (inNum == 3)
 133                return (u8)
 134                    SENSORS_LIMIT((val * 10108 - 1205000) / 250000, 0, 255);
 135        else
 136                return (u8)
 137                    SENSORS_LIMIT((val * 41714 - 12050000) / 2500000, 0, 255);
 138}
 139
 140static inline long IN_FROM_REG(u8 val, int inNum)
 141{
 142        /* To avoid floating point, we multiply constants by 10 (100 for +12V).
 143           We also multiply them by 1000 because we want 0.001V/bit for the
 144           output value. Rounding is done. */
 145        if (inNum <= 1)
 146                return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024);
 147        else if (inNum == 2)
 148                return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737);
 149        else if (inNum == 3)
 150                return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108);
 151        else
 152                return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714);
 153}
 154
 155/********* FAN RPM CONVERSIONS ********/
 156/* Higher register values = slower fans (the fan's strobe gates a counter).
 157 But this chip saturates back at 0, not at 255 like all the other chips.
 158 So, 0 means 0 RPM */
 159static inline u8 FAN_TO_REG(long rpm, int div)
 160{
 161        if (rpm == 0)
 162                return 0;
 163        rpm = SENSORS_LIMIT(rpm, 1, 1000000);
 164        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255);
 165}
 166
 167#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div)))
 168
 169/******** TEMP CONVERSIONS (Bob Dougherty) *********/
 170/* linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
 171      if(temp<169)
 172              return double(temp)*0.427-32.08;
 173      else if(temp>=169 && temp<=202)
 174              return double(temp)*0.582-58.16;
 175      else
 176              return double(temp)*0.924-127.33;
 177
 178 A fifth-order polynomial fits the unofficial data (provided by Alex van
 179 Kaam <darkside@chello.nl>) a bit better.  It also give more reasonable
 180 numbers on my machine (ie. they agree with what my BIOS tells me).
 181 Here's the fifth-order fit to the 8-bit data:
 182 temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
 183        2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
 184
 185 (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
 186 finding my typos in this formula!)
 187
 188 Alas, none of the elegant function-fit solutions will work because we
 189 aren't allowed to use floating point in the kernel and doing it with
 190 integers doesn't provide enough precision.  So we'll do boring old
 191 look-up table stuff.  The unofficial data (see below) have effectively
 192 7-bit resolution (they are rounded to the nearest degree).  I'm assuming
 193 that the transfer function of the device is monotonic and smooth, so a
 194 smooth function fit to the data will allow us to get better precision.
 195 I used the 5th-order poly fit described above and solved for
 196 VIA register values 0-255.  I *10 before rounding, so we get tenth-degree
 197 precision.  (I could have done all 1024 values for our 10-bit readings,
 198 but the function is very linear in the useful range (0-80 deg C), so
 199 we'll just use linear interpolation for 10-bit readings.)  So, tempLUT
 200 is the temp at via register values 0-255: */
 201static const s16 tempLUT[] =
 202{ -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
 203        -503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
 204        -362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
 205        -255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
 206        -173, -166, -159, -152, -145, -139, -132, -126, -120, -114,
 207        -108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49,
 208        -44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16,
 209        20, 25, 29, 33, 37, 42, 46, 50, 54, 59, 63, 67, 71, 75, 79, 84,
 210        88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138,
 211        142, 146, 151, 155, 159, 163, 168, 172, 176, 181, 185, 189,
 212        193, 198, 202, 206, 211, 215, 219, 224, 228, 232, 237, 241,
 213        245, 250, 254, 259, 263, 267, 272, 276, 281, 285, 290, 294,
 214        299, 303, 307, 312, 316, 321, 325, 330, 334, 339, 344, 348,
 215        353, 357, 362, 366, 371, 376, 380, 385, 390, 395, 399, 404,
 216        409, 414, 419, 423, 428, 433, 438, 443, 449, 454, 459, 464,
 217        469, 475, 480, 486, 491, 497, 502, 508, 514, 520, 526, 532,
 218        538, 544, 551, 557, 564, 571, 578, 584, 592, 599, 606, 614,
 219        621, 629, 637, 645, 654, 662, 671, 680, 689, 698, 708, 718,
 220        728, 738, 749, 759, 770, 782, 793, 805, 818, 830, 843, 856,
 221        870, 883, 898, 912, 927, 943, 958, 975, 991, 1008, 1026, 1044,
 222        1062, 1081, 1101, 1121, 1141, 1162, 1184, 1206, 1229, 1252,
 223        1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462
 224};
 225
 226/* the original LUT values from Alex van Kaam <darkside@chello.nl>
 227   (for via register values 12-240):
 228{-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
 229-30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
 230-15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
 231-3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,
 23212,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,
 23322,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,
 23433,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,
 23545,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60,
 23661,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,
 23785,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110};
 238
 239
 240 Here's the reverse LUT.  I got it by doing a 6-th order poly fit (needed
 241 an extra term for a good fit to these inverse data!) and then
 242 solving for each temp value from -50 to 110 (the useable range for
 243 this chip).  Here's the fit:
 244 viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4
 245 - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
 246 Note that n=161: */
 247static const u8 viaLUT[] =
 248{ 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
 249        23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40,
 250        41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66,
 251        69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100,
 252        103, 105, 107, 110, 112, 115, 117, 119, 122, 124, 126, 129,
 253        131, 134, 136, 138, 140, 143, 145, 147, 150, 152, 154, 156,
 254        158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180,
 255        182, 183, 185, 187, 188, 190, 192, 193, 195, 196, 198, 199,
 256        200, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213,
 257        214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224,
 258        225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232,
 259        233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
 260        239, 240
 261};
 262
 263/* Converting temps to (8-bit) hyst and over registers
 264   No interpolation here.
 265   The +50 is because the temps start at -50 */
 266static inline u8 TEMP_TO_REG(long val)
 267{
 268        return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 :
 269                      (val < 0 ? val - 500 : val + 500) / 1000 + 50];
 270}
 271
 272/* for 8-bit temperature hyst and over registers */
 273#define TEMP_FROM_REG(val)      ((long)tempLUT[val] * 100)
 274
 275/* for 10-bit temperature readings */
 276static inline long TEMP_FROM_REG10(u16 val)
 277{
 278        u16 eightBits = val >> 2;
 279        u16 twoBits = val & 3;
 280
 281        /* no interpolation for these */
 282        if (twoBits == 0 || eightBits == 255)
 283                return TEMP_FROM_REG(eightBits);
 284
 285        /* do some linear interpolation */
 286        return (tempLUT[eightBits] * (4 - twoBits) +
 287                tempLUT[eightBits + 1] * twoBits) * 25;
 288}
 289
 290#define DIV_FROM_REG(val) (1 << (val))
 291#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
 292
 293/* For each registered chip, we need to keep some data in memory.
 294   The structure is dynamically allocated. */
 295struct via686a_data {
 296        unsigned short addr;
 297        const char *name;
 298        struct device *hwmon_dev;
 299        struct mutex update_lock;
 300        char valid;             /* !=0 if following fields are valid */
 301        unsigned long last_updated;     /* In jiffies */
 302
 303        u8 in[5];               /* Register value */
 304        u8 in_max[5];           /* Register value */
 305        u8 in_min[5];           /* Register value */
 306        u8 fan[2];              /* Register value */
 307        u8 fan_min[2];          /* Register value */
 308        u16 temp[3];            /* Register value 10 bit */
 309        u8 temp_over[3];        /* Register value */
 310        u8 temp_hyst[3];        /* Register value */
 311        u8 fan_div[2];          /* Register encoding, shifted right */
 312        u16 alarms;             /* Register encoding, combined */
 313};
 314
 315static struct pci_dev *s_bridge;        /* pointer to the (only) via686a */
 316
 317static int via686a_probe(struct platform_device *pdev);
 318static int __devexit via686a_remove(struct platform_device *pdev);
 319
 320static inline int via686a_read_value(struct via686a_data *data, u8 reg)
 321{
 322        return inb_p(data->addr + reg);
 323}
 324
 325static inline void via686a_write_value(struct via686a_data *data, u8 reg,
 326                                       u8 value)
 327{
 328        outb_p(value, data->addr + reg);
 329}
 330
 331static struct via686a_data *via686a_update_device(struct device *dev);
 332static void via686a_init_device(struct via686a_data *data);
 333
 334/* following are the sysfs callback functions */
 335
 336/* 7 voltage sensors */
 337static ssize_t show_in(struct device *dev, struct device_attribute *da,
 338                char *buf) {
 339        struct via686a_data *data = via686a_update_device(dev);
 340        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 341        int nr = attr->index;
 342        return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr));
 343}
 344
 345static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
 346                char *buf) {
 347        struct via686a_data *data = via686a_update_device(dev);
 348        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 349        int nr = attr->index;
 350        return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr));
 351}
 352
 353static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
 354                char *buf) {
 355        struct via686a_data *data = via686a_update_device(dev);
 356        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 357        int nr = attr->index;
 358        return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr));
 359}
 360
 361static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
 362                const char *buf, size_t count) {
 363        struct via686a_data *data = dev_get_drvdata(dev);
 364        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 365        int nr = attr->index;
 366        unsigned long val = simple_strtoul(buf, NULL, 10);
 367
 368        mutex_lock(&data->update_lock);
 369        data->in_min[nr] = IN_TO_REG(val, nr);
 370        via686a_write_value(data, VIA686A_REG_IN_MIN(nr),
 371                        data->in_min[nr]);
 372        mutex_unlock(&data->update_lock);
 373        return count;
 374}
 375static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
 376                const char *buf, size_t count) {
 377        struct via686a_data *data = dev_get_drvdata(dev);
 378        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 379        int nr = attr->index;
 380        unsigned long val = simple_strtoul(buf, NULL, 10);
 381
 382        mutex_lock(&data->update_lock);
 383        data->in_max[nr] = IN_TO_REG(val, nr);
 384        via686a_write_value(data, VIA686A_REG_IN_MAX(nr),
 385                        data->in_max[nr]);
 386        mutex_unlock(&data->update_lock);
 387        return count;
 388}
 389#define show_in_offset(offset)                                  \
 390static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,          \
 391                show_in, NULL, offset);                         \
 392static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,  \
 393                show_in_min, set_in_min, offset);               \
 394static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,  \
 395                show_in_max, set_in_max, offset);
 396
 397show_in_offset(0);
 398show_in_offset(1);
 399show_in_offset(2);
 400show_in_offset(3);
 401show_in_offset(4);
 402
 403/* 3 temperatures */
 404static ssize_t show_temp(struct device *dev, struct device_attribute *da,
 405                char *buf) {
 406        struct via686a_data *data = via686a_update_device(dev);
 407        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 408        int nr = attr->index;
 409        return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr]));
 410}
 411static ssize_t show_temp_over(struct device *dev, struct device_attribute *da,
 412                char *buf) {
 413        struct via686a_data *data = via686a_update_device(dev);
 414        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 415        int nr = attr->index;
 416        return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr]));
 417}
 418static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da,
 419                char *buf) {
 420        struct via686a_data *data = via686a_update_device(dev);
 421        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 422        int nr = attr->index;
 423        return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr]));
 424}
 425static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
 426                const char *buf, size_t count) {
 427        struct via686a_data *data = dev_get_drvdata(dev);
 428        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 429        int nr = attr->index;
 430        int val = simple_strtol(buf, NULL, 10);
 431
 432        mutex_lock(&data->update_lock);
 433        data->temp_over[nr] = TEMP_TO_REG(val);
 434        via686a_write_value(data, VIA686A_REG_TEMP_OVER[nr],
 435                            data->temp_over[nr]);
 436        mutex_unlock(&data->update_lock);
 437        return count;
 438}
 439static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
 440                const char *buf, size_t count) {
 441        struct via686a_data *data = dev_get_drvdata(dev);
 442        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 443        int nr = attr->index;
 444        int val = simple_strtol(buf, NULL, 10);
 445
 446        mutex_lock(&data->update_lock);
 447        data->temp_hyst[nr] = TEMP_TO_REG(val);
 448        via686a_write_value(data, VIA686A_REG_TEMP_HYST[nr],
 449                            data->temp_hyst[nr]);
 450        mutex_unlock(&data->update_lock);
 451        return count;
 452}
 453#define show_temp_offset(offset)                                        \
 454static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,                \
 455                show_temp, NULL, offset - 1);                           \
 456static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,        \
 457                show_temp_over, set_temp_over, offset - 1);             \
 458static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR,   \
 459                show_temp_hyst, set_temp_hyst, offset - 1);
 460
 461show_temp_offset(1);
 462show_temp_offset(2);
 463show_temp_offset(3);
 464
 465/* 2 Fans */
 466static ssize_t show_fan(struct device *dev, struct device_attribute *da,
 467                char *buf) {
 468        struct via686a_data *data = via686a_update_device(dev);
 469        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 470        int nr = attr->index;
 471        return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
 472                                DIV_FROM_REG(data->fan_div[nr])) );
 473}
 474static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
 475                char *buf) {
 476        struct via686a_data *data = via686a_update_device(dev);
 477        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 478        int nr = attr->index;
 479        return sprintf(buf, "%d\n",
 480                FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
 481}
 482static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
 483                char *buf) {
 484        struct via686a_data *data = via686a_update_device(dev);
 485        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 486        int nr = attr->index;
 487        return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
 488}
 489static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
 490                const char *buf, size_t count) {
 491        struct via686a_data *data = dev_get_drvdata(dev);
 492        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 493        int nr = attr->index;
 494        int val = simple_strtol(buf, NULL, 10);
 495
 496        mutex_lock(&data->update_lock);
 497        data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
 498        via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
 499        mutex_unlock(&data->update_lock);
 500        return count;
 501}
 502static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 503                const char *buf, size_t count) {
 504        struct via686a_data *data = dev_get_drvdata(dev);
 505        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 506        int nr = attr->index;
 507        int val = simple_strtol(buf, NULL, 10);
 508        int old;
 509
 510        mutex_lock(&data->update_lock);
 511        old = via686a_read_value(data, VIA686A_REG_FANDIV);
 512        data->fan_div[nr] = DIV_TO_REG(val);
 513        old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
 514        via686a_write_value(data, VIA686A_REG_FANDIV, old);
 515        mutex_unlock(&data->update_lock);
 516        return count;
 517}
 518
 519#define show_fan_offset(offset)                                         \
 520static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,                 \
 521                show_fan, NULL, offset - 1);                            \
 522static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,         \
 523                show_fan_min, set_fan_min, offset - 1);                 \
 524static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,         \
 525                show_fan_div, set_fan_div, offset - 1);
 526
 527show_fan_offset(1);
 528show_fan_offset(2);
 529
 530/* Alarms */
 531static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) {
 532        struct via686a_data *data = via686a_update_device(dev);
 533        return sprintf(buf, "%u\n", data->alarms);
 534}
 535static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 536
 537static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
 538                          char *buf)
 539{
 540        int bitnr = to_sensor_dev_attr(attr)->index;
 541        struct via686a_data *data = via686a_update_device(dev);
 542        return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
 543}
 544static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
 545static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
 546static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
 547static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
 548static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
 549static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
 550static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11);
 551static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 15);
 552static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
 553static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
 554
 555static ssize_t show_name(struct device *dev, struct device_attribute
 556                         *devattr, char *buf)
 557{
 558        struct via686a_data *data = dev_get_drvdata(dev);
 559        return sprintf(buf, "%s\n", data->name);
 560}
 561static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 562
 563static struct attribute *via686a_attributes[] = {
 564        &sensor_dev_attr_in0_input.dev_attr.attr,
 565        &sensor_dev_attr_in1_input.dev_attr.attr,
 566        &sensor_dev_attr_in2_input.dev_attr.attr,
 567        &sensor_dev_attr_in3_input.dev_attr.attr,
 568        &sensor_dev_attr_in4_input.dev_attr.attr,
 569        &sensor_dev_attr_in0_min.dev_attr.attr,
 570        &sensor_dev_attr_in1_min.dev_attr.attr,
 571        &sensor_dev_attr_in2_min.dev_attr.attr,
 572        &sensor_dev_attr_in3_min.dev_attr.attr,
 573        &sensor_dev_attr_in4_min.dev_attr.attr,
 574        &sensor_dev_attr_in0_max.dev_attr.attr,
 575        &sensor_dev_attr_in1_max.dev_attr.attr,
 576        &sensor_dev_attr_in2_max.dev_attr.attr,
 577        &sensor_dev_attr_in3_max.dev_attr.attr,
 578        &sensor_dev_attr_in4_max.dev_attr.attr,
 579        &sensor_dev_attr_in0_alarm.dev_attr.attr,
 580        &sensor_dev_attr_in1_alarm.dev_attr.attr,
 581        &sensor_dev_attr_in2_alarm.dev_attr.attr,
 582        &sensor_dev_attr_in3_alarm.dev_attr.attr,
 583        &sensor_dev_attr_in4_alarm.dev_attr.attr,
 584
 585        &sensor_dev_attr_temp1_input.dev_attr.attr,
 586        &sensor_dev_attr_temp2_input.dev_attr.attr,
 587        &sensor_dev_attr_temp3_input.dev_attr.attr,
 588        &sensor_dev_attr_temp1_max.dev_attr.attr,
 589        &sensor_dev_attr_temp2_max.dev_attr.attr,
 590        &sensor_dev_attr_temp3_max.dev_attr.attr,
 591        &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 592        &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
 593        &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
 594        &sensor_dev_attr_temp1_alarm.dev_attr.attr,
 595        &sensor_dev_attr_temp2_alarm.dev_attr.attr,
 596        &sensor_dev_attr_temp3_alarm.dev_attr.attr,
 597
 598        &sensor_dev_attr_fan1_input.dev_attr.attr,
 599        &sensor_dev_attr_fan2_input.dev_attr.attr,
 600        &sensor_dev_attr_fan1_min.dev_attr.attr,
 601        &sensor_dev_attr_fan2_min.dev_attr.attr,
 602        &sensor_dev_attr_fan1_div.dev_attr.attr,
 603        &sensor_dev_attr_fan2_div.dev_attr.attr,
 604        &sensor_dev_attr_fan1_alarm.dev_attr.attr,
 605        &sensor_dev_attr_fan2_alarm.dev_attr.attr,
 606
 607        &dev_attr_alarms.attr,
 608        &dev_attr_name.attr,
 609        NULL
 610};
 611
 612static const struct attribute_group via686a_group = {
 613        .attrs = via686a_attributes,
 614};
 615
 616static struct platform_driver via686a_driver = {
 617        .driver = {
 618                .owner  = THIS_MODULE,
 619                .name   = "via686a",
 620        },
 621        .probe          = via686a_probe,
 622        .remove         = __devexit_p(via686a_remove),
 623};
 624
 625
 626/* This is called when the module is loaded */
 627static int __devinit via686a_probe(struct platform_device *pdev)
 628{
 629        struct via686a_data *data;
 630        struct resource *res;
 631        int err;
 632
 633        /* Reserve the ISA region */
 634        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 635        if (!request_region(res->start, VIA686A_EXTENT,
 636                            via686a_driver.driver.name)) {
 637                dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n",
 638                        (unsigned long)res->start, (unsigned long)res->end);
 639                return -ENODEV;
 640        }
 641
 642        if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
 643                err = -ENOMEM;
 644                goto exit_release;
 645        }
 646
 647        platform_set_drvdata(pdev, data);
 648        data->addr = res->start;
 649        data->name = "via686a";
 650        mutex_init(&data->update_lock);
 651
 652        /* Initialize the VIA686A chip */
 653        via686a_init_device(data);
 654
 655        /* Register sysfs hooks */
 656        if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group)))
 657                goto exit_free;
 658
 659        data->hwmon_dev = hwmon_device_register(&pdev->dev);
 660        if (IS_ERR(data->hwmon_dev)) {
 661                err = PTR_ERR(data->hwmon_dev);
 662                goto exit_remove_files;
 663        }
 664
 665        return 0;
 666
 667exit_remove_files:
 668        sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
 669exit_free:
 670        kfree(data);
 671exit_release:
 672        release_region(res->start, VIA686A_EXTENT);
 673        return err;
 674}
 675
 676static int __devexit via686a_remove(struct platform_device *pdev)
 677{
 678        struct via686a_data *data = platform_get_drvdata(pdev);
 679
 680        hwmon_device_unregister(data->hwmon_dev);
 681        sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
 682
 683        release_region(data->addr, VIA686A_EXTENT);
 684        platform_set_drvdata(pdev, NULL);
 685        kfree(data);
 686
 687        return 0;
 688}
 689
 690static void __devinit via686a_init_device(struct via686a_data *data)
 691{
 692        u8 reg;
 693
 694        /* Start monitoring */
 695        reg = via686a_read_value(data, VIA686A_REG_CONFIG);
 696        via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F);
 697
 698        /* Configure temp interrupt mode for continuous-interrupt operation */
 699        reg = via686a_read_value(data, VIA686A_REG_TEMP_MODE);
 700        via686a_write_value(data, VIA686A_REG_TEMP_MODE,
 701                            (reg & ~VIA686A_TEMP_MODE_MASK)
 702                            | VIA686A_TEMP_MODE_CONTINUOUS);
 703}
 704
 705static struct via686a_data *via686a_update_device(struct device *dev)
 706{
 707        struct via686a_data *data = dev_get_drvdata(dev);
 708        int i;
 709
 710        mutex_lock(&data->update_lock);
 711
 712        if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
 713            || !data->valid) {
 714                for (i = 0; i <= 4; i++) {
 715                        data->in[i] =
 716                            via686a_read_value(data, VIA686A_REG_IN(i));
 717                        data->in_min[i] = via686a_read_value(data,
 718                                                             VIA686A_REG_IN_MIN
 719                                                             (i));
 720                        data->in_max[i] =
 721                            via686a_read_value(data, VIA686A_REG_IN_MAX(i));
 722                }
 723                for (i = 1; i <= 2; i++) {
 724                        data->fan[i - 1] =
 725                            via686a_read_value(data, VIA686A_REG_FAN(i));
 726                        data->fan_min[i - 1] = via686a_read_value(data,
 727                                                     VIA686A_REG_FAN_MIN(i));
 728                }
 729                for (i = 0; i <= 2; i++) {
 730                        data->temp[i] = via686a_read_value(data,
 731                                                 VIA686A_REG_TEMP[i]) << 2;
 732                        data->temp_over[i] =
 733                            via686a_read_value(data,
 734                                               VIA686A_REG_TEMP_OVER[i]);
 735                        data->temp_hyst[i] =
 736                            via686a_read_value(data,
 737                                               VIA686A_REG_TEMP_HYST[i]);
 738                }
 739                /* add in lower 2 bits
 740                   temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1
 741                   temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23
 742                   temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23
 743                 */
 744                data->temp[0] |= (via686a_read_value(data,
 745                                                     VIA686A_REG_TEMP_LOW1)
 746                                  & 0xc0) >> 6;
 747                data->temp[1] |=
 748                    (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
 749                     0x30) >> 4;
 750                data->temp[2] |=
 751                    (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
 752                     0xc0) >> 6;
 753
 754                i = via686a_read_value(data, VIA686A_REG_FANDIV);
 755                data->fan_div[0] = (i >> 4) & 0x03;
 756                data->fan_div[1] = i >> 6;
 757                data->alarms =
 758                    via686a_read_value(data,
 759                                       VIA686A_REG_ALARM1) |
 760                    (via686a_read_value(data, VIA686A_REG_ALARM2) << 8);
 761                data->last_updated = jiffies;
 762                data->valid = 1;
 763        }
 764
 765        mutex_unlock(&data->update_lock);
 766
 767        return data;
 768}
 769
 770static struct pci_device_id via686a_pci_ids[] = {
 771        { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
 772        { 0, }
 773};
 774
 775MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
 776
 777static int __devinit via686a_device_add(unsigned short address)
 778{
 779        struct resource res = {
 780                .start  = address,
 781                .end    = address + VIA686A_EXTENT - 1,
 782                .name   = "via686a",
 783                .flags  = IORESOURCE_IO,
 784        };
 785        int err;
 786
 787        err = acpi_check_resource_conflict(&res);
 788        if (err)
 789                goto exit;
 790
 791        pdev = platform_device_alloc("via686a", address);
 792        if (!pdev) {
 793                err = -ENOMEM;
 794                printk(KERN_ERR "via686a: Device allocation failed\n");
 795                goto exit;
 796        }
 797
 798        err = platform_device_add_resources(pdev, &res, 1);
 799        if (err) {
 800                printk(KERN_ERR "via686a: Device resource addition failed "
 801                       "(%d)\n", err);
 802                goto exit_device_put;
 803        }
 804
 805        err = platform_device_add(pdev);
 806        if (err) {
 807                printk(KERN_ERR "via686a: Device addition failed (%d)\n",
 808                       err);
 809                goto exit_device_put;
 810        }
 811
 812        return 0;
 813
 814exit_device_put:
 815        platform_device_put(pdev);
 816exit:
 817        return err;
 818}
 819
 820static int __devinit via686a_pci_probe(struct pci_dev *dev,
 821                                       const struct pci_device_id *id)
 822{
 823        u16 address, val;
 824
 825        if (force_addr) {
 826                address = force_addr & ~(VIA686A_EXTENT - 1);
 827                dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address);
 828                if (PCIBIOS_SUCCESSFUL !=
 829                    pci_write_config_word(dev, VIA686A_BASE_REG, address | 1))
 830                        return -ENODEV;
 831        }
 832        if (PCIBIOS_SUCCESSFUL !=
 833            pci_read_config_word(dev, VIA686A_BASE_REG, &val))
 834                return -ENODEV;
 835
 836        address = val & ~(VIA686A_EXTENT - 1);
 837        if (address == 0) {
 838                dev_err(&dev->dev, "base address not set - upgrade BIOS "
 839                        "or use force_addr=0xaddr\n");
 840                return -ENODEV;
 841        }
 842
 843        if (PCIBIOS_SUCCESSFUL !=
 844            pci_read_config_word(dev, VIA686A_ENABLE_REG, &val))
 845                return -ENODEV;
 846        if (!(val & 0x0001)) {
 847                if (!force_addr) {
 848                        dev_warn(&dev->dev, "Sensors disabled, enable "
 849                                 "with force_addr=0x%x\n", address);
 850                        return -ENODEV;
 851                }
 852
 853                dev_warn(&dev->dev, "Enabling sensors\n");
 854                if (PCIBIOS_SUCCESSFUL !=
 855                    pci_write_config_word(dev, VIA686A_ENABLE_REG,
 856                                          val | 0x0001))
 857                        return -ENODEV;
 858        }
 859
 860        if (platform_driver_register(&via686a_driver))
 861                goto exit;
 862
 863        /* Sets global pdev as a side effect */
 864        if (via686a_device_add(address))
 865                goto exit_unregister;
 866
 867        /* Always return failure here.  This is to allow other drivers to bind
 868         * to this pci device.  We don't really want to have control over the
 869         * pci device, we only wanted to read as few register values from it.
 870         */
 871        s_bridge = pci_dev_get(dev);
 872        return -ENODEV;
 873
 874exit_unregister:
 875        platform_driver_unregister(&via686a_driver);
 876exit:
 877        return -ENODEV;
 878}
 879
 880static struct pci_driver via686a_pci_driver = {
 881        .name           = "via686a",
 882        .id_table       = via686a_pci_ids,
 883        .probe          = via686a_pci_probe,
 884};
 885
 886static int __init sm_via686a_init(void)
 887{
 888        return pci_register_driver(&via686a_pci_driver);
 889}
 890
 891static void __exit sm_via686a_exit(void)
 892{
 893        pci_unregister_driver(&via686a_pci_driver);
 894        if (s_bridge != NULL) {
 895                platform_device_unregister(pdev);
 896                platform_driver_unregister(&via686a_driver);
 897                pci_dev_put(s_bridge);
 898                s_bridge = NULL;
 899        }
 900}
 901
 902MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
 903              "Mark Studebaker <mdsxyz123@yahoo.com> "
 904              "and Bob Dougherty <bobd@stanford.edu>");
 905MODULE_DESCRIPTION("VIA 686A Sensor device");
 906MODULE_LICENSE("GPL");
 907
 908module_init(sm_via686a_init);
 909module_exit(sm_via686a_exit);
 910