1 /* 2 * eepc-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 #include <linux/kernel.h> 20 #include <linux/module.h> 21 #include <linux/init.h> 22 #include <linux/types.h> 23 #include <linux/platform_device.h> 24 #include <linux/backlight.h> 25 #include <linux/fb.h> 26 #include <linux/hwmon.h> 27 #include <linux/hwmon-sysfs.h> 28 #include <acpi/acpi_drivers.h> 29 #include <acpi/acpi_bus.h> 30 #include <linux/uaccess.h> 31 #include <linux/input.h> 32 #include <linux/rfkill.h> 33 #include <linux/pci.h> 34 35 #define EEEPC_LAPTOP_VERSION "0.1" 36 37 #define EEEPC_HOTK_NAME "Eee PC Hotkey Driver" 38 #define EEEPC_HOTK_FILE "eeepc" 39 #define EEEPC_HOTK_CLASS "hotkey" 40 #define EEEPC_HOTK_DEVICE_NAME "Hotkey" 41 #define EEEPC_HOTK_HID "ASUS010" 42 43 #define EEEPC_LOG EEEPC_HOTK_FILE ": " 44 #define EEEPC_ERR KERN_ERR EEEPC_LOG 45 #define EEEPC_WARNING KERN_WARNING EEEPC_LOG 46 #define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG 47 #define EEEPC_INFO KERN_INFO EEEPC_LOG 48 49 /* 50 * Definitions for Asus EeePC 51 */ 52 #define NOTIFY_WLAN_ON 0x10 53 #define NOTIFY_BRN_MIN 0x20 54 #define NOTIFY_BRN_MAX 0x2f 55 56 enum { 57 DISABLE_ASL_WLAN = 0x0001, 58 DISABLE_ASL_BLUETOOTH = 0x0002, 59 DISABLE_ASL_IRDA = 0x0004, 60 DISABLE_ASL_CAMERA = 0x0008, 61 DISABLE_ASL_TV = 0x0010, 62 DISABLE_ASL_GPS = 0x0020, 63 DISABLE_ASL_DISPLAYSWITCH = 0x0040, 64 DISABLE_ASL_MODEM = 0x0080, 65 DISABLE_ASL_CARDREADER = 0x0100 66 }; 67 68 enum { 69 CM_ASL_WLAN = 0, 70 CM_ASL_BLUETOOTH, 71 CM_ASL_IRDA, 72 CM_ASL_1394, 73 CM_ASL_CAMERA, 74 CM_ASL_TV, 75 CM_ASL_GPS, 76 CM_ASL_DVDROM, 77 CM_ASL_DISPLAYSWITCH, 78 CM_ASL_PANELBRIGHT, 79 CM_ASL_BIOSFLASH, 80 CM_ASL_ACPIFLASH, 81 CM_ASL_CPUFV, 82 CM_ASL_CPUTEMPERATURE, 83 CM_ASL_FANCPU, 84 CM_ASL_FANCHASSIS, 85 CM_ASL_USBPORT1, 86 CM_ASL_USBPORT2, 87 CM_ASL_USBPORT3, 88 CM_ASL_MODEM, 89 CM_ASL_CARDREADER, 90 CM_ASL_LID 91 }; 92 93 static const char *cm_getv[] = { 94 "WLDG", "BTHG", NULL, NULL, 95 "CAMG", NULL, NULL, NULL, 96 NULL, "PBLG", NULL, NULL, 97 "CFVG", NULL, NULL, NULL, 98 "USBG", NULL, NULL, "MODG", 99 "CRDG", "LIDG" 100 }; 101 102 static const char *cm_setv[] = { 103 "WLDS", "BTHS", NULL, NULL, 104 "CAMS", NULL, NULL, NULL, 105 "SDSP", "PBLS", "HDPS", NULL, 106 "CFVS", NULL, NULL, NULL, 107 "USBG", NULL, NULL, "MODS", 108 "CRDS", NULL 109 }; 110 111 #define EEEPC_EC "\\_SB.PCI0.SBRG.EC0." 112 113 #define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */ 114 #define EEEPC_EC_SC02 0x63 115 #define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */ 116 #define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */ 117 #define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */ 118 #define EEEPC_EC_SFB3 0xD3 119 120 /* 121 * This is the main structure, we can use it to store useful information 122 * about the hotk device 123 */ 124 struct eeepc_hotk { 125 struct acpi_device *device; /* the device we are in */ 126 acpi_handle handle; /* the handle of the hotk device */ 127 u32 cm_supported; /* the control methods supported 128 by this BIOS */ 129 uint init_flag; /* Init flags */ 130 u16 event_count[128]; /* count for each event */ 131 struct input_dev *inputdev; 132 u16 *keycode_map; 133 struct rfkill *eeepc_wlan_rfkill; 134 struct rfkill *eeepc_bluetooth_rfkill; 135 }; 136 137 /* The actual device the driver binds to */ 138 static struct eeepc_hotk *ehotk; 139 140 /* Platform device/driver */ 141 static struct platform_driver platform_driver = { 142 .driver = { 143 .name = EEEPC_HOTK_FILE, 144 .owner = THIS_MODULE, 145 } 146 }; 147 148 static struct platform_device *platform_device; 149 150 struct key_entry { 151 char type; 152 u8 code; 153 u16 keycode; 154 }; 155 156 enum { KE_KEY, KE_END }; 157 158 static struct key_entry eeepc_keymap[] = { 159 /* Sleep already handled via generic ACPI code */ 160 {KE_KEY, 0x10, KEY_WLAN }, 161 {KE_KEY, 0x12, KEY_PROG1 }, 162 {KE_KEY, 0x13, KEY_MUTE }, 163 {KE_KEY, 0x14, KEY_VOLUMEDOWN }, 164 {KE_KEY, 0x15, KEY_VOLUMEUP }, 165 {KE_KEY, 0x1a, KEY_COFFEE }, 166 {KE_KEY, 0x1b, KEY_ZOOM }, 167 {KE_KEY, 0x1c, KEY_PROG2 }, 168 {KE_KEY, 0x1d, KEY_PROG3 }, 169 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, 170 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, 171 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, 172 {KE_END, 0}, 173 }; 174 175 /* 176 * The hotkey driver declaration 177 */ 178 static int eeepc_hotk_add(struct acpi_device *device); 179 static int eeepc_hotk_remove(struct acpi_device *device, int type); 180 181 static const struct acpi_device_id eeepc_device_ids[] = { 182 {EEEPC_HOTK_HID, 0}, 183 {"", 0}, 184 }; 185 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids); 186 187 static struct acpi_driver eeepc_hotk_driver = { 188 .name = EEEPC_HOTK_NAME, 189 .class = EEEPC_HOTK_CLASS, 190 .ids = eeepc_device_ids, 191 .ops = { 192 .add = eeepc_hotk_add, 193 .remove = eeepc_hotk_remove, 194 }, 195 }; 196 197 /* The backlight device /sys/class/backlight */ 198 static struct backlight_device *eeepc_backlight_device; 199 200 /* The hwmon device */ 201 static struct device *eeepc_hwmon_device; 202 203 /* 204 * The backlight class declaration 205 */ 206 static int read_brightness(struct backlight_device *bd); 207 static int update_bl_status(struct backlight_device *bd); 208 static struct backlight_ops eeepcbl_ops = { 209 .get_brightness = read_brightness, 210 .update_status = update_bl_status, 211 }; 212 213 MODULE_AUTHOR("Corentin Chary, Eric Cooper"); 214 MODULE_DESCRIPTION(EEEPC_HOTK_NAME); 215 MODULE_LICENSE("GPL"); 216 217 /* 218 * ACPI Helpers 219 */ 220 static int write_acpi_int(acpi_handle handle, const char *method, int val, 221 struct acpi_buffer *output) 222 { 223 struct acpi_object_list params; 224 union acpi_object in_obj; 225 acpi_status status; 226 227 params.count = 1; 228 params.pointer = &in_obj; 229 in_obj.type = ACPI_TYPE_INTEGER; 230 in_obj.integer.value = val; 231 232 status = acpi_evaluate_object(handle, (char *)method, ¶ms, output); 233 return (status == AE_OK ? 0 : -1); 234 } 235 236 static int read_acpi_int(acpi_handle handle, const char *method, int *val) 237 { 238 acpi_status status; 239 unsigned long long result; 240 241 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result); 242 if (ACPI_FAILURE(status)) { 243 *val = -1; 244 return -1; 245 } else { 246 *val = result; 247 return 0; 248 } 249 } 250 251 static int set_acpi(int cm, int value) 252 { 253 if (ehotk->cm_supported & (0x1 << cm)) { 254 const char *method = cm_setv[cm]; 255 if (method == NULL) 256 return -ENODEV; 257 if (write_acpi_int(ehotk->handle, method, value, NULL)) 258 printk(EEEPC_WARNING "Error writing %s\n", method); 259 } 260 return 0; 261 } 262 263 static int get_acpi(int cm) 264 { 265 int value = -1; 266 if ((ehotk->cm_supported & (0x1 << cm))) { 267 const char *method = cm_getv[cm]; 268 if (method == NULL) 269 return -ENODEV; 270 if (read_acpi_int(ehotk->handle, method, &value)) 271 printk(EEEPC_WARNING "Error reading %s\n", method); 272 } 273 return value; 274 } 275 276 /* 277 * Backlight 278 */ 279 static int read_brightness(struct backlight_device *bd) 280 { 281 return get_acpi(CM_ASL_PANELBRIGHT); 282 } 283 284 static int set_brightness(struct backlight_device *bd, int value) 285 { 286 value = max(0, min(15, value)); 287 return set_acpi(CM_ASL_PANELBRIGHT, value); 288 } 289 290 static int update_bl_status(struct backlight_device *bd) 291 { 292 return set_brightness(bd, bd->props.brightness); 293 } 294 295 /* 296 * Rfkill helpers 297 */ 298 299 static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state) 300 { 301 if (state == RFKILL_STATE_SOFT_BLOCKED) 302 return set_acpi(CM_ASL_WLAN, 0); 303 else 304 return set_acpi(CM_ASL_WLAN, 1); 305 } 306 307 static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state) 308 { 309 if (get_acpi(CM_ASL_WLAN) == 1) 310 *state = RFKILL_STATE_UNBLOCKED; 311 else 312 *state = RFKILL_STATE_SOFT_BLOCKED; 313 return 0; 314 } 315 316 static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state) 317 { 318 if (state == RFKILL_STATE_SOFT_BLOCKED) 319 return set_acpi(CM_ASL_BLUETOOTH, 0); 320 else 321 return set_acpi(CM_ASL_BLUETOOTH, 1); 322 } 323 324 static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state) 325 { 326 if (get_acpi(CM_ASL_BLUETOOTH) == 1) 327 *state = RFKILL_STATE_UNBLOCKED; 328 else 329 *state = RFKILL_STATE_SOFT_BLOCKED; 330 return 0; 331 } 332 333 /* 334 * Sys helpers 335 */ 336 static int parse_arg(const char *buf, unsigned long count, int *val) 337 { 338 if (!count) 339 return 0; 340 if (sscanf(buf, "%i", val) != 1) 341 return -EINVAL; 342 return count; 343 } 344 345 static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) 346 { 347 int rv, value; 348 349 rv = parse_arg(buf, count, &value); 350 if (rv > 0) 351 set_acpi(cm, value); 352 return rv; 353 } 354 355 static ssize_t show_sys_acpi(int cm, char *buf) 356 { 357 return sprintf(buf, "%d\n", get_acpi(cm)); 358 } 359 360 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ 361 static ssize_t show_##_name(struct device *dev, \ 362 struct device_attribute *attr, \ 363 char *buf) \ 364 { \ 365 return show_sys_acpi(_cm, buf); \ 366 } \ 367 static ssize_t store_##_name(struct device *dev, \ 368 struct device_attribute *attr, \ 369 const char *buf, size_t count) \ 370 { \ 371 return store_sys_acpi(_cm, buf, count); \ 372 } \ 373 static struct device_attribute dev_attr_##_name = { \ 374 .attr = { \ 375 .name = __stringify(_name), \ 376 .mode = 0644 }, \ 377 .show = show_##_name, \ 378 .store = store_##_name, \ 379 } 380 381 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); 382 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); 383 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); 384 385 static struct attribute *platform_attributes[] = { 386 &dev_attr_camera.attr, 387 &dev_attr_cardr.attr, 388 &dev_attr_disp.attr, 389 NULL 390 }; 391 392 static struct attribute_group platform_attribute_group = { 393 .attrs = platform_attributes 394 }; 395 396 /* 397 * Hotkey functions 398 */ 399 static struct key_entry *eepc_get_entry_by_scancode(int code) 400 { 401 struct key_entry *key; 402 403 for (key = eeepc_keymap; key->type != KE_END; key++) 404 if (code == key->code) 405 return key; 406 407 return NULL; 408 } 409 410 static struct key_entry *eepc_get_entry_by_keycode(int code) 411 { 412 struct key_entry *key; 413 414 for (key = eeepc_keymap; key->type != KE_END; key++) 415 if (code == key->keycode && key->type == KE_KEY) 416 return key; 417 418 return NULL; 419 } 420 421 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode) 422 { 423 struct key_entry *key = eepc_get_entry_by_scancode(scancode); 424 425 if (key && key->type == KE_KEY) { 426 *keycode = key->keycode; 427 return 0; 428 } 429 430 return -EINVAL; 431 } 432 433 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) 434 { 435 struct key_entry *key; 436 int old_keycode; 437 438 if (keycode < 0 || keycode > KEY_MAX) 439 return -EINVAL; 440 441 key = eepc_get_entry_by_scancode(scancode); 442 if (key && key->type == KE_KEY) { 443 old_keycode = key->keycode; 444 key->keycode = keycode; 445 set_bit(keycode, dev->keybit); 446 if (!eepc_get_entry_by_keycode(old_keycode)) 447 clear_bit(old_keycode, dev->keybit); 448 return 0; 449 } 450 451 return -EINVAL; 452 } 453 454 static int eeepc_hotk_check(void) 455 { 456 const struct key_entry *key; 457 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 458 int result; 459 460 result = acpi_bus_get_status(ehotk->device); 461 if (result) 462 return result; 463 if (ehotk->device->status.present) { 464 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, 465 &buffer)) { 466 printk(EEEPC_ERR "Hotkey initialization failed\n"); 467 return -ENODEV; 468 } else { 469 printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", 470 ehotk->init_flag); 471 } 472 /* get control methods supported */ 473 if (read_acpi_int(ehotk->handle, "CMSG" 474 , &ehotk->cm_supported)) { 475 printk(EEEPC_ERR 476 "Get control methods supported failed\n"); 477 return -ENODEV; 478 } else { 479 printk(EEEPC_INFO 480 "Get control methods supported: 0x%x\n", 481 ehotk->cm_supported); 482 } 483 ehotk->inputdev = input_allocate_device(); 484 if (!ehotk->inputdev) { 485 printk(EEEPC_INFO "Unable to allocate input device\n"); 486 return 0; 487 } 488 ehotk->inputdev->name = "Asus EeePC extra buttons"; 489 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0"; 490 ehotk->inputdev->id.bustype = BUS_HOST; 491 ehotk->inputdev->getkeycode = eeepc_getkeycode; 492 ehotk->inputdev->setkeycode = eeepc_setkeycode; 493 494 for (key = eeepc_keymap; key->type != KE_END; key++) { 495 switch (key->type) { 496 case KE_KEY: 497 set_bit(EV_KEY, ehotk->inputdev->evbit); 498 set_bit(key->keycode, ehotk->inputdev->keybit); 499 break; 500 } 501 } 502 result = input_register_device(ehotk->inputdev); 503 if (result) { 504 printk(EEEPC_INFO "Unable to register input device\n"); 505 input_free_device(ehotk->inputdev); 506 return 0; 507 } 508 } else { 509 printk(EEEPC_ERR "Hotkey device not present, aborting\n"); 510 return -EINVAL; 511 } 512 return 0; 513 } 514 515 static void notify_brn(void) 516 { 517 struct backlight_device *bd = eeepc_backlight_device; 518 if (bd) 519 bd->props.brightness = read_brightness(bd); 520 } 521 522 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) 523 { 524 struct pci_dev *dev; 525 struct pci_bus *bus = pci_find_bus(0, 1); 526 527 if (event != ACPI_NOTIFY_BUS_CHECK) 528 return; 529 530 if (!bus) { 531 printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); 532 return; 533 } 534 535 if (get_acpi(CM_ASL_WLAN) == 1) { 536 dev = pci_get_slot(bus, 0); 537 if (dev) { 538 /* Device already present */ 539 pci_dev_put(dev); 540 return; 541 } 542 dev = pci_scan_single_device(bus, 0); 543 if (dev) { 544 pci_bus_assign_resources(bus); 545 if (pci_bus_add_device(dev)) 546 printk(EEEPC_ERR "Unable to hotplug wifi\n"); 547 } 548 } else { 549 dev = pci_get_slot(bus, 0); 550 if (dev) { 551 pci_remove_bus_device(dev); 552 pci_dev_put(dev); 553 } 554 } 555 } 556 557 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) 558 { 559 static struct key_entry *key; 560 u16 count; 561 562 if (!ehotk) 563 return; 564 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) 565 notify_brn(); 566 count = ehotk->event_count[event % 128]++; 567 acpi_bus_generate_proc_event(ehotk->device, event, count); 568 acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, 569 dev_name(&ehotk->device->dev), event, 570 count); 571 if (ehotk->inputdev) { 572 key = eepc_get_entry_by_scancode(event); 573 if (key) { 574 switch (key->type) { 575 case KE_KEY: 576 input_report_key(ehotk->inputdev, key->keycode, 577 1); 578 input_sync(ehotk->inputdev); 579 input_report_key(ehotk->inputdev, key->keycode, 580 0); 581 input_sync(ehotk->inputdev); 582 break; 583 } 584 } 585 } 586 } 587 588 static int eeepc_register_rfkill_notifier(char *node) 589 { 590 acpi_status status = AE_OK; 591 acpi_handle handle; 592 593 status = acpi_get_handle(NULL, node, &handle); 594 595 if (ACPI_SUCCESS(status)) { 596 status = acpi_install_notify_handler(handle, 597 ACPI_SYSTEM_NOTIFY, 598 eeepc_rfkill_notify, 599 NULL); 600 if (ACPI_FAILURE(status)) 601 printk(EEEPC_WARNING 602 "Failed to register notify on %s\n", node); 603 } else 604 return -ENODEV; 605 606 return 0; 607 } 608 609 static void eeepc_unregister_rfkill_notifier(char *node) 610 { 611 acpi_status status = AE_OK; 612 acpi_handle handle; 613 614 status = acpi_get_handle(NULL, node, &handle); 615 616 if (ACPI_SUCCESS(status)) { 617 status = acpi_remove_notify_handler(handle, 618 ACPI_SYSTEM_NOTIFY, 619 eeepc_rfkill_notify); 620 if (ACPI_FAILURE(status)) 621 printk(EEEPC_ERR 622 "Error removing rfkill notify handler %s\n", 623 node); 624 } 625 } 626 627 static int eeepc_hotk_add(struct acpi_device *device) 628 { 629 acpi_status status = AE_OK; 630 int result; 631 632 if (!device) 633 return -EINVAL; 634 printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); 635 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); 636 if (!ehotk) 637 return -ENOMEM; 638 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; 639 ehotk->handle = device->handle; 640 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); 641 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); 642 device->driver_data = ehotk; 643 ehotk->device = device; 644 result = eeepc_hotk_check(); 645 if (result) 646 goto ehotk_fail; 647 status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, 648 eeepc_hotk_notify, ehotk); 649 if (ACPI_FAILURE(status)) 650 printk(EEEPC_ERR "Error installing notify handler\n"); 651 652 if (get_acpi(CM_ASL_WLAN) != -1) { 653 ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, 654 RFKILL_TYPE_WLAN); 655 656 if (!ehotk->eeepc_wlan_rfkill) 657 goto wlan_fail; 658 659 ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; 660 ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; 661 ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; 662 if (get_acpi(CM_ASL_WLAN) == 1) { 663 ehotk->eeepc_wlan_rfkill->state = 664 RFKILL_STATE_UNBLOCKED; 665 rfkill_set_default(RFKILL_TYPE_WLAN, 666 RFKILL_STATE_UNBLOCKED); 667 } else { 668 ehotk->eeepc_wlan_rfkill->state = 669 RFKILL_STATE_SOFT_BLOCKED; 670 rfkill_set_default(RFKILL_TYPE_WLAN, 671 RFKILL_STATE_SOFT_BLOCKED); 672 } 673 result = rfkill_register(ehotk->eeepc_wlan_rfkill); 674 if (result) 675 goto wlan_fail; 676 } 677 678 if (get_acpi(CM_ASL_BLUETOOTH) != -1) { 679 ehotk->eeepc_bluetooth_rfkill = 680 rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); 681 682 if (!ehotk->eeepc_bluetooth_rfkill) 683 goto bluetooth_fail; 684 685 ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; 686 ehotk->eeepc_bluetooth_rfkill->toggle_radio = 687 eeepc_bluetooth_rfkill_set; 688 ehotk->eeepc_bluetooth_rfkill->get_state = 689 eeepc_bluetooth_rfkill_state; 690 if (get_acpi(CM_ASL_BLUETOOTH) == 1) { 691 ehotk->eeepc_bluetooth_rfkill->state = 692 RFKILL_STATE_UNBLOCKED; 693 rfkill_set_default(RFKILL_TYPE_BLUETOOTH, 694 RFKILL_STATE_UNBLOCKED); 695 } else { 696 ehotk->eeepc_bluetooth_rfkill->state = 697 RFKILL_STATE_SOFT_BLOCKED; 698 rfkill_set_default(RFKILL_TYPE_BLUETOOTH, 699 RFKILL_STATE_SOFT_BLOCKED); 700 } 701 702 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); 703 if (result) 704 goto bluetooth_fail; 705 } 706 707 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); 708 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); 709 710 return 0; 711 712 bluetooth_fail: 713 if (ehotk->eeepc_bluetooth_rfkill) 714 rfkill_free(ehotk->eeepc_bluetooth_rfkill); 715 rfkill_unregister(ehotk->eeepc_wlan_rfkill); 716 ehotk->eeepc_wlan_rfkill = NULL; 717 wlan_fail: 718 if (ehotk->eeepc_wlan_rfkill) 719 rfkill_free(ehotk->eeepc_wlan_rfkill); 720 ehotk_fail: 721 kfree(ehotk); 722 ehotk = NULL; 723 724 return result; 725 } 726 727 static int eeepc_hotk_remove(struct acpi_device *device, int type) 728 { 729 acpi_status status = 0; 730 731 if (!device || !acpi_driver_data(device)) 732 return -EINVAL; 733 status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, 734 eeepc_hotk_notify); 735 if (ACPI_FAILURE(status)) 736 printk(EEEPC_ERR "Error removing notify handler\n"); 737 738 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); 739 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); 740 741 kfree(ehotk); 742 return 0; 743 } 744 745 /* 746 * Hwmon 747 */ 748 static int eeepc_get_fan_pwm(void) 749 { 750 int value = 0; 751 752 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value); 753 value = value * 255 / 100; 754 return (value); 755 } 756 757 static void eeepc_set_fan_pwm(int value) 758 { 759 value = SENSORS_LIMIT(value, 0, 255); 760 value = value * 100 / 255; 761 ec_write(EEEPC_EC_SC02, value); 762 } 763 764 static int eeepc_get_fan_rpm(void) 765 { 766 int high = 0; 767 int low = 0; 768 769 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high); 770 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low); 771 return (high << 8 | low); 772 } 773 774 static int eeepc_get_fan_ctrl(void) 775 { 776 int value = 0; 777 778 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); 779 return ((value & 0x02 ? 1 : 0)); 780 } 781 782 static void eeepc_set_fan_ctrl(int manual) 783 { 784 int value = 0; 785 786 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); 787 if (manual) 788 value |= 0x02; 789 else 790 value &= ~0x02; 791 ec_write(EEEPC_EC_SFB3, value); 792 } 793 794 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count) 795 { 796 int rv, value; 797 798 rv = parse_arg(buf, count, &value); 799 if (rv > 0) 800 set(value); 801 return rv; 802 } 803 804 static ssize_t show_sys_hwmon(int (*get)(void), char *buf) 805 { 806 return sprintf(buf, "%d\n", get()); 807 } 808 809 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \ 810 static ssize_t show_##_name(struct device *dev, \ 811 struct device_attribute *attr, \ 812 char *buf) \ 813 { \ 814 return show_sys_hwmon(_set, buf); \ 815 } \ 816 static ssize_t store_##_name(struct device *dev, \ 817 struct device_attribute *attr, \ 818 const char *buf, size_t count) \ 819 { \ 820 return store_sys_hwmon(_get, buf, count); \ 821 } \ 822 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0); 823 824 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL); 825 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, 826 eeepc_get_fan_pwm, eeepc_set_fan_pwm); 827 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, 828 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl); 829 830 static ssize_t 831 show_name(struct device *dev, struct device_attribute *attr, char *buf) 832 { 833 return sprintf(buf, "eeepc\n"); 834 } 835 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); 836 837 static struct attribute *hwmon_attributes[] = { 838 &sensor_dev_attr_pwm1.dev_attr.attr, 839 &sensor_dev_attr_fan1_input.dev_attr.attr, 840 &sensor_dev_attr_pwm1_enable.dev_attr.attr, 841 &sensor_dev_attr_name.dev_attr.attr, 842 NULL 843 }; 844 845 static struct attribute_group hwmon_attribute_group = { 846 .attrs = hwmon_attributes 847 }; 848 849 /* 850 * exit/init 851 */ 852 static void eeepc_backlight_exit(void) 853 { 854 if (eeepc_backlight_device) 855 backlight_device_unregister(eeepc_backlight_device); 856 eeepc_backlight_device = NULL; 857 } 858 859 static void eeepc_rfkill_exit(void) 860 { 861 if (ehotk->eeepc_wlan_rfkill) 862 rfkill_unregister(ehotk->eeepc_wlan_rfkill); 863 if (ehotk->eeepc_bluetooth_rfkill) 864 rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); 865 } 866 867 static void eeepc_input_exit(void) 868 { 869 if (ehotk->inputdev) 870 input_unregister_device(ehotk->inputdev); 871 } 872 873 static void eeepc_hwmon_exit(void) 874 { 875 struct device *hwmon; 876 877 hwmon = eeepc_hwmon_device; 878 if (!hwmon) 879 return ; 880 sysfs_remove_group(&hwmon->kobj, 881 &hwmon_attribute_group); 882 hwmon_device_unregister(hwmon); 883 eeepc_hwmon_device = NULL; 884 } 885 886 static void __exit eeepc_laptop_exit(void) 887 { 888 eeepc_backlight_exit(); 889 eeepc_rfkill_exit(); 890 eeepc_input_exit(); 891 eeepc_hwmon_exit(); 892 acpi_bus_unregister_driver(&eeepc_hotk_driver); 893 sysfs_remove_group(&platform_device->dev.kobj, 894 &platform_attribute_group); 895 platform_device_unregister(platform_device); 896 platform_driver_unregister(&platform_driver); 897 } 898 899 static int eeepc_backlight_init(struct device *dev) 900 { 901 struct backlight_device *bd; 902 903 bd = backlight_device_register(EEEPC_HOTK_FILE, dev, 904 NULL, &eeepcbl_ops); 905 if (IS_ERR(bd)) { 906 printk(EEEPC_ERR 907 "Could not register eeepc backlight device\n"); 908 eeepc_backlight_device = NULL; 909 return PTR_ERR(bd); 910 } 911 eeepc_backlight_device = bd; 912 bd->props.max_brightness = 15; 913 bd->props.brightness = read_brightness(NULL); 914 bd->props.power = FB_BLANK_UNBLANK; 915 backlight_update_status(bd); 916 return 0; 917 } 918 919 static int eeepc_hwmon_init(struct device *dev) 920 { 921 struct device *hwmon; 922 int result; 923 924 hwmon = hwmon_device_register(dev); 925 if (IS_ERR(hwmon)) { 926 printk(EEEPC_ERR 927 "Could not register eeepc hwmon device\n"); 928 eeepc_hwmon_device = NULL; 929 return PTR_ERR(hwmon); 930 } 931 eeepc_hwmon_device = hwmon; 932 result = sysfs_create_group(&hwmon->kobj, 933 &hwmon_attribute_group); 934 if (result) 935 eeepc_hwmon_exit(); 936 return result; 937 } 938 939 static int __init eeepc_laptop_init(void) 940 { 941 struct device *dev; 942 int result; 943 944 if (acpi_disabled) 945 return -ENODEV; 946 result = acpi_bus_register_driver(&eeepc_hotk_driver); 947 if (result < 0) 948 return result; 949 if (!ehotk) { 950 acpi_bus_unregister_driver(&eeepc_hotk_driver); 951 return -ENODEV; 952 } 953 dev = acpi_get_physical_device(ehotk->device->handle); 954 955 if (!acpi_video_backlight_support()) { 956 result = eeepc_backlight_init(dev); 957 if (result) 958 goto fail_backlight; 959 } else 960 printk(EEEPC_INFO "Backlight controlled by ACPI video " 961 "driver\n"); 962 963 result = eeepc_hwmon_init(dev); 964 if (result) 965 goto fail_hwmon; 966 /* Register platform stuff */ 967 result = platform_driver_register(&platform_driver); 968 if (result) 969 goto fail_platform_driver; 970 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1); 971 if (!platform_device) { 972 result = -ENOMEM; 973 goto fail_platform_device1; 974 } 975 result = platform_device_add(platform_device); 976 if (result) 977 goto fail_platform_device2; 978 result = sysfs_create_group(&platform_device->dev.kobj, 979 &platform_attribute_group); 980 if (result) 981 goto fail_sysfs; 982 return 0; 983 fail_sysfs: 984 platform_device_del(platform_device); 985 fail_platform_device2: 986 platform_device_put(platform_device); 987 fail_platform_device1: 988 platform_driver_unregister(&platform_driver); 989 fail_platform_driver: 990 eeepc_hwmon_exit(); 991 fail_hwmon: 992 eeepc_backlight_exit(); 993 fail_backlight: 994 eeepc_input_exit(); 995 eeepc_rfkill_exit(); 996 return result; 997 } 998 999 module_init(eeepc_laptop_init); 1000 module_exit(eeepc_laptop_exit); 1001