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