]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/platform/x86/eeepc-laptop.c
Merge tag 'befs-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/luisbg...
[karo-tx-linux.git] / drivers / platform / x86 / eeepc-laptop.c
1 /*
2  *  eeepc-laptop.c - Asus Eee PC extras
3  *
4  *  Based on asus_acpi.c as patched for the Eee PC by Asus:
5  *  ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
6  *  Based on eee.c from eeepc-linux
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  */
18
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
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>
40 #include <acpi/video.h>
41
42 #define EEEPC_LAPTOP_VERSION    "0.1"
43 #define EEEPC_LAPTOP_NAME       "Eee PC Hotkey Driver"
44 #define EEEPC_LAPTOP_FILE       "eeepc"
45
46 #define EEEPC_ACPI_CLASS        "hotkey"
47 #define EEEPC_ACPI_DEVICE_NAME  "Hotkey"
48 #define EEEPC_ACPI_HID          "ASUS010"
49
50 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
51 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
52 MODULE_LICENSE("GPL");
53
54 static bool hotplug_disabled;
55
56 module_param(hotplug_disabled, bool, 0444);
57 MODULE_PARM_DESC(hotplug_disabled,
58                  "Disable hotplug for wireless device. "
59                  "If your laptop need that, please report to "
60                  "acpi4asus-user@lists.sourceforge.net.");
61
62 /*
63  * Definitions for Asus EeePC
64  */
65 #define NOTIFY_BRN_MIN  0x20
66 #define NOTIFY_BRN_MAX  0x2f
67
68 enum {
69         DISABLE_ASL_WLAN = 0x0001,
70         DISABLE_ASL_BLUETOOTH = 0x0002,
71         DISABLE_ASL_IRDA = 0x0004,
72         DISABLE_ASL_CAMERA = 0x0008,
73         DISABLE_ASL_TV = 0x0010,
74         DISABLE_ASL_GPS = 0x0020,
75         DISABLE_ASL_DISPLAYSWITCH = 0x0040,
76         DISABLE_ASL_MODEM = 0x0080,
77         DISABLE_ASL_CARDREADER = 0x0100,
78         DISABLE_ASL_3G = 0x0200,
79         DISABLE_ASL_WIMAX = 0x0400,
80         DISABLE_ASL_HWCF = 0x0800
81 };
82
83 enum {
84         CM_ASL_WLAN = 0,
85         CM_ASL_BLUETOOTH,
86         CM_ASL_IRDA,
87         CM_ASL_1394,
88         CM_ASL_CAMERA,
89         CM_ASL_TV,
90         CM_ASL_GPS,
91         CM_ASL_DVDROM,
92         CM_ASL_DISPLAYSWITCH,
93         CM_ASL_PANELBRIGHT,
94         CM_ASL_BIOSFLASH,
95         CM_ASL_ACPIFLASH,
96         CM_ASL_CPUFV,
97         CM_ASL_CPUTEMPERATURE,
98         CM_ASL_FANCPU,
99         CM_ASL_FANCHASSIS,
100         CM_ASL_USBPORT1,
101         CM_ASL_USBPORT2,
102         CM_ASL_USBPORT3,
103         CM_ASL_MODEM,
104         CM_ASL_CARDREADER,
105         CM_ASL_3G,
106         CM_ASL_WIMAX,
107         CM_ASL_HWCF,
108         CM_ASL_LID,
109         CM_ASL_TYPE,
110         CM_ASL_PANELPOWER,      /*P901*/
111         CM_ASL_TPD
112 };
113
114 static const char *cm_getv[] = {
115         "WLDG", "BTHG", NULL, NULL,
116         "CAMG", NULL, NULL, NULL,
117         NULL, "PBLG", NULL, NULL,
118         "CFVG", NULL, NULL, NULL,
119         "USBG", NULL, NULL, "MODG",
120         "CRDG", "M3GG", "WIMG", "HWCF",
121         "LIDG", "TYPE", "PBPG", "TPDG"
122 };
123
124 static const char *cm_setv[] = {
125         "WLDS", "BTHS", NULL, NULL,
126         "CAMS", NULL, NULL, NULL,
127         "SDSP", "PBLS", "HDPS", NULL,
128         "CFVS", NULL, NULL, NULL,
129         "USBG", NULL, NULL, "MODS",
130         "CRDS", "M3GS", "WIMS", NULL,
131         NULL, NULL, "PBPS", "TPDS"
132 };
133
134 static const struct key_entry eeepc_keymap[] = {
135         { KE_KEY, 0x10, { KEY_WLAN } },
136         { KE_KEY, 0x11, { KEY_WLAN } },
137         { KE_KEY, 0x12, { KEY_PROG1 } },
138         { KE_KEY, 0x13, { KEY_MUTE } },
139         { KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
140         { KE_KEY, 0x15, { KEY_VOLUMEUP } },
141         { KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
142         { KE_KEY, 0x1a, { KEY_COFFEE } },
143         { KE_KEY, 0x1b, { KEY_ZOOM } },
144         { KE_KEY, 0x1c, { KEY_PROG2 } },
145         { KE_KEY, 0x1d, { KEY_PROG3 } },
146         { KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
147         { KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
148         { KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
149         { KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
150         { KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
151         { KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
152         { KE_KEY, 0x38, { KEY_F14 } },
153         { KE_IGNORE, 0x50, { KEY_RESERVED } }, /* AC plugged */
154         { KE_IGNORE, 0x51, { KEY_RESERVED } }, /* AC unplugged */
155         { KE_END, 0 },
156 };
157
158 /*
159  * This is the main structure, we can use it to store useful information
160  */
161 struct eeepc_laptop {
162         acpi_handle handle;             /* the handle of the acpi device */
163         u32 cm_supported;               /* the control methods supported
164                                            by this BIOS */
165         bool cpufv_disabled;
166         bool hotplug_disabled;
167         u16 event_count[128];           /* count for each event */
168
169         struct platform_device *platform_device;
170         struct acpi_device *device;             /* the device we are in */
171         struct backlight_device *backlight_device;
172
173         struct input_dev *inputdev;
174
175         struct rfkill *wlan_rfkill;
176         struct rfkill *bluetooth_rfkill;
177         struct rfkill *wwan3g_rfkill;
178         struct rfkill *wimax_rfkill;
179
180         struct hotplug_slot *hotplug_slot;
181         struct mutex hotplug_lock;
182
183         struct led_classdev tpd_led;
184         int tpd_led_wk;
185         struct workqueue_struct *led_workqueue;
186         struct work_struct tpd_led_work;
187 };
188
189 /*
190  * ACPI Helpers
191  */
192 static int write_acpi_int(acpi_handle handle, const char *method, int val)
193 {
194         acpi_status status;
195
196         status = acpi_execute_simple_method(handle, (char *)method, val);
197
198         return (status == AE_OK ? 0 : -1);
199 }
200
201 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
202 {
203         acpi_status status;
204         unsigned long long result;
205
206         status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
207         if (ACPI_FAILURE(status)) {
208                 *val = -1;
209                 return -1;
210         } else {
211                 *val = result;
212                 return 0;
213         }
214 }
215
216 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
217 {
218         const char *method = cm_setv[cm];
219
220         if (method == NULL)
221                 return -ENODEV;
222         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
223                 return -ENODEV;
224
225         if (write_acpi_int(eeepc->handle, method, value))
226                 pr_warn("Error writing %s\n", method);
227         return 0;
228 }
229
230 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
231 {
232         const char *method = cm_getv[cm];
233         int value;
234
235         if (method == NULL)
236                 return -ENODEV;
237         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
238                 return -ENODEV;
239
240         if (read_acpi_int(eeepc->handle, method, &value))
241                 pr_warn("Error reading %s\n", method);
242         return value;
243 }
244
245 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
246                               acpi_handle *handle)
247 {
248         const char *method = cm_setv[cm];
249         acpi_status status;
250
251         if (method == NULL)
252                 return -ENODEV;
253         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
254                 return -ENODEV;
255
256         status = acpi_get_handle(eeepc->handle, (char *)method,
257                                  handle);
258         if (status != AE_OK) {
259                 pr_warn("Error finding %s\n", method);
260                 return -ENODEV;
261         }
262         return 0;
263 }
264
265
266 /*
267  * Sys helpers
268  */
269 static int parse_arg(const char *buf, int *val)
270 {
271         if (sscanf(buf, "%i", val) != 1)
272                 return -EINVAL;
273         return 0;
274 }
275
276 static ssize_t store_sys_acpi(struct device *dev, int cm,
277                               const char *buf, size_t count)
278 {
279         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
280         int rv, value;
281
282         rv = parse_arg(buf, &value);
283         if (rv < 0)
284                 return rv;
285         rv = set_acpi(eeepc, cm, value);
286         if (rv < 0)
287                 return -EIO;
288         return count;
289 }
290
291 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
292 {
293         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
294         int value = get_acpi(eeepc, cm);
295
296         if (value < 0)
297                 return -EIO;
298         return sprintf(buf, "%d\n", value);
299 }
300
301 #define EEEPC_ACPI_SHOW_FUNC(_name, _cm)                                \
302         static ssize_t _name##_show(struct device *dev,                 \
303                                     struct device_attribute *attr,      \
304                                     char *buf)                          \
305         {                                                               \
306                 return show_sys_acpi(dev, _cm, buf);                    \
307         }
308
309 #define EEEPC_ACPI_STORE_FUNC(_name, _cm)                               \
310         static ssize_t _name##_store(struct device *dev,                \
311                                      struct device_attribute *attr,     \
312                                      const char *buf, size_t count)     \
313         {                                                               \
314                 return store_sys_acpi(dev, _cm, buf, count);            \
315         }
316
317 #define EEEPC_CREATE_DEVICE_ATTR_RW(_name, _cm)                         \
318         EEEPC_ACPI_SHOW_FUNC(_name, _cm)                                \
319         EEEPC_ACPI_STORE_FUNC(_name, _cm)                               \
320         static DEVICE_ATTR_RW(_name)
321
322 #define EEEPC_CREATE_DEVICE_ATTR_WO(_name, _cm)                         \
323         EEEPC_ACPI_STORE_FUNC(_name, _cm)                               \
324         static DEVICE_ATTR_WO(_name)
325
326 EEEPC_CREATE_DEVICE_ATTR_RW(camera, CM_ASL_CAMERA);
327 EEEPC_CREATE_DEVICE_ATTR_RW(cardr, CM_ASL_CARDREADER);
328 EEEPC_CREATE_DEVICE_ATTR_WO(disp, CM_ASL_DISPLAYSWITCH);
329
330 struct eeepc_cpufv {
331         int num;
332         int cur;
333 };
334
335 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
336 {
337         c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
338         if (c->cur < 0)
339                 return -ENODEV;
340
341         c->num = (c->cur >> 8) & 0xff;
342         c->cur &= 0xff;
343         if (c->num == 0 || c->num > 12)
344                 return -ENODEV;
345         return 0;
346 }
347
348 static ssize_t available_cpufv_show(struct device *dev,
349                                     struct device_attribute *attr,
350                                     char *buf)
351 {
352         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
353         struct eeepc_cpufv c;
354         int i;
355         ssize_t len = 0;
356
357         if (get_cpufv(eeepc, &c))
358                 return -ENODEV;
359         for (i = 0; i < c.num; i++)
360                 len += sprintf(buf + len, "%d ", i);
361         len += sprintf(buf + len, "\n");
362         return len;
363 }
364
365 static ssize_t cpufv_show(struct device *dev,
366                           struct device_attribute *attr,
367                           char *buf)
368 {
369         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
370         struct eeepc_cpufv c;
371
372         if (get_cpufv(eeepc, &c))
373                 return -ENODEV;
374         return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
375 }
376
377 static ssize_t cpufv_store(struct device *dev,
378                            struct device_attribute *attr,
379                            const char *buf, size_t count)
380 {
381         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
382         struct eeepc_cpufv c;
383         int rv, value;
384
385         if (eeepc->cpufv_disabled)
386                 return -EPERM;
387         if (get_cpufv(eeepc, &c))
388                 return -ENODEV;
389         rv = parse_arg(buf, &value);
390         if (rv < 0)
391                 return rv;
392         if (value < 0 || value >= c.num)
393                 return -EINVAL;
394         rv = set_acpi(eeepc, CM_ASL_CPUFV, value);
395         if (rv)
396                 return rv;
397         return count;
398 }
399
400 static ssize_t cpufv_disabled_show(struct device *dev,
401                           struct device_attribute *attr,
402                           char *buf)
403 {
404         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
405
406         return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
407 }
408
409 static ssize_t cpufv_disabled_store(struct device *dev,
410                            struct device_attribute *attr,
411                            const char *buf, size_t count)
412 {
413         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
414         int rv, value;
415
416         rv = parse_arg(buf, &value);
417         if (rv < 0)
418                 return rv;
419
420         switch (value) {
421         case 0:
422                 if (eeepc->cpufv_disabled)
423                         pr_warn("cpufv enabled (not officially supported on this model)\n");
424                 eeepc->cpufv_disabled = false;
425                 return count;
426         case 1:
427                 return -EPERM;
428         default:
429                 return -EINVAL;
430         }
431 }
432
433
434 static DEVICE_ATTR_RW(cpufv);
435 static DEVICE_ATTR_RO(available_cpufv);
436 static DEVICE_ATTR_RW(cpufv_disabled);
437
438 static struct attribute *platform_attributes[] = {
439         &dev_attr_camera.attr,
440         &dev_attr_cardr.attr,
441         &dev_attr_disp.attr,
442         &dev_attr_cpufv.attr,
443         &dev_attr_available_cpufv.attr,
444         &dev_attr_cpufv_disabled.attr,
445         NULL
446 };
447
448 static const struct attribute_group platform_attribute_group = {
449         .attrs = platform_attributes
450 };
451
452 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
453 {
454         int result;
455
456         eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
457         if (!eeepc->platform_device)
458                 return -ENOMEM;
459         platform_set_drvdata(eeepc->platform_device, eeepc);
460
461         result = platform_device_add(eeepc->platform_device);
462         if (result)
463                 goto fail_platform_device;
464
465         result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
466                                     &platform_attribute_group);
467         if (result)
468                 goto fail_sysfs;
469         return 0;
470
471 fail_sysfs:
472         platform_device_del(eeepc->platform_device);
473 fail_platform_device:
474         platform_device_put(eeepc->platform_device);
475         return result;
476 }
477
478 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
479 {
480         sysfs_remove_group(&eeepc->platform_device->dev.kobj,
481                            &platform_attribute_group);
482         platform_device_unregister(eeepc->platform_device);
483 }
484
485 /*
486  * LEDs
487  */
488 /*
489  * These functions actually update the LED's, and are called from a
490  * workqueue. By doing this as separate work rather than when the LED
491  * subsystem asks, we avoid messing with the Asus ACPI stuff during a
492  * potentially bad time, such as a timer interrupt.
493  */
494 static void tpd_led_update(struct work_struct *work)
495  {
496         struct eeepc_laptop *eeepc;
497
498         eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
499
500         set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
501 }
502
503 static void tpd_led_set(struct led_classdev *led_cdev,
504                         enum led_brightness value)
505 {
506         struct eeepc_laptop *eeepc;
507
508         eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
509
510         eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
511         queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
512 }
513
514 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
515 {
516         struct eeepc_laptop *eeepc;
517
518         eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
519
520         return get_acpi(eeepc, CM_ASL_TPD);
521 }
522
523 static int eeepc_led_init(struct eeepc_laptop *eeepc)
524 {
525         int rv;
526
527         if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
528                 return 0;
529
530         eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
531         if (!eeepc->led_workqueue)
532                 return -ENOMEM;
533         INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
534
535         eeepc->tpd_led.name = "eeepc::touchpad";
536         eeepc->tpd_led.brightness_set = tpd_led_set;
537         if (get_acpi(eeepc, CM_ASL_TPD) >= 0) /* if method is available */
538                 eeepc->tpd_led.brightness_get = tpd_led_get;
539         eeepc->tpd_led.max_brightness = 1;
540
541         rv = led_classdev_register(&eeepc->platform_device->dev,
542                                    &eeepc->tpd_led);
543         if (rv) {
544                 destroy_workqueue(eeepc->led_workqueue);
545                 return rv;
546         }
547
548         return 0;
549 }
550
551 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
552 {
553         if (!IS_ERR_OR_NULL(eeepc->tpd_led.dev))
554                 led_classdev_unregister(&eeepc->tpd_led);
555         if (eeepc->led_workqueue)
556                 destroy_workqueue(eeepc->led_workqueue);
557 }
558
559
560 /*
561  * PCI hotplug (for wlan rfkill)
562  */
563 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
564 {
565         if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
566                 return false;
567         return true;
568 }
569
570 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
571 {
572         struct pci_dev *port;
573         struct pci_dev *dev;
574         struct pci_bus *bus;
575         bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
576         bool absent;
577         u32 l;
578
579         if (eeepc->wlan_rfkill)
580                 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
581
582         mutex_lock(&eeepc->hotplug_lock);
583         pci_lock_rescan_remove();
584
585         if (!eeepc->hotplug_slot)
586                 goto out_unlock;
587
588         port = acpi_get_pci_dev(handle);
589         if (!port) {
590                 pr_warning("Unable to find port\n");
591                 goto out_unlock;
592         }
593
594         bus = port->subordinate;
595
596         if (!bus) {
597                 pr_warn("Unable to find PCI bus 1?\n");
598                 goto out_put_dev;
599         }
600
601         if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
602                 pr_err("Unable to read PCI config space?\n");
603                 goto out_put_dev;
604         }
605
606         absent = (l == 0xffffffff);
607
608         if (blocked != absent) {
609                 pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n",
610                         blocked ? "blocked" : "unblocked",
611                         absent ? "absent" : "present");
612                 pr_warn("skipped wireless hotplug as probably inappropriate for this model\n");
613                 goto out_put_dev;
614         }
615
616         if (!blocked) {
617                 dev = pci_get_slot(bus, 0);
618                 if (dev) {
619                         /* Device already present */
620                         pci_dev_put(dev);
621                         goto out_put_dev;
622                 }
623                 dev = pci_scan_single_device(bus, 0);
624                 if (dev) {
625                         pci_bus_assign_resources(bus);
626                         pci_bus_add_device(dev);
627                 }
628         } else {
629                 dev = pci_get_slot(bus, 0);
630                 if (dev) {
631                         pci_stop_and_remove_bus_device(dev);
632                         pci_dev_put(dev);
633                 }
634         }
635 out_put_dev:
636         pci_dev_put(port);
637
638 out_unlock:
639         pci_unlock_rescan_remove();
640         mutex_unlock(&eeepc->hotplug_lock);
641 }
642
643 static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
644 {
645         acpi_status status = AE_OK;
646         acpi_handle handle;
647
648         status = acpi_get_handle(NULL, node, &handle);
649
650         if (ACPI_SUCCESS(status))
651                 eeepc_rfkill_hotplug(eeepc, handle);
652 }
653
654 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
655 {
656         struct eeepc_laptop *eeepc = data;
657
658         if (event != ACPI_NOTIFY_BUS_CHECK)
659                 return;
660
661         eeepc_rfkill_hotplug(eeepc, handle);
662 }
663
664 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
665                                           char *node)
666 {
667         acpi_status status;
668         acpi_handle handle;
669
670         status = acpi_get_handle(NULL, node, &handle);
671
672         if (ACPI_FAILURE(status))
673                 return -ENODEV;
674
675         status = acpi_install_notify_handler(handle,
676                                              ACPI_SYSTEM_NOTIFY,
677                                              eeepc_rfkill_notify,
678                                              eeepc);
679         if (ACPI_FAILURE(status))
680                 pr_warn("Failed to register notify on %s\n", node);
681
682         /*
683          * Refresh pci hotplug in case the rfkill state was
684          * changed during setup.
685          */
686         eeepc_rfkill_hotplug(eeepc, handle);
687         return 0;
688 }
689
690 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
691                                              char *node)
692 {
693         acpi_status status = AE_OK;
694         acpi_handle handle;
695
696         status = acpi_get_handle(NULL, node, &handle);
697
698         if (ACPI_FAILURE(status))
699                 return;
700
701         status = acpi_remove_notify_handler(handle,
702                                              ACPI_SYSTEM_NOTIFY,
703                                              eeepc_rfkill_notify);
704         if (ACPI_FAILURE(status))
705                 pr_err("Error removing rfkill notify handler %s\n",
706                         node);
707                 /*
708                  * Refresh pci hotplug in case the rfkill
709                  * state was changed after
710                  * eeepc_unregister_rfkill_notifier()
711                  */
712         eeepc_rfkill_hotplug(eeepc, handle);
713 }
714
715 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
716                                     u8 *value)
717 {
718         struct eeepc_laptop *eeepc = hotplug_slot->private;
719         int val = get_acpi(eeepc, CM_ASL_WLAN);
720
721         if (val == 1 || val == 0)
722                 *value = val;
723         else
724                 return -EINVAL;
725
726         return 0;
727 }
728
729 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
730 {
731         kfree(hotplug_slot->info);
732         kfree(hotplug_slot);
733 }
734
735 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
736         .owner = THIS_MODULE,
737         .get_adapter_status = eeepc_get_adapter_status,
738         .get_power_status = eeepc_get_adapter_status,
739 };
740
741 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
742 {
743         int ret = -ENOMEM;
744         struct pci_bus *bus = pci_find_bus(0, 1);
745
746         if (!bus) {
747                 pr_err("Unable to find wifi PCI bus\n");
748                 return -ENODEV;
749         }
750
751         eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
752         if (!eeepc->hotplug_slot)
753                 goto error_slot;
754
755         eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
756                                             GFP_KERNEL);
757         if (!eeepc->hotplug_slot->info)
758                 goto error_info;
759
760         eeepc->hotplug_slot->private = eeepc;
761         eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
762         eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
763         eeepc_get_adapter_status(eeepc->hotplug_slot,
764                                  &eeepc->hotplug_slot->info->adapter_status);
765
766         ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
767         if (ret) {
768                 pr_err("Unable to register hotplug slot - %d\n", ret);
769                 goto error_register;
770         }
771
772         return 0;
773
774 error_register:
775         kfree(eeepc->hotplug_slot->info);
776 error_info:
777         kfree(eeepc->hotplug_slot);
778         eeepc->hotplug_slot = NULL;
779 error_slot:
780         return ret;
781 }
782
783 /*
784  * Rfkill devices
785  */
786 static int eeepc_rfkill_set(void *data, bool blocked)
787 {
788         acpi_handle handle = data;
789
790         return write_acpi_int(handle, NULL, !blocked);
791 }
792
793 static const struct rfkill_ops eeepc_rfkill_ops = {
794         .set_block = eeepc_rfkill_set,
795 };
796
797 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
798                             struct rfkill **rfkill,
799                             const char *name,
800                             enum rfkill_type type, int cm)
801 {
802         acpi_handle handle;
803         int result;
804
805         result = acpi_setter_handle(eeepc, cm, &handle);
806         if (result < 0)
807                 return result;
808
809         *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
810                                &eeepc_rfkill_ops, handle);
811
812         if (!*rfkill)
813                 return -EINVAL;
814
815         rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
816         result = rfkill_register(*rfkill);
817         if (result) {
818                 rfkill_destroy(*rfkill);
819                 *rfkill = NULL;
820                 return result;
821         }
822         return 0;
823 }
824
825 static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5";
826 static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6";
827 static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7";
828
829 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
830 {
831         eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
832         eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
833         eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
834         if (eeepc->wlan_rfkill) {
835                 rfkill_unregister(eeepc->wlan_rfkill);
836                 rfkill_destroy(eeepc->wlan_rfkill);
837                 eeepc->wlan_rfkill = NULL;
838         }
839
840         if (eeepc->hotplug_slot)
841                 pci_hp_deregister(eeepc->hotplug_slot);
842
843         if (eeepc->bluetooth_rfkill) {
844                 rfkill_unregister(eeepc->bluetooth_rfkill);
845                 rfkill_destroy(eeepc->bluetooth_rfkill);
846                 eeepc->bluetooth_rfkill = NULL;
847         }
848         if (eeepc->wwan3g_rfkill) {
849                 rfkill_unregister(eeepc->wwan3g_rfkill);
850                 rfkill_destroy(eeepc->wwan3g_rfkill);
851                 eeepc->wwan3g_rfkill = NULL;
852         }
853         if (eeepc->wimax_rfkill) {
854                 rfkill_unregister(eeepc->wimax_rfkill);
855                 rfkill_destroy(eeepc->wimax_rfkill);
856                 eeepc->wimax_rfkill = NULL;
857         }
858 }
859
860 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
861 {
862         int result = 0;
863
864         mutex_init(&eeepc->hotplug_lock);
865
866         result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
867                                   "eeepc-wlan", RFKILL_TYPE_WLAN,
868                                   CM_ASL_WLAN);
869
870         if (result && result != -ENODEV)
871                 goto exit;
872
873         result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
874                                   "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
875                                   CM_ASL_BLUETOOTH);
876
877         if (result && result != -ENODEV)
878                 goto exit;
879
880         result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
881                                   "eeepc-wwan3g", RFKILL_TYPE_WWAN,
882                                   CM_ASL_3G);
883
884         if (result && result != -ENODEV)
885                 goto exit;
886
887         result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
888                                   "eeepc-wimax", RFKILL_TYPE_WIMAX,
889                                   CM_ASL_WIMAX);
890
891         if (result && result != -ENODEV)
892                 goto exit;
893
894         if (eeepc->hotplug_disabled)
895                 return 0;
896
897         result = eeepc_setup_pci_hotplug(eeepc);
898         /*
899          * If we get -EBUSY then something else is handling the PCI hotplug -
900          * don't fail in this case
901          */
902         if (result == -EBUSY)
903                 result = 0;
904
905         eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
906         eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
907         eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
908
909 exit:
910         if (result && result != -ENODEV)
911                 eeepc_rfkill_exit(eeepc);
912         return result;
913 }
914
915 /*
916  * Platform driver - hibernate/resume callbacks
917  */
918 static int eeepc_hotk_thaw(struct device *device)
919 {
920         struct eeepc_laptop *eeepc = dev_get_drvdata(device);
921
922         if (eeepc->wlan_rfkill) {
923                 int wlan;
924
925                 /*
926                  * Work around bios bug - acpi _PTS turns off the wireless led
927                  * during suspend.  Normally it restores it on resume, but
928                  * we should kick it ourselves in case hibernation is aborted.
929                  */
930                 wlan = get_acpi(eeepc, CM_ASL_WLAN);
931                 if (wlan >= 0)
932                         set_acpi(eeepc, CM_ASL_WLAN, wlan);
933         }
934
935         return 0;
936 }
937
938 static int eeepc_hotk_restore(struct device *device)
939 {
940         struct eeepc_laptop *eeepc = dev_get_drvdata(device);
941
942         /* Refresh both wlan rfkill state and pci hotplug */
943         if (eeepc->wlan_rfkill) {
944                 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1);
945                 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2);
946                 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3);
947         }
948
949         if (eeepc->bluetooth_rfkill)
950                 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
951                                     get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
952         if (eeepc->wwan3g_rfkill)
953                 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
954                                     get_acpi(eeepc, CM_ASL_3G) != 1);
955         if (eeepc->wimax_rfkill)
956                 rfkill_set_sw_state(eeepc->wimax_rfkill,
957                                     get_acpi(eeepc, CM_ASL_WIMAX) != 1);
958
959         return 0;
960 }
961
962 static const struct dev_pm_ops eeepc_pm_ops = {
963         .thaw = eeepc_hotk_thaw,
964         .restore = eeepc_hotk_restore,
965 };
966
967 static struct platform_driver platform_driver = {
968         .driver = {
969                 .name = EEEPC_LAPTOP_FILE,
970                 .pm = &eeepc_pm_ops,
971         }
972 };
973
974 /*
975  * Hwmon device
976  */
977
978 #define EEEPC_EC_SC00      0x61
979 #define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
980 #define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
981 #define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
982
983 #define EEEPC_EC_SFB0      0xD0
984 #define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
985
986 static inline int eeepc_pwm_to_lmsensors(int value)
987 {
988         return value * 255 / 100;
989 }
990
991 static inline int eeepc_lmsensors_to_pwm(int value)
992 {
993         value = clamp_val(value, 0, 255);
994         return value * 100 / 255;
995 }
996
997 static int eeepc_get_fan_pwm(void)
998 {
999         u8 value = 0;
1000
1001         ec_read(EEEPC_EC_FAN_PWM, &value);
1002         return eeepc_pwm_to_lmsensors(value);
1003 }
1004
1005 static void eeepc_set_fan_pwm(int value)
1006 {
1007         value = eeepc_lmsensors_to_pwm(value);
1008         ec_write(EEEPC_EC_FAN_PWM, value);
1009 }
1010
1011 static int eeepc_get_fan_rpm(void)
1012 {
1013         u8 high = 0;
1014         u8 low = 0;
1015
1016         ec_read(EEEPC_EC_FAN_HRPM, &high);
1017         ec_read(EEEPC_EC_FAN_LRPM, &low);
1018         return high << 8 | low;
1019 }
1020
1021 #define EEEPC_EC_FAN_CTRL_BIT   0x02
1022 #define EEEPC_FAN_CTRL_MANUAL   1
1023 #define EEEPC_FAN_CTRL_AUTO     2
1024
1025 static int eeepc_get_fan_ctrl(void)
1026 {
1027         u8 value = 0;
1028
1029         ec_read(EEEPC_EC_FAN_CTRL, &value);
1030         if (value & EEEPC_EC_FAN_CTRL_BIT)
1031                 return EEEPC_FAN_CTRL_MANUAL;
1032         else
1033                 return EEEPC_FAN_CTRL_AUTO;
1034 }
1035
1036 static void eeepc_set_fan_ctrl(int manual)
1037 {
1038         u8 value = 0;
1039
1040         ec_read(EEEPC_EC_FAN_CTRL, &value);
1041         if (manual == EEEPC_FAN_CTRL_MANUAL)
1042                 value |= EEEPC_EC_FAN_CTRL_BIT;
1043         else
1044                 value &= ~EEEPC_EC_FAN_CTRL_BIT;
1045         ec_write(EEEPC_EC_FAN_CTRL, value);
1046 }
1047
1048 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1049 {
1050         int rv, value;
1051
1052         rv = parse_arg(buf, &value);
1053         if (rv < 0)
1054                 return rv;
1055         set(value);
1056         return count;
1057 }
1058
1059 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1060 {
1061         return sprintf(buf, "%d\n", get());
1062 }
1063
1064 #define EEEPC_SENSOR_SHOW_FUNC(_name, _get)                             \
1065         static ssize_t _name##_show(struct device *dev,                 \
1066                                     struct device_attribute *attr,      \
1067                                     char *buf)                          \
1068         {                                                               \
1069                 return show_sys_hwmon(_get, buf);                       \
1070         }
1071
1072 #define EEEPC_SENSOR_STORE_FUNC(_name, _set)                            \
1073         static ssize_t _name##_store(struct device *dev,                \
1074                                      struct device_attribute *attr,     \
1075                                      const char *buf, size_t count)     \
1076         {                                                               \
1077                 return store_sys_hwmon(_set, buf, count);               \
1078         }
1079
1080 #define EEEPC_CREATE_SENSOR_ATTR_RW(_name, _get, _set)                  \
1081         EEEPC_SENSOR_SHOW_FUNC(_name, _get)                             \
1082         EEEPC_SENSOR_STORE_FUNC(_name, _set)                            \
1083         static DEVICE_ATTR_RW(_name)
1084
1085 #define EEEPC_CREATE_SENSOR_ATTR_RO(_name, _get)                        \
1086         EEEPC_SENSOR_SHOW_FUNC(_name, _get)                             \
1087         static DEVICE_ATTR_RO(_name)
1088
1089 EEEPC_CREATE_SENSOR_ATTR_RO(fan1_input, eeepc_get_fan_rpm);
1090 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1, eeepc_get_fan_pwm,
1091                             eeepc_set_fan_pwm);
1092 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1_enable, eeepc_get_fan_ctrl,
1093                             eeepc_set_fan_ctrl);
1094
1095 static struct attribute *hwmon_attrs[] = {
1096         &dev_attr_pwm1.attr,
1097         &dev_attr_fan1_input.attr,
1098         &dev_attr_pwm1_enable.attr,
1099         NULL
1100 };
1101 ATTRIBUTE_GROUPS(hwmon);
1102
1103 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1104 {
1105         struct device *dev = &eeepc->platform_device->dev;
1106         struct device *hwmon;
1107
1108         hwmon = devm_hwmon_device_register_with_groups(dev, "eeepc", NULL,
1109                                                        hwmon_groups);
1110         if (IS_ERR(hwmon)) {
1111                 pr_err("Could not register eeepc hwmon device\n");
1112                 return PTR_ERR(hwmon);
1113         }
1114         return 0;
1115 }
1116
1117 /*
1118  * Backlight device
1119  */
1120 static int read_brightness(struct backlight_device *bd)
1121 {
1122         struct eeepc_laptop *eeepc = bl_get_data(bd);
1123
1124         return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1125 }
1126
1127 static int set_brightness(struct backlight_device *bd, int value)
1128 {
1129         struct eeepc_laptop *eeepc = bl_get_data(bd);
1130
1131         return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1132 }
1133
1134 static int update_bl_status(struct backlight_device *bd)
1135 {
1136         return set_brightness(bd, bd->props.brightness);
1137 }
1138
1139 static const struct backlight_ops eeepcbl_ops = {
1140         .get_brightness = read_brightness,
1141         .update_status = update_bl_status,
1142 };
1143
1144 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1145 {
1146         struct backlight_device *bd = eeepc->backlight_device;
1147         int old = bd->props.brightness;
1148
1149         backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1150
1151         return old;
1152 }
1153
1154 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1155 {
1156         struct backlight_properties props;
1157         struct backlight_device *bd;
1158
1159         memset(&props, 0, sizeof(struct backlight_properties));
1160         props.type = BACKLIGHT_PLATFORM;
1161         props.max_brightness = 15;
1162         bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1163                                        &eeepc->platform_device->dev, eeepc,
1164                                        &eeepcbl_ops, &props);
1165         if (IS_ERR(bd)) {
1166                 pr_err("Could not register eeepc backlight device\n");
1167                 eeepc->backlight_device = NULL;
1168                 return PTR_ERR(bd);
1169         }
1170         eeepc->backlight_device = bd;
1171         bd->props.brightness = read_brightness(bd);
1172         bd->props.power = FB_BLANK_UNBLANK;
1173         backlight_update_status(bd);
1174         return 0;
1175 }
1176
1177 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1178 {
1179         backlight_device_unregister(eeepc->backlight_device);
1180         eeepc->backlight_device = NULL;
1181 }
1182
1183
1184 /*
1185  * Input device (i.e. hotkeys)
1186  */
1187 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1188 {
1189         struct input_dev *input;
1190         int error;
1191
1192         input = input_allocate_device();
1193         if (!input)
1194                 return -ENOMEM;
1195
1196         input->name = "Asus EeePC extra buttons";
1197         input->phys = EEEPC_LAPTOP_FILE "/input0";
1198         input->id.bustype = BUS_HOST;
1199         input->dev.parent = &eeepc->platform_device->dev;
1200
1201         error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1202         if (error) {
1203                 pr_err("Unable to setup input device keymap\n");
1204                 goto err_free_dev;
1205         }
1206
1207         error = input_register_device(input);
1208         if (error) {
1209                 pr_err("Unable to register input device\n");
1210                 goto err_free_dev;
1211         }
1212
1213         eeepc->inputdev = input;
1214         return 0;
1215
1216 err_free_dev:
1217         input_free_device(input);
1218         return error;
1219 }
1220
1221 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1222 {
1223         if (eeepc->inputdev)
1224                 input_unregister_device(eeepc->inputdev);
1225         eeepc->inputdev = NULL;
1226 }
1227
1228 /*
1229  * ACPI driver
1230  */
1231 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1232 {
1233         if (!eeepc->inputdev)
1234                 return;
1235         if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
1236                 pr_info("Unknown key %x pressed\n", event);
1237 }
1238
1239 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1240 {
1241         struct eeepc_laptop *eeepc = acpi_driver_data(device);
1242         int old_brightness, new_brightness;
1243         u16 count;
1244
1245         if (event > ACPI_MAX_SYS_NOTIFY)
1246                 return;
1247         count = eeepc->event_count[event % 128]++;
1248         acpi_bus_generate_netlink_event(device->pnp.device_class,
1249                                         dev_name(&device->dev), event,
1250                                         count);
1251
1252         /* Brightness events are special */
1253         if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) {
1254                 eeepc_input_notify(eeepc, event);
1255                 return;
1256         }
1257
1258         /* Ignore them completely if the acpi video driver is used */
1259         if (!eeepc->backlight_device)
1260                 return;
1261
1262         /* Update the backlight device. */
1263         old_brightness = eeepc_backlight_notify(eeepc);
1264
1265         /* Convert event to keypress (obsolescent hack) */
1266         new_brightness = event - NOTIFY_BRN_MIN;
1267
1268         if (new_brightness < old_brightness) {
1269                 event = NOTIFY_BRN_MIN; /* brightness down */
1270         } else if (new_brightness > old_brightness) {
1271                 event = NOTIFY_BRN_MAX; /* brightness up */
1272         } else {
1273                 /*
1274                  * no change in brightness - already at min/max,
1275                  * event will be desired value (or else ignored)
1276                  */
1277         }
1278         eeepc_input_notify(eeepc, event);
1279 }
1280
1281 static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1282 {
1283         const char *model;
1284
1285         model = dmi_get_system_info(DMI_PRODUCT_NAME);
1286         if (!model)
1287                 return;
1288
1289         /*
1290          * Blacklist for setting cpufv (cpu speed).
1291          *
1292          * EeePC 4G ("701") implements CFVS, but it is not supported
1293          * by the pre-installed OS, and the original option to change it
1294          * in the BIOS setup screen was removed in later versions.
1295          *
1296          * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1297          * this applies to all "701" models (4G/4G Surf/2G Surf).
1298          *
1299          * So Asus made a deliberate decision not to support it on this model.
1300          * We have several reports that using it can cause the system to hang
1301          *
1302          * The hang has also been reported on a "702" (Model name "8G"?).
1303          *
1304          * We avoid dmi_check_system() / dmi_match(), because they use
1305          * substring matching.  We don't want to affect the "701SD"
1306          * and "701SDX" models, because they do support S.H.E.
1307          */
1308         if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1309                 eeepc->cpufv_disabled = true;
1310                 pr_info("model %s does not officially support setting cpu speed\n",
1311                         model);
1312                 pr_info("cpufv disabled to avoid instability\n");
1313         }
1314
1315         /*
1316          * Blacklist for wlan hotplug
1317          *
1318          * Eeepc 1005HA doesn't work like others models and don't need the
1319          * hotplug code. In fact, current hotplug code seems to unplug another
1320          * device...
1321          */
1322         if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1323             strcmp(model, "1005PE") == 0) {
1324                 eeepc->hotplug_disabled = true;
1325                 pr_info("wlan hotplug disabled\n");
1326         }
1327 }
1328
1329 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1330 {
1331         int dummy;
1332
1333         /* Some BIOSes do not report cm although it is available.
1334            Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1335         if (!(eeepc->cm_supported & (1 << cm))
1336             && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1337                 pr_info("%s (%x) not reported by BIOS, enabling anyway\n",
1338                         name, 1 << cm);
1339                 eeepc->cm_supported |= 1 << cm;
1340         }
1341 }
1342
1343 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1344 {
1345         cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1346         cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1347         cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1348         cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1349 }
1350
1351 static int eeepc_acpi_init(struct eeepc_laptop *eeepc)
1352 {
1353         unsigned int init_flags;
1354         int result;
1355
1356         result = acpi_bus_get_status(eeepc->device);
1357         if (result)
1358                 return result;
1359         if (!eeepc->device->status.present) {
1360                 pr_err("Hotkey device not present, aborting\n");
1361                 return -ENODEV;
1362         }
1363
1364         init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1365         pr_notice("Hotkey init flags 0x%x\n", init_flags);
1366
1367         if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1368                 pr_err("Hotkey initialization failed\n");
1369                 return -ENODEV;
1370         }
1371
1372         /* get control methods supported */
1373         if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1374                 pr_err("Get control methods supported failed\n");
1375                 return -ENODEV;
1376         }
1377         cmsg_quirks(eeepc);
1378         pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1379
1380         return 0;
1381 }
1382
1383 static void eeepc_enable_camera(struct eeepc_laptop *eeepc)
1384 {
1385         /*
1386          * If the following call to set_acpi() fails, it's because there's no
1387          * camera so we can ignore the error.
1388          */
1389         if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1390                 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1391 }
1392
1393 static bool eeepc_device_present;
1394
1395 static int eeepc_acpi_add(struct acpi_device *device)
1396 {
1397         struct eeepc_laptop *eeepc;
1398         int result;
1399
1400         pr_notice(EEEPC_LAPTOP_NAME "\n");
1401         eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1402         if (!eeepc)
1403                 return -ENOMEM;
1404         eeepc->handle = device->handle;
1405         strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1406         strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1407         device->driver_data = eeepc;
1408         eeepc->device = device;
1409
1410         eeepc->hotplug_disabled = hotplug_disabled;
1411
1412         eeepc_dmi_check(eeepc);
1413
1414         result = eeepc_acpi_init(eeepc);
1415         if (result)
1416                 goto fail_platform;
1417         eeepc_enable_camera(eeepc);
1418
1419         /*
1420          * Register the platform device first.  It is used as a parent for the
1421          * sub-devices below.
1422          *
1423          * Note that if there are multiple instances of this ACPI device it
1424          * will bail out, because the platform device is registered with a
1425          * fixed name.  Of course it doesn't make sense to have more than one,
1426          * and machine-specific scripts find the fixed name convenient.  But
1427          * It's also good for us to exclude multiple instances because both
1428          * our hwmon and our wlan rfkill subdevice use global ACPI objects
1429          * (the EC and the wlan PCI slot respectively).
1430          */
1431         result = eeepc_platform_init(eeepc);
1432         if (result)
1433                 goto fail_platform;
1434
1435         if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
1436                 result = eeepc_backlight_init(eeepc);
1437                 if (result)
1438                         goto fail_backlight;
1439         }
1440
1441         result = eeepc_input_init(eeepc);
1442         if (result)
1443                 goto fail_input;
1444
1445         result = eeepc_hwmon_init(eeepc);
1446         if (result)
1447                 goto fail_hwmon;
1448
1449         result = eeepc_led_init(eeepc);
1450         if (result)
1451                 goto fail_led;
1452
1453         result = eeepc_rfkill_init(eeepc);
1454         if (result)
1455                 goto fail_rfkill;
1456
1457         eeepc_device_present = true;
1458         return 0;
1459
1460 fail_rfkill:
1461         eeepc_led_exit(eeepc);
1462 fail_led:
1463 fail_hwmon:
1464         eeepc_input_exit(eeepc);
1465 fail_input:
1466         eeepc_backlight_exit(eeepc);
1467 fail_backlight:
1468         eeepc_platform_exit(eeepc);
1469 fail_platform:
1470         kfree(eeepc);
1471
1472         return result;
1473 }
1474
1475 static int eeepc_acpi_remove(struct acpi_device *device)
1476 {
1477         struct eeepc_laptop *eeepc = acpi_driver_data(device);
1478
1479         eeepc_backlight_exit(eeepc);
1480         eeepc_rfkill_exit(eeepc);
1481         eeepc_input_exit(eeepc);
1482         eeepc_led_exit(eeepc);
1483         eeepc_platform_exit(eeepc);
1484
1485         kfree(eeepc);
1486         return 0;
1487 }
1488
1489
1490 static const struct acpi_device_id eeepc_device_ids[] = {
1491         {EEEPC_ACPI_HID, 0},
1492         {"", 0},
1493 };
1494 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1495
1496 static struct acpi_driver eeepc_acpi_driver = {
1497         .name = EEEPC_LAPTOP_NAME,
1498         .class = EEEPC_ACPI_CLASS,
1499         .owner = THIS_MODULE,
1500         .ids = eeepc_device_ids,
1501         .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1502         .ops = {
1503                 .add = eeepc_acpi_add,
1504                 .remove = eeepc_acpi_remove,
1505                 .notify = eeepc_acpi_notify,
1506         },
1507 };
1508
1509
1510 static int __init eeepc_laptop_init(void)
1511 {
1512         int result;
1513
1514         result = platform_driver_register(&platform_driver);
1515         if (result < 0)
1516                 return result;
1517
1518         result = acpi_bus_register_driver(&eeepc_acpi_driver);
1519         if (result < 0)
1520                 goto fail_acpi_driver;
1521
1522         if (!eeepc_device_present) {
1523                 result = -ENODEV;
1524                 goto fail_no_device;
1525         }
1526
1527         return 0;
1528
1529 fail_no_device:
1530         acpi_bus_unregister_driver(&eeepc_acpi_driver);
1531 fail_acpi_driver:
1532         platform_driver_unregister(&platform_driver);
1533         return result;
1534 }
1535
1536 static void __exit eeepc_laptop_exit(void)
1537 {
1538         acpi_bus_unregister_driver(&eeepc_acpi_driver);
1539         platform_driver_unregister(&platform_driver);
1540 }
1541
1542 module_init(eeepc_laptop_init);
1543 module_exit(eeepc_laptop_exit);