aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/eeepc-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/eeepc-laptop.c')
-rw-r--r--drivers/platform/x86/eeepc-laptop.c500
1 files changed, 376 insertions, 124 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 03bf522bd7ab..ec560f16d720 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -16,6 +16,8 @@
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 */ 17 */
18 18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
19#include <linux/kernel.h> 21#include <linux/kernel.h>
20#include <linux/module.h> 22#include <linux/module.h>
21#include <linux/init.h> 23#include <linux/init.h>
@@ -31,6 +33,7 @@
31#include <linux/input.h> 33#include <linux/input.h>
32#include <linux/rfkill.h> 34#include <linux/rfkill.h>
33#include <linux/pci.h> 35#include <linux/pci.h>
36#include <linux/pci_hotplug.h>
34 37
35#define EEEPC_LAPTOP_VERSION "0.1" 38#define EEEPC_LAPTOP_VERSION "0.1"
36 39
@@ -40,11 +43,6 @@
40#define EEEPC_HOTK_DEVICE_NAME "Hotkey" 43#define EEEPC_HOTK_DEVICE_NAME "Hotkey"
41#define EEEPC_HOTK_HID "ASUS010" 44#define EEEPC_HOTK_HID "ASUS010"
42 45
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 46
49/* 47/*
50 * Definitions for Asus EeePC 48 * Definitions for Asus EeePC
@@ -62,7 +60,10 @@ enum {
62 DISABLE_ASL_GPS = 0x0020, 60 DISABLE_ASL_GPS = 0x0020,
63 DISABLE_ASL_DISPLAYSWITCH = 0x0040, 61 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
64 DISABLE_ASL_MODEM = 0x0080, 62 DISABLE_ASL_MODEM = 0x0080,
65 DISABLE_ASL_CARDREADER = 0x0100 63 DISABLE_ASL_CARDREADER = 0x0100,
64 DISABLE_ASL_3G = 0x0200,
65 DISABLE_ASL_WIMAX = 0x0400,
66 DISABLE_ASL_HWCF = 0x0800
66}; 67};
67 68
68enum { 69enum {
@@ -87,7 +88,13 @@ enum {
87 CM_ASL_USBPORT3, 88 CM_ASL_USBPORT3,
88 CM_ASL_MODEM, 89 CM_ASL_MODEM,
89 CM_ASL_CARDREADER, 90 CM_ASL_CARDREADER,
90 CM_ASL_LID 91 CM_ASL_3G,
92 CM_ASL_WIMAX,
93 CM_ASL_HWCF,
94 CM_ASL_LID,
95 CM_ASL_TYPE,
96 CM_ASL_PANELPOWER, /*P901*/
97 CM_ASL_TPD
91}; 98};
92 99
93static const char *cm_getv[] = { 100static const char *cm_getv[] = {
@@ -96,7 +103,8 @@ static const char *cm_getv[] = {
96 NULL, "PBLG", NULL, NULL, 103 NULL, "PBLG", NULL, NULL,
97 "CFVG", NULL, NULL, NULL, 104 "CFVG", NULL, NULL, NULL,
98 "USBG", NULL, NULL, "MODG", 105 "USBG", NULL, NULL, "MODG",
99 "CRDG", "LIDG" 106 "CRDG", "M3GG", "WIMG", "HWCF",
107 "LIDG", "TYPE", "PBPG", "TPDG"
100}; 108};
101 109
102static const char *cm_setv[] = { 110static const char *cm_setv[] = {
@@ -105,7 +113,8 @@ static const char *cm_setv[] = {
105 "SDSP", "PBLS", "HDPS", NULL, 113 "SDSP", "PBLS", "HDPS", NULL,
106 "CFVS", NULL, NULL, NULL, 114 "CFVS", NULL, NULL, NULL,
107 "USBG", NULL, NULL, "MODS", 115 "USBG", NULL, NULL, "MODS",
108 "CRDS", NULL 116 "CRDS", "M3GS", "WIMS", NULL,
117 NULL, NULL, "PBPS", "TPDS"
109}; 118};
110 119
111#define EEEPC_EC "\\_SB.PCI0.SBRG.EC0." 120#define EEEPC_EC "\\_SB.PCI0.SBRG.EC0."
@@ -130,8 +139,10 @@ struct eeepc_hotk {
130 u16 event_count[128]; /* count for each event */ 139 u16 event_count[128]; /* count for each event */
131 struct input_dev *inputdev; 140 struct input_dev *inputdev;
132 u16 *keycode_map; 141 u16 *keycode_map;
133 struct rfkill *eeepc_wlan_rfkill; 142 struct rfkill *wlan_rfkill;
134 struct rfkill *eeepc_bluetooth_rfkill; 143 struct rfkill *bluetooth_rfkill;
144 struct rfkill *wwan3g_rfkill;
145 struct hotplug_slot *hotplug_slot;
135}; 146};
136 147
137/* The actual device the driver binds to */ 148/* The actual device the driver binds to */
@@ -180,6 +191,8 @@ static struct key_entry eeepc_keymap[] = {
180 */ 191 */
181static int eeepc_hotk_add(struct acpi_device *device); 192static int eeepc_hotk_add(struct acpi_device *device);
182static int eeepc_hotk_remove(struct acpi_device *device, int type); 193static int eeepc_hotk_remove(struct acpi_device *device, int type);
194static int eeepc_hotk_resume(struct acpi_device *device);
195static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
183 196
184static const struct acpi_device_id eeepc_device_ids[] = { 197static const struct acpi_device_id eeepc_device_ids[] = {
185 {EEEPC_HOTK_HID, 0}, 198 {EEEPC_HOTK_HID, 0},
@@ -191,12 +204,24 @@ static struct acpi_driver eeepc_hotk_driver = {
191 .name = EEEPC_HOTK_NAME, 204 .name = EEEPC_HOTK_NAME,
192 .class = EEEPC_HOTK_CLASS, 205 .class = EEEPC_HOTK_CLASS,
193 .ids = eeepc_device_ids, 206 .ids = eeepc_device_ids,
207 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
194 .ops = { 208 .ops = {
195 .add = eeepc_hotk_add, 209 .add = eeepc_hotk_add,
196 .remove = eeepc_hotk_remove, 210 .remove = eeepc_hotk_remove,
211 .resume = eeepc_hotk_resume,
212 .notify = eeepc_hotk_notify,
197 }, 213 },
198}; 214};
199 215
216/* PCI hotplug ops */
217static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
218
219static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
220 .owner = THIS_MODULE,
221 .get_adapter_status = eeepc_get_adapter_status,
222 .get_power_status = eeepc_get_adapter_status,
223};
224
200/* The backlight device /sys/class/backlight */ 225/* The backlight device /sys/class/backlight */
201static struct backlight_device *eeepc_backlight_device; 226static struct backlight_device *eeepc_backlight_device;
202 227
@@ -258,20 +283,20 @@ static int set_acpi(int cm, int value)
258 if (method == NULL) 283 if (method == NULL)
259 return -ENODEV; 284 return -ENODEV;
260 if (write_acpi_int(ehotk->handle, method, value, NULL)) 285 if (write_acpi_int(ehotk->handle, method, value, NULL))
261 printk(EEEPC_WARNING "Error writing %s\n", method); 286 pr_warning("Error writing %s\n", method);
262 } 287 }
263 return 0; 288 return 0;
264} 289}
265 290
266static int get_acpi(int cm) 291static int get_acpi(int cm)
267{ 292{
268 int value = -1; 293 int value = -ENODEV;
269 if ((ehotk->cm_supported & (0x1 << cm))) { 294 if ((ehotk->cm_supported & (0x1 << cm))) {
270 const char *method = cm_getv[cm]; 295 const char *method = cm_getv[cm];
271 if (method == NULL) 296 if (method == NULL)
272 return -ENODEV; 297 return -ENODEV;
273 if (read_acpi_int(ehotk->handle, method, &value)) 298 if (read_acpi_int(ehotk->handle, method, &value))
274 printk(EEEPC_WARNING "Error reading %s\n", method); 299 pr_warning("Error reading %s\n", method);
275 } 300 }
276 return value; 301 return value;
277} 302}
@@ -316,6 +341,15 @@ static const struct rfkill_ops eeepc_rfkill_ops = {
316 .set_block = eeepc_rfkill_set, 341 .set_block = eeepc_rfkill_set,
317}; 342};
318 343
344static void __init eeepc_enable_camera(void)
345{
346 /*
347 * If the following call to set_acpi() fails, it's because there's no
348 * camera so we can ignore the error.
349 */
350 set_acpi(CM_ASL_CAMERA, 1);
351}
352
319/* 353/*
320 * Sys helpers 354 * Sys helpers
321 */ 355 */
@@ -334,13 +368,19 @@ static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
334 368
335 rv = parse_arg(buf, count, &value); 369 rv = parse_arg(buf, count, &value);
336 if (rv > 0) 370 if (rv > 0)
337 set_acpi(cm, value); 371 value = set_acpi(cm, value);
372 if (value < 0)
373 return value;
338 return rv; 374 return rv;
339} 375}
340 376
341static ssize_t show_sys_acpi(int cm, char *buf) 377static ssize_t show_sys_acpi(int cm, char *buf)
342{ 378{
343 return sprintf(buf, "%d\n", get_acpi(cm)); 379 int value = get_acpi(cm);
380
381 if (value < 0)
382 return value;
383 return sprintf(buf, "%d\n", value);
344} 384}
345 385
346#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ 386#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
@@ -367,13 +407,88 @@ static ssize_t show_sys_acpi(int cm, char *buf)
367EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); 407EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
368EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); 408EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
369EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); 409EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
370EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV); 410
411struct eeepc_cpufv {
412 int num;
413 int cur;
414};
415
416static int get_cpufv(struct eeepc_cpufv *c)
417{
418 c->cur = get_acpi(CM_ASL_CPUFV);
419 c->num = (c->cur >> 8) & 0xff;
420 c->cur &= 0xff;
421 if (c->cur < 0 || c->num <= 0 || c->num > 12)
422 return -ENODEV;
423 return 0;
424}
425
426static ssize_t show_available_cpufv(struct device *dev,
427 struct device_attribute *attr,
428 char *buf)
429{
430 struct eeepc_cpufv c;
431 int i;
432 ssize_t len = 0;
433
434 if (get_cpufv(&c))
435 return -ENODEV;
436 for (i = 0; i < c.num; i++)
437 len += sprintf(buf + len, "%d ", i);
438 len += sprintf(buf + len, "\n");
439 return len;
440}
441
442static ssize_t show_cpufv(struct device *dev,
443 struct device_attribute *attr,
444 char *buf)
445{
446 struct eeepc_cpufv c;
447
448 if (get_cpufv(&c))
449 return -ENODEV;
450 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
451}
452
453static ssize_t store_cpufv(struct device *dev,
454 struct device_attribute *attr,
455 const char *buf, size_t count)
456{
457 struct eeepc_cpufv c;
458 int rv, value;
459
460 if (get_cpufv(&c))
461 return -ENODEV;
462 rv = parse_arg(buf, count, &value);
463 if (rv < 0)
464 return rv;
465 if (!rv || value < 0 || value >= c.num)
466 return -EINVAL;
467 set_acpi(CM_ASL_CPUFV, value);
468 return rv;
469}
470
471static struct device_attribute dev_attr_cpufv = {
472 .attr = {
473 .name = "cpufv",
474 .mode = 0644 },
475 .show = show_cpufv,
476 .store = store_cpufv
477};
478
479static struct device_attribute dev_attr_available_cpufv = {
480 .attr = {
481 .name = "available_cpufv",
482 .mode = 0444 },
483 .show = show_available_cpufv
484};
371 485
372static struct attribute *platform_attributes[] = { 486static struct attribute *platform_attributes[] = {
373 &dev_attr_camera.attr, 487 &dev_attr_camera.attr,
374 &dev_attr_cardr.attr, 488 &dev_attr_cardr.attr,
375 &dev_attr_disp.attr, 489 &dev_attr_disp.attr,
376 &dev_attr_cpufv.attr, 490 &dev_attr_cpufv.attr,
491 &dev_attr_available_cpufv.attr,
377 NULL 492 NULL
378}; 493};
379 494
@@ -439,6 +554,28 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
439 return -EINVAL; 554 return -EINVAL;
440} 555}
441 556
557static void cmsg_quirk(int cm, const char *name)
558{
559 int dummy;
560
561 /* Some BIOSes do not report cm although it is avaliable.
562 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
563 if (!(ehotk->cm_supported & (1 << cm))
564 && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) {
565 pr_info("%s (%x) not reported by BIOS,"
566 " enabling anyway\n", name, 1 << cm);
567 ehotk->cm_supported |= 1 << cm;
568 }
569}
570
571static void cmsg_quirks(void)
572{
573 cmsg_quirk(CM_ASL_LID, "LID");
574 cmsg_quirk(CM_ASL_TYPE, "TYPE");
575 cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER");
576 cmsg_quirk(CM_ASL_TPD, "TPD");
577}
578
442static int eeepc_hotk_check(void) 579static int eeepc_hotk_check(void)
443{ 580{
444 const struct key_entry *key; 581 const struct key_entry *key;
@@ -451,26 +588,24 @@ static int eeepc_hotk_check(void)
451 if (ehotk->device->status.present) { 588 if (ehotk->device->status.present) {
452 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, 589 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
453 &buffer)) { 590 &buffer)) {
454 printk(EEEPC_ERR "Hotkey initialization failed\n"); 591 pr_err("Hotkey initialization failed\n");
455 return -ENODEV; 592 return -ENODEV;
456 } else { 593 } else {
457 printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", 594 pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
458 ehotk->init_flag);
459 } 595 }
460 /* get control methods supported */ 596 /* get control methods supported */
461 if (read_acpi_int(ehotk->handle, "CMSG" 597 if (read_acpi_int(ehotk->handle, "CMSG"
462 , &ehotk->cm_supported)) { 598 , &ehotk->cm_supported)) {
463 printk(EEEPC_ERR 599 pr_err("Get control methods supported failed\n");
464 "Get control methods supported failed\n");
465 return -ENODEV; 600 return -ENODEV;
466 } else { 601 } else {
467 printk(EEEPC_INFO 602 cmsg_quirks();
468 "Get control methods supported: 0x%x\n", 603 pr_info("Get control methods supported: 0x%x\n",
469 ehotk->cm_supported); 604 ehotk->cm_supported);
470 } 605 }
471 ehotk->inputdev = input_allocate_device(); 606 ehotk->inputdev = input_allocate_device();
472 if (!ehotk->inputdev) { 607 if (!ehotk->inputdev) {
473 printk(EEEPC_INFO "Unable to allocate input device\n"); 608 pr_info("Unable to allocate input device\n");
474 return 0; 609 return 0;
475 } 610 }
476 ehotk->inputdev->name = "Asus EeePC extra buttons"; 611 ehotk->inputdev->name = "Asus EeePC extra buttons";
@@ -489,12 +624,12 @@ static int eeepc_hotk_check(void)
489 } 624 }
490 result = input_register_device(ehotk->inputdev); 625 result = input_register_device(ehotk->inputdev);
491 if (result) { 626 if (result) {
492 printk(EEEPC_INFO "Unable to register input device\n"); 627 pr_info("Unable to register input device\n");
493 input_free_device(ehotk->inputdev); 628 input_free_device(ehotk->inputdev);
494 return 0; 629 return 0;
495 } 630 }
496 } else { 631 } else {
497 printk(EEEPC_ERR "Hotkey device not present, aborting\n"); 632 pr_err("Hotkey device not present, aborting\n");
498 return -EINVAL; 633 return -EINVAL;
499 } 634 }
500 return 0; 635 return 0;
@@ -512,17 +647,27 @@ static int notify_brn(void)
512 return -1; 647 return -1;
513} 648}
514 649
515static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) 650static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
651 u8 *value)
652{
653 int val = get_acpi(CM_ASL_WLAN);
654
655 if (val == 1 || val == 0)
656 *value = val;
657 else
658 return -EINVAL;
659
660 return 0;
661}
662
663static void eeepc_rfkill_hotplug(void)
516{ 664{
517 struct pci_dev *dev; 665 struct pci_dev *dev;
518 struct pci_bus *bus = pci_find_bus(0, 1); 666 struct pci_bus *bus = pci_find_bus(0, 1);
519 bool blocked; 667 bool blocked;
520 668
521 if (event != ACPI_NOTIFY_BUS_CHECK)
522 return;
523
524 if (!bus) { 669 if (!bus) {
525 printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); 670 pr_warning("Unable to find PCI bus 1?\n");
526 return; 671 return;
527 } 672 }
528 673
@@ -538,7 +683,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
538 if (dev) { 683 if (dev) {
539 pci_bus_assign_resources(bus); 684 pci_bus_assign_resources(bus);
540 if (pci_bus_add_device(dev)) 685 if (pci_bus_add_device(dev))
541 printk(EEEPC_ERR "Unable to hotplug wifi\n"); 686 pr_err("Unable to hotplug wifi\n");
542 } 687 }
543 } else { 688 } else {
544 dev = pci_get_slot(bus, 0); 689 dev = pci_get_slot(bus, 0);
@@ -548,10 +693,18 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
548 } 693 }
549 } 694 }
550 695
551 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); 696 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
552} 697}
553 698
554static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) 699static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
700{
701 if (event != ACPI_NOTIFY_BUS_CHECK)
702 return;
703
704 eeepc_rfkill_hotplug();
705}
706
707static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
555{ 708{
556 static struct key_entry *key; 709 static struct key_entry *key;
557 u16 count; 710 u16 count;
@@ -559,6 +712,8 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
559 712
560 if (!ehotk) 713 if (!ehotk)
561 return; 714 return;
715 if (event > ACPI_MAX_SYS_NOTIFY)
716 return;
562 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) 717 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
563 brn = notify_brn(); 718 brn = notify_brn();
564 count = ehotk->event_count[event % 128]++; 719 count = ehotk->event_count[event % 128]++;
@@ -611,8 +766,7 @@ static int eeepc_register_rfkill_notifier(char *node)
611 eeepc_rfkill_notify, 766 eeepc_rfkill_notify,
612 NULL); 767 NULL);
613 if (ACPI_FAILURE(status)) 768 if (ACPI_FAILURE(status))
614 printk(EEEPC_WARNING 769 pr_warning("Failed to register notify on %s\n", node);
615 "Failed to register notify on %s\n", node);
616 } else 770 } else
617 return -ENODEV; 771 return -ENODEV;
618 772
@@ -631,20 +785,66 @@ static void eeepc_unregister_rfkill_notifier(char *node)
631 ACPI_SYSTEM_NOTIFY, 785 ACPI_SYSTEM_NOTIFY,
632 eeepc_rfkill_notify); 786 eeepc_rfkill_notify);
633 if (ACPI_FAILURE(status)) 787 if (ACPI_FAILURE(status))
634 printk(EEEPC_ERR 788 pr_err("Error removing rfkill notify handler %s\n",
635 "Error removing rfkill notify handler %s\n",
636 node); 789 node);
637 } 790 }
638} 791}
639 792
793static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
794{
795 kfree(hotplug_slot->info);
796 kfree(hotplug_slot);
797}
798
799static int eeepc_setup_pci_hotplug(void)
800{
801 int ret = -ENOMEM;
802 struct pci_bus *bus = pci_find_bus(0, 1);
803
804 if (!bus) {
805 pr_err("Unable to find wifi PCI bus\n");
806 return -ENODEV;
807 }
808
809 ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
810 if (!ehotk->hotplug_slot)
811 goto error_slot;
812
813 ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
814 GFP_KERNEL);
815 if (!ehotk->hotplug_slot->info)
816 goto error_info;
817
818 ehotk->hotplug_slot->private = ehotk;
819 ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
820 ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
821 eeepc_get_adapter_status(ehotk->hotplug_slot,
822 &ehotk->hotplug_slot->info->adapter_status);
823
824 ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
825 if (ret) {
826 pr_err("Unable to register hotplug slot - %d\n", ret);
827 goto error_register;
828 }
829
830 return 0;
831
832error_register:
833 kfree(ehotk->hotplug_slot->info);
834error_info:
835 kfree(ehotk->hotplug_slot);
836 ehotk->hotplug_slot = NULL;
837error_slot:
838 return ret;
839}
840
640static int eeepc_hotk_add(struct acpi_device *device) 841static int eeepc_hotk_add(struct acpi_device *device)
641{ 842{
642 acpi_status status = AE_OK;
643 int result; 843 int result;
644 844
645 if (!device) 845 if (!device)
646 return -EINVAL; 846 return -EINVAL;
647 printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); 847 pr_notice(EEEPC_HOTK_NAME "\n");
648 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); 848 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
649 if (!ehotk) 849 if (!ehotk)
650 return -ENOMEM; 850 return -ENOMEM;
@@ -657,58 +857,9 @@ static int eeepc_hotk_add(struct acpi_device *device)
657 result = eeepc_hotk_check(); 857 result = eeepc_hotk_check();
658 if (result) 858 if (result)
659 goto ehotk_fail; 859 goto ehotk_fail;
660 status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
661 eeepc_hotk_notify, ehotk);
662 if (ACPI_FAILURE(status))
663 printk(EEEPC_ERR "Error installing notify handler\n");
664
665 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
666 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
667
668 if (get_acpi(CM_ASL_WLAN) != -1) {
669 ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
670 &device->dev,
671 RFKILL_TYPE_WLAN,
672 &eeepc_rfkill_ops,
673 (void *)CM_ASL_WLAN);
674
675 if (!ehotk->eeepc_wlan_rfkill)
676 goto wlan_fail;
677
678 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill,
679 get_acpi(CM_ASL_WLAN) != 1);
680 result = rfkill_register(ehotk->eeepc_wlan_rfkill);
681 if (result)
682 goto wlan_fail;
683 }
684
685 if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
686 ehotk->eeepc_bluetooth_rfkill =
687 rfkill_alloc("eeepc-bluetooth",
688 &device->dev,
689 RFKILL_TYPE_BLUETOOTH,
690 &eeepc_rfkill_ops,
691 (void *)CM_ASL_BLUETOOTH);
692
693 if (!ehotk->eeepc_bluetooth_rfkill)
694 goto bluetooth_fail;
695
696 rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill,
697 get_acpi(CM_ASL_BLUETOOTH) != 1);
698 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
699 if (result)
700 goto bluetooth_fail;
701 }
702 860
703 return 0; 861 return 0;
704 862
705 bluetooth_fail:
706 rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
707 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
708 wlan_fail:
709 rfkill_destroy(ehotk->eeepc_wlan_rfkill);
710 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
711 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
712 ehotk_fail: 863 ehotk_fail:
713 kfree(ehotk); 864 kfree(ehotk);
714 ehotk = NULL; 865 ehotk = NULL;
@@ -718,22 +869,39 @@ static int eeepc_hotk_add(struct acpi_device *device)
718 869
719static int eeepc_hotk_remove(struct acpi_device *device, int type) 870static int eeepc_hotk_remove(struct acpi_device *device, int type)
720{ 871{
721 acpi_status status = 0;
722
723 if (!device || !acpi_driver_data(device)) 872 if (!device || !acpi_driver_data(device))
724 return -EINVAL; 873 return -EINVAL;
725 status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
726 eeepc_hotk_notify);
727 if (ACPI_FAILURE(status))
728 printk(EEEPC_ERR "Error removing notify handler\n");
729
730 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
731 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
732 874
733 kfree(ehotk); 875 kfree(ehotk);
734 return 0; 876 return 0;
735} 877}
736 878
879static int eeepc_hotk_resume(struct acpi_device *device)
880{
881 if (ehotk->wlan_rfkill) {
882 bool wlan;
883
884 /* Workaround - it seems that _PTS disables the wireless
885 without notification or changing the value read by WLAN.
886 Normally this is fine because the correct value is restored
887 from the non-volatile storage on resume, but we need to do
888 it ourself if case suspend is aborted, or we lose wireless.
889 */
890 wlan = get_acpi(CM_ASL_WLAN);
891 set_acpi(CM_ASL_WLAN, wlan);
892
893 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
894
895 eeepc_rfkill_hotplug();
896 }
897
898 if (ehotk->bluetooth_rfkill)
899 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
900 get_acpi(CM_ASL_BLUETOOTH) != 1);
901
902 return 0;
903}
904
737/* 905/*
738 * Hwmon 906 * Hwmon
739 */ 907 */
@@ -850,10 +1018,16 @@ static void eeepc_backlight_exit(void)
850 1018
851static void eeepc_rfkill_exit(void) 1019static void eeepc_rfkill_exit(void)
852{ 1020{
853 if (ehotk->eeepc_wlan_rfkill) 1021 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
854 rfkill_unregister(ehotk->eeepc_wlan_rfkill); 1022 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
855 if (ehotk->eeepc_bluetooth_rfkill) 1023 if (ehotk->wlan_rfkill)
856 rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); 1024 rfkill_unregister(ehotk->wlan_rfkill);
1025 if (ehotk->bluetooth_rfkill)
1026 rfkill_unregister(ehotk->bluetooth_rfkill);
1027 if (ehotk->wwan3g_rfkill)
1028 rfkill_unregister(ehotk->wwan3g_rfkill);
1029 if (ehotk->hotplug_slot)
1030 pci_hp_deregister(ehotk->hotplug_slot);
857} 1031}
858 1032
859static void eeepc_input_exit(void) 1033static void eeepc_input_exit(void)
@@ -888,6 +1062,75 @@ static void __exit eeepc_laptop_exit(void)
888 platform_driver_unregister(&platform_driver); 1062 platform_driver_unregister(&platform_driver);
889} 1063}
890 1064
1065static int eeepc_new_rfkill(struct rfkill **rfkill,
1066 const char *name, struct device *dev,
1067 enum rfkill_type type, int cm)
1068{
1069 int result;
1070
1071 result = get_acpi(cm);
1072 if (result < 0)
1073 return result;
1074
1075 *rfkill = rfkill_alloc(name, dev, type,
1076 &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1077
1078 if (!*rfkill)
1079 return -EINVAL;
1080
1081 rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1082 result = rfkill_register(*rfkill);
1083 if (result) {
1084 rfkill_destroy(*rfkill);
1085 *rfkill = NULL;
1086 return result;
1087 }
1088 return 0;
1089}
1090
1091
1092static int eeepc_rfkill_init(struct device *dev)
1093{
1094 int result = 0;
1095
1096 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1097 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1098
1099 result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1100 "eeepc-wlan", dev,
1101 RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1102
1103 if (result && result != -ENODEV)
1104 goto exit;
1105
1106 result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1107 "eeepc-bluetooth", dev,
1108 RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1109
1110 if (result && result != -ENODEV)
1111 goto exit;
1112
1113 result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill,
1114 "eeepc-wwan3g", dev,
1115 RFKILL_TYPE_WWAN, CM_ASL_3G);
1116
1117 if (result && result != -ENODEV)
1118 goto exit;
1119
1120 result = eeepc_setup_pci_hotplug();
1121 /*
1122 * If we get -EBUSY then something else is handling the PCI hotplug -
1123 * don't fail in this case
1124 */
1125 if (result == -EBUSY)
1126 result = 0;
1127
1128exit:
1129 if (result && result != -ENODEV)
1130 eeepc_rfkill_exit();
1131 return result;
1132}
1133
891static int eeepc_backlight_init(struct device *dev) 1134static int eeepc_backlight_init(struct device *dev)
892{ 1135{
893 struct backlight_device *bd; 1136 struct backlight_device *bd;
@@ -895,8 +1138,7 @@ static int eeepc_backlight_init(struct device *dev)
895 bd = backlight_device_register(EEEPC_HOTK_FILE, dev, 1138 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
896 NULL, &eeepcbl_ops); 1139 NULL, &eeepcbl_ops);
897 if (IS_ERR(bd)) { 1140 if (IS_ERR(bd)) {
898 printk(EEEPC_ERR 1141 pr_err("Could not register eeepc backlight device\n");
899 "Could not register eeepc backlight device\n");
900 eeepc_backlight_device = NULL; 1142 eeepc_backlight_device = NULL;
901 return PTR_ERR(bd); 1143 return PTR_ERR(bd);
902 } 1144 }
@@ -915,8 +1157,7 @@ static int eeepc_hwmon_init(struct device *dev)
915 1157
916 hwmon = hwmon_device_register(dev); 1158 hwmon = hwmon_device_register(dev);
917 if (IS_ERR(hwmon)) { 1159 if (IS_ERR(hwmon)) {
918 printk(EEEPC_ERR 1160 pr_err("Could not register eeepc hwmon device\n");
919 "Could not register eeepc hwmon device\n");
920 eeepc_hwmon_device = NULL; 1161 eeepc_hwmon_device = NULL;
921 return PTR_ERR(hwmon); 1162 return PTR_ERR(hwmon);
922 } 1163 }
@@ -942,19 +1183,9 @@ static int __init eeepc_laptop_init(void)
942 acpi_bus_unregister_driver(&eeepc_hotk_driver); 1183 acpi_bus_unregister_driver(&eeepc_hotk_driver);
943 return -ENODEV; 1184 return -ENODEV;
944 } 1185 }
945 dev = acpi_get_physical_device(ehotk->device->handle);
946 1186
947 if (!acpi_video_backlight_support()) { 1187 eeepc_enable_camera();
948 result = eeepc_backlight_init(dev);
949 if (result)
950 goto fail_backlight;
951 } else
952 printk(EEEPC_INFO "Backlight controlled by ACPI video "
953 "driver\n");
954 1188
955 result = eeepc_hwmon_init(dev);
956 if (result)
957 goto fail_hwmon;
958 /* Register platform stuff */ 1189 /* Register platform stuff */
959 result = platform_driver_register(&platform_driver); 1190 result = platform_driver_register(&platform_driver);
960 if (result) 1191 if (result)
@@ -971,7 +1202,33 @@ static int __init eeepc_laptop_init(void)
971 &platform_attribute_group); 1202 &platform_attribute_group);
972 if (result) 1203 if (result)
973 goto fail_sysfs; 1204 goto fail_sysfs;
1205
1206 dev = &platform_device->dev;
1207
1208 if (!acpi_video_backlight_support()) {
1209 result = eeepc_backlight_init(dev);
1210 if (result)
1211 goto fail_backlight;
1212 } else
1213 pr_info("Backlight controlled by ACPI video "
1214 "driver\n");
1215
1216 result = eeepc_hwmon_init(dev);
1217 if (result)
1218 goto fail_hwmon;
1219
1220 result = eeepc_rfkill_init(dev);
1221 if (result)
1222 goto fail_rfkill;
1223
974 return 0; 1224 return 0;
1225fail_rfkill:
1226 eeepc_hwmon_exit();
1227fail_hwmon:
1228 eeepc_backlight_exit();
1229fail_backlight:
1230 sysfs_remove_group(&platform_device->dev.kobj,
1231 &platform_attribute_group);
975fail_sysfs: 1232fail_sysfs:
976 platform_device_del(platform_device); 1233 platform_device_del(platform_device);
977fail_platform_device2: 1234fail_platform_device2:
@@ -979,12 +1236,7 @@ fail_platform_device2:
979fail_platform_device1: 1236fail_platform_device1:
980 platform_driver_unregister(&platform_driver); 1237 platform_driver_unregister(&platform_driver);
981fail_platform_driver: 1238fail_platform_driver:
982 eeepc_hwmon_exit();
983fail_hwmon:
984 eeepc_backlight_exit();
985fail_backlight:
986 eeepc_input_exit(); 1239 eeepc_input_exit();
987 eeepc_rfkill_exit();
988 return result; 1240 return result;
989} 1241}
990 1242