linux/drivers/platform/x86/eeepc-laptop.c
<<
>>
Prefs
   1/*
   2 *  eeepc-laptop.c - Asus Eee PC extras
   3 *
   4 *  Based on asus_acpi.c as patched for the Eee PC by Asus:
   5 *  ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
   6 *  Based on eee.c from eeepc-linux
   7 *
   8 *  This program is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License as published by
  10 *  the Free Software Foundation; either version 2 of the License, or
  11 *  (at your option) any later version.
  12 *
  13 *  This program is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *  GNU General Public License for more details.
  17 */
  18
  19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  20
  21#include <linux/kernel.h>
  22#include <linux/module.h>
  23#include <linux/init.h>
  24#include <linux/types.h>
  25#include <linux/platform_device.h>
  26#include <linux/backlight.h>
  27#include <linux/fb.h>
  28#include <linux/hwmon.h>
  29#include <linux/hwmon-sysfs.h>
  30#include <linux/slab.h>
  31#include <linux/acpi.h>
  32#include <linux/uaccess.h>
  33#include <linux/input.h>
  34#include <linux/input/sparse-keymap.h>
  35#include <linux/rfkill.h>
  36#include <linux/pci.h>
  37#include <linux/pci_hotplug.h>
  38#include <linux/leds.h>
  39#include <linux/dmi.h>
  40#include <acpi/video.h>
  41
  42#define EEEPC_LAPTOP_VERSION    "0.1"
  43#define EEEPC_LAPTOP_NAME       "Eee PC Hotkey Driver"
  44#define EEEPC_LAPTOP_FILE       "eeepc"
  45
  46#define EEEPC_ACPI_CLASS        "hotkey"
  47#define EEEPC_ACPI_DEVICE_NAME  "Hotkey"
  48#define EEEPC_ACPI_HID          "ASUS010"
  49
  50MODULE_AUTHOR("Corentin Chary, Eric Cooper");
  51MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
  52MODULE_LICENSE("GPL");
  53
  54static bool hotplug_disabled;
  55
  56module_param(hotplug_disabled, bool, 0444);
  57MODULE_PARM_DESC(hotplug_disabled,
  58                 "Disable hotplug for wireless device. "
  59                 "If your laptop need that, please report to "
  60                 "acpi4asus-user@lists.sourceforge.net.");
  61
  62/*
  63 * Definitions for Asus EeePC
  64 */
  65#define NOTIFY_BRN_MIN  0x20
  66#define NOTIFY_BRN_MAX  0x2f
  67
  68enum {
  69        DISABLE_ASL_WLAN = 0x0001,
  70        DISABLE_ASL_BLUETOOTH = 0x0002,
  71        DISABLE_ASL_IRDA = 0x0004,
  72        DISABLE_ASL_CAMERA = 0x0008,
  73        DISABLE_ASL_TV = 0x0010,
  74        DISABLE_ASL_GPS = 0x0020,
  75        DISABLE_ASL_DISPLAYSWITCH = 0x0040,
  76        DISABLE_ASL_MODEM = 0x0080,
  77        DISABLE_ASL_CARDREADER = 0x0100,
  78        DISABLE_ASL_3G = 0x0200,
  79        DISABLE_ASL_WIMAX = 0x0400,
  80        DISABLE_ASL_HWCF = 0x0800
  81};
  82
  83enum {
  84        CM_ASL_WLAN = 0,
  85        CM_ASL_BLUETOOTH,
  86        CM_ASL_IRDA,
  87        CM_ASL_1394,
  88        CM_ASL_CAMERA,
  89        CM_ASL_TV,
  90        CM_ASL_GPS,
  91        CM_ASL_DVDROM,
  92        CM_ASL_DISPLAYSWITCH,
  93        CM_ASL_PANELBRIGHT,
  94        CM_ASL_BIOSFLASH,
  95        CM_ASL_ACPIFLASH,
  96        CM_ASL_CPUFV,
  97        CM_ASL_CPUTEMPERATURE,
  98        CM_ASL_FANCPU,
  99        CM_ASL_FANCHASSIS,
 100        CM_ASL_USBPORT1,
 101        CM_ASL_USBPORT2,
 102        CM_ASL_USBPORT3,
 103        CM_ASL_MODEM,
 104        CM_ASL_CARDREADER,
 105        CM_ASL_3G,
 106        CM_ASL_WIMAX,
 107        CM_ASL_HWCF,
 108        CM_ASL_LID,
 109        CM_ASL_TYPE,
 110        CM_ASL_PANELPOWER,      /*P901*/
 111        CM_ASL_TPD
 112};
 113
 114static const char *cm_getv[] = {
 115        "WLDG", "BTHG", NULL, NULL,
 116        "CAMG", NULL, NULL, NULL,
 117        NULL, "PBLG", NULL, NULL,
 118        "CFVG", NULL, NULL, NULL,
 119        "USBG", NULL, NULL, "MODG",
 120        "CRDG", "M3GG", "WIMG", "HWCF",
 121        "LIDG", "TYPE", "PBPG", "TPDG"
 122};
 123
 124static const char *cm_setv[] = {
 125        "WLDS", "BTHS", NULL, NULL,
 126        "CAMS", NULL, NULL, NULL,
 127        "SDSP", "PBLS", "HDPS", NULL,
 128        "CFVS", NULL, NULL, NULL,
 129        "USBG", NULL, NULL, "MODS",
 130        "CRDS", "M3GS", "WIMS", NULL,
 131        NULL, NULL, "PBPS", "TPDS"
 132};
 133
 134static const struct key_entry eeepc_keymap[] = {
 135        { KE_KEY, 0x10, { KEY_WLAN } },
 136        { KE_KEY, 0x11, { KEY_WLAN } },
 137        { KE_KEY, 0x12, { KEY_PROG1 } },
 138        { KE_KEY, 0x13, { KEY_MUTE } },
 139        { KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
 140        { KE_KEY, 0x15, { KEY_VOLUMEUP } },
 141        { KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
 142        { KE_KEY, 0x1a, { KEY_COFFEE } },
 143        { KE_KEY, 0x1b, { KEY_ZOOM } },
 144        { KE_KEY, 0x1c, { KEY_PROG2 } },
 145        { KE_KEY, 0x1d, { KEY_PROG3 } },
 146        { KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
 147        { KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
 148        { KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
 149        { KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
 150        { KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
 151        { KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
 152        { KE_KEY, 0x38, { KEY_F14 } },
 153        { KE_IGNORE, 0x50, { KEY_RESERVED } }, /* AC plugged */
 154        { KE_IGNORE, 0x51, { KEY_RESERVED } }, /* AC unplugged */
 155        { KE_END, 0 },
 156};
 157
 158/*
 159 * This is the main structure, we can use it to store useful information
 160 */
 161struct eeepc_laptop {
 162        acpi_handle handle;             /* the handle of the acpi device */
 163        u32 cm_supported;               /* the control methods supported
 164                                           by this BIOS */
 165        bool cpufv_disabled;
 166        bool hotplug_disabled;
 167        u16 event_count[128];           /* count for each event */
 168
 169        struct platform_device *platform_device;
 170        struct acpi_device *device;             /* the device we are in */
 171        struct backlight_device *backlight_device;
 172
 173        struct input_dev *inputdev;
 174
 175        struct rfkill *wlan_rfkill;
 176        struct rfkill *bluetooth_rfkill;
 177        struct rfkill *wwan3g_rfkill;
 178        struct rfkill *wimax_rfkill;
 179
 180        struct hotplug_slot *hotplug_slot;
 181        struct mutex hotplug_lock;
 182
 183        struct led_classdev tpd_led;
 184        int tpd_led_wk;
 185        struct workqueue_struct *led_workqueue;
 186        struct work_struct tpd_led_work;
 187};
 188
 189/*
 190 * ACPI Helpers
 191 */
 192static int write_acpi_int(acpi_handle handle, const char *method, int val)
 193{
 194        acpi_status status;
 195
 196        status = acpi_execute_simple_method(handle, (char *)method, val);
 197
 198        return (status == AE_OK ? 0 : -1);
 199}
 200
 201static int read_acpi_int(acpi_handle handle, const char *method, int *val)
 202{
 203        acpi_status status;
 204        unsigned long long result;
 205
 206        status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
 207        if (ACPI_FAILURE(status)) {
 208                *val = -1;
 209                return -1;
 210        } else {
 211                *val = result;
 212                return 0;
 213        }
 214}
 215
 216static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
 217{
 218        const char *method = cm_setv[cm];
 219
 220        if (method == NULL)
 221                return -ENODEV;
 222        if ((eeepc->cm_supported & (0x1 << cm)) == 0)
 223                return -ENODEV;
 224
 225        if (write_acpi_int(eeepc->handle, method, value))
 226                pr_warn("Error writing %s\n", method);
 227        return 0;
 228}
 229
 230static int get_acpi(struct eeepc_laptop *eeepc, int cm)
 231{
 232        const char *method = cm_getv[cm];
 233        int value;
 234
 235        if (method == NULL)
 236                return -ENODEV;
 237        if ((eeepc->cm_supported & (0x1 << cm)) == 0)
 238                return -ENODEV;
 239
 240        if (read_acpi_int(eeepc->handle, method, &value))
 241                pr_warn("Error reading %s\n", method);
 242        return value;
 243}
 244
 245static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
 246                              acpi_handle *handle)
 247{
 248        const char *method = cm_setv[cm];
 249        acpi_status status;
 250
 251        if (method == NULL)
 252                return -ENODEV;
 253        if ((eeepc->cm_supported & (0x1 << cm)) == 0)
 254                return -ENODEV;
 255
 256        status = acpi_get_handle(eeepc->handle, (char *)method,
 257                                 handle);
 258        if (status != AE_OK) {
 259                pr_warn("Error finding %s\n", method);
 260                return -ENODEV;
 261        }
 262        return 0;
 263}
 264
 265
 266/*
 267 * Sys helpers
 268 */
 269static int parse_arg(const char *buf, int *val)
 270{
 271        if (sscanf(buf, "%i", val) != 1)
 272                return -EINVAL;
 273        return 0;
 274}
 275
 276static ssize_t store_sys_acpi(struct device *dev, int cm,
 277                              const char *buf, size_t count)
 278{
 279        struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 280        int rv, value;
 281
 282        rv = parse_arg(buf, &value);
 283        if (rv < 0)
 284                return rv;
 285        rv = set_acpi(eeepc, cm, value);
 286        if (rv < 0)
 287                return -EIO;
 288        return count;
 289}
 290
 291static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
 292{
 293        struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 294        int value = get_acpi(eeepc, cm);
 295
 296        if (value < 0)
 297                return -EIO;
 298        return sprintf(buf, "%d\n", value);
 299}
 300
 301#define EEEPC_ACPI_SHOW_FUNC(_name, _cm)                                \
 302        static ssize_t _name##_show(struct device *dev,                 \
 303                                    struct device_attribute *attr,      \
 304                                    char *buf)                          \
 305        {                                                               \
 306                return show_sys_acpi(dev, _cm, buf);                    \
 307        }
 308
 309#define EEEPC_ACPI_STORE_FUNC(_name, _cm)                               \
 310        static ssize_t _name##_store(struct device *dev,                \
 311                                     struct device_attribute *attr,     \
 312                                     const char *buf, size_t count)     \
 313        {                                                               \
 314                return store_sys_acpi(dev, _cm, buf, count);            \
 315        }
 316
 317#define EEEPC_CREATE_DEVICE_ATTR_RW(_name, _cm)                         \
 318        EEEPC_ACPI_SHOW_FUNC(_name, _cm)                                \
 319        EEEPC_ACPI_STORE_FUNC(_name, _cm)                               \
 320        static DEVICE_ATTR_RW(_name)
 321
 322#define EEEPC_CREATE_DEVICE_ATTR_WO(_name, _cm)                         \
 323        EEEPC_ACPI_STORE_FUNC(_name, _cm)                               \
 324        static DEVICE_ATTR_WO(_name)
 325
 326EEEPC_CREATE_DEVICE_ATTR_RW(camera, CM_ASL_CAMERA);
 327EEEPC_CREATE_DEVICE_ATTR_RW(cardr, CM_ASL_CARDREADER);
 328EEEPC_CREATE_DEVICE_ATTR_WO(disp, CM_ASL_DISPLAYSWITCH);
 329
 330struct eeepc_cpufv {
 331        int num;
 332        int cur;
 333};
 334
 335static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
 336{
 337        c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
 338        if (c->cur < 0)
 339                return -ENODEV;
 340
 341        c->num = (c->cur >> 8) & 0xff;
 342        c->cur &= 0xff;
 343        if (c->num == 0 || c->num > 12)
 344                return -ENODEV;
 345        return 0;
 346}
 347
 348static ssize_t available_cpufv_show(struct device *dev,
 349                                    struct device_attribute *attr,
 350                                    char *buf)
 351{
 352        struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 353        struct eeepc_cpufv c;
 354        int i;
 355        ssize_t len = 0;
 356
 357        if (get_cpufv(eeepc, &c))
 358                return -ENODEV;
 359        for (i = 0; i < c.num; i++)
 360                len += sprintf(buf + len, "%d ", i);
 361        len += sprintf(buf + len, "\n");
 362        return len;
 363}
 364
 365static ssize_t cpufv_show(struct device *dev,
 366                          struct device_attribute *attr,
 367                          char *buf)
 368{
 369        struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 370        struct eeepc_cpufv c;
 371
 372        if (get_cpufv(eeepc, &c))
 373                return -ENODEV;
 374        return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
 375}
 376
 377static ssize_t cpufv_store(struct device *dev,
 378                           struct device_attribute *attr,
 379                           const char *buf, size_t count)
 380{
 381        struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 382        struct eeepc_cpufv c;
 383        int rv, value;
 384
 385        if (eeepc->cpufv_disabled)
 386                return -EPERM;
 387        if (get_cpufv(eeepc, &c))
 388                return -ENODEV;
 389        rv = parse_arg(buf, &value);
 390        if (rv < 0)
 391                return rv;
 392        if (value < 0 || value >= c.num)
 393                return -EINVAL;
 394        rv = set_acpi(eeepc, CM_ASL_CPUFV, value);
 395        if (rv)
 396                return rv;
 397        return count;
 398}
 399
 400static ssize_t cpufv_disabled_show(struct device *dev,
 401                          struct device_attribute *attr,
 402                          char *buf)
 403{
 404        struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 405
 406        return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
 407}
 408
 409static ssize_t cpufv_disabled_store(struct device *dev,
 410                           struct device_attribute *attr,
 411                           const char *buf, size_t count)
 412{
 413        struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
 414        int rv, value;
 415
 416        rv = parse_arg(buf, &value);
 417        if (rv < 0)
 418                return rv;
 419
 420        switch (value) {
 421        case 0:
 422                if (eeepc->cpufv_disabled)
 423                        pr_warn("cpufv enabled (not officially supported on this model)\n");
 424                eeepc->cpufv_disabled = false;
 425                return count;
 426        case 1:
 427                return -EPERM;
 428        default:
 429                return -EINVAL;
 430        }
 431}
 432
 433
 434static DEVICE_ATTR_RW(cpufv);
 435static DEVICE_ATTR_RO(available_cpufv);
 436static DEVICE_ATTR_RW(cpufv_disabled);
 437
 438static struct attribute *platform_attributes[] = {
 439        &dev_attr_camera.attr,
 440        &dev_attr_cardr.attr,
 441        &dev_attr_disp.attr,
 442        &dev_attr_cpufv.attr,
 443        &dev_attr_available_cpufv.attr,
 444        &dev_attr_cpufv_disabled.attr,
 445        NULL
 446};
 447
 448static const struct attribute_group platform_attribute_group = {
 449        .attrs = platform_attributes
 450};
 451
 452static int eeepc_platform_init(struct eeepc_laptop *eeepc)
 453{
 454        int result;
 455
 456        eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
 457        if (!eeepc->platform_device)
 458                return -ENOMEM;
 459        platform_set_drvdata(eeepc->platform_device, eeepc);
 460
 461        result = platform_device_add(eeepc->platform_device);
 462        if (result)
 463                goto fail_platform_device;
 464
 465        result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
 466                                    &platform_attribute_group);
 467        if (result)
 468                goto fail_sysfs;
 469        return 0;
 470
 471fail_sysfs:
 472        platform_device_del(eeepc->platform_device);
 473fail_platform_device:
 474        platform_device_put(eeepc->platform_device);
 475        return result;
 476}
 477
 478static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
 479{
 480        sysfs_remove_group(&eeepc->platform_device->dev.kobj,
 481                           &platform_attribute_group);
 482        platform_device_unregister(eeepc->platform_device);
 483}
 484
 485/*
 486 * LEDs
 487 */
 488/*
 489 * These functions actually update the LED's, and are called from a
 490 * workqueue. By doing this as separate work rather than when the LED
 491 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
 492 * potentially bad time, such as a timer interrupt.
 493 */
 494static void tpd_led_update(struct work_struct *work)
 495 {
 496        struct eeepc_laptop *eeepc;
 497
 498        eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
 499
 500        set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
 501}
 502
 503static void tpd_led_set(struct led_classdev *led_cdev,
 504                        enum led_brightness value)
 505{
 506        struct eeepc_laptop *eeepc;
 507
 508        eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
 509
 510        eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
 511        queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
 512}
 513
 514static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
 515{
 516        struct eeepc_laptop *eeepc;
 517
 518        eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
 519
 520        return get_acpi(eeepc, CM_ASL_TPD);
 521}
 522
 523static int eeepc_led_init(struct eeepc_laptop *eeepc)
 524{
 525        int rv;
 526
 527        if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
 528                return 0;
 529
 530        eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
 531        if (!eeepc->led_workqueue)
 532                return -ENOMEM;
 533        INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
 534
 535        eeepc->tpd_led.name = "eeepc::touchpad";
 536        eeepc->tpd_led.brightness_set = tpd_led_set;
 537        if (get_acpi(eeepc, CM_ASL_TPD) >= 0) /* if method is available */
 538                eeepc->tpd_led.brightness_get = tpd_led_get;
 539        eeepc->tpd_led.max_brightness = 1;
 540
 541        rv = led_classdev_register(&eeepc->platform_device->dev,
 542                                   &eeepc->tpd_led);
 543        if (rv) {
 544                destroy_workqueue(eeepc->led_workqueue);
 545                return rv;
 546        }
 547
 548        return 0;
 549}
 550
 551static void eeepc_led_exit(struct eeepc_laptop *eeepc)
 552{
 553        if (!IS_ERR_OR_NULL(eeepc->tpd_led.dev))
 554                led_classdev_unregister(&eeepc->tpd_led);
 555        if (eeepc->led_workqueue)
 556                destroy_workqueue(eeepc->led_workqueue);
 557}
 558
 559
 560/*
 561 * PCI hotplug (for wlan rfkill)
 562 */
 563static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
 564{
 565        if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
 566                return false;
 567        return true;
 568}
 569
 570static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
 571{
 572        struct pci_dev *port;
 573        struct pci_dev *dev;
 574        struct pci_bus *bus;
 575        bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
 576        bool absent;
 577        u32 l;
 578
 579        if (eeepc->wlan_rfkill)
 580                rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
 581
 582        mutex_lock(&eeepc->hotplug_lock);
 583        pci_lock_rescan_remove();
 584
 585        if (!eeepc->hotplug_slot)
 586                goto out_unlock;
 587
 588        port = acpi_get_pci_dev(handle);
 589        if (!port) {
 590                pr_warning("Unable to find port\n");
 591                goto out_unlock;
 592        }
 593
 594        bus = port->subordinate;
 595
 596        if (!bus) {
 597                pr_warn("Unable to find PCI bus 1?\n");
 598                goto out_put_dev;
 599        }
 600
 601        if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
 602                pr_err("Unable to read PCI config space?\n");
 603                goto out_put_dev;
 604        }
 605
 606        absent = (l == 0xffffffff);
 607
 608        if (blocked != absent) {
 609                pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n",
 610                        blocked ? "blocked" : "unblocked",
 611                        absent ? "absent" : "present");
 612                pr_warn("skipped wireless hotplug as probably inappropriate for this model\n");
 613                goto out_put_dev;
 614        }
 615
 616        if (!blocked) {
 617                dev = pci_get_slot(bus, 0);
 618                if (dev) {
 619                        /* Device already present */
 620                        pci_dev_put(dev);
 621                        goto out_put_dev;
 622                }
 623                dev = pci_scan_single_device(bus, 0);
 624                if (dev) {
 625                        pci_bus_assign_resources(bus);
 626                        pci_bus_add_device(dev);
 627                }
 628        } else {
 629                dev = pci_get_slot(bus, 0);
 630                if (dev) {
 631                        pci_stop_and_remove_bus_device(dev);
 632                        pci_dev_put(dev);
 633                }
 634        }
 635out_put_dev:
 636        pci_dev_put(port);
 637
 638out_unlock:
 639        pci_unlock_rescan_remove();
 640        mutex_unlock(&eeepc->hotplug_lock);
 641}
 642
 643static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
 644{
 645        acpi_status status = AE_OK;
 646        acpi_handle handle;
 647
 648        status = acpi_get_handle(NULL, node, &handle);
 649
 650        if (ACPI_SUCCESS(status))
 651                eeepc_rfkill_hotplug(eeepc, handle);
 652}
 653
 654static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
 655{
 656        struct eeepc_laptop *eeepc = data;
 657
 658        if (event != ACPI_NOTIFY_BUS_CHECK)
 659                return;
 660
 661        eeepc_rfkill_hotplug(eeepc, handle);
 662}
 663
 664static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
 665                                          char *node)
 666{
 667        acpi_status status;
 668        acpi_handle handle;
 669
 670        status = acpi_get_handle(NULL, node, &handle);
 671
 672        if (ACPI_FAILURE(status))
 673                return -ENODEV;
 674
 675        status = acpi_install_notify_handler(handle,
 676                                             ACPI_SYSTEM_NOTIFY,
 677                                             eeepc_rfkill_notify,
 678                                             eeepc);
 679        if (ACPI_FAILURE(status))
 680                pr_warn("Failed to register notify on %s\n", node);
 681
 682        /*
 683         * Refresh pci hotplug in case the rfkill state was
 684         * changed during setup.
 685         */
 686        eeepc_rfkill_hotplug(eeepc, handle);
 687        return 0;
 688}
 689
 690static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
 691                                             char *node)
 692{
 693        acpi_status status = AE_OK;
 694        acpi_handle handle;
 695
 696        status = acpi_get_handle(NULL, node, &handle);
 697
 698        if (ACPI_FAILURE(status))
 699                return;
 700
 701        status = acpi_remove_notify_handler(handle,
 702                                             ACPI_SYSTEM_NOTIFY,
 703                                             eeepc_rfkill_notify);
 704        if (ACPI_FAILURE(status))
 705                pr_err("Error removing rfkill notify handler %s\n",
 706                        node);
 707                /*
 708                 * Refresh pci hotplug in case the rfkill
 709                 * state was changed after
 710                 * eeepc_unregister_rfkill_notifier()
 711                 */
 712        eeepc_rfkill_hotplug(eeepc, handle);
 713}
 714
 715static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
 716                                    u8 *value)
 717{
 718        struct eeepc_laptop *eeepc = hotplug_slot->private;
 719        int val = get_acpi(eeepc, CM_ASL_WLAN);
 720
 721        if (val == 1 || val == 0)
 722                *value = val;
 723        else
 724                return -EINVAL;
 725
 726        return 0;
 727}
 728
 729static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
 730{
 731        kfree(hotplug_slot->info);
 732        kfree(hotplug_slot);
 733}
 734
 735static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
 736        .owner = THIS_MODULE,
 737        .get_adapter_status = eeepc_get_adapter_status,
 738        .get_power_status = eeepc_get_adapter_status,
 739};
 740
 741static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
 742{
 743        int ret = -ENOMEM;
 744        struct pci_bus *bus = pci_find_bus(0, 1);
 745
 746        if (!bus) {
 747                pr_err("Unable to find wifi PCI bus\n");
 748                return -ENODEV;
 749        }
 750
 751        eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
 752        if (!eeepc->hotplug_slot)
 753                goto error_slot;
 754
 755        eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
 756                                            GFP_KERNEL);
 757        if (!eeepc->hotplug_slot->info)
 758                goto error_info;
 759
 760        eeepc->hotplug_slot->private = eeepc;
 761        eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
 762        eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
 763        eeepc_get_adapter_status(eeepc->hotplug_slot,
 764                                 &eeepc->hotplug_slot->info->adapter_status);
 765
 766        ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
 767        if (ret) {
 768                pr_err("Unable to register hotplug slot - %d\n", ret);
 769                goto error_register;
 770        }
 771
 772        return 0;
 773
 774error_register:
 775        kfree(eeepc->hotplug_slot->info);
 776error_info:
 777        kfree(eeepc->hotplug_slot);
 778        eeepc->hotplug_slot = NULL;
 779error_slot:
 780        return ret;
 781}
 782
 783/*
 784 * Rfkill devices
 785 */
 786static int eeepc_rfkill_set(void *data, bool blocked)
 787{
 788        acpi_handle handle = data;
 789
 790        return write_acpi_int(handle, NULL, !blocked);
 791}
 792
 793static const struct rfkill_ops eeepc_rfkill_ops = {
 794        .set_block = eeepc_rfkill_set,
 795};
 796
 797static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
 798                            struct rfkill **rfkill,
 799                            const char *name,
 800                            enum rfkill_type type, int cm)
 801{
 802        acpi_handle handle;
 803        int result;
 804
 805        result = acpi_setter_handle(eeepc, cm, &handle);
 806        if (result < 0)
 807                return result;
 808
 809        *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
 810                               &eeepc_rfkill_ops, handle);
 811
 812        if (!*rfkill)
 813                return -EINVAL;
 814
 815        rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
 816        result = rfkill_register(*rfkill);
 817        if (result) {
 818                rfkill_destroy(*rfkill);
 819                *rfkill = NULL;
 820                return result;
 821        }
 822        return 0;
 823}
 824
 825static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5";
 826static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6";
 827static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7";
 828
 829static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
 830{
 831        eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
 832        eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
 833        eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
 834        if (eeepc->wlan_rfkill) {
 835                rfkill_unregister(eeepc->wlan_rfkill);
 836                rfkill_destroy(eeepc->wlan_rfkill);
 837                eeepc->wlan_rfkill = NULL;
 838        }
 839
 840        if (eeepc->hotplug_slot)
 841                pci_hp_deregister(eeepc->hotplug_slot);
 842
 843        if (eeepc->bluetooth_rfkill) {
 844                rfkill_unregister(eeepc->bluetooth_rfkill);
 845                rfkill_destroy(eeepc->bluetooth_rfkill);
 846                eeepc->bluetooth_rfkill = NULL;
 847        }
 848        if (eeepc->wwan3g_rfkill) {
 849                rfkill_unregister(eeepc->wwan3g_rfkill);
 850                rfkill_destroy(eeepc->wwan3g_rfkill);
 851                eeepc->wwan3g_rfkill = NULL;
 852        }
 853        if (eeepc->wimax_rfkill) {
 854                rfkill_unregister(eeepc->wimax_rfkill);
 855                rfkill_destroy(eeepc->wimax_rfkill);
 856                eeepc->wimax_rfkill = NULL;
 857        }
 858}
 859
 860static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
 861{
 862        int result = 0;
 863
 864        mutex_init(&eeepc->hotplug_lock);
 865
 866        result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
 867                                  "eeepc-wlan", RFKILL_TYPE_WLAN,
 868                                  CM_ASL_WLAN);
 869
 870        if (result && result != -ENODEV)
 871                goto exit;
 872
 873        result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
 874                                  "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
 875                                  CM_ASL_BLUETOOTH);
 876
 877        if (result && result != -ENODEV)
 878                goto exit;
 879
 880        result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
 881                                  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
 882                                  CM_ASL_3G);
 883
 884        if (result && result != -ENODEV)
 885                goto exit;
 886
 887        result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
 888                                  "eeepc-wimax", RFKILL_TYPE_WIMAX,
 889                                  CM_ASL_WIMAX);
 890
 891        if (result && result != -ENODEV)
 892                goto exit;
 893
 894        if (eeepc->hotplug_disabled)
 895                return 0;
 896
 897        result = eeepc_setup_pci_hotplug(eeepc);
 898        /*
 899         * If we get -EBUSY then something else is handling the PCI hotplug -
 900         * don't fail in this case
 901         */
 902        if (result == -EBUSY)
 903                result = 0;
 904
 905        eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
 906        eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
 907        eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
 908
 909exit:
 910        if (result && result != -ENODEV)
 911                eeepc_rfkill_exit(eeepc);
 912        return result;
 913}
 914
 915/*
 916 * Platform driver - hibernate/resume callbacks
 917 */
 918static int eeepc_hotk_thaw(struct device *device)
 919{
 920        struct eeepc_laptop *eeepc = dev_get_drvdata(device);
 921
 922        if (eeepc->wlan_rfkill) {
 923                int wlan;
 924
 925                /*
 926                 * Work around bios bug - acpi _PTS turns off the wireless led
 927                 * during suspend.  Normally it restores it on resume, but
 928                 * we should kick it ourselves in case hibernation is aborted.
 929                 */
 930                wlan = get_acpi(eeepc, CM_ASL_WLAN);
 931                if (wlan >= 0)
 932                        set_acpi(eeepc, CM_ASL_WLAN, wlan);
 933        }
 934
 935        return 0;
 936}
 937
 938static int eeepc_hotk_restore(struct device *device)
 939{
 940        struct eeepc_laptop *eeepc = dev_get_drvdata(device);
 941
 942        /* Refresh both wlan rfkill state and pci hotplug */
 943        if (eeepc->wlan_rfkill) {
 944                eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1);
 945                eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2);
 946                eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3);
 947        }
 948
 949        if (eeepc->bluetooth_rfkill)
 950                rfkill_set_sw_state(eeepc->bluetooth_rfkill,
 951                                    get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
 952        if (eeepc->wwan3g_rfkill)
 953                rfkill_set_sw_state(eeepc->wwan3g_rfkill,
 954                                    get_acpi(eeepc, CM_ASL_3G) != 1);
 955        if (eeepc->wimax_rfkill)
 956                rfkill_set_sw_state(eeepc->wimax_rfkill,
 957                                    get_acpi(eeepc, CM_ASL_WIMAX) != 1);
 958
 959        return 0;
 960}
 961
 962static const struct dev_pm_ops eeepc_pm_ops = {
 963        .thaw = eeepc_hotk_thaw,
 964        .restore = eeepc_hotk_restore,
 965};
 966
 967static struct platform_driver platform_driver = {
 968        .driver = {
 969                .name = EEEPC_LAPTOP_FILE,
 970                .pm = &eeepc_pm_ops,
 971        }
 972};
 973
 974/*
 975 * Hwmon device
 976 */
 977
 978#define EEEPC_EC_SC00      0x61
 979#define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
 980#define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
 981#define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
 982
 983#define EEEPC_EC_SFB0      0xD0
 984#define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
 985
 986static inline int eeepc_pwm_to_lmsensors(int value)
 987{
 988        return value * 255 / 100;
 989}
 990
 991static inline int eeepc_lmsensors_to_pwm(int value)
 992{
 993        value = clamp_val(value, 0, 255);
 994        return value * 100 / 255;
 995}
 996
 997static int eeepc_get_fan_pwm(void)
 998{
 999        u8 value = 0;
1000
1001        ec_read(EEEPC_EC_FAN_PWM, &value);
1002        return eeepc_pwm_to_lmsensors(value);
1003}
1004
1005static void eeepc_set_fan_pwm(int value)
1006{
1007        value = eeepc_lmsensors_to_pwm(value);
1008        ec_write(EEEPC_EC_FAN_PWM, value);
1009}
1010
1011static int eeepc_get_fan_rpm(void)
1012{
1013        u8 high = 0;
1014        u8 low = 0;
1015
1016        ec_read(EEEPC_EC_FAN_HRPM, &high);
1017        ec_read(EEEPC_EC_FAN_LRPM, &low);
1018        return high << 8 | low;
1019}
1020
1021#define EEEPC_EC_FAN_CTRL_BIT   0x02
1022#define EEEPC_FAN_CTRL_MANUAL   1
1023#define EEEPC_FAN_CTRL_AUTO     2
1024
1025static int eeepc_get_fan_ctrl(void)
1026{
1027        u8 value = 0;
1028
1029        ec_read(EEEPC_EC_FAN_CTRL, &value);
1030        if (value & EEEPC_EC_FAN_CTRL_BIT)
1031                return EEEPC_FAN_CTRL_MANUAL;
1032        else
1033                return EEEPC_FAN_CTRL_AUTO;
1034}
1035
1036static void eeepc_set_fan_ctrl(int manual)
1037{
1038        u8 value = 0;
1039
1040        ec_read(EEEPC_EC_FAN_CTRL, &value);
1041        if (manual == EEEPC_FAN_CTRL_MANUAL)
1042                value |= EEEPC_EC_FAN_CTRL_BIT;
1043        else
1044                value &= ~EEEPC_EC_FAN_CTRL_BIT;
1045        ec_write(EEEPC_EC_FAN_CTRL, value);
1046}
1047
1048static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1049{
1050        int rv, value;
1051
1052        rv = parse_arg(buf, &value);
1053        if (rv < 0)
1054                return rv;
1055        set(value);
1056        return count;
1057}
1058
1059static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1060{
1061        return sprintf(buf, "%d\n", get());
1062}
1063
1064#define EEEPC_SENSOR_SHOW_FUNC(_name, _get)                             \
1065        static ssize_t _name##_show(struct device *dev,                 \
1066                                    struct device_attribute *attr,      \
1067                                    char *buf)                          \
1068        {                                                               \
1069                return show_sys_hwmon(_get, buf);                       \
1070        }
1071
1072#define EEEPC_SENSOR_STORE_FUNC(_name, _set)                            \
1073        static ssize_t _name##_store(struct device *dev,                \
1074                                     struct device_attribute *attr,     \
1075                                     const char *buf, size_t count)     \
1076        {                                                               \
1077                return store_sys_hwmon(_set, buf, count);               \
1078        }
1079
1080#define EEEPC_CREATE_SENSOR_ATTR_RW(_name, _get, _set)                  \
1081        EEEPC_SENSOR_SHOW_FUNC(_name, _get)                             \
1082        EEEPC_SENSOR_STORE_FUNC(_name, _set)                            \
1083        static DEVICE_ATTR_RW(_name)
1084
1085#define EEEPC_CREATE_SENSOR_ATTR_RO(_name, _get)                        \
1086        EEEPC_SENSOR_SHOW_FUNC(_name, _get)                             \
1087        static DEVICE_ATTR_RO(_name)
1088
1089EEEPC_CREATE_SENSOR_ATTR_RO(fan1_input, eeepc_get_fan_rpm);
1090EEEPC_CREATE_SENSOR_ATTR_RW(pwm1, eeepc_get_fan_pwm,
1091                            eeepc_set_fan_pwm);
1092EEEPC_CREATE_SENSOR_ATTR_RW(pwm1_enable, eeepc_get_fan_ctrl,
1093                            eeepc_set_fan_ctrl);
1094
1095static struct attribute *hwmon_attrs[] = {
1096        &dev_attr_pwm1.attr,
1097        &dev_attr_fan1_input.attr,
1098        &dev_attr_pwm1_enable.attr,
1099        NULL
1100};
1101ATTRIBUTE_GROUPS(hwmon);
1102
1103static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1104{
1105        struct device *dev = &eeepc->platform_device->dev;
1106        struct device *hwmon;
1107
1108        hwmon = devm_hwmon_device_register_with_groups(dev, "eeepc", NULL,
1109                                                       hwmon_groups);
1110        if (IS_ERR(hwmon)) {
1111                pr_err("Could not register eeepc hwmon device\n");
1112                return PTR_ERR(hwmon);
1113        }
1114        return 0;
1115}
1116
1117/*
1118 * Backlight device
1119 */
1120static int read_brightness(struct backlight_device *bd)
1121{
1122        struct eeepc_laptop *eeepc = bl_get_data(bd);
1123
1124        return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1125}
1126
1127static int set_brightness(struct backlight_device *bd, int value)
1128{
1129        struct eeepc_laptop *eeepc = bl_get_data(bd);
1130
1131        return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1132}
1133
1134static int update_bl_status(struct backlight_device *bd)
1135{
1136        return set_brightness(bd, bd->props.brightness);
1137}
1138
1139static const struct backlight_ops eeepcbl_ops = {
1140        .get_brightness = read_brightness,
1141        .update_status = update_bl_status,
1142};
1143
1144static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1145{
1146        struct backlight_device *bd = eeepc->backlight_device;
1147        int old = bd->props.brightness;
1148
1149        backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1150
1151        return old;
1152}
1153
1154static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1155{
1156        struct backlight_properties props;
1157        struct backlight_device *bd;
1158
1159        memset(&props, 0, sizeof(struct backlight_properties));
1160        props.type = BACKLIGHT_PLATFORM;
1161        props.max_brightness = 15;
1162        bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1163                                       &eeepc->platform_device->dev, eeepc,
1164                                       &eeepcbl_ops, &props);
1165        if (IS_ERR(bd)) {
1166                pr_err("Could not register eeepc backlight device\n");
1167                eeepc->backlight_device = NULL;
1168                return PTR_ERR(bd);
1169        }
1170        eeepc->backlight_device = bd;
1171        bd->props.brightness = read_brightness(bd);
1172        bd->props.power = FB_BLANK_UNBLANK;
1173        backlight_update_status(bd);
1174        return 0;
1175}
1176
1177static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1178{
1179        backlight_device_unregister(eeepc->backlight_device);
1180        eeepc->backlight_device = NULL;
1181}
1182
1183
1184/*
1185 * Input device (i.e. hotkeys)
1186 */
1187static int eeepc_input_init(struct eeepc_laptop *eeepc)
1188{
1189        struct input_dev *input;
1190        int error;
1191
1192        input = input_allocate_device();
1193        if (!input)
1194                return -ENOMEM;
1195
1196        input->name = "Asus EeePC extra buttons";
1197        input->phys = EEEPC_LAPTOP_FILE "/input0";
1198        input->id.bustype = BUS_HOST;
1199        input->dev.parent = &eeepc->platform_device->dev;
1200
1201        error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1202        if (error) {
1203                pr_err("Unable to setup input device keymap\n");
1204                goto err_free_dev;
1205        }
1206
1207        error = input_register_device(input);
1208        if (error) {
1209                pr_err("Unable to register input device\n");
1210                goto err_free_dev;
1211        }
1212
1213        eeepc->inputdev = input;
1214        return 0;
1215
1216err_free_dev:
1217        input_free_device(input);
1218        return error;
1219}
1220
1221static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1222{
1223        if (eeepc->inputdev)
1224                input_unregister_device(eeepc->inputdev);
1225        eeepc->inputdev = NULL;
1226}
1227
1228/*
1229 * ACPI driver
1230 */
1231static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1232{
1233        if (!eeepc->inputdev)
1234                return;
1235        if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
1236                pr_info("Unknown key %x pressed\n", event);
1237}
1238
1239static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1240{
1241        struct eeepc_laptop *eeepc = acpi_driver_data(device);
1242        int old_brightness, new_brightness;
1243        u16 count;
1244
1245        if (event > ACPI_MAX_SYS_NOTIFY)
1246                return;
1247        count = eeepc->event_count[event % 128]++;
1248        acpi_bus_generate_netlink_event(device->pnp.device_class,
1249                                        dev_name(&device->dev), event,
1250                                        count);
1251
1252        /* Brightness events are special */
1253        if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) {
1254                eeepc_input_notify(eeepc, event);
1255                return;
1256        }
1257
1258        /* Ignore them completely if the acpi video driver is used */
1259        if (!eeepc->backlight_device)
1260                return;
1261
1262        /* Update the backlight device. */
1263        old_brightness = eeepc_backlight_notify(eeepc);
1264
1265        /* Convert event to keypress (obsolescent hack) */
1266        new_brightness = event - NOTIFY_BRN_MIN;
1267
1268        if (new_brightness < old_brightness) {
1269                event = NOTIFY_BRN_MIN; /* brightness down */
1270        } else if (new_brightness > old_brightness) {
1271                event = NOTIFY_BRN_MAX; /* brightness up */
1272        } else {
1273                /*
1274                 * no change in brightness - already at min/max,
1275                 * event will be desired value (or else ignored)
1276                 */
1277        }
1278        eeepc_input_notify(eeepc, event);
1279}
1280
1281static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1282{
1283        const char *model;
1284
1285        model = dmi_get_system_info(DMI_PRODUCT_NAME);
1286        if (!model)
1287                return;
1288
1289        /*
1290         * Blacklist for setting cpufv (cpu speed).
1291         *
1292         * EeePC 4G ("701") implements CFVS, but it is not supported
1293         * by the pre-installed OS, and the original option to change it
1294         * in the BIOS setup screen was removed in later versions.
1295         *
1296         * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1297         * this applies to all "701" models (4G/4G Surf/2G Surf).
1298         *
1299         * So Asus made a deliberate decision not to support it on this model.
1300         * We have several reports that using it can cause the system to hang
1301         *
1302         * The hang has also been reported on a "702" (Model name "8G"?).
1303         *
1304         * We avoid dmi_check_system() / dmi_match(), because they use
1305         * substring matching.  We don't want to affect the "701SD"
1306         * and "701SDX" models, because they do support S.H.E.
1307         */
1308        if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1309                eeepc->cpufv_disabled = true;
1310                pr_info("model %s does not officially support setting cpu speed\n",
1311                        model);
1312                pr_info("cpufv disabled to avoid instability\n");
1313        }
1314
1315        /*
1316         * Blacklist for wlan hotplug
1317         *
1318         * Eeepc 1005HA doesn't work like others models and don't need the
1319         * hotplug code. In fact, current hotplug code seems to unplug another
1320         * device...
1321         */
1322        if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1323            strcmp(model, "1005PE") == 0) {
1324                eeepc->hotplug_disabled = true;
1325                pr_info("wlan hotplug disabled\n");
1326        }
1327}
1328
1329static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1330{
1331        int dummy;
1332
1333        /* Some BIOSes do not report cm although it is available.
1334           Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1335        if (!(eeepc->cm_supported & (1 << cm))
1336            && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1337                pr_info("%s (%x) not reported by BIOS, enabling anyway\n",
1338                        name, 1 << cm);
1339                eeepc->cm_supported |= 1 << cm;
1340        }
1341}
1342
1343static void cmsg_quirks(struct eeepc_laptop *eeepc)
1344{
1345        cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1346        cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1347        cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1348        cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1349}
1350
1351static int eeepc_acpi_init(struct eeepc_laptop *eeepc)
1352{
1353        unsigned int init_flags;
1354        int result;
1355
1356        result = acpi_bus_get_status(eeepc->device);
1357        if (result)
1358                return result;
1359        if (!eeepc->device->status.present) {
1360                pr_err("Hotkey device not present, aborting\n");
1361                return -ENODEV;
1362        }
1363
1364        init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1365        pr_notice("Hotkey init flags 0x%x\n", init_flags);
1366
1367        if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1368                pr_err("Hotkey initialization failed\n");
1369                return -ENODEV;
1370        }
1371
1372        /* get control methods supported */
1373        if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1374                pr_err("Get control methods supported failed\n");
1375                return -ENODEV;
1376        }
1377        cmsg_quirks(eeepc);
1378        pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1379
1380        return 0;
1381}
1382
1383static void eeepc_enable_camera(struct eeepc_laptop *eeepc)
1384{
1385        /*
1386         * If the following call to set_acpi() fails, it's because there's no
1387         * camera so we can ignore the error.
1388         */
1389        if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1390                set_acpi(eeepc, CM_ASL_CAMERA, 1);
1391}
1392
1393static bool eeepc_device_present;
1394
1395static int eeepc_acpi_add(struct acpi_device *device)
1396{
1397        struct eeepc_laptop *eeepc;
1398        int result;
1399
1400        pr_notice(EEEPC_LAPTOP_NAME "\n");
1401        eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1402        if (!eeepc)
1403                return -ENOMEM;
1404        eeepc->handle = device->handle;
1405        strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1406        strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1407        device->driver_data = eeepc;
1408        eeepc->device = device;
1409
1410        eeepc->hotplug_disabled = hotplug_disabled;
1411
1412        eeepc_dmi_check(eeepc);
1413
1414        result = eeepc_acpi_init(eeepc);
1415        if (result)
1416                goto fail_platform;
1417        eeepc_enable_camera(eeepc);
1418
1419        /*
1420         * Register the platform device first.  It is used as a parent for the
1421         * sub-devices below.
1422         *
1423         * Note that if there are multiple instances of this ACPI device it
1424         * will bail out, because the platform device is registered with a
1425         * fixed name.  Of course it doesn't make sense to have more than one,
1426         * and machine-specific scripts find the fixed name convenient.  But
1427         * It's also good for us to exclude multiple instances because both
1428         * our hwmon and our wlan rfkill subdevice use global ACPI objects
1429         * (the EC and the wlan PCI slot respectively).
1430         */
1431        result = eeepc_platform_init(eeepc);
1432        if (result)
1433                goto fail_platform;
1434
1435        if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
1436                result = eeepc_backlight_init(eeepc);
1437                if (result)
1438                        goto fail_backlight;
1439        }
1440
1441        result = eeepc_input_init(eeepc);
1442        if (result)
1443                goto fail_input;
1444
1445        result = eeepc_hwmon_init(eeepc);
1446        if (result)
1447                goto fail_hwmon;
1448
1449        result = eeepc_led_init(eeepc);
1450        if (result)
1451                goto fail_led;
1452
1453        result = eeepc_rfkill_init(eeepc);
1454        if (result)
1455                goto fail_rfkill;
1456
1457        eeepc_device_present = true;
1458        return 0;
1459
1460fail_rfkill:
1461        eeepc_led_exit(eeepc);
1462fail_led:
1463fail_hwmon:
1464        eeepc_input_exit(eeepc);
1465fail_input:
1466        eeepc_backlight_exit(eeepc);
1467fail_backlight:
1468        eeepc_platform_exit(eeepc);
1469fail_platform:
1470        kfree(eeepc);
1471
1472        return result;
1473}
1474
1475static int eeepc_acpi_remove(struct acpi_device *device)
1476{
1477        struct eeepc_laptop *eeepc = acpi_driver_data(device);
1478
1479        eeepc_backlight_exit(eeepc);
1480        eeepc_rfkill_exit(eeepc);
1481        eeepc_input_exit(eeepc);
1482        eeepc_led_exit(eeepc);
1483        eeepc_platform_exit(eeepc);
1484
1485        kfree(eeepc);
1486        return 0;
1487}
1488
1489
1490static const struct acpi_device_id eeepc_device_ids[] = {
1491        {EEEPC_ACPI_HID, 0},
1492        {"", 0},
1493};
1494MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1495
1496static struct acpi_driver eeepc_acpi_driver = {
1497        .name = EEEPC_LAPTOP_NAME,
1498        .class = EEEPC_ACPI_CLASS,
1499        .owner = THIS_MODULE,
1500        .ids = eeepc_device_ids,
1501        .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1502        .ops = {
1503                .add = eeepc_acpi_add,
1504                .remove = eeepc_acpi_remove,
1505                .notify = eeepc_acpi_notify,
1506        },
1507};
1508
1509
1510static int __init eeepc_laptop_init(void)
1511{
1512        int result;
1513
1514        result = platform_driver_register(&platform_driver);
1515        if (result < 0)
1516                return result;
1517
1518        result = acpi_bus_register_driver(&eeepc_acpi_driver);
1519        if (result < 0)
1520                goto fail_acpi_driver;
1521
1522        if (!eeepc_device_present) {
1523                result = -ENODEV;
1524                goto fail_no_device;
1525        }
1526
1527        return 0;
1528
1529fail_no_device:
1530        acpi_bus_unregister_driver(&eeepc_acpi_driver);
1531fail_acpi_driver:
1532        platform_driver_unregister(&platform_driver);
1533        return result;
1534}
1535
1536static void __exit eeepc_laptop_exit(void)
1537{
1538        acpi_bus_unregister_driver(&eeepc_acpi_driver);
1539        platform_driver_unregister(&platform_driver);
1540}
1541
1542module_init(eeepc_laptop_init);
1543module_exit(eeepc_laptop_exit);
1544