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