linux/drivers/hwmon/smsc47m1.c
<<
>>
Prefs
   1/*
   2    smsc47m1.c - Part of lm_sensors, Linux kernel modules
   3                 for hardware monitoring
   4
   5    Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
   6    LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997
   7    Super-I/O chips.
   8
   9    Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
  10    Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org>
  11    Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
  12                        and Jean Delvare
  13
  14    This program is free software; you can redistribute it and/or modify
  15    it under the terms of the GNU General Public License as published by
  16    the Free Software Foundation; either version 2 of the License, or
  17    (at your option) any later version.
  18
  19    This program is distributed in the hope that it will be useful,
  20    but WITHOUT ANY WARRANTY; without even the implied warranty of
  21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22    GNU General Public License for more details.
  23
  24    You should have received a copy of the GNU General Public License
  25    along with this program; if not, write to the Free Software
  26    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27*/
  28
  29#include <linux/module.h>
  30#include <linux/slab.h>
  31#include <linux/ioport.h>
  32#include <linux/jiffies.h>
  33#include <linux/platform_device.h>
  34#include <linux/hwmon.h>
  35#include <linux/hwmon-sysfs.h>
  36#include <linux/err.h>
  37#include <linux/init.h>
  38#include <linux/mutex.h>
  39#include <linux/sysfs.h>
  40#include <asm/io.h>
  41
  42static unsigned short force_id;
  43module_param(force_id, ushort, 0);
  44MODULE_PARM_DESC(force_id, "Override the detected device ID");
  45
  46static struct platform_device *pdev;
  47
  48#define DRVNAME "smsc47m1"
  49enum chips { smsc47m1, smsc47m2 };
  50
  51/* Super-I/0 registers and commands */
  52
  53#define REG     0x2e    /* The register to read/write */
  54#define VAL     0x2f    /* The value to read/write */
  55
  56static inline void
  57superio_outb(int reg, int val)
  58{
  59        outb(reg, REG);
  60        outb(val, VAL);
  61}
  62
  63static inline int
  64superio_inb(int reg)
  65{
  66        outb(reg, REG);
  67        return inb(VAL);
  68}
  69
  70/* logical device for fans is 0x0A */
  71#define superio_select() superio_outb(0x07, 0x0A)
  72
  73static inline void
  74superio_enter(void)
  75{
  76        outb(0x55, REG);
  77}
  78
  79static inline void
  80superio_exit(void)
  81{
  82        outb(0xAA, REG);
  83}
  84
  85#define SUPERIO_REG_ACT         0x30
  86#define SUPERIO_REG_BASE        0x60
  87#define SUPERIO_REG_DEVID       0x20
  88
  89/* Logical device registers */
  90
  91#define SMSC_EXTENT             0x80
  92
  93/* nr is 0 or 1 in the macros below */
  94#define SMSC47M1_REG_ALARM              0x04
  95#define SMSC47M1_REG_TPIN(nr)           (0x34 - (nr))
  96#define SMSC47M1_REG_PPIN(nr)           (0x36 - (nr))
  97#define SMSC47M1_REG_FANDIV             0x58
  98
  99static const u8 SMSC47M1_REG_FAN[3]             = { 0x59, 0x5a, 0x6b };
 100static const u8 SMSC47M1_REG_FAN_PRELOAD[3]     = { 0x5b, 0x5c, 0x6c };
 101static const u8 SMSC47M1_REG_PWM[3]             = { 0x56, 0x57, 0x69 };
 102
 103#define SMSC47M2_REG_ALARM6             0x09
 104#define SMSC47M2_REG_TPIN1              0x38
 105#define SMSC47M2_REG_TPIN2              0x37
 106#define SMSC47M2_REG_TPIN3              0x2d
 107#define SMSC47M2_REG_PPIN3              0x2c
 108#define SMSC47M2_REG_FANDIV3            0x6a
 109
 110#define MIN_FROM_REG(reg,div)           ((reg)>=192 ? 0 : \
 111                                         983040/((192-(reg))*(div)))
 112#define FAN_FROM_REG(reg,div,preload)   ((reg)<=(preload) || (reg)==255 ? 0 : \
 113                                         983040/(((reg)-(preload))*(div)))
 114#define DIV_FROM_REG(reg)               (1 << (reg))
 115#define PWM_FROM_REG(reg)               (((reg) & 0x7E) << 1)
 116#define PWM_EN_FROM_REG(reg)            ((~(reg)) & 0x01)
 117#define PWM_TO_REG(reg)                 (((reg) >> 1) & 0x7E)
 118
 119struct smsc47m1_data {
 120        unsigned short addr;
 121        const char *name;
 122        enum chips type;
 123        struct device *hwmon_dev;
 124
 125        struct mutex update_lock;
 126        unsigned long last_updated;     /* In jiffies */
 127
 128        u8 fan[3];              /* Register value */
 129        u8 fan_preload[3];      /* Register value */
 130        u8 fan_div[3];          /* Register encoding, shifted right */
 131        u8 alarms;              /* Register encoding */
 132        u8 pwm[3];              /* Register value (bit 0 is disable) */
 133};
 134
 135struct smsc47m1_sio_data {
 136        enum chips type;
 137};
 138
 139
 140static int smsc47m1_probe(struct platform_device *pdev);
 141static int __devexit smsc47m1_remove(struct platform_device *pdev);
 142static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
 143                int init);
 144
 145static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg)
 146{
 147        return inb_p(data->addr + reg);
 148}
 149
 150static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg,
 151                u8 value)
 152{
 153        outb_p(value, data->addr + reg);
 154}
 155
 156static struct platform_driver smsc47m1_driver = {
 157        .driver = {
 158                .owner  = THIS_MODULE,
 159                .name   = DRVNAME,
 160        },
 161        .probe          = smsc47m1_probe,
 162        .remove         = __devexit_p(smsc47m1_remove),
 163};
 164
 165static ssize_t get_fan(struct device *dev, struct device_attribute
 166                       *devattr, char *buf)
 167{
 168        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 169        struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
 170        int nr = attr->index;
 171        /* This chip (stupidly) stops monitoring fan speed if PWM is
 172           enabled and duty cycle is 0%. This is fine if the monitoring
 173           and control concern the same fan, but troublesome if they are
 174           not (which could as well happen). */
 175        int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 :
 176                  FAN_FROM_REG(data->fan[nr],
 177                               DIV_FROM_REG(data->fan_div[nr]),
 178                               data->fan_preload[nr]);
 179        return sprintf(buf, "%d\n", rpm);
 180}
 181
 182static ssize_t get_fan_min(struct device *dev, struct device_attribute
 183                           *devattr, char *buf)
 184{
 185        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 186        struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
 187        int nr = attr->index;
 188        int rpm = MIN_FROM_REG(data->fan_preload[nr],
 189                               DIV_FROM_REG(data->fan_div[nr]));
 190        return sprintf(buf, "%d\n", rpm);
 191}
 192
 193static ssize_t get_fan_div(struct device *dev, struct device_attribute
 194                           *devattr, char *buf)
 195{
 196        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 197        struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
 198        return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
 199}
 200
 201static ssize_t get_fan_alarm(struct device *dev, struct device_attribute
 202                             *devattr, char *buf)
 203{
 204        int bitnr = to_sensor_dev_attr(devattr)->index;
 205        struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
 206        return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
 207}
 208
 209static ssize_t get_pwm(struct device *dev, struct device_attribute
 210                       *devattr, char *buf)
 211{
 212        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 213        struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
 214        return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[attr->index]));
 215}
 216
 217static ssize_t get_pwm_en(struct device *dev, struct device_attribute
 218                          *devattr, char *buf)
 219{
 220        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 221        struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
 222        return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[attr->index]));
 223}
 224
 225static ssize_t get_alarms(struct device *dev, struct device_attribute
 226                          *devattr, char *buf)
 227{
 228        struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
 229        return sprintf(buf, "%d\n", data->alarms);
 230}
 231
 232static ssize_t set_fan_min(struct device *dev, struct device_attribute
 233                           *devattr, const char *buf, size_t count)
 234{
 235        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 236        struct smsc47m1_data *data = dev_get_drvdata(dev);
 237        int nr = attr->index;
 238        long rpmdiv, val = simple_strtol(buf, NULL, 10);
 239
 240        mutex_lock(&data->update_lock);
 241        rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
 242
 243        if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
 244                mutex_unlock(&data->update_lock);
 245                return -EINVAL;
 246        }
 247
 248        data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
 249        smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
 250                             data->fan_preload[nr]);
 251        mutex_unlock(&data->update_lock);
 252
 253        return count;
 254}
 255
 256/* Note: we save and restore the fan minimum here, because its value is
 257   determined in part by the fan clock divider.  This follows the principle
 258   of least surprise; the user doesn't expect the fan minimum to change just
 259   because the divider changed. */
 260static ssize_t set_fan_div(struct device *dev, struct device_attribute
 261                           *devattr, const char *buf, size_t count)
 262{
 263        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 264        struct smsc47m1_data *data = dev_get_drvdata(dev);
 265        int nr = attr->index;
 266        long new_div = simple_strtol(buf, NULL, 10), tmp;
 267        u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
 268
 269        if (new_div == old_div) /* No change */
 270                return count;
 271
 272        mutex_lock(&data->update_lock);
 273        switch (new_div) {
 274        case 1: data->fan_div[nr] = 0; break;
 275        case 2: data->fan_div[nr] = 1; break;
 276        case 4: data->fan_div[nr] = 2; break;
 277        case 8: data->fan_div[nr] = 3; break;
 278        default:
 279                mutex_unlock(&data->update_lock);
 280                return -EINVAL;
 281        }
 282
 283        switch (nr) {
 284        case 0:
 285        case 1:
 286                tmp = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV)
 287                      & ~(0x03 << (4 + 2 * nr));
 288                tmp |= data->fan_div[nr] << (4 + 2 * nr);
 289                smsc47m1_write_value(data, SMSC47M1_REG_FANDIV, tmp);
 290                break;
 291        case 2:
 292                tmp = smsc47m1_read_value(data, SMSC47M2_REG_FANDIV3) & 0xCF;
 293                tmp |= data->fan_div[2] << 4;
 294                smsc47m1_write_value(data, SMSC47M2_REG_FANDIV3, tmp);
 295                break;
 296        }
 297
 298        /* Preserve fan min */
 299        tmp = 192 - (old_div * (192 - data->fan_preload[nr])
 300                     + new_div / 2) / new_div;
 301        data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
 302        smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
 303                             data->fan_preload[nr]);
 304        mutex_unlock(&data->update_lock);
 305
 306        return count;
 307}
 308
 309static ssize_t set_pwm(struct device *dev, struct device_attribute
 310                       *devattr, const char *buf, size_t count)
 311{
 312        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 313        struct smsc47m1_data *data = dev_get_drvdata(dev);
 314        int nr = attr->index;
 315        long val = simple_strtol(buf, NULL, 10);
 316
 317        if (val < 0 || val > 255)
 318                return -EINVAL;
 319
 320        mutex_lock(&data->update_lock);
 321        data->pwm[nr] &= 0x81; /* Preserve additional bits */
 322        data->pwm[nr] |= PWM_TO_REG(val);
 323        smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
 324                             data->pwm[nr]);
 325        mutex_unlock(&data->update_lock);
 326
 327        return count;
 328}
 329
 330static ssize_t set_pwm_en(struct device *dev, struct device_attribute
 331                          *devattr, const char *buf, size_t count)
 332{
 333        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 334        struct smsc47m1_data *data = dev_get_drvdata(dev);
 335        int nr = attr->index;
 336        long val = simple_strtol(buf, NULL, 10);
 337        
 338        if (val != 0 && val != 1)
 339                return -EINVAL;
 340
 341        mutex_lock(&data->update_lock);
 342        data->pwm[nr] &= 0xFE; /* preserve the other bits */
 343        data->pwm[nr] |= !val;
 344        smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
 345                             data->pwm[nr]);
 346        mutex_unlock(&data->update_lock);
 347
 348        return count;
 349}
 350
 351#define fan_present(offset)                                             \
 352static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan,        \
 353                NULL, offset - 1);                                      \
 354static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,         \
 355                get_fan_min, set_fan_min, offset - 1);                  \
 356static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,         \
 357                get_fan_div, set_fan_div, offset - 1);                  \
 358static SENSOR_DEVICE_ATTR(fan##offset##_alarm, S_IRUGO, get_fan_alarm,  \
 359                NULL, offset - 1);                                      \
 360static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,               \
 361                get_pwm, set_pwm, offset - 1);                          \
 362static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,      \
 363                get_pwm_en, set_pwm_en, offset - 1)
 364
 365fan_present(1);
 366fan_present(2);
 367fan_present(3);
 368
 369static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
 370
 371static ssize_t show_name(struct device *dev, struct device_attribute
 372                         *devattr, char *buf)
 373{
 374        struct smsc47m1_data *data = dev_get_drvdata(dev);
 375
 376        return sprintf(buf, "%s\n", data->name);
 377}
 378static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 379
 380/* Almost all sysfs files may or may not be created depending on the chip
 381   setup so we create them individually. It is still convenient to define a
 382   group to remove them all at once. */
 383static struct attribute *smsc47m1_attributes[] = {
 384        &sensor_dev_attr_fan1_input.dev_attr.attr,
 385        &sensor_dev_attr_fan1_min.dev_attr.attr,
 386        &sensor_dev_attr_fan1_div.dev_attr.attr,
 387        &sensor_dev_attr_fan1_alarm.dev_attr.attr,
 388        &sensor_dev_attr_fan2_input.dev_attr.attr,
 389        &sensor_dev_attr_fan2_min.dev_attr.attr,
 390        &sensor_dev_attr_fan2_div.dev_attr.attr,
 391        &sensor_dev_attr_fan2_alarm.dev_attr.attr,
 392        &sensor_dev_attr_fan3_input.dev_attr.attr,
 393        &sensor_dev_attr_fan3_min.dev_attr.attr,
 394        &sensor_dev_attr_fan3_div.dev_attr.attr,
 395        &sensor_dev_attr_fan3_alarm.dev_attr.attr,
 396
 397        &sensor_dev_attr_pwm1.dev_attr.attr,
 398        &sensor_dev_attr_pwm1_enable.dev_attr.attr,
 399        &sensor_dev_attr_pwm2.dev_attr.attr,
 400        &sensor_dev_attr_pwm2_enable.dev_attr.attr,
 401        &sensor_dev_attr_pwm3.dev_attr.attr,
 402        &sensor_dev_attr_pwm3_enable.dev_attr.attr,
 403
 404        &dev_attr_alarms.attr,
 405        &dev_attr_name.attr,
 406        NULL
 407};
 408
 409static const struct attribute_group smsc47m1_group = {
 410        .attrs = smsc47m1_attributes,
 411};
 412
 413static int __init smsc47m1_find(unsigned short *addr,
 414                                struct smsc47m1_sio_data *sio_data)
 415{
 416        u8 val;
 417
 418        superio_enter();
 419        val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
 420
 421        /*
 422         * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x
 423         * (device id 0x5F) and LPC47B27x (device id 0x51) have fan control.
 424         * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
 425         * can do much more besides (device id 0x60).
 426         * The LPC47M997 is undocumented, but seems to be compatible with
 427         * the LPC47M192, and has the same device id.
 428         * The LPC47M292 (device id 0x6B) is somewhat compatible, but it
 429         * supports a 3rd fan, and the pin configuration registers are
 430         * unfortunately different.
 431         */
 432        switch (val) {
 433        case 0x51:
 434                pr_info(DRVNAME ": Found SMSC LPC47B27x\n");
 435                sio_data->type = smsc47m1;
 436                break;
 437        case 0x59:
 438                pr_info(DRVNAME ": Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n");
 439                sio_data->type = smsc47m1;
 440                break;
 441        case 0x5F:
 442                pr_info(DRVNAME ": Found SMSC LPC47M14x\n");
 443                sio_data->type = smsc47m1;
 444                break;
 445        case 0x60:
 446                pr_info(DRVNAME ": Found SMSC LPC47M15x/LPC47M192/LPC47M997\n");
 447                sio_data->type = smsc47m1;
 448                break;
 449        case 0x6B:
 450                pr_info(DRVNAME ": Found SMSC LPC47M292\n");
 451                sio_data->type = smsc47m2;
 452                break;
 453        default:
 454                superio_exit();
 455                return -ENODEV;
 456        }
 457
 458        superio_select();
 459        *addr = (superio_inb(SUPERIO_REG_BASE) << 8)
 460              |  superio_inb(SUPERIO_REG_BASE + 1);
 461        val = superio_inb(SUPERIO_REG_ACT);
 462        if (*addr == 0 || (val & 0x01) == 0) {
 463                pr_info(DRVNAME ": Device is disabled, will not use\n");
 464                superio_exit();
 465                return -ENODEV;
 466        }
 467
 468        superio_exit();
 469        return 0;
 470}
 471
 472static int __devinit smsc47m1_probe(struct platform_device *pdev)
 473{
 474        struct device *dev = &pdev->dev;
 475        struct smsc47m1_sio_data *sio_data = dev->platform_data;
 476        struct smsc47m1_data *data;
 477        struct resource *res;
 478        int err = 0;
 479        int fan1, fan2, fan3, pwm1, pwm2, pwm3;
 480
 481        static const char *names[] = {
 482                "smsc47m1",
 483                "smsc47m2",
 484        };
 485
 486        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 487        if (!request_region(res->start, SMSC_EXTENT, DRVNAME)) {
 488                dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
 489                        (unsigned long)res->start,
 490                        (unsigned long)res->end);
 491                return -EBUSY;
 492        }
 493
 494        if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
 495                err = -ENOMEM;
 496                goto error_release;
 497        }
 498
 499        data->addr = res->start;
 500        data->type = sio_data->type;
 501        data->name = names[sio_data->type];
 502        mutex_init(&data->update_lock);
 503        platform_set_drvdata(pdev, data);
 504
 505        /* If no function is properly configured, there's no point in
 506           actually registering the chip. */
 507        pwm1 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(0)) & 0x05)
 508               == 0x04;
 509        pwm2 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(1)) & 0x05)
 510               == 0x04;
 511        if (data->type == smsc47m2) {
 512                fan1 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN1)
 513                        & 0x0d) == 0x09;
 514                fan2 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN2)
 515                        & 0x0d) == 0x09;
 516                fan3 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN3)
 517                        & 0x0d) == 0x0d;
 518                pwm3 = (smsc47m1_read_value(data, SMSC47M2_REG_PPIN3)
 519                        & 0x0d) == 0x08;
 520        } else {
 521                fan1 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(0))
 522                        & 0x05) == 0x05;
 523                fan2 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(1))
 524                        & 0x05) == 0x05;
 525                fan3 = 0;
 526                pwm3 = 0;
 527        }
 528        if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) {
 529                dev_warn(dev, "Device not configured, will not use\n");
 530                err = -ENODEV;
 531                goto error_free;
 532        }
 533
 534        /* Some values (fan min, clock dividers, pwm registers) may be
 535           needed before any update is triggered, so we better read them
 536           at least once here. We don't usually do it that way, but in
 537           this particular case, manually reading 5 registers out of 8
 538           doesn't make much sense and we're better using the existing
 539           function. */
 540        smsc47m1_update_device(dev, 1);
 541
 542        /* Register sysfs hooks */
 543        if (fan1) {
 544                if ((err = device_create_file(dev,
 545                                &sensor_dev_attr_fan1_input.dev_attr))
 546                 || (err = device_create_file(dev,
 547                                &sensor_dev_attr_fan1_min.dev_attr))
 548                 || (err = device_create_file(dev,
 549                                &sensor_dev_attr_fan1_div.dev_attr))
 550                 || (err = device_create_file(dev,
 551                                &sensor_dev_attr_fan1_alarm.dev_attr)))
 552                        goto error_remove_files;
 553        } else
 554                dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n");
 555
 556        if (fan2) {
 557                if ((err = device_create_file(dev,
 558                                &sensor_dev_attr_fan2_input.dev_attr))
 559                 || (err = device_create_file(dev,
 560                                &sensor_dev_attr_fan2_min.dev_attr))
 561                 || (err = device_create_file(dev,
 562                                &sensor_dev_attr_fan2_div.dev_attr))
 563                 || (err = device_create_file(dev,
 564                                &sensor_dev_attr_fan2_alarm.dev_attr)))
 565                        goto error_remove_files;
 566        } else
 567                dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n");
 568
 569        if (fan3) {
 570                if ((err = device_create_file(dev,
 571                                &sensor_dev_attr_fan3_input.dev_attr))
 572                 || (err = device_create_file(dev,
 573                                &sensor_dev_attr_fan3_min.dev_attr))
 574                 || (err = device_create_file(dev,
 575                                &sensor_dev_attr_fan3_div.dev_attr))
 576                 || (err = device_create_file(dev,
 577                                &sensor_dev_attr_fan3_alarm.dev_attr)))
 578                        goto error_remove_files;
 579        } else if (data->type == smsc47m2)
 580                dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n");
 581
 582        if (pwm1) {
 583                if ((err = device_create_file(dev,
 584                                &sensor_dev_attr_pwm1.dev_attr))
 585                 || (err = device_create_file(dev,
 586                                &sensor_dev_attr_pwm1_enable.dev_attr)))
 587                        goto error_remove_files;
 588        } else
 589                dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n");
 590
 591        if (pwm2) {
 592                if ((err = device_create_file(dev,
 593                                &sensor_dev_attr_pwm2.dev_attr))
 594                 || (err = device_create_file(dev,
 595                                &sensor_dev_attr_pwm2_enable.dev_attr)))
 596                        goto error_remove_files;
 597        } else
 598                dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n");
 599
 600        if (pwm3) {
 601                if ((err = device_create_file(dev,
 602                                &sensor_dev_attr_pwm3.dev_attr))
 603                 || (err = device_create_file(dev,
 604                                &sensor_dev_attr_pwm3_enable.dev_attr)))
 605                        goto error_remove_files;
 606        } else if (data->type == smsc47m2)
 607                dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n");
 608
 609        if ((err = device_create_file(dev, &dev_attr_alarms)))
 610                goto error_remove_files;
 611        if ((err = device_create_file(dev, &dev_attr_name)))
 612                goto error_remove_files;
 613
 614        data->hwmon_dev = hwmon_device_register(dev);
 615        if (IS_ERR(data->hwmon_dev)) {
 616                err = PTR_ERR(data->hwmon_dev);
 617                goto error_remove_files;
 618        }
 619
 620        return 0;
 621
 622error_remove_files:
 623        sysfs_remove_group(&dev->kobj, &smsc47m1_group);
 624error_free:
 625        platform_set_drvdata(pdev, NULL);
 626        kfree(data);
 627error_release:
 628        release_region(res->start, SMSC_EXTENT);
 629        return err;
 630}
 631
 632static int __devexit smsc47m1_remove(struct platform_device *pdev)
 633{
 634        struct smsc47m1_data *data = platform_get_drvdata(pdev);
 635        struct resource *res;
 636
 637        hwmon_device_unregister(data->hwmon_dev);
 638        sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
 639
 640        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 641        release_region(res->start, SMSC_EXTENT);
 642        platform_set_drvdata(pdev, NULL);
 643        kfree(data);
 644
 645        return 0;
 646}
 647
 648static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
 649                int init)
 650{
 651        struct smsc47m1_data *data = dev_get_drvdata(dev);
 652
 653        mutex_lock(&data->update_lock);
 654
 655        if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
 656                int i, fan_nr;
 657                fan_nr = data->type == smsc47m2 ? 3 : 2;
 658
 659                for (i = 0; i < fan_nr; i++) {
 660                        data->fan[i] = smsc47m1_read_value(data,
 661                                       SMSC47M1_REG_FAN[i]);
 662                        data->fan_preload[i] = smsc47m1_read_value(data,
 663                                               SMSC47M1_REG_FAN_PRELOAD[i]);
 664                        data->pwm[i] = smsc47m1_read_value(data,
 665                                       SMSC47M1_REG_PWM[i]);
 666                }
 667
 668                i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
 669                data->fan_div[0] = (i >> 4) & 0x03;
 670                data->fan_div[1] = i >> 6;
 671
 672                data->alarms = smsc47m1_read_value(data,
 673                               SMSC47M1_REG_ALARM) >> 6;
 674                /* Clear alarms if needed */
 675                if (data->alarms)
 676                        smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
 677
 678                if (fan_nr >= 3) {
 679                        data->fan_div[2] = (smsc47m1_read_value(data,
 680                                            SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
 681                        data->alarms |= (smsc47m1_read_value(data,
 682                                         SMSC47M2_REG_ALARM6) & 0x40) >> 4;
 683                        /* Clear alarm if needed */
 684                        if (data->alarms & 0x04)
 685                                smsc47m1_write_value(data,
 686                                                     SMSC47M2_REG_ALARM6,
 687                                                     0x40);
 688                }
 689
 690                data->last_updated = jiffies;
 691        }
 692
 693        mutex_unlock(&data->update_lock);
 694        return data;
 695}
 696
 697static int __init smsc47m1_device_add(unsigned short address,
 698                                      const struct smsc47m1_sio_data *sio_data)
 699{
 700        struct resource res = {
 701                .start  = address,
 702                .end    = address + SMSC_EXTENT - 1,
 703                .name   = DRVNAME,
 704                .flags  = IORESOURCE_IO,
 705        };
 706        int err;
 707
 708        pdev = platform_device_alloc(DRVNAME, address);
 709        if (!pdev) {
 710                err = -ENOMEM;
 711                printk(KERN_ERR DRVNAME ": Device allocation failed\n");
 712                goto exit;
 713        }
 714
 715        err = platform_device_add_resources(pdev, &res, 1);
 716        if (err) {
 717                printk(KERN_ERR DRVNAME ": Device resource addition failed "
 718                       "(%d)\n", err);
 719                goto exit_device_put;
 720        }
 721
 722        err = platform_device_add_data(pdev, sio_data,
 723                                       sizeof(struct smsc47m1_sio_data));
 724        if (err) {
 725                printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
 726                goto exit_device_put;
 727        }
 728
 729        err = platform_device_add(pdev);
 730        if (err) {
 731                printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
 732                       err);
 733                goto exit_device_put;
 734        }
 735
 736        return 0;
 737
 738exit_device_put:
 739        platform_device_put(pdev);
 740exit:
 741        return err;
 742}
 743
 744static int __init sm_smsc47m1_init(void)
 745{
 746        int err;
 747        unsigned short address;
 748        struct smsc47m1_sio_data sio_data;
 749
 750        if (smsc47m1_find(&address, &sio_data))
 751                return -ENODEV;
 752
 753        err = platform_driver_register(&smsc47m1_driver);
 754        if (err)
 755                goto exit;
 756
 757        /* Sets global pdev as a side effect */
 758        err = smsc47m1_device_add(address, &sio_data);
 759        if (err)
 760                goto exit_driver;
 761
 762        return 0;
 763
 764exit_driver:
 765        platform_driver_unregister(&smsc47m1_driver);
 766exit:
 767        return err;
 768}
 769
 770static void __exit sm_smsc47m1_exit(void)
 771{
 772        platform_device_unregister(pdev);
 773        platform_driver_unregister(&smsc47m1_driver);
 774}
 775
 776MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
 777MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver");
 778MODULE_LICENSE("GPL");
 779
 780module_init(sm_smsc47m1_init);
 781module_exit(sm_smsc47m1_exit);
 782
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.