linux/drivers/hwmon/sis5595.c
<<
>>
Prefs
   1/*
   2    sis5595.c - Part of lm_sensors, Linux kernel modules
   3                for hardware monitoring
   4
   5    Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
   6                        Kyösti Mälkki <kmalkki@cc.hut.fi>, and
   7                        Mark D. Studebaker <mdsxyz123@yahoo.com>
   8    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
   9    the help of Jean Delvare <khali@linux-fr.org>
  10
  11    This program is free software; you can redistribute it and/or modify
  12    it under the terms of the GNU General Public License as published by
  13    the Free Software Foundation; either version 2 of the License, or
  14    (at your option) any later version.
  15
  16    This program is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19    GNU General Public License for more details.
  20
  21    You should have received a copy of the GNU General Public License
  22    along with this program; if not, write to the Free Software
  23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24*/
  25
  26/*
  27   SiS southbridge has a LM78-like chip integrated on the same IC.
  28   This driver is a customized copy of lm78.c
  29   
  30   Supports following revisions:
  31        Version         PCI ID          PCI Revision
  32        1               1039/0008       AF or less
  33        2               1039/0008       B0 or greater
  34
  35   Note: these chips contain a 0008 device which is incompatible with the
  36         5595. We recognize these by the presence of the listed
  37         "blacklist" PCI ID and refuse to load.
  38
  39   NOT SUPPORTED        PCI ID          BLACKLIST PCI ID        
  40         540            0008            0540
  41         550            0008            0550
  42        5513            0008            5511
  43        5581            0008            5597
  44        5582            0008            5597
  45        5597            0008            5597
  46        5598            0008            5597/5598
  47         630            0008            0630
  48         645            0008            0645
  49         730            0008            0730
  50         735            0008            0735
  51*/
  52
  53#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  54
  55#include <linux/module.h>
  56#include <linux/slab.h>
  57#include <linux/ioport.h>
  58#include <linux/pci.h>
  59#include <linux/platform_device.h>
  60#include <linux/hwmon.h>
  61#include <linux/hwmon-sysfs.h>
  62#include <linux/err.h>
  63#include <linux/init.h>
  64#include <linux/jiffies.h>
  65#include <linux/mutex.h>
  66#include <linux/sysfs.h>
  67#include <linux/acpi.h>
  68#include <linux/io.h>
  69
  70
  71/* If force_addr is set to anything different from 0, we forcibly enable
  72   the device at the given address. */
  73static u16 force_addr;
  74module_param(force_addr, ushort, 0);
  75MODULE_PARM_DESC(force_addr,
  76                 "Initialize the base address of the sensors");
  77
  78static struct platform_device *pdev;
  79
  80/* Many SIS5595 constants specified below */
  81
  82/* Length of ISA address segment */
  83#define SIS5595_EXTENT 8
  84/* PCI Config Registers */
  85#define SIS5595_BASE_REG 0x68
  86#define SIS5595_PIN_REG 0x7A
  87#define SIS5595_ENABLE_REG 0x7B
  88
  89/* Where are the ISA address/data registers relative to the base address */
  90#define SIS5595_ADDR_REG_OFFSET 5
  91#define SIS5595_DATA_REG_OFFSET 6
  92
  93/* The SIS5595 registers */
  94#define SIS5595_REG_IN_MAX(nr) (0x2b + (nr) * 2)
  95#define SIS5595_REG_IN_MIN(nr) (0x2c + (nr) * 2)
  96#define SIS5595_REG_IN(nr) (0x20 + (nr))
  97
  98#define SIS5595_REG_FAN_MIN(nr) (0x3b + (nr))
  99#define SIS5595_REG_FAN(nr) (0x28 + (nr))
 100
 101/* On the first version of the chip, the temp registers are separate.
 102   On the second version,
 103   TEMP pin is shared with IN4, configured in PCI register 0x7A.
 104   The registers are the same as well.
 105   OVER and HYST are really MAX and MIN. */
 106
 107#define REV2MIN 0xb0
 108#define SIS5595_REG_TEMP        (( data->revision) >= REV2MIN) ? \
 109                                        SIS5595_REG_IN(4) : 0x27
 110#define SIS5595_REG_TEMP_OVER   (( data->revision) >= REV2MIN) ? \
 111                                        SIS5595_REG_IN_MAX(4) : 0x39
 112#define SIS5595_REG_TEMP_HYST   (( data->revision) >= REV2MIN) ? \
 113                                        SIS5595_REG_IN_MIN(4) : 0x3a
 114
 115#define SIS5595_REG_CONFIG 0x40
 116#define SIS5595_REG_ALARM1 0x41
 117#define SIS5595_REG_ALARM2 0x42
 118#define SIS5595_REG_FANDIV 0x47
 119
 120/* Conversions. Limit checking is only done on the TO_REG
 121   variants. */
 122
 123/* IN: mV, (0V to 4.08V)
 124   REG: 16mV/bit */
 125static inline u8 IN_TO_REG(unsigned long val)
 126{
 127        unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
 128        return (nval + 8) / 16;
 129}
 130#define IN_FROM_REG(val) ((val) *  16)
 131
 132static inline u8 FAN_TO_REG(long rpm, int div)
 133{
 134        if (rpm <= 0)
 135                return 255;
 136        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 137}
 138
 139static inline int FAN_FROM_REG(u8 val, int div)
 140{
 141        return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
 142}
 143
 144/* TEMP: mC (-54.12C to +157.53C)
 145   REG: 0.83C/bit + 52.12, two's complement  */
 146static inline int TEMP_FROM_REG(s8 val)
 147{
 148        return val * 830 + 52120;
 149}
 150static inline s8 TEMP_TO_REG(int val)
 151{
 152        int nval = SENSORS_LIMIT(val, -54120, 157530) ;
 153        return nval<0 ? (nval-5212-415)/830 : (nval-5212+415)/830;
 154}
 155
 156/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
 157   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
 158static inline u8 DIV_TO_REG(int val)
 159{
 160        return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
 161}
 162#define DIV_FROM_REG(val) (1 << (val))
 163
 164/* For each registered chip, we need to keep some data in memory.
 165   The structure is dynamically allocated. */
 166struct sis5595_data {
 167        unsigned short addr;
 168        const char *name;
 169        struct device *hwmon_dev;
 170        struct mutex lock;
 171
 172        struct mutex update_lock;
 173        char valid;             /* !=0 if following fields are valid */
 174        unsigned long last_updated;     /* In jiffies */
 175        char maxins;            /* == 3 if temp enabled, otherwise == 4 */
 176        u8 revision;            /* Reg. value */
 177
 178        u8 in[5];               /* Register value */
 179        u8 in_max[5];           /* Register value */
 180        u8 in_min[5];           /* Register value */
 181        u8 fan[2];              /* Register value */
 182        u8 fan_min[2];          /* Register value */
 183        s8 temp;                /* Register value */
 184        s8 temp_over;           /* Register value */
 185        s8 temp_hyst;           /* Register value */
 186        u8 fan_div[2];          /* Register encoding, shifted right */
 187        u16 alarms;             /* Register encoding, combined */
 188};
 189
 190static struct pci_dev *s_bridge;        /* pointer to the (only) sis5595 */
 191
 192static int sis5595_probe(struct platform_device *pdev);
 193static int __devexit sis5595_remove(struct platform_device *pdev);
 194
 195static int sis5595_read_value(struct sis5595_data *data, u8 reg);
 196static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value);
 197static struct sis5595_data *sis5595_update_device(struct device *dev);
 198static void sis5595_init_device(struct sis5595_data *data);
 199
 200static struct platform_driver sis5595_driver = {
 201        .driver = {
 202                .owner  = THIS_MODULE,
 203                .name   = "sis5595",
 204        },
 205        .probe          = sis5595_probe,
 206        .remove         = __devexit_p(sis5595_remove),
 207};
 208
 209/* 4 Voltages */
 210static ssize_t show_in(struct device *dev, struct device_attribute *da,
 211                       char *buf)
 212{
 213        struct sis5595_data *data = sis5595_update_device(dev);
 214        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 215        int nr = attr->index;
 216        return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
 217}
 218
 219static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
 220                           char *buf)
 221{
 222        struct sis5595_data *data = sis5595_update_device(dev);
 223        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 224        int nr = attr->index;
 225        return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
 226}
 227
 228static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
 229                           char *buf)
 230{
 231        struct sis5595_data *data = sis5595_update_device(dev);
 232        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 233        int nr = attr->index;
 234        return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
 235}
 236
 237static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
 238                          const char *buf, size_t count)
 239{
 240        struct sis5595_data *data = dev_get_drvdata(dev);
 241        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 242        int nr = attr->index;
 243        unsigned long val = simple_strtoul(buf, NULL, 10);
 244
 245        mutex_lock(&data->update_lock);
 246        data->in_min[nr] = IN_TO_REG(val);
 247        sis5595_write_value(data, SIS5595_REG_IN_MIN(nr), data->in_min[nr]);
 248        mutex_unlock(&data->update_lock);
 249        return count;
 250}
 251
 252static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
 253                          const char *buf, size_t count)
 254{
 255        struct sis5595_data *data = dev_get_drvdata(dev);
 256        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 257        int nr = attr->index;
 258        unsigned long val = simple_strtoul(buf, NULL, 10);
 259
 260        mutex_lock(&data->update_lock);
 261        data->in_max[nr] = IN_TO_REG(val);
 262        sis5595_write_value(data, SIS5595_REG_IN_MAX(nr), data->in_max[nr]);
 263        mutex_unlock(&data->update_lock);
 264        return count;
 265}
 266
 267#define show_in_offset(offset)                                  \
 268static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,          \
 269                show_in, NULL, offset);                         \
 270static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,  \
 271                show_in_min, set_in_min, offset);               \
 272static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,  \
 273                show_in_max, set_in_max, offset);
 274
 275show_in_offset(0);
 276show_in_offset(1);
 277show_in_offset(2);
 278show_in_offset(3);
 279show_in_offset(4);
 280
 281/* Temperature */
 282static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
 283{
 284        struct sis5595_data *data = sis5595_update_device(dev);
 285        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
 286}
 287
 288static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
 289{
 290        struct sis5595_data *data = sis5595_update_device(dev);
 291        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
 292}
 293
 294static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 295{
 296        struct sis5595_data *data = dev_get_drvdata(dev);
 297        long val = simple_strtol(buf, NULL, 10);
 298
 299        mutex_lock(&data->update_lock);
 300        data->temp_over = TEMP_TO_REG(val);
 301        sis5595_write_value(data, SIS5595_REG_TEMP_OVER, data->temp_over);
 302        mutex_unlock(&data->update_lock);
 303        return count;
 304}
 305
 306static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
 307{
 308        struct sis5595_data *data = sis5595_update_device(dev);
 309        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
 310}
 311
 312static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 313{
 314        struct sis5595_data *data = dev_get_drvdata(dev);
 315        long val = simple_strtol(buf, NULL, 10);
 316
 317        mutex_lock(&data->update_lock);
 318        data->temp_hyst = TEMP_TO_REG(val);
 319        sis5595_write_value(data, SIS5595_REG_TEMP_HYST, data->temp_hyst);
 320        mutex_unlock(&data->update_lock);
 321        return count;
 322}
 323
 324static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
 325static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
 326                show_temp_over, set_temp_over);
 327static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
 328                show_temp_hyst, set_temp_hyst);
 329
 330/* 2 Fans */
 331static ssize_t show_fan(struct device *dev, struct device_attribute *da,
 332                        char *buf)
 333{
 334        struct sis5595_data *data = sis5595_update_device(dev);
 335        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 336        int nr = attr->index;
 337        return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
 338                DIV_FROM_REG(data->fan_div[nr])) );
 339}
 340
 341static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
 342                            char *buf)
 343{
 344        struct sis5595_data *data = sis5595_update_device(dev);
 345        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 346        int nr = attr->index;
 347        return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
 348                DIV_FROM_REG(data->fan_div[nr])) );
 349}
 350
 351static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
 352                           const char *buf, size_t count)
 353{
 354        struct sis5595_data *data = dev_get_drvdata(dev);
 355        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 356        int nr = attr->index;
 357        unsigned long val = simple_strtoul(buf, NULL, 10);
 358
 359        mutex_lock(&data->update_lock);
 360        data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
 361        sis5595_write_value(data, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
 362        mutex_unlock(&data->update_lock);
 363        return count;
 364}
 365
 366static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
 367                            char *buf)
 368{
 369        struct sis5595_data *data = sis5595_update_device(dev);
 370        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 371        int nr = attr->index;
 372        return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
 373}
 374
 375/* Note: we save and restore the fan minimum here, because its value is
 376   determined in part by the fan divisor.  This follows the principle of
 377   least surprise; the user doesn't expect the fan minimum to change just
 378   because the divisor changed. */
 379static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 380                           const char *buf, size_t count)
 381{
 382        struct sis5595_data *data = dev_get_drvdata(dev);
 383        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 384        int nr = attr->index;
 385        unsigned long min;
 386        unsigned long val = simple_strtoul(buf, NULL, 10);
 387        int reg;
 388
 389        mutex_lock(&data->update_lock);
 390        min = FAN_FROM_REG(data->fan_min[nr],
 391                        DIV_FROM_REG(data->fan_div[nr]));
 392        reg = sis5595_read_value(data, SIS5595_REG_FANDIV);
 393
 394        switch (val) {
 395        case 1: data->fan_div[nr] = 0; break;
 396        case 2: data->fan_div[nr] = 1; break;
 397        case 4: data->fan_div[nr] = 2; break;
 398        case 8: data->fan_div[nr] = 3; break;
 399        default:
 400                dev_err(dev, "fan_div value %ld not "
 401                        "supported. Choose one of 1, 2, 4 or 8!\n", val);
 402                mutex_unlock(&data->update_lock);
 403                return -EINVAL;
 404        }
 405        
 406        switch (nr) {
 407        case 0:
 408                reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
 409                break;
 410        case 1:
 411                reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
 412                break;
 413        }
 414        sis5595_write_value(data, SIS5595_REG_FANDIV, reg);
 415        data->fan_min[nr] =
 416                FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
 417        sis5595_write_value(data, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
 418        mutex_unlock(&data->update_lock);
 419        return count;
 420}
 421
 422#define show_fan_offset(offset)                                         \
 423static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,                 \
 424                show_fan, NULL, offset - 1);                            \
 425static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,         \
 426                show_fan_min, set_fan_min, offset - 1);                 \
 427static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,         \
 428                show_fan_div, set_fan_div, offset - 1);
 429
 430show_fan_offset(1);
 431show_fan_offset(2);
 432
 433/* Alarms */
 434static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
 435{
 436        struct sis5595_data *data = sis5595_update_device(dev);
 437        return sprintf(buf, "%d\n", data->alarms);
 438}
 439static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 440
 441static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
 442                          char *buf)
 443{
 444        struct sis5595_data *data = sis5595_update_device(dev);
 445        int nr = to_sensor_dev_attr(da)->index;
 446        return sprintf(buf, "%u\n", (data->alarms >> nr) & 1);
 447}
 448static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
 449static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
 450static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
 451static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
 452static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 15);
 453static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
 454static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
 455static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 15);
 456
 457static ssize_t show_name(struct device *dev, struct device_attribute *attr,
 458                         char *buf)
 459{
 460        struct sis5595_data *data = dev_get_drvdata(dev);
 461        return sprintf(buf, "%s\n", data->name);
 462}
 463static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 464
 465static struct attribute *sis5595_attributes[] = {
 466        &sensor_dev_attr_in0_input.dev_attr.attr,
 467        &sensor_dev_attr_in0_min.dev_attr.attr,
 468        &sensor_dev_attr_in0_max.dev_attr.attr,
 469        &sensor_dev_attr_in0_alarm.dev_attr.attr,
 470        &sensor_dev_attr_in1_input.dev_attr.attr,
 471        &sensor_dev_attr_in1_min.dev_attr.attr,
 472        &sensor_dev_attr_in1_max.dev_attr.attr,
 473        &sensor_dev_attr_in1_alarm.dev_attr.attr,
 474        &sensor_dev_attr_in2_input.dev_attr.attr,
 475        &sensor_dev_attr_in2_min.dev_attr.attr,
 476        &sensor_dev_attr_in2_max.dev_attr.attr,
 477        &sensor_dev_attr_in2_alarm.dev_attr.attr,
 478        &sensor_dev_attr_in3_input.dev_attr.attr,
 479        &sensor_dev_attr_in3_min.dev_attr.attr,
 480        &sensor_dev_attr_in3_max.dev_attr.attr,
 481        &sensor_dev_attr_in3_alarm.dev_attr.attr,
 482
 483        &sensor_dev_attr_fan1_input.dev_attr.attr,
 484        &sensor_dev_attr_fan1_min.dev_attr.attr,
 485        &sensor_dev_attr_fan1_div.dev_attr.attr,
 486        &sensor_dev_attr_fan1_alarm.dev_attr.attr,
 487        &sensor_dev_attr_fan2_input.dev_attr.attr,
 488        &sensor_dev_attr_fan2_min.dev_attr.attr,
 489        &sensor_dev_attr_fan2_div.dev_attr.attr,
 490        &sensor_dev_attr_fan2_alarm.dev_attr.attr,
 491
 492        &dev_attr_alarms.attr,
 493        &dev_attr_name.attr,
 494        NULL
 495};
 496
 497static const struct attribute_group sis5595_group = {
 498        .attrs = sis5595_attributes,
 499};
 500
 501static struct attribute *sis5595_attributes_in4[] = {
 502        &sensor_dev_attr_in4_input.dev_attr.attr,
 503        &sensor_dev_attr_in4_min.dev_attr.attr,
 504        &sensor_dev_attr_in4_max.dev_attr.attr,
 505        &sensor_dev_attr_in4_alarm.dev_attr.attr,
 506        NULL
 507};
 508
 509static const struct attribute_group sis5595_group_in4 = {
 510        .attrs = sis5595_attributes_in4,
 511};
 512
 513static struct attribute *sis5595_attributes_temp1[] = {
 514        &dev_attr_temp1_input.attr,
 515        &dev_attr_temp1_max.attr,
 516        &dev_attr_temp1_max_hyst.attr,
 517        &sensor_dev_attr_temp1_alarm.dev_attr.attr,
 518        NULL
 519};
 520
 521static const struct attribute_group sis5595_group_temp1 = {
 522        .attrs = sis5595_attributes_temp1,
 523};
 524 
 525/* This is called when the module is loaded */
 526static int __devinit sis5595_probe(struct platform_device *pdev)
 527{
 528        int err = 0;
 529        int i;
 530        struct sis5595_data *data;
 531        struct resource *res;
 532        char val;
 533
 534        /* Reserve the ISA region */
 535        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 536        if (!request_region(res->start, SIS5595_EXTENT,
 537                            sis5595_driver.driver.name)) {
 538                err = -EBUSY;
 539                goto exit;
 540        }
 541
 542        if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) {
 543                err = -ENOMEM;
 544                goto exit_release;
 545        }
 546
 547        mutex_init(&data->lock);
 548        mutex_init(&data->update_lock);
 549        data->addr = res->start;
 550        data->name = "sis5595";
 551        platform_set_drvdata(pdev, data);
 552
 553        /* Check revision and pin registers to determine whether 4 or 5 voltages */
 554        data->revision = s_bridge->revision;
 555        /* 4 voltages, 1 temp */
 556        data->maxins = 3;
 557        if (data->revision >= REV2MIN) {
 558                pci_read_config_byte(s_bridge, SIS5595_PIN_REG, &val);
 559                if (!(val & 0x80))
 560                        /* 5 voltages, no temps */
 561                        data->maxins = 4;
 562        }
 563        
 564        /* Initialize the SIS5595 chip */
 565        sis5595_init_device(data);
 566
 567        /* A few vars need to be filled upon startup */
 568        for (i = 0; i < 2; i++) {
 569                data->fan_min[i] = sis5595_read_value(data,
 570                                        SIS5595_REG_FAN_MIN(i));
 571        }
 572
 573        /* Register sysfs hooks */
 574        if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group)))
 575                goto exit_free;
 576        if (data->maxins == 4) {
 577                if ((err = sysfs_create_group(&pdev->dev.kobj,
 578                                              &sis5595_group_in4)))
 579                        goto exit_remove_files;
 580        } else {
 581                if ((err = sysfs_create_group(&pdev->dev.kobj,
 582                                              &sis5595_group_temp1)))
 583                        goto exit_remove_files;
 584        }
 585
 586        data->hwmon_dev = hwmon_device_register(&pdev->dev);
 587        if (IS_ERR(data->hwmon_dev)) {
 588                err = PTR_ERR(data->hwmon_dev);
 589                goto exit_remove_files;
 590        }
 591
 592        return 0;
 593
 594exit_remove_files:
 595        sysfs_remove_group(&pdev->dev.kobj, &sis5595_group);
 596        sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_in4);
 597        sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_temp1);
 598exit_free:
 599        kfree(data);
 600exit_release:
 601        release_region(res->start, SIS5595_EXTENT);
 602exit:
 603        return err;
 604}
 605
 606static int __devexit sis5595_remove(struct platform_device *pdev)
 607{
 608        struct sis5595_data *data = platform_get_drvdata(pdev);
 609
 610        hwmon_device_unregister(data->hwmon_dev);
 611        sysfs_remove_group(&pdev->dev.kobj, &sis5595_group);
 612        sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_in4);
 613        sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_temp1);
 614
 615        release_region(data->addr, SIS5595_EXTENT);
 616        platform_set_drvdata(pdev, NULL);
 617        kfree(data);
 618
 619        return 0;
 620}
 621
 622
 623/* ISA access must be locked explicitly. */
 624static int sis5595_read_value(struct sis5595_data *data, u8 reg)
 625{
 626        int res;
 627
 628        mutex_lock(&data->lock);
 629        outb_p(reg, data->addr + SIS5595_ADDR_REG_OFFSET);
 630        res = inb_p(data->addr + SIS5595_DATA_REG_OFFSET);
 631        mutex_unlock(&data->lock);
 632        return res;
 633}
 634
 635static void sis5595_write_value(struct sis5595_data *data, u8 reg, u8 value)
 636{
 637        mutex_lock(&data->lock);
 638        outb_p(reg, data->addr + SIS5595_ADDR_REG_OFFSET);
 639        outb_p(value, data->addr + SIS5595_DATA_REG_OFFSET);
 640        mutex_unlock(&data->lock);
 641}
 642
 643/* Called when we have found a new SIS5595. */
 644static void __devinit sis5595_init_device(struct sis5595_data *data)
 645{
 646        u8 config = sis5595_read_value(data, SIS5595_REG_CONFIG);
 647        if (!(config & 0x01))
 648                sis5595_write_value(data, SIS5595_REG_CONFIG,
 649                                (config & 0xf7) | 0x01);
 650}
 651
 652static struct sis5595_data *sis5595_update_device(struct device *dev)
 653{
 654        struct sis5595_data *data = dev_get_drvdata(dev);
 655        int i;
 656
 657        mutex_lock(&data->update_lock);
 658
 659        if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
 660            || !data->valid) {
 661
 662                for (i = 0; i <= data->maxins; i++) {
 663                        data->in[i] =
 664                            sis5595_read_value(data, SIS5595_REG_IN(i));
 665                        data->in_min[i] =
 666                            sis5595_read_value(data,
 667                                               SIS5595_REG_IN_MIN(i));
 668                        data->in_max[i] =
 669                            sis5595_read_value(data,
 670                                               SIS5595_REG_IN_MAX(i));
 671                }
 672                for (i = 0; i < 2; i++) {
 673                        data->fan[i] =
 674                            sis5595_read_value(data, SIS5595_REG_FAN(i));
 675                        data->fan_min[i] =
 676                            sis5595_read_value(data,
 677                                               SIS5595_REG_FAN_MIN(i));
 678                }
 679                if (data->maxins == 3) {
 680                        data->temp =
 681                            sis5595_read_value(data, SIS5595_REG_TEMP);
 682                        data->temp_over =
 683                            sis5595_read_value(data, SIS5595_REG_TEMP_OVER);
 684                        data->temp_hyst =
 685                            sis5595_read_value(data, SIS5595_REG_TEMP_HYST);
 686                }
 687                i = sis5595_read_value(data, SIS5595_REG_FANDIV);
 688                data->fan_div[0] = (i >> 4) & 0x03;
 689                data->fan_div[1] = i >> 6;
 690                data->alarms =
 691                    sis5595_read_value(data, SIS5595_REG_ALARM1) |
 692                    (sis5595_read_value(data, SIS5595_REG_ALARM2) << 8);
 693                data->last_updated = jiffies;
 694                data->valid = 1;
 695        }
 696
 697        mutex_unlock(&data->update_lock);
 698
 699        return data;
 700}
 701
 702static const struct pci_device_id sis5595_pci_ids[] = {
 703        { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
 704        { 0, }
 705};
 706
 707MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
 708
 709static int blacklist[] __devinitdata = {
 710        PCI_DEVICE_ID_SI_540,
 711        PCI_DEVICE_ID_SI_550,
 712        PCI_DEVICE_ID_SI_630,
 713        PCI_DEVICE_ID_SI_645,
 714        PCI_DEVICE_ID_SI_730,
 715        PCI_DEVICE_ID_SI_735,
 716        PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but
 717                                  that ID shows up in other chips so we
 718                                  use the 5511 ID for recognition */
 719        PCI_DEVICE_ID_SI_5597,
 720        PCI_DEVICE_ID_SI_5598,
 721        0 };
 722
 723static int __devinit sis5595_device_add(unsigned short address)
 724{
 725        struct resource res = {
 726                .start  = address,
 727                .end    = address + SIS5595_EXTENT - 1,
 728                .name   = "sis5595",
 729                .flags  = IORESOURCE_IO,
 730        };
 731        int err;
 732
 733        err = acpi_check_resource_conflict(&res);
 734        if (err)
 735                goto exit;
 736
 737        pdev = platform_device_alloc("sis5595", address);
 738        if (!pdev) {
 739                err = -ENOMEM;
 740                pr_err("Device allocation failed\n");
 741                goto exit;
 742        }
 743
 744        err = platform_device_add_resources(pdev, &res, 1);
 745        if (err) {
 746                pr_err("Device resource addition failed (%d)\n", err);
 747                goto exit_device_put;
 748        }
 749
 750        err = platform_device_add(pdev);
 751        if (err) {
 752                pr_err("Device addition failed (%d)\n", err);
 753                goto exit_device_put;
 754        }
 755
 756        return 0;
 757
 758exit_device_put:
 759        platform_device_put(pdev);
 760exit:
 761        return err;
 762}
 763
 764static int __devinit sis5595_pci_probe(struct pci_dev *dev,
 765                                       const struct pci_device_id *id)
 766{
 767        u16 address;
 768        u8 enable;
 769        int *i;
 770
 771        for (i = blacklist; *i != 0; i++) {
 772                struct pci_dev *d;
 773                if ((d = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL))) {
 774                        dev_err(&d->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
 775                        pci_dev_put(d);
 776                        return -ENODEV;
 777                }
 778        }
 779        
 780        force_addr &= ~(SIS5595_EXTENT - 1);
 781        if (force_addr) {
 782                dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", force_addr);
 783                pci_write_config_word(dev, SIS5595_BASE_REG, force_addr);
 784        }
 785
 786        if (PCIBIOS_SUCCESSFUL !=
 787            pci_read_config_word(dev, SIS5595_BASE_REG, &address)) {
 788                dev_err(&dev->dev, "Failed to read ISA address\n");
 789                return -ENODEV;
 790        }
 791        
 792        address &= ~(SIS5595_EXTENT - 1);
 793        if (!address) {
 794                dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n");
 795                return -ENODEV;
 796        }
 797        if (force_addr && address != force_addr) {
 798                /* doesn't work for some chips? */
 799                dev_err(&dev->dev, "Failed to force ISA address\n");
 800                return -ENODEV;
 801        }
 802
 803        if (PCIBIOS_SUCCESSFUL !=
 804            pci_read_config_byte(dev, SIS5595_ENABLE_REG, &enable)) {
 805                dev_err(&dev->dev, "Failed to read enable register\n");
 806                return -ENODEV;
 807        }
 808        if (!(enable & 0x80)) {
 809                if ((PCIBIOS_SUCCESSFUL !=
 810                     pci_write_config_byte(dev, SIS5595_ENABLE_REG,
 811                                           enable | 0x80))
 812                 || (PCIBIOS_SUCCESSFUL !=
 813                     pci_read_config_byte(dev, SIS5595_ENABLE_REG, &enable))
 814                 || (!(enable & 0x80))) {
 815                        /* doesn't work for some chips! */
 816                        dev_err(&dev->dev, "Failed to enable HWM device\n");
 817                        return -ENODEV;
 818                }
 819        }
 820
 821        if (platform_driver_register(&sis5595_driver)) {
 822                dev_dbg(&dev->dev, "Failed to register sis5595 driver\n");
 823                goto exit;
 824        }
 825
 826        s_bridge = pci_dev_get(dev);
 827        /* Sets global pdev as a side effect */
 828        if (sis5595_device_add(address))
 829                goto exit_unregister;
 830
 831        /* Always return failure here.  This is to allow other drivers to bind
 832         * to this pci device.  We don't really want to have control over the
 833         * pci device, we only wanted to read as few register values from it.
 834         */
 835        return -ENODEV;
 836
 837exit_unregister:
 838        pci_dev_put(dev);
 839        platform_driver_unregister(&sis5595_driver);
 840exit:
 841        return -ENODEV;
 842}
 843
 844static struct pci_driver sis5595_pci_driver = {
 845        .name            = "sis5595",
 846        .id_table        = sis5595_pci_ids,
 847        .probe           = sis5595_pci_probe,
 848};
 849
 850static int __init sm_sis5595_init(void)
 851{
 852        return pci_register_driver(&sis5595_pci_driver);
 853}
 854
 855static void __exit sm_sis5595_exit(void)
 856{
 857        pci_unregister_driver(&sis5595_pci_driver);
 858        if (s_bridge != NULL) {
 859                platform_device_unregister(pdev);
 860                platform_driver_unregister(&sis5595_driver);
 861                pci_dev_put(s_bridge);
 862                s_bridge = NULL;
 863        }
 864}
 865
 866MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
 867MODULE_DESCRIPTION("SiS 5595 Sensor device");
 868MODULE_LICENSE("GPL");
 869
 870module_init(sm_sis5595_init);
 871module_exit(sm_sis5595_exit);
 872