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
 602        if (eeepc->hotplug_slot) {
 603                port = acpi_get_pci_dev(handle);
 604                if (!port) {
 605                        pr_warning("Unable to find port\n");
 606                        goto out_unlock;
 607                }
 608
 609                bus = port->subordinate;
 610
 611                if (!bus) {
 612                        pr_warn("Unable to find PCI bus 1?\n");
 613                        goto out_unlock;
 614                }
 615
 616                if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
 617                        pr_err("Unable to read PCI config space?\n");
 618                        goto out_unlock;
 619                }
 620
 621                absent = (l == 0xffffffff);
 622
 623                if (blocked != absent) {
 624                        pr_warn("BIOS says wireless lan is %s, "
 625                                "but the pci device is %s\n",
 626                                blocked ? "blocked" : "unblocked",
 627                                absent ? "absent" : "present");
 628                        pr_warn("skipped wireless hotplug as probably "
 629                                "inappropriate for this model\n");
 630                        goto out_unlock;
 631                }
 632
 633                if (!blocked) {
 634                        dev = pci_get_slot(bus, 0);
 635                        if (dev) {
 636                                /* Device already present */
 637                                pci_dev_put(dev);
 638                                goto out_unlock;
 639                        }
 640                        dev = pci_scan_single_device(bus, 0);
 641                        if (dev) {
 642                                pci_bus_assign_resources(bus);
 643                                if (pci_bus_add_device(dev))
 644                                        pr_err("Unable to hotplug wifi\n");
 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                }
 653        }
 654
 655out_unlock:
 656        mutex_unlock(&eeepc->hotplug_lock);
 657}
 658
 659static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
 660{
 661        acpi_status status = AE_OK;
 662        acpi_handle handle;
 663
 664        status = acpi_get_handle(NULL, node, &handle);
 665
 666        if (ACPI_SUCCESS(status))
 667                eeepc_rfkill_hotplug(eeepc, handle);
 668}
 669
 670static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
 671{
 672        struct eeepc_laptop *eeepc = data;
 673
 674        if (event != ACPI_NOTIFY_BUS_CHECK)
 675                return;
 676
 677        eeepc_rfkill_hotplug(eeepc, handle);
 678}
 679
 680static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
 681                                          char *node)
 682{
 683        acpi_status status;
 684        acpi_handle handle;
 685
 686        status = acpi_get_handle(NULL, node, &handle);
 687
 688        if (ACPI_SUCCESS(status)) {
 689                status = acpi_install_notify_handler(handle,
 690                                                     ACPI_SYSTEM_NOTIFY,
 691                                                     eeepc_rfkill_notify,
 692                                                     eeepc);
 693                if (ACPI_FAILURE(status))
 694                        pr_warn("Failed to register notify on %s\n", node);
 695
 696                /*
 697                 * Refresh pci hotplug in case the rfkill state was
 698                 * changed during setup.
 699                 */
 700                eeepc_rfkill_hotplug(eeepc, handle);
 701        } else
 702                return -ENODEV;
 703
 704        return 0;
 705}
 706
 707static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
 708                                             char *node)
 709{
 710        acpi_status status = AE_OK;
 711        acpi_handle handle;
 712
 713        status = acpi_get_handle(NULL, node, &handle);
 714
 715        if (ACPI_SUCCESS(status)) {
 716                status = acpi_remove_notify_handler(handle,
 717                                                     ACPI_SYSTEM_NOTIFY,
 718                                                     eeepc_rfkill_notify);
 719                if (ACPI_FAILURE(status))
 720                        pr_err("Error removing rfkill notify handler %s\n",
 721                                node);
 722                        /*
 723                         * Refresh pci hotplug in case the rfkill
 724                         * state was changed after
 725                         * eeepc_unregister_rfkill_notifier()
 726                         */
 727                eeepc_rfkill_hotplug(eeepc, handle);
 728        }
 729}
 730
 731static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
 732                                    u8 *value)
 733{
 734        struct eeepc_laptop *eeepc = hotplug_slot->private;
 735        int val = get_acpi(eeepc, CM_ASL_WLAN);
 736
 737        if (val == 1 || val == 0)
 738                *value = val;
 739        else
 740                return -EINVAL;
 741
 742        return 0;
 743}
 744
 745static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
 746{
 747        kfree(hotplug_slot->info);
 748        kfree(hotplug_slot);
 749}
 750
 751static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
 752        .owner = THIS_MODULE,
 753        .get_adapter_status = eeepc_get_adapter_status,
 754        .get_power_status = eeepc_get_adapter_status,
 755};
 756
 757static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
 758{
 759        int ret = -ENOMEM;
 760        struct pci_bus *bus = pci_find_bus(0, 1);
 761
 762        if (!bus) {
 763                pr_err("Unable to find wifi PCI bus\n");
 764                return -ENODEV;
 765        }
 766
 767        eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
 768        if (!eeepc->hotplug_slot)
 769                goto error_slot;
 770
 771        eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
 772                                            GFP_KERNEL);
 773        if (!eeepc->hotplug_slot->info)
 774                goto error_info;
 775
 776        eeepc->hotplug_slot->private = eeepc;
 777        eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
 778        eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
 779        eeepc_get_adapter_status(eeepc->hotplug_slot,
 780                                 &eeepc->hotplug_slot->info->adapter_status);
 781
 782        ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
 783        if (ret) {
 784                pr_err("Unable to register hotplug slot - %d\n", ret);
 785                goto error_register;
 786        }
 787
 788        return 0;
 789
 790error_register:
 791        kfree(eeepc->hotplug_slot->info);
 792error_info:
 793        kfree(eeepc->hotplug_slot);
 794        eeepc->hotplug_slot = NULL;
 795error_slot:
 796        return ret;
 797}
 798
 799/*
 800 * Rfkill devices
 801 */
 802static int eeepc_rfkill_set(void *data, bool blocked)
 803{
 804        acpi_handle handle = data;
 805
 806        return write_acpi_int(handle, NULL, !blocked);
 807}
 808
 809static const struct rfkill_ops eeepc_rfkill_ops = {
 810        .set_block = eeepc_rfkill_set,
 811};
 812
 813static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
 814                            struct rfkill **rfkill,
 815                            const char *name,
 816                            enum rfkill_type type, int cm)
 817{
 818        acpi_handle handle;
 819        int result;
 820
 821        result = acpi_setter_handle(eeepc, cm, &handle);
 822        if (result < 0)
 823                return result;
 824
 825        *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
 826                               &eeepc_rfkill_ops, handle);
 827
 828        if (!*rfkill)
 829                return -EINVAL;
 830
 831        rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
 832        result = rfkill_register(*rfkill);
 833        if (result) {
 834                rfkill_destroy(*rfkill);
 835                *rfkill = NULL;
 836                return result;
 837        }
 838        return 0;
 839}
 840
 841static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
 842{
 843        eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
 844        eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
 845        eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
 846        if (eeepc->wlan_rfkill) {
 847                rfkill_unregister(eeepc->wlan_rfkill);
 848                rfkill_destroy(eeepc->wlan_rfkill);
 849                eeepc->wlan_rfkill = NULL;
 850        }
 851
 852        if (eeepc->hotplug_slot)
 853                pci_hp_deregister(eeepc->hotplug_slot);
 854
 855        if (eeepc->bluetooth_rfkill) {
 856                rfkill_unregister(eeepc->bluetooth_rfkill);
 857                rfkill_destroy(eeepc->bluetooth_rfkill);
 858                eeepc->bluetooth_rfkill = NULL;
 859        }
 860        if (eeepc->wwan3g_rfkill) {
 861                rfkill_unregister(eeepc->wwan3g_rfkill);
 862                rfkill_destroy(eeepc->wwan3g_rfkill);
 863                eeepc->wwan3g_rfkill = NULL;
 864        }
 865        if (eeepc->wimax_rfkill) {
 866                rfkill_unregister(eeepc->wimax_rfkill);
 867                rfkill_destroy(eeepc->wimax_rfkill);
 868                eeepc->wimax_rfkill = NULL;
 869        }
 870}
 871
 872static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
 873{
 874        int result = 0;
 875
 876        mutex_init(&eeepc->hotplug_lock);
 877
 878        result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
 879                                  "eeepc-wlan", RFKILL_TYPE_WLAN,
 880                                  CM_ASL_WLAN);
 881
 882        if (result && result != -ENODEV)
 883                goto exit;
 884
 885        result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
 886                                  "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
 887                                  CM_ASL_BLUETOOTH);
 888
 889        if (result && result != -ENODEV)
 890                goto exit;
 891
 892        result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
 893                                  "eeepc-wwan3g", RFKILL_TYPE_WWAN,
 894                                  CM_ASL_3G);
 895
 896        if (result && result != -ENODEV)
 897                goto exit;
 898
 899        result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
 900                                  "eeepc-wimax", RFKILL_TYPE_WIMAX,
 901                                  CM_ASL_WIMAX);
 902
 903        if (result && result != -ENODEV)
 904                goto exit;
 905
 906        if (eeepc->hotplug_disabled)
 907                return 0;
 908
 909        result = eeepc_setup_pci_hotplug(eeepc);
 910        /*
 911         * If we get -EBUSY then something else is handling the PCI hotplug -
 912         * don't fail in this case
 913         */
 914        if (result == -EBUSY)
 915                result = 0;
 916
 917        eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
 918        eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
 919        eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
 920
 921exit:
 922        if (result && result != -ENODEV)
 923                eeepc_rfkill_exit(eeepc);
 924        return result;
 925}
 926
 927/*
 928 * Platform driver - hibernate/resume callbacks
 929 */
 930static int eeepc_hotk_thaw(struct device *device)
 931{
 932        struct eeepc_laptop *eeepc = dev_get_drvdata(device);
 933
 934        if (eeepc->wlan_rfkill) {
 935                bool wlan;
 936
 937                /*
 938                 * Work around bios bug - acpi _PTS turns off the wireless led
 939                 * during suspend.  Normally it restores it on resume, but
 940                 * we should kick it ourselves in case hibernation is aborted.
 941                 */
 942                wlan = get_acpi(eeepc, CM_ASL_WLAN);
 943                set_acpi(eeepc, CM_ASL_WLAN, wlan);
 944        }
 945
 946        return 0;
 947}
 948
 949static int eeepc_hotk_restore(struct device *device)
 950{
 951        struct eeepc_laptop *eeepc = dev_get_drvdata(device);
 952
 953        /* Refresh both wlan rfkill state and pci hotplug */
 954        if (eeepc->wlan_rfkill) {
 955                eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5");
 956                eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6");
 957                eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7");
 958        }
 959
 960        if (eeepc->bluetooth_rfkill)
 961                rfkill_set_sw_state(eeepc->bluetooth_rfkill,
 962                                    get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
 963        if (eeepc->wwan3g_rfkill)
 964                rfkill_set_sw_state(eeepc->wwan3g_rfkill,
 965                                    get_acpi(eeepc, CM_ASL_3G) != 1);
 966        if (eeepc->wimax_rfkill)
 967                rfkill_set_sw_state(eeepc->wimax_rfkill,
 968                                    get_acpi(eeepc, CM_ASL_WIMAX) != 1);
 969
 970        return 0;
 971}
 972
 973static const struct dev_pm_ops eeepc_pm_ops = {
 974        .thaw = eeepc_hotk_thaw,
 975        .restore = eeepc_hotk_restore,
 976};
 977
 978static struct platform_driver platform_driver = {
 979        .driver = {
 980                .name = EEEPC_LAPTOP_FILE,
 981                .owner = THIS_MODULE,
 982                .pm = &eeepc_pm_ops,
 983        }
 984};
 985
 986/*
 987 * Hwmon device
 988 */
 989
 990#define EEEPC_EC_SC00      0x61
 991#define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
 992#define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
 993#define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
 994
 995#define EEEPC_EC_SFB0      0xD0
 996#define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
 997
 998static int eeepc_get_fan_pwm(void)
 999{
1000        u8 value = 0;
1001
1002        ec_read(EEEPC_EC_FAN_PWM, &value);
1003        return value * 255 / 100;
1004}
1005
1006static void eeepc_set_fan_pwm(int value)
1007{
1008        value = SENSORS_LIMIT(value, 0, 255);
1009        value = value * 100 / 255;
1010        ec_write(EEEPC_EC_FAN_PWM, value);
1011}
1012
1013static int eeepc_get_fan_rpm(void)
1014{
1015        u8 high = 0;
1016        u8 low = 0;
1017
1018        ec_read(EEEPC_EC_FAN_HRPM, &high);
1019        ec_read(EEEPC_EC_FAN_LRPM, &low);
1020        return high << 8 | low;
1021}
1022
1023static int eeepc_get_fan_ctrl(void)
1024{
1025        u8 value = 0;
1026
1027        ec_read(EEEPC_EC_FAN_CTRL, &value);
1028        if (value & 0x02)
1029                return 1; /* manual */
1030        else
1031                return 2; /* automatic */
1032}
1033
1034static void eeepc_set_fan_ctrl(int manual)
1035{
1036        u8 value = 0;
1037
1038        ec_read(EEEPC_EC_FAN_CTRL, &value);
1039        if (manual == 1)
1040                value |= 0x02;
1041        else
1042                value &= ~0x02;
1043        ec_write(EEEPC_EC_FAN_CTRL, value);
1044}
1045
1046static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1047{
1048        int rv, value;
1049
1050        rv = parse_arg(buf, count, &value);
1051        if (rv > 0)
1052                set(value);
1053        return rv;
1054}
1055
1056static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1057{
1058        return sprintf(buf, "%d\n", get());
1059}
1060
1061#define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)              \
1062        static ssize_t show_##_name(struct device *dev,                 \
1063                                    struct device_attribute *attr,      \
1064                                    char *buf)                          \
1065        {                                                               \
1066                return show_sys_hwmon(_set, buf);                       \
1067        }                                                               \
1068        static ssize_t store_##_name(struct device *dev,                \
1069                                     struct device_attribute *attr,     \
1070                                     const char *buf, size_t count)     \
1071        {                                                               \
1072                return store_sys_hwmon(_get, buf, count);               \
1073        }                                                               \
1074        static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
1075
1076EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
1077EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
1078                         eeepc_get_fan_pwm, eeepc_set_fan_pwm);
1079EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
1080                         eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
1081
1082static ssize_t
1083show_name(struct device *dev, struct device_attribute *attr, char *buf)
1084{
1085        return sprintf(buf, "eeepc\n");
1086}
1087static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
1088
1089static struct attribute *hwmon_attributes[] = {
1090        &sensor_dev_attr_pwm1.dev_attr.attr,
1091        &sensor_dev_attr_fan1_input.dev_attr.attr,
1092        &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1093        &sensor_dev_attr_name.dev_attr.attr,
1094        NULL
1095};
1096
1097static struct attribute_group hwmon_attribute_group = {
1098        .attrs = hwmon_attributes
1099};
1100
1101static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
1102{
1103        struct device *hwmon;
1104
1105        hwmon = eeepc->hwmon_device;
1106        if (!hwmon)
1107                return;
1108        sysfs_remove_group(&hwmon->kobj,
1109                           &hwmon_attribute_group);
1110        hwmon_device_unregister(hwmon);
1111        eeepc->hwmon_device = NULL;
1112}
1113
1114static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1115{
1116        struct device *hwmon;
1117        int result;
1118
1119        hwmon = hwmon_device_register(&eeepc->platform_device->dev);
1120        if (IS_ERR(hwmon)) {
1121                pr_err("Could not register eeepc hwmon device\n");
1122                eeepc->hwmon_device = NULL;
1123                return PTR_ERR(hwmon);
1124        }
1125        eeepc->hwmon_device = hwmon;
1126        result = sysfs_create_group(&hwmon->kobj,
1127                                    &hwmon_attribute_group);
1128        if (result)
1129                eeepc_hwmon_exit(eeepc);
1130        return result;
1131}
1132
1133/*
1134 * Backlight device
1135 */
1136static int read_brightness(struct backlight_device *bd)
1137{
1138        struct eeepc_laptop *eeepc = bl_get_data(bd);
1139
1140        return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1141}
1142
1143static int set_brightness(struct backlight_device *bd, int value)
1144{
1145        struct eeepc_laptop *eeepc = bl_get_data(bd);
1146
1147        return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1148}
1149
1150static int update_bl_status(struct backlight_device *bd)
1151{
1152        return set_brightness(bd, bd->props.brightness);
1153}
1154
1155static const struct backlight_ops eeepcbl_ops = {
1156        .get_brightness = read_brightness,
1157        .update_status = update_bl_status,
1158};
1159
1160static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1161{
1162        struct backlight_device *bd = eeepc->backlight_device;
1163        int old = bd->props.brightness;
1164
1165        backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1166
1167        return old;
1168}
1169
1170static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1171{
1172        struct backlight_properties props;
1173        struct backlight_device *bd;
1174
1175        memset(&props, 0, sizeof(struct backlight_properties));
1176        props.type = BACKLIGHT_PLATFORM;
1177        props.max_brightness = 15;
1178        bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1179                                       &eeepc->platform_device->dev, eeepc,
1180                                       &eeepcbl_ops, &props);
1181        if (IS_ERR(bd)) {
1182                pr_err("Could not register eeepc backlight device\n");
1183                eeepc->backlight_device = NULL;
1184                return PTR_ERR(bd);
1185        }
1186        eeepc->backlight_device = bd;
1187        bd->props.brightness = read_brightness(bd);
1188        bd->props.power = FB_BLANK_UNBLANK;
1189        backlight_update_status(bd);
1190        return 0;
1191}
1192
1193static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1194{
1195        if (eeepc->backlight_device)
1196                backlight_device_unregister(eeepc->backlight_device);
1197        eeepc->backlight_device = NULL;
1198}
1199
1200
1201/*
1202 * Input device (i.e. hotkeys)
1203 */
1204static int eeepc_input_init(struct eeepc_laptop *eeepc)
1205{
1206        struct input_dev *input;
1207        int error;
1208
1209        input = input_allocate_device();
1210        if (!input) {
1211                pr_info("Unable to allocate input device\n");
1212                return -ENOMEM;
1213        }
1214
1215        input->name = "Asus EeePC extra buttons";
1216        input->phys = EEEPC_LAPTOP_FILE "/input0";
1217        input->id.bustype = BUS_HOST;
1218        input->dev.parent = &eeepc->platform_device->dev;
1219
1220        error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1221        if (error) {
1222                pr_err("Unable to setup input device keymap\n");
1223                goto err_free_dev;
1224        }
1225
1226        error = input_register_device(input);
1227        if (error) {
1228                pr_err("Unable to register input device\n");
1229                goto err_free_keymap;
1230        }
1231
1232        eeepc->inputdev = input;
1233        return 0;
1234
1235err_free_keymap:
1236        sparse_keymap_free(input);
1237err_free_dev:
1238        input_free_device(input);
1239        return error;
1240}
1241
1242static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1243{
1244        if (eeepc->inputdev) {
1245                sparse_keymap_free(eeepc->inputdev);
1246                input_unregister_device(eeepc->inputdev);
1247        }
1248        eeepc->inputdev = NULL;
1249}
1250
1251/*
1252 * ACPI driver
1253 */
1254static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1255{
1256        if (!eeepc->inputdev)
1257                return ;
1258        if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
1259                pr_info("Unknown key %x pressed\n", event);
1260}
1261
1262static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1263{
1264        struct eeepc_laptop *eeepc = acpi_driver_data(device);
1265        u16 count;
1266
1267        if (event > ACPI_MAX_SYS_NOTIFY)
1268                return;
1269        count = eeepc->event_count[event % 128]++;
1270        acpi_bus_generate_proc_event(device, event, count);
1271        acpi_bus_generate_netlink_event(device->pnp.device_class,
1272                                        dev_name(&device->dev), event,
1273                                        count);
1274
1275        /* Brightness events are special */
1276        if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
1277
1278                /* Ignore them completely if the acpi video driver is used */
1279                if (eeepc->backlight_device != NULL) {
1280                        int old_brightness, new_brightness;
1281
1282                        /* Update the backlight device. */
1283                        old_brightness = eeepc_backlight_notify(eeepc);
1284
1285                        /* Convert event to keypress (obsolescent hack) */
1286                        new_brightness = event - NOTIFY_BRN_MIN;
1287
1288                        if (new_brightness < old_brightness) {
1289                                event = NOTIFY_BRN_MIN; /* brightness down */
1290                        } else if (new_brightness > old_brightness) {
1291                                event = NOTIFY_BRN_MAX; /* brightness up */
1292                        } else {
1293                                /*
1294                                * no change in brightness - already at min/max,
1295                                * event will be desired value (or else ignored)
1296                                */
1297                        }
1298                        eeepc_input_notify(eeepc, event);
1299                }
1300        } else {
1301                /* Everything else is a bona-fide keypress event */
1302                eeepc_input_notify(eeepc, event);
1303        }
1304}
1305
1306static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1307{
1308        const char *model;
1309
1310        model = dmi_get_system_info(DMI_PRODUCT_NAME);
1311        if (!model)
1312                return;
1313
1314        /*
1315         * Blacklist for setting cpufv (cpu speed).
1316         *
1317         * EeePC 4G ("701") implements CFVS, but it is not supported
1318         * by the pre-installed OS, and the original option to change it
1319         * in the BIOS setup screen was removed in later versions.
1320         *
1321         * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1322         * this applies to all "701" models (4G/4G Surf/2G Surf).
1323         *
1324         * So Asus made a deliberate decision not to support it on this model.
1325         * We have several reports that using it can cause the system to hang
1326         *
1327         * The hang has also been reported on a "702" (Model name "8G"?).
1328         *
1329         * We avoid dmi_check_system() / dmi_match(), because they use
1330         * substring matching.  We don't want to affect the "701SD"
1331         * and "701SDX" models, because they do support S.H.E.
1332         */
1333        if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1334                eeepc->cpufv_disabled = true;
1335                pr_info("model %s does not officially support setting cpu "
1336                        "speed\n", model);
1337                pr_info("cpufv disabled to avoid instability\n");
1338        }
1339
1340        /*
1341         * Blacklist for wlan hotplug
1342         *
1343         * Eeepc 1005HA doesn't work like others models and don't need the
1344         * hotplug code. In fact, current hotplug code seems to unplug another
1345         * device...
1346         */
1347        if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1348            strcmp(model, "1005PE") == 0) {
1349                eeepc->hotplug_disabled = true;
1350                pr_info("wlan hotplug disabled\n");
1351        }
1352}
1353
1354static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1355{
1356        int dummy;
1357
1358        /* Some BIOSes do not report cm although it is available.
1359           Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1360        if (!(eeepc->cm_supported & (1 << cm))
1361            && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1362                pr_info("%s (%x) not reported by BIOS,"
1363                        " enabling anyway\n", name, 1 << cm);
1364                eeepc->cm_supported |= 1 << cm;
1365        }
1366}
1367
1368static void cmsg_quirks(struct eeepc_laptop *eeepc)
1369{
1370        cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1371        cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1372        cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1373        cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1374}
1375
1376static int __devinit eeepc_acpi_init(struct eeepc_laptop *eeepc)
1377{
1378        unsigned int init_flags;
1379        int result;
1380
1381        result = acpi_bus_get_status(eeepc->device);
1382        if (result)
1383                return result;
1384        if (!eeepc->device->status.present) {
1385                pr_err("Hotkey device not present, aborting\n");
1386                return -ENODEV;
1387        }
1388
1389        init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1390        pr_notice("Hotkey init flags 0x%x\n", init_flags);
1391
1392        if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1393                pr_err("Hotkey initialization failed\n");
1394                return -ENODEV;
1395        }
1396
1397        /* get control methods supported */
1398        if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1399                pr_err("Get control methods supported failed\n");
1400                return -ENODEV;
1401        }
1402        cmsg_quirks(eeepc);
1403        pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1404
1405        return 0;
1406}
1407
1408static void __devinit eeepc_enable_camera(struct eeepc_laptop *eeepc)
1409{
1410        /*
1411         * If the following call to set_acpi() fails, it's because there's no
1412         * camera so we can ignore the error.
1413         */
1414        if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1415                set_acpi(eeepc, CM_ASL_CAMERA, 1);
1416}
1417
1418static bool eeepc_device_present;
1419
1420static int __devinit eeepc_acpi_add(struct acpi_device *device)
1421{
1422        struct eeepc_laptop *eeepc;
1423        int result;
1424
1425        pr_notice(EEEPC_LAPTOP_NAME "\n");
1426        eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1427        if (!eeepc)
1428                return -ENOMEM;
1429        eeepc->handle = device->handle;
1430        strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1431        strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1432        device->driver_data = eeepc;
1433        eeepc->device = device;
1434
1435        eeepc->hotplug_disabled = hotplug_disabled;
1436
1437        eeepc_dmi_check(eeepc);
1438
1439        result = eeepc_acpi_init(eeepc);
1440        if (result)
1441                goto fail_platform;
1442        eeepc_enable_camera(eeepc);
1443
1444        /*
1445         * Register the platform device first.  It is used as a parent for the
1446         * sub-devices below.
1447         *
1448         * Note that if there are multiple instances of this ACPI device it
1449         * will bail out, because the platform device is registered with a
1450         * fixed name.  Of course it doesn't make sense to have more than one,
1451         * and machine-specific scripts find the fixed name convenient.  But
1452         * It's also good for us to exclude multiple instances because both
1453         * our hwmon and our wlan rfkill subdevice use global ACPI objects
1454         * (the EC and the wlan PCI slot respectively).
1455         */
1456        result = eeepc_platform_init(eeepc);
1457        if (result)
1458                goto fail_platform;
1459
1460        if (!acpi_video_backlight_support()) {
1461                result = eeepc_backlight_init(eeepc);
1462                if (result)
1463                        goto fail_backlight;
1464        } else
1465                pr_info("Backlight controlled by ACPI video driver\n");
1466
1467        result = eeepc_input_init(eeepc);
1468        if (result)
1469                goto fail_input;
1470
1471        result = eeepc_hwmon_init(eeepc);
1472        if (result)
1473                goto fail_hwmon;
1474
1475        result = eeepc_led_init(eeepc);
1476        if (result)
1477                goto fail_led;
1478
1479        result = eeepc_rfkill_init(eeepc);
1480        if (result)
1481                goto fail_rfkill;
1482
1483        eeepc_device_present = true;
1484        return 0;
1485
1486fail_rfkill:
1487        eeepc_led_exit(eeepc);
1488fail_led:
1489        eeepc_hwmon_exit(eeepc);
1490fail_hwmon:
1491        eeepc_input_exit(eeepc);
1492fail_input:
1493        eeepc_backlight_exit(eeepc);
1494fail_backlight:
1495        eeepc_platform_exit(eeepc);
1496fail_platform:
1497        kfree(eeepc);
1498
1499        return result;
1500}
1501
1502static int eeepc_acpi_remove(struct acpi_device *device, int type)
1503{
1504        struct eeepc_laptop *eeepc = acpi_driver_data(device);
1505
1506        eeepc_backlight_exit(eeepc);
1507        eeepc_rfkill_exit(eeepc);
1508        eeepc_input_exit(eeepc);
1509        eeepc_hwmon_exit(eeepc);
1510        eeepc_led_exit(eeepc);
1511        eeepc_platform_exit(eeepc);
1512
1513        kfree(eeepc);
1514        return 0;
1515}
1516
1517
1518static const struct acpi_device_id eeepc_device_ids[] = {
1519        {EEEPC_ACPI_HID, 0},
1520        {"", 0},
1521};
1522MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1523
1524static struct acpi_driver eeepc_acpi_driver = {
1525        .name = EEEPC_LAPTOP_NAME,
1526        .class = EEEPC_ACPI_CLASS,
1527        .owner = THIS_MODULE,
1528        .ids = eeepc_device_ids,
1529        .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1530        .ops = {
1531                .add = eeepc_acpi_add,
1532                .remove = eeepc_acpi_remove,
1533                .notify = eeepc_acpi_notify,
1534        },
1535};
1536
1537
1538static int __init eeepc_laptop_init(void)
1539{
1540        int result;
1541
1542        result = platform_driver_register(&platform_driver);
1543        if (result < 0)
1544                return result;
1545
1546        result = acpi_bus_register_driver(&eeepc_acpi_driver);
1547        if (result < 0)
1548                goto fail_acpi_driver;
1549
1550        if (!eeepc_device_present) {
1551                result = -ENODEV;
1552                goto fail_no_device;
1553        }
1554
1555        return 0;
1556
1557fail_no_device:
1558        acpi_bus_unregister_driver(&eeepc_acpi_driver);
1559fail_acpi_driver:
1560        platform_driver_unregister(&platform_driver);
1561        return result;
1562}
1563
1564static void __exit eeepc_laptop_exit(void)
1565{
1566        acpi_bus_unregister_driver(&eeepc_acpi_driver);
1567        platform_driver_unregister(&platform_driver);
1568}
1569
1570module_init(eeepc_laptop_init);
1571module_exit(eeepc_laptop_exit);
1572