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