diff options
| -rw-r--r-- | drivers/platform/x86/dell-laptop.c | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index c188d43b93c5..5f78aac9b163 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/err.h> | 21 | #include <linux/err.h> |
| 22 | #include <linux/dmi.h> | 22 | #include <linux/dmi.h> |
| 23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 24 | #include <linux/rfkill.h> | ||
| 25 | #include <linux/power_supply.h> | 24 | #include <linux/power_supply.h> |
| 26 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
| 27 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
| @@ -90,9 +89,6 @@ static struct platform_driver platform_driver = { | |||
| 90 | 89 | ||
| 91 | static struct platform_device *platform_device; | 90 | static struct platform_device *platform_device; |
| 92 | static struct backlight_device *dell_backlight_device; | 91 | static struct backlight_device *dell_backlight_device; |
| 93 | static struct rfkill *wifi_rfkill; | ||
| 94 | static struct rfkill *bluetooth_rfkill; | ||
| 95 | static struct rfkill *wwan_rfkill; | ||
| 96 | 92 | ||
| 97 | static const struct dmi_system_id dell_device_table[] __initconst = { | 93 | static const struct dmi_system_id dell_device_table[] __initconst = { |
| 98 | { | 94 | { |
| @@ -119,53 +115,6 @@ static const struct dmi_system_id dell_device_table[] __initconst = { | |||
| 119 | }; | 115 | }; |
| 120 | MODULE_DEVICE_TABLE(dmi, dell_device_table); | 116 | MODULE_DEVICE_TABLE(dmi, dell_device_table); |
| 121 | 117 | ||
| 122 | static struct dmi_system_id __devinitdata dell_blacklist[] = { | ||
| 123 | /* Supported by compal-laptop */ | ||
| 124 | { | ||
| 125 | .ident = "Dell Mini 9", | ||
| 126 | .matches = { | ||
| 127 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 128 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 910"), | ||
| 129 | }, | ||
| 130 | }, | ||
| 131 | { | ||
| 132 | .ident = "Dell Mini 10", | ||
| 133 | .matches = { | ||
| 134 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 135 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1010"), | ||
| 136 | }, | ||
| 137 | }, | ||
| 138 | { | ||
| 139 | .ident = "Dell Mini 10v", | ||
| 140 | .matches = { | ||
| 141 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 142 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"), | ||
| 143 | }, | ||
| 144 | }, | ||
| 145 | { | ||
| 146 | .ident = "Dell Mini 1012", | ||
| 147 | .matches = { | ||
| 148 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 149 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), | ||
| 150 | }, | ||
| 151 | }, | ||
| 152 | { | ||
| 153 | .ident = "Dell Inspiron 11z", | ||
| 154 | .matches = { | ||
| 155 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 156 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1110"), | ||
| 157 | }, | ||
| 158 | }, | ||
| 159 | { | ||
| 160 | .ident = "Dell Mini 12", | ||
| 161 | .matches = { | ||
| 162 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 163 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1210"), | ||
| 164 | }, | ||
| 165 | }, | ||
| 166 | {} | ||
| 167 | }; | ||
| 168 | |||
| 169 | static struct dmi_system_id __devinitdata dell_quirks[] = { | 118 | static struct dmi_system_id __devinitdata dell_quirks[] = { |
| 170 | { | 119 | { |
| 171 | .callback = dmi_matched, | 120 | .callback = dmi_matched, |
| @@ -350,94 +299,6 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, | |||
| 350 | return buffer; | 299 | return buffer; |
| 351 | } | 300 | } |
| 352 | 301 | ||
| 353 | /* Derived from information in DellWirelessCtl.cpp: | ||
| 354 | Class 17, select 11 is radio control. It returns an array of 32-bit values. | ||
| 355 | |||
| 356 | Input byte 0 = 0: Wireless information | ||
| 357 | |||
| 358 | result[0]: return code | ||
| 359 | result[1]: | ||
| 360 | Bit 0: Hardware switch supported | ||
| 361 | Bit 1: Wifi locator supported | ||
| 362 | Bit 2: Wifi is supported | ||
| 363 | Bit 3: Bluetooth is supported | ||
| 364 | Bit 4: WWAN is supported | ||
| 365 | Bit 5: Wireless keyboard supported | ||
| 366 | Bits 6-7: Reserved | ||
| 367 | Bit 8: Wifi is installed | ||
| 368 | Bit 9: Bluetooth is installed | ||
| 369 | Bit 10: WWAN is installed | ||
| 370 | Bits 11-15: Reserved | ||
| 371 | Bit 16: Hardware switch is on | ||
| 372 | Bit 17: Wifi is blocked | ||
| 373 | Bit 18: Bluetooth is blocked | ||
| 374 | Bit 19: WWAN is blocked | ||
| 375 | Bits 20-31: Reserved | ||
| 376 | result[2]: NVRAM size in bytes | ||
| 377 | result[3]: NVRAM format version number | ||
| 378 | |||
| 379 | Input byte 0 = 2: Wireless switch configuration | ||
| 380 | result[0]: return code | ||
| 381 | result[1]: | ||
| 382 | Bit 0: Wifi controlled by switch | ||
| 383 | Bit 1: Bluetooth controlled by switch | ||
| 384 | Bit 2: WWAN controlled by switch | ||
| 385 | Bits 3-6: Reserved | ||
| 386 | Bit 7: Wireless switch config locked | ||
| 387 | Bit 8: Wifi locator enabled | ||
| 388 | Bits 9-14: Reserved | ||
| 389 | Bit 15: Wifi locator setting locked | ||
| 390 | Bits 16-31: Reserved | ||
| 391 | */ | ||
| 392 | |||
| 393 | static int dell_rfkill_set(void *data, bool blocked) | ||
| 394 | { | ||
| 395 | int disable = blocked ? 1 : 0; | ||
| 396 | unsigned long radio = (unsigned long)data; | ||
| 397 | int hwswitch_bit = (unsigned long)data - 1; | ||
| 398 | int ret = 0; | ||
| 399 | |||
| 400 | get_buffer(); | ||
| 401 | dell_send_request(buffer, 17, 11); | ||
| 402 | |||
| 403 | /* If the hardware switch controls this radio, and the hardware | ||
| 404 | switch is disabled, don't allow changing the software state */ | ||
| 405 | if ((hwswitch_state & BIT(hwswitch_bit)) && | ||
| 406 | !(buffer->output[1] & BIT(16))) { | ||
| 407 | ret = -EINVAL; | ||
| 408 | goto out; | ||
| 409 | } | ||
| 410 | |||
| 411 | buffer->input[0] = (1 | (radio<<8) | (disable << 16)); | ||
| 412 | dell_send_request(buffer, 17, 11); | ||
| 413 | |||
| 414 | out: | ||
| 415 | release_buffer(); | ||
| 416 | return ret; | ||
| 417 | } | ||
| 418 | |||
| 419 | static void dell_rfkill_query(struct rfkill *rfkill, void *data) | ||
| 420 | { | ||
| 421 | int status; | ||
| 422 | int bit = (unsigned long)data + 16; | ||
| 423 | int hwswitch_bit = (unsigned long)data - 1; | ||
| 424 | |||
| 425 | get_buffer(); | ||
| 426 | dell_send_request(buffer, 17, 11); | ||
| 427 | status = buffer->output[1]; | ||
| 428 | release_buffer(); | ||
| 429 | |||
| 430 | rfkill_set_sw_state(rfkill, !!(status & BIT(bit))); | ||
| 431 | |||
| 432 | if (hwswitch_state & (BIT(hwswitch_bit))) | ||
| 433 | rfkill_set_hw_state(rfkill, !(status & BIT(16))); | ||
| 434 | } | ||
| 435 | |||
| 436 | static const struct rfkill_ops dell_rfkill_ops = { | ||
| 437 | .set_block = dell_rfkill_set, | ||
| 438 | .query = dell_rfkill_query, | ||
| 439 | }; | ||
| 440 | |||
| 441 | static struct dentry *dell_laptop_dir; | 302 | static struct dentry *dell_laptop_dir; |
| 442 | 303 | ||
| 443 | static int dell_debugfs_show(struct seq_file *s, void *data) | 304 | static int dell_debugfs_show(struct seq_file *s, void *data) |
| @@ -507,108 +368,6 @@ static const struct file_operations dell_debugfs_fops = { | |||
| 507 | .release = single_release, | 368 | .release = single_release, |
| 508 | }; | 369 | }; |
| 509 | 370 | ||
| 510 | static void dell_update_rfkill(struct work_struct *ignored) | ||
| 511 | { | ||
| 512 | if (wifi_rfkill) | ||
| 513 | dell_rfkill_query(wifi_rfkill, (void *)1); | ||
| 514 | if (bluetooth_rfkill) | ||
| 515 | dell_rfkill_query(bluetooth_rfkill, (void *)2); | ||
| 516 | if (wwan_rfkill) | ||
| 517 | dell_rfkill_query(wwan_rfkill, (void *)3); | ||
| 518 | } | ||
| 519 | static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); | ||
| 520 | |||
| 521 | |||
| 522 | static int __init dell_setup_rfkill(void) | ||
| 523 | { | ||
| 524 | int status; | ||
| 525 | int ret; | ||
| 526 | |||
| 527 | if (dmi_check_system(dell_blacklist)) { | ||
| 528 | pr_info("Blacklisted hardware detected - not enabling rfkill\n"); | ||
| 529 | return 0; | ||
| 530 | } | ||
| 531 | |||
| 532 | get_buffer(); | ||
| 533 | dell_send_request(buffer, 17, 11); | ||
| 534 | status = buffer->output[1]; | ||
| 535 | buffer->input[0] = 0x2; | ||
| 536 | dell_send_request(buffer, 17, 11); | ||
| 537 | hwswitch_state = buffer->output[1]; | ||
| 538 | release_buffer(); | ||
| 539 | |||
| 540 | if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { | ||
| 541 | wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, | ||
| 542 | RFKILL_TYPE_WLAN, | ||
| 543 | &dell_rfkill_ops, (void *) 1); | ||
| 544 | if (!wifi_rfkill) { | ||
| 545 | ret = -ENOMEM; | ||
| 546 | goto err_wifi; | ||
| 547 | } | ||
| 548 | ret = rfkill_register(wifi_rfkill); | ||
| 549 | if (ret) | ||
| 550 | goto err_wifi; | ||
| 551 | } | ||
| 552 | |||
| 553 | if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { | ||
| 554 | bluetooth_rfkill = rfkill_alloc("dell-bluetooth", | ||
| 555 | &platform_device->dev, | ||
| 556 | RFKILL_TYPE_BLUETOOTH, | ||
| 557 | &dell_rfkill_ops, (void *) 2); | ||
| 558 | if (!bluetooth_rfkill) { | ||
| 559 | ret = -ENOMEM; | ||
| 560 | goto err_bluetooth; | ||
| 561 | } | ||
| 562 | ret = rfkill_register(bluetooth_rfkill); | ||
| 563 | if (ret) | ||
| 564 | goto err_bluetooth; | ||
| 565 | } | ||
| 566 | |||
| 567 | if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { | ||
| 568 | wwan_rfkill = rfkill_alloc("dell-wwan", | ||
| 569 | &platform_device->dev, | ||
| 570 | RFKILL_TYPE_WWAN, | ||
| 571 | &dell_rfkill_ops, (void *) 3); | ||
| 572 | if (!wwan_rfkill) { | ||
| 573 | ret = -ENOMEM; | ||
| 574 | goto err_wwan; | ||
| 575 | } | ||
| 576 | ret = rfkill_register(wwan_rfkill); | ||
| 577 | if (ret) | ||
| 578 | goto err_wwan; | ||
| 579 | } | ||
| 580 | |||
| 581 | return 0; | ||
| 582 | err_wwan: | ||
| 583 | rfkill_destroy(wwan_rfkill); | ||
| 584 | if (bluetooth_rfkill) | ||
| 585 | rfkill_unregister(bluetooth_rfkill); | ||
| 586 | err_bluetooth: | ||
| 587 | rfkill_destroy(bluetooth_rfkill); | ||
| 588 | if (wifi_rfkill) | ||
| 589 | rfkill_unregister(wifi_rfkill); | ||
| 590 | err_wifi: | ||
| 591 | rfkill_destroy(wifi_rfkill); | ||
| 592 | |||
| 593 | return ret; | ||
| 594 | } | ||
| 595 | |||
| 596 | static void dell_cleanup_rfkill(void) | ||
| 597 | { | ||
| 598 | if (wifi_rfkill) { | ||
| 599 | rfkill_unregister(wifi_rfkill); | ||
| 600 | rfkill_destroy(wifi_rfkill); | ||
| 601 | } | ||
| 602 | if (bluetooth_rfkill) { | ||
| 603 | rfkill_unregister(bluetooth_rfkill); | ||
| 604 | rfkill_destroy(bluetooth_rfkill); | ||
| 605 | } | ||
| 606 | if (wwan_rfkill) { | ||
| 607 | rfkill_unregister(wwan_rfkill); | ||
| 608 | rfkill_destroy(wwan_rfkill); | ||
| 609 | } | ||
| 610 | } | ||
| 611 | |||
| 612 | static int dell_send_intensity(struct backlight_device *bd) | 371 | static int dell_send_intensity(struct backlight_device *bd) |
| 613 | { | 372 | { |
| 614 | int ret = 0; | 373 | int ret = 0; |
| @@ -700,30 +459,6 @@ static void touchpad_led_exit(void) | |||
| 700 | led_classdev_unregister(&touchpad_led); | 459 | led_classdev_unregister(&touchpad_led); |
| 701 | } | 460 | } |
| 702 | 461 | ||
| 703 | static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, | ||
| 704 | struct serio *port) | ||
| 705 | { | ||
| 706 | static bool extended; | ||
| 707 | |||
| 708 | if (str & 0x20) | ||
| 709 | return false; | ||
| 710 | |||
| 711 | if (unlikely(data == 0xe0)) { | ||
| 712 | extended = true; | ||
| 713 | return false; | ||
| 714 | } else if (unlikely(extended)) { | ||
| 715 | switch (data) { | ||
| 716 | case 0x8: | ||
| 717 | schedule_delayed_work(&dell_rfkill_work, | ||
| 718 | round_jiffies_relative(HZ)); | ||
| 719 | break; | ||
| 720 | } | ||
| 721 | extended = false; | ||
| 722 | } | ||
| 723 | |||
| 724 | return false; | ||
| 725 | } | ||
| 726 | |||
| 727 | static int __init dell_init(void) | 462 | static int __init dell_init(void) |
| 728 | { | 463 | { |
| 729 | int max_intensity = 0; | 464 | int max_intensity = 0; |
| @@ -765,26 +500,10 @@ static int __init dell_init(void) | |||
| 765 | goto fail_buffer; | 500 | goto fail_buffer; |
| 766 | buffer = page_address(bufferpage); | 501 | buffer = page_address(bufferpage); |
| 767 | 502 | ||
| 768 | ret = dell_setup_rfkill(); | ||
| 769 | |||
| 770 | if (ret) { | ||
| 771 | pr_warn("Unable to setup rfkill\n"); | ||
| 772 | goto fail_rfkill; | ||
| 773 | } | ||
| 774 | |||
| 775 | ret = i8042_install_filter(dell_laptop_i8042_filter); | ||
| 776 | if (ret) { | ||
| 777 | pr_warn("Unable to install key filter\n"); | ||
| 778 | goto fail_filter; | ||
| 779 | } | ||
| 780 | |||
| 781 | if (quirks && quirks->touchpad_led) | 503 | if (quirks && quirks->touchpad_led) |
| 782 | touchpad_led_init(&platform_device->dev); | 504 | touchpad_led_init(&platform_device->dev); |
| 783 | 505 | ||
| 784 | dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); | 506 | dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); |
| 785 | if (dell_laptop_dir != NULL) | ||
| 786 | debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, | ||
| 787 | &dell_debugfs_fops); | ||
| 788 | 507 | ||
| 789 | #ifdef CONFIG_ACPI | 508 | #ifdef CONFIG_ACPI |
| 790 | /* In the event of an ACPI backlight being available, don't | 509 | /* In the event of an ACPI backlight being available, don't |
| @@ -827,11 +546,6 @@ static int __init dell_init(void) | |||
| 827 | return 0; | 546 | return 0; |
| 828 | 547 | ||
| 829 | fail_backlight: | 548 | fail_backlight: |
| 830 | i8042_remove_filter(dell_laptop_i8042_filter); | ||
| 831 | cancel_delayed_work_sync(&dell_rfkill_work); | ||
| 832 | fail_filter: | ||
| 833 | dell_cleanup_rfkill(); | ||
| 834 | fail_rfkill: | ||
| 835 | free_page((unsigned long)bufferpage); | 549 | free_page((unsigned long)bufferpage); |
| 836 | fail_buffer: | 550 | fail_buffer: |
| 837 | platform_device_del(platform_device); | 551 | platform_device_del(platform_device); |
| @@ -849,10 +563,7 @@ static void __exit dell_exit(void) | |||
| 849 | debugfs_remove_recursive(dell_laptop_dir); | 563 | debugfs_remove_recursive(dell_laptop_dir); |
| 850 | if (quirks && quirks->touchpad_led) | 564 | if (quirks && quirks->touchpad_led) |
| 851 | touchpad_led_exit(); | 565 | touchpad_led_exit(); |
| 852 | i8042_remove_filter(dell_laptop_i8042_filter); | ||
| 853 | cancel_delayed_work_sync(&dell_rfkill_work); | ||
| 854 | backlight_device_unregister(dell_backlight_device); | 566 | backlight_device_unregister(dell_backlight_device); |
| 855 | dell_cleanup_rfkill(); | ||
| 856 | if (platform_device) { | 567 | if (platform_device) { |
| 857 | platform_device_unregister(platform_device); | 568 | platform_device_unregister(platform_device); |
| 858 | platform_driver_unregister(&platform_driver); | 569 | platform_driver_unregister(&platform_driver); |
