root/drivers/platform/x86/eeepc-laptop.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. write_acpi_int
  2. read_acpi_int
  3. set_acpi
  4. get_acpi
  5. acpi_setter_handle
  6. parse_arg
  7. store_sys_acpi
  8. show_sys_acpi
  9. get_cpufv
  10. available_cpufv_show
  11. cpufv_show
  12. cpufv_store
  13. cpufv_disabled_show
  14. cpufv_disabled_store
  15. eeepc_platform_init
  16. eeepc_platform_exit
  17. tpd_led_update
  18. tpd_led_set
  19. tpd_led_get
  20. eeepc_led_init
  21. eeepc_led_exit
  22. eeepc_wlan_rfkill_blocked
  23. eeepc_rfkill_hotplug
  24. eeepc_rfkill_hotplug_update
  25. eeepc_rfkill_notify
  26. eeepc_register_rfkill_notifier
  27. eeepc_unregister_rfkill_notifier
  28. eeepc_get_adapter_status
  29. eeepc_setup_pci_hotplug
  30. eeepc_rfkill_set
  31. eeepc_new_rfkill
  32. eeepc_rfkill_exit
  33. eeepc_rfkill_init
  34. eeepc_hotk_thaw
  35. eeepc_hotk_restore
  36. eeepc_pwm_to_lmsensors
  37. eeepc_lmsensors_to_pwm
  38. eeepc_get_fan_pwm
  39. eeepc_set_fan_pwm
  40. eeepc_get_fan_rpm
  41. eeepc_get_fan_ctrl
  42. eeepc_set_fan_ctrl
  43. store_sys_hwmon
  44. show_sys_hwmon
  45. eeepc_hwmon_init
  46. read_brightness
  47. set_brightness
  48. update_bl_status
  49. eeepc_backlight_notify
  50. eeepc_backlight_init
  51. eeepc_backlight_exit
  52. eeepc_input_init
  53. eeepc_input_exit
  54. eeepc_input_notify
  55. eeepc_acpi_notify
  56. eeepc_dmi_check
  57. cmsg_quirk
  58. cmsg_quirks
  59. eeepc_acpi_init
  60. eeepc_enable_camera
  61. eeepc_acpi_add
  62. eeepc_acpi_remove
  63. eeepc_laptop_init
  64. eeepc_laptop_exit

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

/* [<][>][^][v][top][bottom][index][help] */