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