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