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