linux/drivers/hwmon/dell-smm-hwmon.c
<<
>>
Prefs
   1/*
   2 * dell-smm-hwmon.c -- Linux driver for accessing the SMM BIOS on Dell laptops.
   3 *
   4 * Copyright (C) 2001  Massimo Dal Zotto <dz@debian.org>
   5 *
   6 * Hwmon integration:
   7 * Copyright (C) 2011  Jean Delvare <jdelvare@suse.de>
   8 * Copyright (C) 2013, 2014  Guenter Roeck <linux@roeck-us.net>
   9 * Copyright (C) 2014, 2015  Pali Rohár <pali.rohar@gmail.com>
  10 *
  11 * This program is free software; you can redistribute it and/or modify it
  12 * under the terms of the GNU General Public License as published by the
  13 * Free Software Foundation; either version 2, or (at your option) any
  14 * later version.
  15 *
  16 * This program is distributed in the hope that it will be useful, but
  17 * WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19 * General Public License for more details.
  20 */
  21
  22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  23
  24#include <linux/delay.h>
  25#include <linux/module.h>
  26#include <linux/types.h>
  27#include <linux/init.h>
  28#include <linux/proc_fs.h>
  29#include <linux/seq_file.h>
  30#include <linux/dmi.h>
  31#include <linux/capability.h>
  32#include <linux/mutex.h>
  33#include <linux/hwmon.h>
  34#include <linux/hwmon-sysfs.h>
  35#include <linux/uaccess.h>
  36#include <linux/io.h>
  37#include <linux/sched.h>
  38
  39#include <linux/i8k.h>
  40
  41#define I8K_SMM_FN_STATUS       0x0025
  42#define I8K_SMM_POWER_STATUS    0x0069
  43#define I8K_SMM_SET_FAN         0x01a3
  44#define I8K_SMM_GET_FAN         0x00a3
  45#define I8K_SMM_GET_SPEED       0x02a3
  46#define I8K_SMM_GET_FAN_TYPE    0x03a3
  47#define I8K_SMM_GET_NOM_SPEED   0x04a3
  48#define I8K_SMM_GET_TEMP        0x10a3
  49#define I8K_SMM_GET_TEMP_TYPE   0x11a3
  50#define I8K_SMM_GET_DELL_SIG1   0xfea3
  51#define I8K_SMM_GET_DELL_SIG2   0xffa3
  52
  53#define I8K_FAN_MULT            30
  54#define I8K_FAN_MAX_RPM         30000
  55#define I8K_MAX_TEMP            127
  56
  57#define I8K_FN_NONE             0x00
  58#define I8K_FN_UP               0x01
  59#define I8K_FN_DOWN             0x02
  60#define I8K_FN_MUTE             0x04
  61#define I8K_FN_MASK             0x07
  62#define I8K_FN_SHIFT            8
  63
  64#define I8K_POWER_AC            0x05
  65#define I8K_POWER_BATTERY       0x01
  66
  67static DEFINE_MUTEX(i8k_mutex);
  68static char bios_version[4];
  69static struct device *i8k_hwmon_dev;
  70static u32 i8k_hwmon_flags;
  71static uint i8k_fan_mult = I8K_FAN_MULT;
  72static uint i8k_pwm_mult;
  73static uint i8k_fan_max = I8K_FAN_HIGH;
  74
  75#define I8K_HWMON_HAVE_TEMP1    (1 << 0)
  76#define I8K_HWMON_HAVE_TEMP2    (1 << 1)
  77#define I8K_HWMON_HAVE_TEMP3    (1 << 2)
  78#define I8K_HWMON_HAVE_TEMP4    (1 << 3)
  79#define I8K_HWMON_HAVE_FAN1     (1 << 4)
  80#define I8K_HWMON_HAVE_FAN2     (1 << 5)
  81
  82MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
  83MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
  84MODULE_DESCRIPTION("Dell laptop SMM BIOS hwmon driver");
  85MODULE_LICENSE("GPL");
  86MODULE_ALIAS("i8k");
  87
  88static bool force;
  89module_param(force, bool, 0);
  90MODULE_PARM_DESC(force, "Force loading without checking for supported models");
  91
  92static bool ignore_dmi;
  93module_param(ignore_dmi, bool, 0);
  94MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
  95
  96#if IS_ENABLED(CONFIG_I8K)
  97static bool restricted;
  98module_param(restricted, bool, 0);
  99MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
 100
 101static bool power_status;
 102module_param(power_status, bool, 0600);
 103MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
 104#endif
 105
 106static uint fan_mult;
 107module_param(fan_mult, uint, 0);
 108MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with (default: autodetect)");
 109
 110static uint fan_max;
 111module_param(fan_max, uint, 0);
 112MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed (default: autodetect)");
 113
 114struct smm_regs {
 115        unsigned int eax;
 116        unsigned int ebx __packed;
 117        unsigned int ecx __packed;
 118        unsigned int edx __packed;
 119        unsigned int esi __packed;
 120        unsigned int edi __packed;
 121};
 122
 123static inline const char *i8k_get_dmi_data(int field)
 124{
 125        const char *dmi_data = dmi_get_system_info(field);
 126
 127        return dmi_data && *dmi_data ? dmi_data : "?";
 128}
 129
 130/*
 131 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
 132 */
 133static int i8k_smm(struct smm_regs *regs)
 134{
 135        int rc;
 136        int eax = regs->eax;
 137        cpumask_var_t old_mask;
 138
 139        /* SMM requires CPU 0 */
 140        if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
 141                return -ENOMEM;
 142        cpumask_copy(old_mask, &current->cpus_allowed);
 143        rc = set_cpus_allowed_ptr(current, cpumask_of(0));
 144        if (rc)
 145                goto out;
 146        if (smp_processor_id() != 0) {
 147                rc = -EBUSY;
 148                goto out;
 149        }
 150
 151#if defined(CONFIG_X86_64)
 152        asm volatile("pushq %%rax\n\t"
 153                "movl 0(%%rax),%%edx\n\t"
 154                "pushq %%rdx\n\t"
 155                "movl 4(%%rax),%%ebx\n\t"
 156                "movl 8(%%rax),%%ecx\n\t"
 157                "movl 12(%%rax),%%edx\n\t"
 158                "movl 16(%%rax),%%esi\n\t"
 159                "movl 20(%%rax),%%edi\n\t"
 160                "popq %%rax\n\t"
 161                "out %%al,$0xb2\n\t"
 162                "out %%al,$0x84\n\t"
 163                "xchgq %%rax,(%%rsp)\n\t"
 164                "movl %%ebx,4(%%rax)\n\t"
 165                "movl %%ecx,8(%%rax)\n\t"
 166                "movl %%edx,12(%%rax)\n\t"
 167                "movl %%esi,16(%%rax)\n\t"
 168                "movl %%edi,20(%%rax)\n\t"
 169                "popq %%rdx\n\t"
 170                "movl %%edx,0(%%rax)\n\t"
 171                "pushfq\n\t"
 172                "popq %%rax\n\t"
 173                "andl $1,%%eax\n"
 174                : "=a"(rc)
 175                :    "a"(regs)
 176                :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 177#else
 178        asm volatile("pushl %%eax\n\t"
 179            "movl 0(%%eax),%%edx\n\t"
 180            "push %%edx\n\t"
 181            "movl 4(%%eax),%%ebx\n\t"
 182            "movl 8(%%eax),%%ecx\n\t"
 183            "movl 12(%%eax),%%edx\n\t"
 184            "movl 16(%%eax),%%esi\n\t"
 185            "movl 20(%%eax),%%edi\n\t"
 186            "popl %%eax\n\t"
 187            "out %%al,$0xb2\n\t"
 188            "out %%al,$0x84\n\t"
 189            "xchgl %%eax,(%%esp)\n\t"
 190            "movl %%ebx,4(%%eax)\n\t"
 191            "movl %%ecx,8(%%eax)\n\t"
 192            "movl %%edx,12(%%eax)\n\t"
 193            "movl %%esi,16(%%eax)\n\t"
 194            "movl %%edi,20(%%eax)\n\t"
 195            "popl %%edx\n\t"
 196            "movl %%edx,0(%%eax)\n\t"
 197            "lahf\n\t"
 198            "shrl $8,%%eax\n\t"
 199            "andl $1,%%eax\n"
 200            : "=a"(rc)
 201            :    "a"(regs)
 202            :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 203#endif
 204        if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
 205                rc = -EINVAL;
 206
 207out:
 208        set_cpus_allowed_ptr(current, old_mask);
 209        free_cpumask_var(old_mask);
 210        return rc;
 211}
 212
 213/*
 214 * Read the fan status.
 215 */
 216static int i8k_get_fan_status(int fan)
 217{
 218        struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
 219
 220        regs.ebx = fan & 0xff;
 221        return i8k_smm(&regs) ? : regs.eax & 0xff;
 222}
 223
 224/*
 225 * Read the fan speed in RPM.
 226 */
 227static int i8k_get_fan_speed(int fan)
 228{
 229        struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
 230
 231        regs.ebx = fan & 0xff;
 232        return i8k_smm(&regs) ? : (regs.eax & 0xffff) * i8k_fan_mult;
 233}
 234
 235/*
 236 * Read the fan type.
 237 */
 238static int i8k_get_fan_type(int fan)
 239{
 240        struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
 241
 242        regs.ebx = fan & 0xff;
 243        return i8k_smm(&regs) ? : regs.eax & 0xff;
 244}
 245
 246/*
 247 * Read the fan nominal rpm for specific fan speed.
 248 */
 249static int i8k_get_fan_nominal_speed(int fan, int speed)
 250{
 251        struct smm_regs regs = { .eax = I8K_SMM_GET_NOM_SPEED, };
 252
 253        regs.ebx = (fan & 0xff) | (speed << 8);
 254        return i8k_smm(&regs) ? : (regs.eax & 0xffff) * i8k_fan_mult;
 255}
 256
 257/*
 258 * Set the fan speed (off, low, high). Returns the new fan status.
 259 */
 260static int i8k_set_fan(int fan, int speed)
 261{
 262        struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
 263
 264        speed = (speed < 0) ? 0 : ((speed > i8k_fan_max) ? i8k_fan_max : speed);
 265        regs.ebx = (fan & 0xff) | (speed << 8);
 266
 267        return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
 268}
 269
 270static int i8k_get_temp_type(int sensor)
 271{
 272        struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP_TYPE, };
 273
 274        regs.ebx = sensor & 0xff;
 275        return i8k_smm(&regs) ? : regs.eax & 0xff;
 276}
 277
 278/*
 279 * Read the cpu temperature.
 280 */
 281static int _i8k_get_temp(int sensor)
 282{
 283        struct smm_regs regs = {
 284                .eax = I8K_SMM_GET_TEMP,
 285                .ebx = sensor & 0xff,
 286        };
 287
 288        return i8k_smm(&regs) ? : regs.eax & 0xff;
 289}
 290
 291static int i8k_get_temp(int sensor)
 292{
 293        int temp = _i8k_get_temp(sensor);
 294
 295        /*
 296         * Sometimes the temperature sensor returns 0x99, which is out of range.
 297         * In this case we retry (once) before returning an error.
 298         # 1003655137 00000058 00005a4b
 299         # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
 300         # 1003655139 00000054 00005c52
 301         */
 302        if (temp == 0x99) {
 303                msleep(100);
 304                temp = _i8k_get_temp(sensor);
 305        }
 306        /*
 307         * Return -ENODATA for all invalid temperatures.
 308         *
 309         * Known instances are the 0x99 value as seen above as well as
 310         * 0xc1 (193), which may be returned when trying to read the GPU
 311         * temperature if the system supports a GPU and it is currently
 312         * turned off.
 313         */
 314        if (temp > I8K_MAX_TEMP)
 315                return -ENODATA;
 316
 317        return temp;
 318}
 319
 320static int i8k_get_dell_signature(int req_fn)
 321{
 322        struct smm_regs regs = { .eax = req_fn, };
 323        int rc;
 324
 325        rc = i8k_smm(&regs);
 326        if (rc < 0)
 327                return rc;
 328
 329        return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
 330}
 331
 332#if IS_ENABLED(CONFIG_I8K)
 333
 334/*
 335 * Read the Fn key status.
 336 */
 337static int i8k_get_fn_status(void)
 338{
 339        struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
 340        int rc;
 341
 342        rc = i8k_smm(&regs);
 343        if (rc < 0)
 344                return rc;
 345
 346        switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
 347        case I8K_FN_UP:
 348                return I8K_VOL_UP;
 349        case I8K_FN_DOWN:
 350                return I8K_VOL_DOWN;
 351        case I8K_FN_MUTE:
 352                return I8K_VOL_MUTE;
 353        default:
 354                return 0;
 355        }
 356}
 357
 358/*
 359 * Read the power status.
 360 */
 361static int i8k_get_power_status(void)
 362{
 363        struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
 364        int rc;
 365
 366        rc = i8k_smm(&regs);
 367        if (rc < 0)
 368                return rc;
 369
 370        return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
 371}
 372
 373/*
 374 * Procfs interface
 375 */
 376
 377static int
 378i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
 379{
 380        int val = 0;
 381        int speed;
 382        unsigned char buff[16];
 383        int __user *argp = (int __user *)arg;
 384
 385        if (!argp)
 386                return -EINVAL;
 387
 388        switch (cmd) {
 389        case I8K_BIOS_VERSION:
 390                val = (bios_version[0] << 16) |
 391                                (bios_version[1] << 8) | bios_version[2];
 392                break;
 393
 394        case I8K_MACHINE_ID:
 395                memset(buff, 0, 16);
 396                strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
 397                        sizeof(buff));
 398                break;
 399
 400        case I8K_FN_STATUS:
 401                val = i8k_get_fn_status();
 402                break;
 403
 404        case I8K_POWER_STATUS:
 405                val = i8k_get_power_status();
 406                break;
 407
 408        case I8K_GET_TEMP:
 409                val = i8k_get_temp(0);
 410                break;
 411
 412        case I8K_GET_SPEED:
 413                if (copy_from_user(&val, argp, sizeof(int)))
 414                        return -EFAULT;
 415
 416                val = i8k_get_fan_speed(val);
 417                break;
 418
 419        case I8K_GET_FAN:
 420                if (copy_from_user(&val, argp, sizeof(int)))
 421                        return -EFAULT;
 422
 423                val = i8k_get_fan_status(val);
 424                break;
 425
 426        case I8K_SET_FAN:
 427                if (restricted && !capable(CAP_SYS_ADMIN))
 428                        return -EPERM;
 429
 430                if (copy_from_user(&val, argp, sizeof(int)))
 431                        return -EFAULT;
 432
 433                if (copy_from_user(&speed, argp + 1, sizeof(int)))
 434                        return -EFAULT;
 435
 436                val = i8k_set_fan(val, speed);
 437                break;
 438
 439        default:
 440                return -EINVAL;
 441        }
 442
 443        if (val < 0)
 444                return val;
 445
 446        switch (cmd) {
 447        case I8K_BIOS_VERSION:
 448                if (copy_to_user(argp, &val, 4))
 449                        return -EFAULT;
 450
 451                break;
 452        case I8K_MACHINE_ID:
 453                if (copy_to_user(argp, buff, 16))
 454                        return -EFAULT;
 455
 456                break;
 457        default:
 458                if (copy_to_user(argp, &val, sizeof(int)))
 459                        return -EFAULT;
 460
 461                break;
 462        }
 463
 464        return 0;
 465}
 466
 467static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 468{
 469        long ret;
 470
 471        mutex_lock(&i8k_mutex);
 472        ret = i8k_ioctl_unlocked(fp, cmd, arg);
 473        mutex_unlock(&i8k_mutex);
 474
 475        return ret;
 476}
 477
 478/*
 479 * Print the information for /proc/i8k.
 480 */
 481static int i8k_proc_show(struct seq_file *seq, void *offset)
 482{
 483        int fn_key, cpu_temp, ac_power;
 484        int left_fan, right_fan, left_speed, right_speed;
 485
 486        cpu_temp        = i8k_get_temp(0);                      /* 11100 µs */
 487        left_fan        = i8k_get_fan_status(I8K_FAN_LEFT);     /*   580 µs */
 488        right_fan       = i8k_get_fan_status(I8K_FAN_RIGHT);    /*   580 µs */
 489        left_speed      = i8k_get_fan_speed(I8K_FAN_LEFT);      /*   580 µs */
 490        right_speed     = i8k_get_fan_speed(I8K_FAN_RIGHT);     /*   580 µs */
 491        fn_key          = i8k_get_fn_status();                  /*   750 µs */
 492        if (power_status)
 493                ac_power = i8k_get_power_status();              /* 14700 µs */
 494        else
 495                ac_power = -1;
 496
 497        /*
 498         * Info:
 499         *
 500         * 1)  Format version (this will change if format changes)
 501         * 2)  BIOS version
 502         * 3)  BIOS machine ID
 503         * 4)  Cpu temperature
 504         * 5)  Left fan status
 505         * 6)  Right fan status
 506         * 7)  Left fan speed
 507         * 8)  Right fan speed
 508         * 9)  AC power
 509         * 10) Fn Key status
 510         */
 511        seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
 512                   I8K_PROC_FMT,
 513                   bios_version,
 514                   i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
 515                   cpu_temp,
 516                   left_fan, right_fan, left_speed, right_speed,
 517                   ac_power, fn_key);
 518
 519        return 0;
 520}
 521
 522static int i8k_open_fs(struct inode *inode, struct file *file)
 523{
 524        return single_open(file, i8k_proc_show, NULL);
 525}
 526
 527static const struct file_operations i8k_fops = {
 528        .owner          = THIS_MODULE,
 529        .open           = i8k_open_fs,
 530        .read           = seq_read,
 531        .llseek         = seq_lseek,
 532        .release        = single_release,
 533        .unlocked_ioctl = i8k_ioctl,
 534};
 535
 536static void __init i8k_init_procfs(void)
 537{
 538        /* Register the proc entry */
 539        proc_create("i8k", 0, NULL, &i8k_fops);
 540}
 541
 542static void __exit i8k_exit_procfs(void)
 543{
 544        remove_proc_entry("i8k", NULL);
 545}
 546
 547#else
 548
 549static inline void __init i8k_init_procfs(void)
 550{
 551}
 552
 553static inline void __exit i8k_exit_procfs(void)
 554{
 555}
 556
 557#endif
 558
 559/*
 560 * Hwmon interface
 561 */
 562
 563static ssize_t i8k_hwmon_show_temp_label(struct device *dev,
 564                                         struct device_attribute *devattr,
 565                                         char *buf)
 566{
 567        static const char * const labels[] = {
 568                "CPU",
 569                "GPU",
 570                "SODIMM",
 571                "Other",
 572                "Ambient",
 573                "Other",
 574        };
 575        int index = to_sensor_dev_attr(devattr)->index;
 576        int type;
 577
 578        type = i8k_get_temp_type(index);
 579        if (type < 0)
 580                return type;
 581        if (type >= ARRAY_SIZE(labels))
 582                type = ARRAY_SIZE(labels) - 1;
 583        return sprintf(buf, "%s\n", labels[type]);
 584}
 585
 586static ssize_t i8k_hwmon_show_temp(struct device *dev,
 587                                   struct device_attribute *devattr,
 588                                   char *buf)
 589{
 590        int index = to_sensor_dev_attr(devattr)->index;
 591        int temp;
 592
 593        temp = i8k_get_temp(index);
 594        if (temp < 0)
 595                return temp;
 596        return sprintf(buf, "%d\n", temp * 1000);
 597}
 598
 599static ssize_t i8k_hwmon_show_fan_label(struct device *dev,
 600                                        struct device_attribute *devattr,
 601                                        char *buf)
 602{
 603        static const char * const labels[] = {
 604                "Processor Fan",
 605                "Motherboard Fan",
 606                "Video Fan",
 607                "Power Supply Fan",
 608                "Chipset Fan",
 609                "Other Fan",
 610        };
 611        int index = to_sensor_dev_attr(devattr)->index;
 612        bool dock = false;
 613        int type;
 614
 615        type = i8k_get_fan_type(index);
 616        if (type < 0)
 617                return type;
 618
 619        if (type & 0x10) {
 620                dock = true;
 621                type &= 0x0F;
 622        }
 623
 624        if (type >= ARRAY_SIZE(labels))
 625                type = (ARRAY_SIZE(labels) - 1);
 626
 627        return sprintf(buf, "%s%s\n", (dock ? "Docking " : ""), labels[type]);
 628}
 629
 630static ssize_t i8k_hwmon_show_fan(struct device *dev,
 631                                  struct device_attribute *devattr,
 632                                  char *buf)
 633{
 634        int index = to_sensor_dev_attr(devattr)->index;
 635        int fan_speed;
 636
 637        fan_speed = i8k_get_fan_speed(index);
 638        if (fan_speed < 0)
 639                return fan_speed;
 640        return sprintf(buf, "%d\n", fan_speed);
 641}
 642
 643static ssize_t i8k_hwmon_show_pwm(struct device *dev,
 644                                  struct device_attribute *devattr,
 645                                  char *buf)
 646{
 647        int index = to_sensor_dev_attr(devattr)->index;
 648        int status;
 649
 650        status = i8k_get_fan_status(index);
 651        if (status < 0)
 652                return -EIO;
 653        return sprintf(buf, "%d\n", clamp_val(status * i8k_pwm_mult, 0, 255));
 654}
 655
 656static ssize_t i8k_hwmon_set_pwm(struct device *dev,
 657                                 struct device_attribute *attr,
 658                                 const char *buf, size_t count)
 659{
 660        int index = to_sensor_dev_attr(attr)->index;
 661        unsigned long val;
 662        int err;
 663
 664        err = kstrtoul(buf, 10, &val);
 665        if (err)
 666                return err;
 667        val = clamp_val(DIV_ROUND_CLOSEST(val, i8k_pwm_mult), 0, i8k_fan_max);
 668
 669        mutex_lock(&i8k_mutex);
 670        err = i8k_set_fan(index, val);
 671        mutex_unlock(&i8k_mutex);
 672
 673        return err < 0 ? -EIO : count;
 674}
 675
 676static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 0);
 677static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_temp_label, NULL,
 678                          0);
 679static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 1);
 680static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, i8k_hwmon_show_temp_label, NULL,
 681                          1);
 682static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 2);
 683static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, i8k_hwmon_show_temp_label, NULL,
 684                          2);
 685static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 3);
 686static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, i8k_hwmon_show_temp_label, NULL,
 687                          3);
 688static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL, 0);
 689static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_fan_label, NULL,
 690                          0);
 691static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
 692                          i8k_hwmon_set_pwm, 0);
 693static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
 694                          1);
 695static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_fan_label, NULL,
 696                          1);
 697static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
 698                          i8k_hwmon_set_pwm, 1);
 699
 700static struct attribute *i8k_attrs[] = {
 701        &sensor_dev_attr_temp1_input.dev_attr.attr,     /* 0 */
 702        &sensor_dev_attr_temp1_label.dev_attr.attr,     /* 1 */
 703        &sensor_dev_attr_temp2_input.dev_attr.attr,     /* 2 */
 704        &sensor_dev_attr_temp2_label.dev_attr.attr,     /* 3 */
 705        &sensor_dev_attr_temp3_input.dev_attr.attr,     /* 4 */
 706        &sensor_dev_attr_temp3_label.dev_attr.attr,     /* 5 */
 707        &sensor_dev_attr_temp4_input.dev_attr.attr,     /* 6 */
 708        &sensor_dev_attr_temp4_label.dev_attr.attr,     /* 7 */
 709        &sensor_dev_attr_fan1_input.dev_attr.attr,      /* 8 */
 710        &sensor_dev_attr_fan1_label.dev_attr.attr,      /* 9 */
 711        &sensor_dev_attr_pwm1.dev_attr.attr,            /* 10 */
 712        &sensor_dev_attr_fan2_input.dev_attr.attr,      /* 11 */
 713        &sensor_dev_attr_fan2_label.dev_attr.attr,      /* 12 */
 714        &sensor_dev_attr_pwm2.dev_attr.attr,            /* 13 */
 715        NULL
 716};
 717
 718static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
 719                              int index)
 720{
 721        if (index >= 0 && index <= 1 &&
 722            !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
 723                return 0;
 724        if (index >= 2 && index <= 3 &&
 725            !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP2))
 726                return 0;
 727        if (index >= 4 && index <= 5 &&
 728            !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP3))
 729                return 0;
 730        if (index >= 6 && index <= 7 &&
 731            !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP4))
 732                return 0;
 733        if (index >= 8 && index <= 10 &&
 734            !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN1))
 735                return 0;
 736        if (index >= 11 && index <= 13 &&
 737            !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2))
 738                return 0;
 739
 740        return attr->mode;
 741}
 742
 743static const struct attribute_group i8k_group = {
 744        .attrs = i8k_attrs,
 745        .is_visible = i8k_is_visible,
 746};
 747__ATTRIBUTE_GROUPS(i8k);
 748
 749static int __init i8k_init_hwmon(void)
 750{
 751        int err;
 752
 753        i8k_hwmon_flags = 0;
 754
 755        /* CPU temperature attributes, if temperature type is OK */
 756        err = i8k_get_temp_type(0);
 757        if (err >= 0)
 758                i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP1;
 759        /* check for additional temperature sensors */
 760        err = i8k_get_temp_type(1);
 761        if (err >= 0)
 762                i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP2;
 763        err = i8k_get_temp_type(2);
 764        if (err >= 0)
 765                i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP3;
 766        err = i8k_get_temp_type(3);
 767        if (err >= 0)
 768                i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
 769
 770        /* First fan attributes, if fan type is OK */
 771        err = i8k_get_fan_type(0);
 772        if (err >= 0)
 773                i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
 774
 775        /* Second fan attributes, if fan type is OK */
 776        err = i8k_get_fan_type(1);
 777        if (err >= 0)
 778                i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
 779
 780        i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "dell_smm",
 781                                                          NULL, i8k_groups);
 782        if (IS_ERR(i8k_hwmon_dev)) {
 783                err = PTR_ERR(i8k_hwmon_dev);
 784                i8k_hwmon_dev = NULL;
 785                pr_err("hwmon registration failed (%d)\n", err);
 786                return err;
 787        }
 788        return 0;
 789}
 790
 791struct i8k_config_data {
 792        uint fan_mult;
 793        uint fan_max;
 794};
 795
 796enum i8k_configs {
 797        DELL_LATITUDE_D520,
 798        DELL_PRECISION_490,
 799        DELL_STUDIO,
 800        DELL_XPS,
 801};
 802
 803static const struct i8k_config_data i8k_config_data[] = {
 804        [DELL_LATITUDE_D520] = {
 805                .fan_mult = 1,
 806                .fan_max = I8K_FAN_TURBO,
 807        },
 808        [DELL_PRECISION_490] = {
 809                .fan_mult = 1,
 810                .fan_max = I8K_FAN_TURBO,
 811        },
 812        [DELL_STUDIO] = {
 813                .fan_mult = 1,
 814                .fan_max = I8K_FAN_HIGH,
 815        },
 816        [DELL_XPS] = {
 817                .fan_mult = 1,
 818                .fan_max = I8K_FAN_HIGH,
 819        },
 820};
 821
 822static struct dmi_system_id i8k_dmi_table[] __initdata = {
 823        {
 824                .ident = "Dell Inspiron",
 825                .matches = {
 826                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
 827                        DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
 828                },
 829        },
 830        {
 831                .ident = "Dell Latitude",
 832                .matches = {
 833                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
 834                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
 835                },
 836        },
 837        {
 838                .ident = "Dell Inspiron 2",
 839                .matches = {
 840                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 841                        DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
 842                },
 843        },
 844        {
 845                .ident = "Dell Latitude D520",
 846                .matches = {
 847                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 848                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D520"),
 849                },
 850                .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520],
 851        },
 852        {
 853                .ident = "Dell Latitude 2",
 854                .matches = {
 855                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 856                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
 857                },
 858        },
 859        {       /* UK Inspiron 6400  */
 860                .ident = "Dell Inspiron 3",
 861                .matches = {
 862                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 863                        DMI_MATCH(DMI_PRODUCT_NAME, "MM061"),
 864                },
 865        },
 866        {
 867                .ident = "Dell Inspiron 3",
 868                .matches = {
 869                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 870                        DMI_MATCH(DMI_PRODUCT_NAME, "MP061"),
 871                },
 872        },
 873        {
 874                .ident = "Dell Precision 490",
 875                .matches = {
 876                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 877                        DMI_MATCH(DMI_PRODUCT_NAME,
 878                                  "Precision WorkStation 490"),
 879                },
 880                .driver_data = (void *)&i8k_config_data[DELL_PRECISION_490],
 881        },
 882        {
 883                .ident = "Dell Precision",
 884                .matches = {
 885                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 886                        DMI_MATCH(DMI_PRODUCT_NAME, "Precision"),
 887                },
 888        },
 889        {
 890                .ident = "Dell Vostro",
 891                .matches = {
 892                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 893                        DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),
 894                },
 895        },
 896        {
 897                .ident = "Dell XPS421",
 898                .matches = {
 899                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 900                        DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
 901                },
 902        },
 903        {
 904                .ident = "Dell Studio",
 905                .matches = {
 906                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 907                        DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),
 908                },
 909                .driver_data = (void *)&i8k_config_data[DELL_STUDIO],
 910        },
 911        {
 912                .ident = "Dell XPS 13",
 913                .matches = {
 914                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 915                        DMI_MATCH(DMI_PRODUCT_NAME, "XPS13"),
 916                },
 917                .driver_data = (void *)&i8k_config_data[DELL_XPS],
 918        },
 919        {
 920                .ident = "Dell XPS M140",
 921                .matches = {
 922                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 923                        DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),
 924                },
 925                .driver_data = (void *)&i8k_config_data[DELL_XPS],
 926        },
 927        { }
 928};
 929
 930MODULE_DEVICE_TABLE(dmi, i8k_dmi_table);
 931
 932static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = {
 933        {
 934                /*
 935                 * CPU fan speed going up and down on Dell Studio XPS 8100
 936                 * for unknown reasons.
 937                 */
 938                .ident = "Dell Studio XPS 8100",
 939                .matches = {
 940                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 941                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"),
 942                },
 943        },
 944        { }
 945};
 946
 947/*
 948 * Probe for the presence of a supported laptop.
 949 */
 950static int __init i8k_probe(void)
 951{
 952        const struct dmi_system_id *id;
 953        int fan, ret;
 954
 955        /*
 956         * Get DMI information
 957         */
 958        if (!dmi_check_system(i8k_dmi_table) ||
 959            dmi_check_system(i8k_blacklist_dmi_table)) {
 960                if (!ignore_dmi && !force)
 961                        return -ENODEV;
 962
 963                pr_info("not running on a supported Dell system.\n");
 964                pr_info("vendor=%s, model=%s, version=%s\n",
 965                        i8k_get_dmi_data(DMI_SYS_VENDOR),
 966                        i8k_get_dmi_data(DMI_PRODUCT_NAME),
 967                        i8k_get_dmi_data(DMI_BIOS_VERSION));
 968        }
 969
 970        strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
 971                sizeof(bios_version));
 972
 973        /*
 974         * Get SMM Dell signature
 975         */
 976        if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
 977            i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
 978                pr_err("unable to get SMM Dell signature\n");
 979                if (!force)
 980                        return -ENODEV;
 981        }
 982
 983        /*
 984         * Set fan multiplier and maximal fan speed from dmi config
 985         * Values specified in module parameters override values from dmi
 986         */
 987        id = dmi_first_match(i8k_dmi_table);
 988        if (id && id->driver_data) {
 989                const struct i8k_config_data *conf = id->driver_data;
 990                if (!fan_mult && conf->fan_mult)
 991                        fan_mult = conf->fan_mult;
 992                if (!fan_max && conf->fan_max)
 993                        fan_max = conf->fan_max;
 994        }
 995
 996        i8k_fan_max = fan_max ? : I8K_FAN_HIGH; /* Must not be 0 */
 997        i8k_pwm_mult = DIV_ROUND_UP(255, i8k_fan_max);
 998
 999        if (!fan_mult) {
1000                /*
1001                 * Autodetect fan multiplier based on nominal rpm
1002                 * If fan reports rpm value too high then set multiplier to 1
1003                 */
1004                for (fan = 0; fan < 2; ++fan) {
1005                        ret = i8k_get_fan_nominal_speed(fan, i8k_fan_max);
1006                        if (ret < 0)
1007                                continue;
1008                        if (ret > I8K_FAN_MAX_RPM)
1009                                i8k_fan_mult = 1;
1010                        break;
1011                }
1012        } else {
1013                /* Fan multiplier was specified in module param or in dmi */
1014                i8k_fan_mult = fan_mult;
1015        }
1016
1017        return 0;
1018}
1019
1020static int __init i8k_init(void)
1021{
1022        int err;
1023
1024        /* Are we running on an supported laptop? */
1025        if (i8k_probe())
1026                return -ENODEV;
1027
1028        err = i8k_init_hwmon();
1029        if (err)
1030                return err;
1031
1032        i8k_init_procfs();
1033        return 0;
1034}
1035
1036static void __exit i8k_exit(void)
1037{
1038        hwmon_device_unregister(i8k_hwmon_dev);
1039        i8k_exit_procfs();
1040}
1041
1042module_init(i8k_init);
1043module_exit(i8k_exit);
1044