Linux 4.1.16
[linux/fpc-iii.git] / drivers / platform / x86 / eeepc-laptop.c
blob844c2096bde9244c3daaf504892f2bbcefad3db0
1 /*
2 * eeepc-laptop.c - Asus Eee PC extras
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
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.
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.
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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 <linux/slab.h>
31 #include <linux/acpi.h>
32 #include <linux/uaccess.h>
33 #include <linux/input.h>
34 #include <linux/input/sparse-keymap.h>
35 #include <linux/rfkill.h>
36 #include <linux/pci.h>
37 #include <linux/pci_hotplug.h>
38 #include <linux/leds.h>
39 #include <linux/dmi.h>
41 #define EEEPC_LAPTOP_VERSION "0.1"
42 #define EEEPC_LAPTOP_NAME "Eee PC Hotkey Driver"
43 #define EEEPC_LAPTOP_FILE "eeepc"
45 #define EEEPC_ACPI_CLASS "hotkey"
46 #define EEEPC_ACPI_DEVICE_NAME "Hotkey"
47 #define EEEPC_ACPI_HID "ASUS010"
49 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
50 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
51 MODULE_LICENSE("GPL");
53 static bool hotplug_disabled;
55 module_param(hotplug_disabled, bool, 0444);
56 MODULE_PARM_DESC(hotplug_disabled,
57 "Disable hotplug for wireless device. "
58 "If your laptop need that, please report to "
59 "acpi4asus-user@lists.sourceforge.net.");
62 * Definitions for Asus EeePC
64 #define NOTIFY_BRN_MIN 0x20
65 #define NOTIFY_BRN_MAX 0x2f
67 enum {
68 DISABLE_ASL_WLAN = 0x0001,
69 DISABLE_ASL_BLUETOOTH = 0x0002,
70 DISABLE_ASL_IRDA = 0x0004,
71 DISABLE_ASL_CAMERA = 0x0008,
72 DISABLE_ASL_TV = 0x0010,
73 DISABLE_ASL_GPS = 0x0020,
74 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
75 DISABLE_ASL_MODEM = 0x0080,
76 DISABLE_ASL_CARDREADER = 0x0100,
77 DISABLE_ASL_3G = 0x0200,
78 DISABLE_ASL_WIMAX = 0x0400,
79 DISABLE_ASL_HWCF = 0x0800
82 enum {
83 CM_ASL_WLAN = 0,
84 CM_ASL_BLUETOOTH,
85 CM_ASL_IRDA,
86 CM_ASL_1394,
87 CM_ASL_CAMERA,
88 CM_ASL_TV,
89 CM_ASL_GPS,
90 CM_ASL_DVDROM,
91 CM_ASL_DISPLAYSWITCH,
92 CM_ASL_PANELBRIGHT,
93 CM_ASL_BIOSFLASH,
94 CM_ASL_ACPIFLASH,
95 CM_ASL_CPUFV,
96 CM_ASL_CPUTEMPERATURE,
97 CM_ASL_FANCPU,
98 CM_ASL_FANCHASSIS,
99 CM_ASL_USBPORT1,
100 CM_ASL_USBPORT2,
101 CM_ASL_USBPORT3,
102 CM_ASL_MODEM,
103 CM_ASL_CARDREADER,
104 CM_ASL_3G,
105 CM_ASL_WIMAX,
106 CM_ASL_HWCF,
107 CM_ASL_LID,
108 CM_ASL_TYPE,
109 CM_ASL_PANELPOWER, /*P901*/
110 CM_ASL_TPD
113 static const char *cm_getv[] = {
114 "WLDG", "BTHG", NULL, NULL,
115 "CAMG", NULL, NULL, NULL,
116 NULL, "PBLG", NULL, NULL,
117 "CFVG", NULL, NULL, NULL,
118 "USBG", NULL, NULL, "MODG",
119 "CRDG", "M3GG", "WIMG", "HWCF",
120 "LIDG", "TYPE", "PBPG", "TPDG"
123 static const char *cm_setv[] = {
124 "WLDS", "BTHS", NULL, NULL,
125 "CAMS", NULL, NULL, NULL,
126 "SDSP", "PBLS", "HDPS", NULL,
127 "CFVS", NULL, NULL, NULL,
128 "USBG", NULL, NULL, "MODS",
129 "CRDS", "M3GS", "WIMS", NULL,
130 NULL, NULL, "PBPS", "TPDS"
133 static const struct key_entry eeepc_keymap[] = {
134 { KE_KEY, 0x10, { KEY_WLAN } },
135 { KE_KEY, 0x11, { KEY_WLAN } },
136 { KE_KEY, 0x12, { KEY_PROG1 } },
137 { KE_KEY, 0x13, { KEY_MUTE } },
138 { KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
139 { KE_KEY, 0x15, { KEY_VOLUMEUP } },
140 { KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
141 { KE_KEY, 0x1a, { KEY_COFFEE } },
142 { KE_KEY, 0x1b, { KEY_ZOOM } },
143 { KE_KEY, 0x1c, { KEY_PROG2 } },
144 { KE_KEY, 0x1d, { KEY_PROG3 } },
145 { KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
146 { KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
147 { KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
148 { KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
149 { KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
150 { KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
151 { KE_KEY, 0x38, { KEY_F14 } },
152 { KE_END, 0 },
156 * This is the main structure, we can use it to store useful information
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 bool cpufv_disabled;
163 bool hotplug_disabled;
164 u16 event_count[128]; /* count for each event */
166 struct platform_device *platform_device;
167 struct acpi_device *device; /* the device we are in */
168 struct backlight_device *backlight_device;
170 struct input_dev *inputdev;
172 struct rfkill *wlan_rfkill;
173 struct rfkill *bluetooth_rfkill;
174 struct rfkill *wwan3g_rfkill;
175 struct rfkill *wimax_rfkill;
177 struct hotplug_slot *hotplug_slot;
178 struct mutex hotplug_lock;
180 struct led_classdev tpd_led;
181 int tpd_led_wk;
182 struct workqueue_struct *led_workqueue;
183 struct work_struct tpd_led_work;
187 * ACPI Helpers
189 static int write_acpi_int(acpi_handle handle, const char *method, int val)
191 acpi_status status;
193 status = acpi_execute_simple_method(handle, (char *)method, val);
195 return (status == AE_OK ? 0 : -1);
198 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
200 acpi_status status;
201 unsigned long long result;
203 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
204 if (ACPI_FAILURE(status)) {
205 *val = -1;
206 return -1;
207 } else {
208 *val = result;
209 return 0;
213 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
215 const char *method = cm_setv[cm];
217 if (method == NULL)
218 return -ENODEV;
219 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
220 return -ENODEV;
222 if (write_acpi_int(eeepc->handle, method, value))
223 pr_warn("Error writing %s\n", method);
224 return 0;
227 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
229 const char *method = cm_getv[cm];
230 int value;
232 if (method == NULL)
233 return -ENODEV;
234 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
235 return -ENODEV;
237 if (read_acpi_int(eeepc->handle, method, &value))
238 pr_warn("Error reading %s\n", method);
239 return value;
242 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
243 acpi_handle *handle)
245 const char *method = cm_setv[cm];
246 acpi_status status;
248 if (method == NULL)
249 return -ENODEV;
250 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
251 return -ENODEV;
253 status = acpi_get_handle(eeepc->handle, (char *)method,
254 handle);
255 if (status != AE_OK) {
256 pr_warn("Error finding %s\n", method);
257 return -ENODEV;
259 return 0;
264 * Sys helpers
266 static int parse_arg(const char *buf, int *val)
268 if (sscanf(buf, "%i", val) != 1)
269 return -EINVAL;
270 return 0;
273 static ssize_t store_sys_acpi(struct device *dev, int cm,
274 const char *buf, size_t count)
276 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
277 int rv, value;
279 rv = parse_arg(buf, &value);
280 if (rv < 0)
281 return rv;
282 rv = set_acpi(eeepc, cm, value);
283 if (rv < 0)
284 return -EIO;
285 return count;
288 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
290 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
291 int value = get_acpi(eeepc, cm);
293 if (value < 0)
294 return -EIO;
295 return sprintf(buf, "%d\n", value);
298 #define EEEPC_ACPI_SHOW_FUNC(_name, _cm) \
299 static ssize_t _name##_show(struct device *dev, \
300 struct device_attribute *attr, \
301 char *buf) \
303 return show_sys_acpi(dev, _cm, buf); \
306 #define EEEPC_ACPI_STORE_FUNC(_name, _cm) \
307 static ssize_t _name##_store(struct device *dev, \
308 struct device_attribute *attr, \
309 const char *buf, size_t count) \
311 return store_sys_acpi(dev, _cm, buf, count); \
314 #define EEEPC_CREATE_DEVICE_ATTR_RW(_name, _cm) \
315 EEEPC_ACPI_SHOW_FUNC(_name, _cm) \
316 EEEPC_ACPI_STORE_FUNC(_name, _cm) \
317 static DEVICE_ATTR_RW(_name)
319 #define EEEPC_CREATE_DEVICE_ATTR_WO(_name, _cm) \
320 EEEPC_ACPI_STORE_FUNC(_name, _cm) \
321 static DEVICE_ATTR_WO(_name)
323 EEEPC_CREATE_DEVICE_ATTR_RW(camera, CM_ASL_CAMERA);
324 EEEPC_CREATE_DEVICE_ATTR_RW(cardr, CM_ASL_CARDREADER);
325 EEEPC_CREATE_DEVICE_ATTR_WO(disp, CM_ASL_DISPLAYSWITCH);
327 struct eeepc_cpufv {
328 int num;
329 int cur;
332 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
334 c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
335 if (c->cur < 0)
336 return -ENODEV;
338 c->num = (c->cur >> 8) & 0xff;
339 c->cur &= 0xff;
340 if (c->num == 0 || c->num > 12)
341 return -ENODEV;
342 return 0;
345 static ssize_t available_cpufv_show(struct device *dev,
346 struct device_attribute *attr,
347 char *buf)
349 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
350 struct eeepc_cpufv c;
351 int i;
352 ssize_t len = 0;
354 if (get_cpufv(eeepc, &c))
355 return -ENODEV;
356 for (i = 0; i < c.num; i++)
357 len += sprintf(buf + len, "%d ", i);
358 len += sprintf(buf + len, "\n");
359 return len;
362 static ssize_t cpufv_show(struct device *dev,
363 struct device_attribute *attr,
364 char *buf)
366 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
367 struct eeepc_cpufv c;
369 if (get_cpufv(eeepc, &c))
370 return -ENODEV;
371 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
374 static ssize_t cpufv_store(struct device *dev,
375 struct device_attribute *attr,
376 const char *buf, size_t count)
378 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
379 struct eeepc_cpufv c;
380 int rv, value;
382 if (eeepc->cpufv_disabled)
383 return -EPERM;
384 if (get_cpufv(eeepc, &c))
385 return -ENODEV;
386 rv = parse_arg(buf, &value);
387 if (rv < 0)
388 return rv;
389 if (value < 0 || value >= c.num)
390 return -EINVAL;
391 rv = set_acpi(eeepc, CM_ASL_CPUFV, value);
392 if (rv)
393 return rv;
394 return count;
397 static ssize_t cpufv_disabled_show(struct device *dev,
398 struct device_attribute *attr,
399 char *buf)
401 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
403 return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
406 static ssize_t cpufv_disabled_store(struct device *dev,
407 struct device_attribute *attr,
408 const char *buf, size_t count)
410 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
411 int rv, value;
413 rv = parse_arg(buf, &value);
414 if (rv < 0)
415 return rv;
417 switch (value) {
418 case 0:
419 if (eeepc->cpufv_disabled)
420 pr_warn("cpufv enabled (not officially supported on this model)\n");
421 eeepc->cpufv_disabled = false;
422 return count;
423 case 1:
424 return -EPERM;
425 default:
426 return -EINVAL;
431 static DEVICE_ATTR_RW(cpufv);
432 static DEVICE_ATTR_RO(available_cpufv);
433 static DEVICE_ATTR_RW(cpufv_disabled);
435 static struct attribute *platform_attributes[] = {
436 &dev_attr_camera.attr,
437 &dev_attr_cardr.attr,
438 &dev_attr_disp.attr,
439 &dev_attr_cpufv.attr,
440 &dev_attr_available_cpufv.attr,
441 &dev_attr_cpufv_disabled.attr,
442 NULL
445 static struct attribute_group platform_attribute_group = {
446 .attrs = platform_attributes
449 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
451 int result;
453 eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
454 if (!eeepc->platform_device)
455 return -ENOMEM;
456 platform_set_drvdata(eeepc->platform_device, eeepc);
458 result = platform_device_add(eeepc->platform_device);
459 if (result)
460 goto fail_platform_device;
462 result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
463 &platform_attribute_group);
464 if (result)
465 goto fail_sysfs;
466 return 0;
468 fail_sysfs:
469 platform_device_del(eeepc->platform_device);
470 fail_platform_device:
471 platform_device_put(eeepc->platform_device);
472 return result;
475 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
477 sysfs_remove_group(&eeepc->platform_device->dev.kobj,
478 &platform_attribute_group);
479 platform_device_unregister(eeepc->platform_device);
483 * LEDs
486 * These functions actually update the LED's, and are called from a
487 * workqueue. By doing this as separate work rather than when the LED
488 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
489 * potentially bad time, such as a timer interrupt.
491 static void tpd_led_update(struct work_struct *work)
493 struct eeepc_laptop *eeepc;
495 eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
497 set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
500 static void tpd_led_set(struct led_classdev *led_cdev,
501 enum led_brightness value)
503 struct eeepc_laptop *eeepc;
505 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
507 eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
508 queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
511 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
513 struct eeepc_laptop *eeepc;
515 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
517 return get_acpi(eeepc, CM_ASL_TPD);
520 static int eeepc_led_init(struct eeepc_laptop *eeepc)
522 int rv;
524 if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
525 return 0;
527 eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
528 if (!eeepc->led_workqueue)
529 return -ENOMEM;
530 INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
532 eeepc->tpd_led.name = "eeepc::touchpad";
533 eeepc->tpd_led.brightness_set = tpd_led_set;
534 if (get_acpi(eeepc, CM_ASL_TPD) >= 0) /* if method is available */
535 eeepc->tpd_led.brightness_get = tpd_led_get;
536 eeepc->tpd_led.max_brightness = 1;
538 rv = led_classdev_register(&eeepc->platform_device->dev,
539 &eeepc->tpd_led);
540 if (rv) {
541 destroy_workqueue(eeepc->led_workqueue);
542 return rv;
545 return 0;
548 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
550 if (!IS_ERR_OR_NULL(eeepc->tpd_led.dev))
551 led_classdev_unregister(&eeepc->tpd_led);
552 if (eeepc->led_workqueue)
553 destroy_workqueue(eeepc->led_workqueue);
558 * PCI hotplug (for wlan rfkill)
560 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
562 if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
563 return false;
564 return true;
567 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
569 struct pci_dev *port;
570 struct pci_dev *dev;
571 struct pci_bus *bus;
572 bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
573 bool absent;
574 u32 l;
576 if (eeepc->wlan_rfkill)
577 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
579 mutex_lock(&eeepc->hotplug_lock);
580 pci_lock_rescan_remove();
582 if (!eeepc->hotplug_slot)
583 goto out_unlock;
585 port = acpi_get_pci_dev(handle);
586 if (!port) {
587 pr_warning("Unable to find port\n");
588 goto out_unlock;
591 bus = port->subordinate;
593 if (!bus) {
594 pr_warn("Unable to find PCI bus 1?\n");
595 goto out_put_dev;
598 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
599 pr_err("Unable to read PCI config space?\n");
600 goto out_put_dev;
603 absent = (l == 0xffffffff);
605 if (blocked != absent) {
606 pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n",
607 blocked ? "blocked" : "unblocked",
608 absent ? "absent" : "present");
609 pr_warn("skipped wireless hotplug as probably inappropriate for this model\n");
610 goto out_put_dev;
613 if (!blocked) {
614 dev = pci_get_slot(bus, 0);
615 if (dev) {
616 /* Device already present */
617 pci_dev_put(dev);
618 goto out_put_dev;
620 dev = pci_scan_single_device(bus, 0);
621 if (dev) {
622 pci_bus_assign_resources(bus);
623 pci_bus_add_device(dev);
625 } else {
626 dev = pci_get_slot(bus, 0);
627 if (dev) {
628 pci_stop_and_remove_bus_device(dev);
629 pci_dev_put(dev);
632 out_put_dev:
633 pci_dev_put(port);
635 out_unlock:
636 pci_unlock_rescan_remove();
637 mutex_unlock(&eeepc->hotplug_lock);
640 static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
642 acpi_status status = AE_OK;
643 acpi_handle handle;
645 status = acpi_get_handle(NULL, node, &handle);
647 if (ACPI_SUCCESS(status))
648 eeepc_rfkill_hotplug(eeepc, handle);
651 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
653 struct eeepc_laptop *eeepc = data;
655 if (event != ACPI_NOTIFY_BUS_CHECK)
656 return;
658 eeepc_rfkill_hotplug(eeepc, handle);
661 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
662 char *node)
664 acpi_status status;
665 acpi_handle handle;
667 status = acpi_get_handle(NULL, node, &handle);
669 if (ACPI_FAILURE(status))
670 return -ENODEV;
672 status = acpi_install_notify_handler(handle,
673 ACPI_SYSTEM_NOTIFY,
674 eeepc_rfkill_notify,
675 eeepc);
676 if (ACPI_FAILURE(status))
677 pr_warn("Failed to register notify on %s\n", node);
680 * Refresh pci hotplug in case the rfkill state was
681 * changed during setup.
683 eeepc_rfkill_hotplug(eeepc, handle);
684 return 0;
687 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
688 char *node)
690 acpi_status status = AE_OK;
691 acpi_handle handle;
693 status = acpi_get_handle(NULL, node, &handle);
695 if (ACPI_FAILURE(status))
696 return;
698 status = acpi_remove_notify_handler(handle,
699 ACPI_SYSTEM_NOTIFY,
700 eeepc_rfkill_notify);
701 if (ACPI_FAILURE(status))
702 pr_err("Error removing rfkill notify handler %s\n",
703 node);
705 * Refresh pci hotplug in case the rfkill
706 * state was changed after
707 * eeepc_unregister_rfkill_notifier()
709 eeepc_rfkill_hotplug(eeepc, handle);
712 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
713 u8 *value)
715 struct eeepc_laptop *eeepc = hotplug_slot->private;
716 int val = get_acpi(eeepc, CM_ASL_WLAN);
718 if (val == 1 || val == 0)
719 *value = val;
720 else
721 return -EINVAL;
723 return 0;
726 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
728 kfree(hotplug_slot->info);
729 kfree(hotplug_slot);
732 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
733 .owner = THIS_MODULE,
734 .get_adapter_status = eeepc_get_adapter_status,
735 .get_power_status = eeepc_get_adapter_status,
738 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
740 int ret = -ENOMEM;
741 struct pci_bus *bus = pci_find_bus(0, 1);
743 if (!bus) {
744 pr_err("Unable to find wifi PCI bus\n");
745 return -ENODEV;
748 eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
749 if (!eeepc->hotplug_slot)
750 goto error_slot;
752 eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
753 GFP_KERNEL);
754 if (!eeepc->hotplug_slot->info)
755 goto error_info;
757 eeepc->hotplug_slot->private = eeepc;
758 eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
759 eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
760 eeepc_get_adapter_status(eeepc->hotplug_slot,
761 &eeepc->hotplug_slot->info->adapter_status);
763 ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
764 if (ret) {
765 pr_err("Unable to register hotplug slot - %d\n", ret);
766 goto error_register;
769 return 0;
771 error_register:
772 kfree(eeepc->hotplug_slot->info);
773 error_info:
774 kfree(eeepc->hotplug_slot);
775 eeepc->hotplug_slot = NULL;
776 error_slot:
777 return ret;
781 * Rfkill devices
783 static int eeepc_rfkill_set(void *data, bool blocked)
785 acpi_handle handle = data;
787 return write_acpi_int(handle, NULL, !blocked);
790 static const struct rfkill_ops eeepc_rfkill_ops = {
791 .set_block = eeepc_rfkill_set,
794 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
795 struct rfkill **rfkill,
796 const char *name,
797 enum rfkill_type type, int cm)
799 acpi_handle handle;
800 int result;
802 result = acpi_setter_handle(eeepc, cm, &handle);
803 if (result < 0)
804 return result;
806 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
807 &eeepc_rfkill_ops, handle);
809 if (!*rfkill)
810 return -EINVAL;
812 rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
813 result = rfkill_register(*rfkill);
814 if (result) {
815 rfkill_destroy(*rfkill);
816 *rfkill = NULL;
817 return result;
819 return 0;
822 static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5";
823 static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6";
824 static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7";
826 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
828 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
829 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
830 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
831 if (eeepc->wlan_rfkill) {
832 rfkill_unregister(eeepc->wlan_rfkill);
833 rfkill_destroy(eeepc->wlan_rfkill);
834 eeepc->wlan_rfkill = NULL;
837 if (eeepc->hotplug_slot)
838 pci_hp_deregister(eeepc->hotplug_slot);
840 if (eeepc->bluetooth_rfkill) {
841 rfkill_unregister(eeepc->bluetooth_rfkill);
842 rfkill_destroy(eeepc->bluetooth_rfkill);
843 eeepc->bluetooth_rfkill = NULL;
845 if (eeepc->wwan3g_rfkill) {
846 rfkill_unregister(eeepc->wwan3g_rfkill);
847 rfkill_destroy(eeepc->wwan3g_rfkill);
848 eeepc->wwan3g_rfkill = NULL;
850 if (eeepc->wimax_rfkill) {
851 rfkill_unregister(eeepc->wimax_rfkill);
852 rfkill_destroy(eeepc->wimax_rfkill);
853 eeepc->wimax_rfkill = NULL;
857 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
859 int result = 0;
861 mutex_init(&eeepc->hotplug_lock);
863 result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
864 "eeepc-wlan", RFKILL_TYPE_WLAN,
865 CM_ASL_WLAN);
867 if (result && result != -ENODEV)
868 goto exit;
870 result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
871 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
872 CM_ASL_BLUETOOTH);
874 if (result && result != -ENODEV)
875 goto exit;
877 result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
878 "eeepc-wwan3g", RFKILL_TYPE_WWAN,
879 CM_ASL_3G);
881 if (result && result != -ENODEV)
882 goto exit;
884 result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
885 "eeepc-wimax", RFKILL_TYPE_WIMAX,
886 CM_ASL_WIMAX);
888 if (result && result != -ENODEV)
889 goto exit;
891 if (eeepc->hotplug_disabled)
892 return 0;
894 result = eeepc_setup_pci_hotplug(eeepc);
896 * If we get -EBUSY then something else is handling the PCI hotplug -
897 * don't fail in this case
899 if (result == -EBUSY)
900 result = 0;
902 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
903 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
904 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
906 exit:
907 if (result && result != -ENODEV)
908 eeepc_rfkill_exit(eeepc);
909 return result;
913 * Platform driver - hibernate/resume callbacks
915 static int eeepc_hotk_thaw(struct device *device)
917 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
919 if (eeepc->wlan_rfkill) {
920 int wlan;
923 * Work around bios bug - acpi _PTS turns off the wireless led
924 * during suspend. Normally it restores it on resume, but
925 * we should kick it ourselves in case hibernation is aborted.
927 wlan = get_acpi(eeepc, CM_ASL_WLAN);
928 if (wlan >= 0)
929 set_acpi(eeepc, CM_ASL_WLAN, wlan);
932 return 0;
935 static int eeepc_hotk_restore(struct device *device)
937 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
939 /* Refresh both wlan rfkill state and pci hotplug */
940 if (eeepc->wlan_rfkill) {
941 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1);
942 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2);
943 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3);
946 if (eeepc->bluetooth_rfkill)
947 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
948 get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
949 if (eeepc->wwan3g_rfkill)
950 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
951 get_acpi(eeepc, CM_ASL_3G) != 1);
952 if (eeepc->wimax_rfkill)
953 rfkill_set_sw_state(eeepc->wimax_rfkill,
954 get_acpi(eeepc, CM_ASL_WIMAX) != 1);
956 return 0;
959 static const struct dev_pm_ops eeepc_pm_ops = {
960 .thaw = eeepc_hotk_thaw,
961 .restore = eeepc_hotk_restore,
964 static struct platform_driver platform_driver = {
965 .driver = {
966 .name = EEEPC_LAPTOP_FILE,
967 .pm = &eeepc_pm_ops,
972 * Hwmon device
975 #define EEEPC_EC_SC00 0x61
976 #define EEEPC_EC_FAN_PWM (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
977 #define EEEPC_EC_FAN_HRPM (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
978 #define EEEPC_EC_FAN_LRPM (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
980 #define EEEPC_EC_SFB0 0xD0
981 #define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */
983 static inline int eeepc_pwm_to_lmsensors(int value)
985 return value * 255 / 100;
988 static inline int eeepc_lmsensors_to_pwm(int value)
990 value = clamp_val(value, 0, 255);
991 return value * 100 / 255;
994 static int eeepc_get_fan_pwm(void)
996 u8 value = 0;
998 ec_read(EEEPC_EC_FAN_PWM, &value);
999 return eeepc_pwm_to_lmsensors(value);
1002 static void eeepc_set_fan_pwm(int value)
1004 value = eeepc_lmsensors_to_pwm(value);
1005 ec_write(EEEPC_EC_FAN_PWM, value);
1008 static int eeepc_get_fan_rpm(void)
1010 u8 high = 0;
1011 u8 low = 0;
1013 ec_read(EEEPC_EC_FAN_HRPM, &high);
1014 ec_read(EEEPC_EC_FAN_LRPM, &low);
1015 return high << 8 | low;
1018 #define EEEPC_EC_FAN_CTRL_BIT 0x02
1019 #define EEEPC_FAN_CTRL_MANUAL 1
1020 #define EEEPC_FAN_CTRL_AUTO 2
1022 static int eeepc_get_fan_ctrl(void)
1024 u8 value = 0;
1026 ec_read(EEEPC_EC_FAN_CTRL, &value);
1027 if (value & EEEPC_EC_FAN_CTRL_BIT)
1028 return EEEPC_FAN_CTRL_MANUAL;
1029 else
1030 return EEEPC_FAN_CTRL_AUTO;
1033 static void eeepc_set_fan_ctrl(int manual)
1035 u8 value = 0;
1037 ec_read(EEEPC_EC_FAN_CTRL, &value);
1038 if (manual == EEEPC_FAN_CTRL_MANUAL)
1039 value |= EEEPC_EC_FAN_CTRL_BIT;
1040 else
1041 value &= ~EEEPC_EC_FAN_CTRL_BIT;
1042 ec_write(EEEPC_EC_FAN_CTRL, value);
1045 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1047 int rv, value;
1049 rv = parse_arg(buf, &value);
1050 if (rv < 0)
1051 return rv;
1052 set(value);
1053 return count;
1056 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1058 return sprintf(buf, "%d\n", get());
1061 #define EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1062 static ssize_t _name##_show(struct device *dev, \
1063 struct device_attribute *attr, \
1064 char *buf) \
1066 return show_sys_hwmon(_get, buf); \
1069 #define EEEPC_SENSOR_STORE_FUNC(_name, _set) \
1070 static ssize_t _name##_store(struct device *dev, \
1071 struct device_attribute *attr, \
1072 const char *buf, size_t count) \
1074 return store_sys_hwmon(_set, buf, count); \
1077 #define EEEPC_CREATE_SENSOR_ATTR_RW(_name, _get, _set) \
1078 EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1079 EEEPC_SENSOR_STORE_FUNC(_name, _set) \
1080 static DEVICE_ATTR_RW(_name)
1082 #define EEEPC_CREATE_SENSOR_ATTR_RO(_name, _get) \
1083 EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1084 static DEVICE_ATTR_RO(_name)
1086 EEEPC_CREATE_SENSOR_ATTR_RO(fan1_input, eeepc_get_fan_rpm);
1087 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1, eeepc_get_fan_pwm,
1088 eeepc_set_fan_pwm);
1089 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1_enable, eeepc_get_fan_ctrl,
1090 eeepc_set_fan_ctrl);
1092 static struct attribute *hwmon_attrs[] = {
1093 &dev_attr_pwm1.attr,
1094 &dev_attr_fan1_input.attr,
1095 &dev_attr_pwm1_enable.attr,
1096 NULL
1098 ATTRIBUTE_GROUPS(hwmon);
1100 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1102 struct device *dev = &eeepc->platform_device->dev;
1103 struct device *hwmon;
1105 hwmon = devm_hwmon_device_register_with_groups(dev, "eeepc", NULL,
1106 hwmon_groups);
1107 if (IS_ERR(hwmon)) {
1108 pr_err("Could not register eeepc hwmon device\n");
1109 return PTR_ERR(hwmon);
1111 return 0;
1115 * Backlight device
1117 static int read_brightness(struct backlight_device *bd)
1119 struct eeepc_laptop *eeepc = bl_get_data(bd);
1121 return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1124 static int set_brightness(struct backlight_device *bd, int value)
1126 struct eeepc_laptop *eeepc = bl_get_data(bd);
1128 return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1131 static int update_bl_status(struct backlight_device *bd)
1133 return set_brightness(bd, bd->props.brightness);
1136 static const struct backlight_ops eeepcbl_ops = {
1137 .get_brightness = read_brightness,
1138 .update_status = update_bl_status,
1141 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1143 struct backlight_device *bd = eeepc->backlight_device;
1144 int old = bd->props.brightness;
1146 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1148 return old;
1151 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1153 struct backlight_properties props;
1154 struct backlight_device *bd;
1156 memset(&props, 0, sizeof(struct backlight_properties));
1157 props.type = BACKLIGHT_PLATFORM;
1158 props.max_brightness = 15;
1159 bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1160 &eeepc->platform_device->dev, eeepc,
1161 &eeepcbl_ops, &props);
1162 if (IS_ERR(bd)) {
1163 pr_err("Could not register eeepc backlight device\n");
1164 eeepc->backlight_device = NULL;
1165 return PTR_ERR(bd);
1167 eeepc->backlight_device = bd;
1168 bd->props.brightness = read_brightness(bd);
1169 bd->props.power = FB_BLANK_UNBLANK;
1170 backlight_update_status(bd);
1171 return 0;
1174 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1176 backlight_device_unregister(eeepc->backlight_device);
1177 eeepc->backlight_device = NULL;
1182 * Input device (i.e. hotkeys)
1184 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1186 struct input_dev *input;
1187 int error;
1189 input = input_allocate_device();
1190 if (!input)
1191 return -ENOMEM;
1193 input->name = "Asus EeePC extra buttons";
1194 input->phys = EEEPC_LAPTOP_FILE "/input0";
1195 input->id.bustype = BUS_HOST;
1196 input->dev.parent = &eeepc->platform_device->dev;
1198 error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1199 if (error) {
1200 pr_err("Unable to setup input device keymap\n");
1201 goto err_free_dev;
1204 error = input_register_device(input);
1205 if (error) {
1206 pr_err("Unable to register input device\n");
1207 goto err_free_keymap;
1210 eeepc->inputdev = input;
1211 return 0;
1213 err_free_keymap:
1214 sparse_keymap_free(input);
1215 err_free_dev:
1216 input_free_device(input);
1217 return error;
1220 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1222 if (eeepc->inputdev) {
1223 sparse_keymap_free(eeepc->inputdev);
1224 input_unregister_device(eeepc->inputdev);
1226 eeepc->inputdev = NULL;
1230 * ACPI driver
1232 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1234 if (!eeepc->inputdev)
1235 return;
1236 if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
1237 pr_info("Unknown key %x pressed\n", event);
1240 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1242 struct eeepc_laptop *eeepc = acpi_driver_data(device);
1243 int old_brightness, new_brightness;
1244 u16 count;
1246 if (event > ACPI_MAX_SYS_NOTIFY)
1247 return;
1248 count = eeepc->event_count[event % 128]++;
1249 acpi_bus_generate_netlink_event(device->pnp.device_class,
1250 dev_name(&device->dev), event,
1251 count);
1253 /* Brightness events are special */
1254 if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) {
1255 eeepc_input_notify(eeepc, event);
1256 return;
1259 /* Ignore them completely if the acpi video driver is used */
1260 if (!eeepc->backlight_device)
1261 return;
1263 /* Update the backlight device. */
1264 old_brightness = eeepc_backlight_notify(eeepc);
1266 /* Convert event to keypress (obsolescent hack) */
1267 new_brightness = event - NOTIFY_BRN_MIN;
1269 if (new_brightness < old_brightness) {
1270 event = NOTIFY_BRN_MIN; /* brightness down */
1271 } else if (new_brightness > old_brightness) {
1272 event = NOTIFY_BRN_MAX; /* brightness up */
1273 } else {
1275 * no change in brightness - already at min/max,
1276 * event will be desired value (or else ignored)
1279 eeepc_input_notify(eeepc, event);
1282 static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1284 const char *model;
1286 model = dmi_get_system_info(DMI_PRODUCT_NAME);
1287 if (!model)
1288 return;
1291 * Blacklist for setting cpufv (cpu speed).
1293 * EeePC 4G ("701") implements CFVS, but it is not supported
1294 * by the pre-installed OS, and the original option to change it
1295 * in the BIOS setup screen was removed in later versions.
1297 * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1298 * this applies to all "701" models (4G/4G Surf/2G Surf).
1300 * So Asus made a deliberate decision not to support it on this model.
1301 * We have several reports that using it can cause the system to hang
1303 * The hang has also been reported on a "702" (Model name "8G"?).
1305 * We avoid dmi_check_system() / dmi_match(), because they use
1306 * substring matching. We don't want to affect the "701SD"
1307 * and "701SDX" models, because they do support S.H.E.
1309 if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1310 eeepc->cpufv_disabled = true;
1311 pr_info("model %s does not officially support setting cpu speed\n",
1312 model);
1313 pr_info("cpufv disabled to avoid instability\n");
1317 * Blacklist for wlan hotplug
1319 * Eeepc 1005HA doesn't work like others models and don't need the
1320 * hotplug code. In fact, current hotplug code seems to unplug another
1321 * device...
1323 if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1324 strcmp(model, "1005PE") == 0) {
1325 eeepc->hotplug_disabled = true;
1326 pr_info("wlan hotplug disabled\n");
1330 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1332 int dummy;
1334 /* Some BIOSes do not report cm although it is available.
1335 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1336 if (!(eeepc->cm_supported & (1 << cm))
1337 && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1338 pr_info("%s (%x) not reported by BIOS, enabling anyway\n",
1339 name, 1 << cm);
1340 eeepc->cm_supported |= 1 << cm;
1344 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1346 cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1347 cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1348 cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1349 cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1352 static int eeepc_acpi_init(struct eeepc_laptop *eeepc)
1354 unsigned int init_flags;
1355 int result;
1357 result = acpi_bus_get_status(eeepc->device);
1358 if (result)
1359 return result;
1360 if (!eeepc->device->status.present) {
1361 pr_err("Hotkey device not present, aborting\n");
1362 return -ENODEV;
1365 init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1366 pr_notice("Hotkey init flags 0x%x\n", init_flags);
1368 if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1369 pr_err("Hotkey initialization failed\n");
1370 return -ENODEV;
1373 /* get control methods supported */
1374 if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1375 pr_err("Get control methods supported failed\n");
1376 return -ENODEV;
1378 cmsg_quirks(eeepc);
1379 pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1381 return 0;
1384 static void eeepc_enable_camera(struct eeepc_laptop *eeepc)
1387 * If the following call to set_acpi() fails, it's because there's no
1388 * camera so we can ignore the error.
1390 if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1391 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1394 static bool eeepc_device_present;
1396 static int eeepc_acpi_add(struct acpi_device *device)
1398 struct eeepc_laptop *eeepc;
1399 int result;
1401 pr_notice(EEEPC_LAPTOP_NAME "\n");
1402 eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1403 if (!eeepc)
1404 return -ENOMEM;
1405 eeepc->handle = device->handle;
1406 strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1407 strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1408 device->driver_data = eeepc;
1409 eeepc->device = device;
1411 eeepc->hotplug_disabled = hotplug_disabled;
1413 eeepc_dmi_check(eeepc);
1415 result = eeepc_acpi_init(eeepc);
1416 if (result)
1417 goto fail_platform;
1418 eeepc_enable_camera(eeepc);
1421 * Register the platform device first. It is used as a parent for the
1422 * sub-devices below.
1424 * Note that if there are multiple instances of this ACPI device it
1425 * will bail out, because the platform device is registered with a
1426 * fixed name. Of course it doesn't make sense to have more than one,
1427 * and machine-specific scripts find the fixed name convenient. But
1428 * It's also good for us to exclude multiple instances because both
1429 * our hwmon and our wlan rfkill subdevice use global ACPI objects
1430 * (the EC and the wlan PCI slot respectively).
1432 result = eeepc_platform_init(eeepc);
1433 if (result)
1434 goto fail_platform;
1436 if (!acpi_video_backlight_support()) {
1437 result = eeepc_backlight_init(eeepc);
1438 if (result)
1439 goto fail_backlight;
1440 } else {
1441 pr_info("Backlight controlled by ACPI video driver\n");
1444 result = eeepc_input_init(eeepc);
1445 if (result)
1446 goto fail_input;
1448 result = eeepc_hwmon_init(eeepc);
1449 if (result)
1450 goto fail_hwmon;
1452 result = eeepc_led_init(eeepc);
1453 if (result)
1454 goto fail_led;
1456 result = eeepc_rfkill_init(eeepc);
1457 if (result)
1458 goto fail_rfkill;
1460 eeepc_device_present = true;
1461 return 0;
1463 fail_rfkill:
1464 eeepc_led_exit(eeepc);
1465 fail_led:
1466 fail_hwmon:
1467 eeepc_input_exit(eeepc);
1468 fail_input:
1469 eeepc_backlight_exit(eeepc);
1470 fail_backlight:
1471 eeepc_platform_exit(eeepc);
1472 fail_platform:
1473 kfree(eeepc);
1475 return result;
1478 static int eeepc_acpi_remove(struct acpi_device *device)
1480 struct eeepc_laptop *eeepc = acpi_driver_data(device);
1482 eeepc_backlight_exit(eeepc);
1483 eeepc_rfkill_exit(eeepc);
1484 eeepc_input_exit(eeepc);
1485 eeepc_led_exit(eeepc);
1486 eeepc_platform_exit(eeepc);
1488 kfree(eeepc);
1489 return 0;
1493 static const struct acpi_device_id eeepc_device_ids[] = {
1494 {EEEPC_ACPI_HID, 0},
1495 {"", 0},
1497 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1499 static struct acpi_driver eeepc_acpi_driver = {
1500 .name = EEEPC_LAPTOP_NAME,
1501 .class = EEEPC_ACPI_CLASS,
1502 .owner = THIS_MODULE,
1503 .ids = eeepc_device_ids,
1504 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1505 .ops = {
1506 .add = eeepc_acpi_add,
1507 .remove = eeepc_acpi_remove,
1508 .notify = eeepc_acpi_notify,
1513 static int __init eeepc_laptop_init(void)
1515 int result;
1517 result = platform_driver_register(&platform_driver);
1518 if (result < 0)
1519 return result;
1521 result = acpi_bus_register_driver(&eeepc_acpi_driver);
1522 if (result < 0)
1523 goto fail_acpi_driver;
1525 if (!eeepc_device_present) {
1526 result = -ENODEV;
1527 goto fail_no_device;
1530 return 0;
1532 fail_no_device:
1533 acpi_bus_unregister_driver(&eeepc_acpi_driver);
1534 fail_acpi_driver:
1535 platform_driver_unregister(&platform_driver);
1536 return result;
1539 static void __exit eeepc_laptop_exit(void)
1541 acpi_bus_unregister_driver(&eeepc_acpi_driver);
1542 platform_driver_unregister(&platform_driver);
1545 module_init(eeepc_laptop_init);
1546 module_exit(eeepc_laptop_exit);