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