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); |