]> Pileus Git - ~andy/linux/blob - drivers/platform/x86/eeepc-laptop.c
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~andy/linux] / 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         pci_lock_rescan_remove();
596
597         if (eeepc->hotplug_slot) {
598                 port = acpi_get_pci_dev(handle);
599                 if (!port) {
600                         pr_warning("Unable to find port\n");
601                         goto out_unlock;
602                 }
603
604                 bus = port->subordinate;
605
606                 if (!bus) {
607                         pr_warn("Unable to find PCI bus 1?\n");
608                         goto out_put_dev;
609                 }
610
611                 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
612                         pr_err("Unable to read PCI config space?\n");
613                         goto out_put_dev;
614                 }
615
616                 absent = (l == 0xffffffff);
617
618                 if (blocked != absent) {
619                         pr_warn("BIOS says wireless lan is %s, "
620                                 "but the pci device is %s\n",
621                                 blocked ? "blocked" : "unblocked",
622                                 absent ? "absent" : "present");
623                         pr_warn("skipped wireless hotplug as probably "
624                                 "inappropriate for this model\n");
625                         goto out_put_dev;
626                 }
627
628                 if (!blocked) {
629                         dev = pci_get_slot(bus, 0);
630                         if (dev) {
631                                 /* Device already present */
632                                 pci_dev_put(dev);
633                                 goto out_put_dev;
634                         }
635                         dev = pci_scan_single_device(bus, 0);
636                         if (dev) {
637                                 pci_bus_assign_resources(bus);
638                                 if (pci_bus_add_device(dev))
639                                         pr_err("Unable to hotplug wifi\n");
640                         }
641                 } else {
642                         dev = pci_get_slot(bus, 0);
643                         if (dev) {
644                                 pci_stop_and_remove_bus_device(dev);
645                                 pci_dev_put(dev);
646                         }
647                 }
648 out_put_dev:
649                 pci_dev_put(port);
650         }
651
652 out_unlock:
653         pci_unlock_rescan_remove();
654         mutex_unlock(&eeepc->hotplug_lock);
655 }
656
657 static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
658 {
659         acpi_status status = AE_OK;
660         acpi_handle handle;
661
662         status = acpi_get_handle(NULL, node, &handle);
663
664         if (ACPI_SUCCESS(status))
665                 eeepc_rfkill_hotplug(eeepc, handle);
666 }
667
668 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
669 {
670         struct eeepc_laptop *eeepc = data;
671
672         if (event != ACPI_NOTIFY_BUS_CHECK)
673                 return;
674
675         eeepc_rfkill_hotplug(eeepc, handle);
676 }
677
678 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
679                                           char *node)
680 {
681         acpi_status status;
682         acpi_handle handle;
683
684         status = acpi_get_handle(NULL, node, &handle);
685
686         if (ACPI_SUCCESS(status)) {
687                 status = acpi_install_notify_handler(handle,
688                                                      ACPI_SYSTEM_NOTIFY,
689                                                      eeepc_rfkill_notify,
690                                                      eeepc);
691                 if (ACPI_FAILURE(status))
692                         pr_warn("Failed to register notify on %s\n", node);
693
694                 /*
695                  * Refresh pci hotplug in case the rfkill state was
696                  * changed during setup.
697                  */
698                 eeepc_rfkill_hotplug(eeepc, handle);
699         } else
700                 return -ENODEV;
701
702         return 0;
703 }
704
705 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
706                                              char *node)
707 {
708         acpi_status status = AE_OK;
709         acpi_handle handle;
710
711         status = acpi_get_handle(NULL, node, &handle);
712
713         if (ACPI_SUCCESS(status)) {
714                 status = acpi_remove_notify_handler(handle,
715                                                      ACPI_SYSTEM_NOTIFY,
716                                                      eeepc_rfkill_notify);
717                 if (ACPI_FAILURE(status))
718                         pr_err("Error removing rfkill notify handler %s\n",
719                                 node);
720                         /*
721                          * Refresh pci hotplug in case the rfkill
722                          * state was changed after
723                          * eeepc_unregister_rfkill_notifier()
724                          */
725                 eeepc_rfkill_hotplug(eeepc, handle);
726         }
727 }
728
729 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
730                                     u8 *value)
731 {
732         struct eeepc_laptop *eeepc = hotplug_slot->private;
733         int val = get_acpi(eeepc, CM_ASL_WLAN);
734
735         if (val == 1 || val == 0)
736                 *value = val;
737         else
738                 return -EINVAL;
739
740         return 0;
741 }
742
743 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
744 {
745         kfree(hotplug_slot->info);
746         kfree(hotplug_slot);
747 }
748
749 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
750         .owner = THIS_MODULE,
751         .get_adapter_status = eeepc_get_adapter_status,
752         .get_power_status = eeepc_get_adapter_status,
753 };
754
755 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
756 {
757         int ret = -ENOMEM;
758         struct pci_bus *bus = pci_find_bus(0, 1);
759
760         if (!bus) {
761                 pr_err("Unable to find wifi PCI bus\n");
762                 return -ENODEV;
763         }
764
765         eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
766         if (!eeepc->hotplug_slot)
767                 goto error_slot;
768
769         eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
770                                             GFP_KERNEL);
771         if (!eeepc->hotplug_slot->info)
772                 goto error_info;
773
774         eeepc->hotplug_slot->private = eeepc;
775         eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
776         eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
777         eeepc_get_adapter_status(eeepc->hotplug_slot,
778                                  &eeepc->hotplug_slot->info->adapter_status);
779
780         ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
781         if (ret) {
782                 pr_err("Unable to register hotplug slot - %d\n", ret);
783                 goto error_register;
784         }
785
786         return 0;
787
788 error_register:
789         kfree(eeepc->hotplug_slot->info);
790 error_info:
791         kfree(eeepc->hotplug_slot);
792         eeepc->hotplug_slot = NULL;
793 error_slot:
794         return ret;
795 }
796
797 /*
798  * Rfkill devices
799  */
800 static int eeepc_rfkill_set(void *data, bool blocked)
801 {
802         acpi_handle handle = data;
803
804         return write_acpi_int(handle, NULL, !blocked);
805 }
806
807 static const struct rfkill_ops eeepc_rfkill_ops = {
808         .set_block = eeepc_rfkill_set,
809 };
810
811 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
812                             struct rfkill **rfkill,
813                             const char *name,
814                             enum rfkill_type type, int cm)
815 {
816         acpi_handle handle;
817         int result;
818
819         result = acpi_setter_handle(eeepc, cm, &handle);
820         if (result < 0)
821                 return result;
822
823         *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
824                                &eeepc_rfkill_ops, handle);
825
826         if (!*rfkill)
827                 return -EINVAL;
828
829         rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
830         result = rfkill_register(*rfkill);
831         if (result) {
832                 rfkill_destroy(*rfkill);
833                 *rfkill = NULL;
834                 return result;
835         }
836         return 0;
837 }
838
839 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
840 {
841         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
842         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
843         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
844         if (eeepc->wlan_rfkill) {
845                 rfkill_unregister(eeepc->wlan_rfkill);
846                 rfkill_destroy(eeepc->wlan_rfkill);
847                 eeepc->wlan_rfkill = NULL;
848         }
849
850         if (eeepc->hotplug_slot)
851                 pci_hp_deregister(eeepc->hotplug_slot);
852
853         if (eeepc->bluetooth_rfkill) {
854                 rfkill_unregister(eeepc->bluetooth_rfkill);
855                 rfkill_destroy(eeepc->bluetooth_rfkill);
856                 eeepc->bluetooth_rfkill = NULL;
857         }
858         if (eeepc->wwan3g_rfkill) {
859                 rfkill_unregister(eeepc->wwan3g_rfkill);
860                 rfkill_destroy(eeepc->wwan3g_rfkill);
861                 eeepc->wwan3g_rfkill = NULL;
862         }
863         if (eeepc->wimax_rfkill) {
864                 rfkill_unregister(eeepc->wimax_rfkill);
865                 rfkill_destroy(eeepc->wimax_rfkill);
866                 eeepc->wimax_rfkill = NULL;
867         }
868 }
869
870 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
871 {
872         int result = 0;
873
874         mutex_init(&eeepc->hotplug_lock);
875
876         result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
877                                   "eeepc-wlan", RFKILL_TYPE_WLAN,
878                                   CM_ASL_WLAN);
879
880         if (result && result != -ENODEV)
881                 goto exit;
882
883         result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
884                                   "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
885                                   CM_ASL_BLUETOOTH);
886
887         if (result && result != -ENODEV)
888                 goto exit;
889
890         result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
891                                   "eeepc-wwan3g", RFKILL_TYPE_WWAN,
892                                   CM_ASL_3G);
893
894         if (result && result != -ENODEV)
895                 goto exit;
896
897         result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
898                                   "eeepc-wimax", RFKILL_TYPE_WIMAX,
899                                   CM_ASL_WIMAX);
900
901         if (result && result != -ENODEV)
902                 goto exit;
903
904         if (eeepc->hotplug_disabled)
905                 return 0;
906
907         result = eeepc_setup_pci_hotplug(eeepc);
908         /*
909          * If we get -EBUSY then something else is handling the PCI hotplug -
910          * don't fail in this case
911          */
912         if (result == -EBUSY)
913                 result = 0;
914
915         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
916         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
917         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
918
919 exit:
920         if (result && result != -ENODEV)
921                 eeepc_rfkill_exit(eeepc);
922         return result;
923 }
924
925 /*
926  * Platform driver - hibernate/resume callbacks
927  */
928 static int eeepc_hotk_thaw(struct device *device)
929 {
930         struct eeepc_laptop *eeepc = dev_get_drvdata(device);
931
932         if (eeepc->wlan_rfkill) {
933                 bool wlan;
934
935                 /*
936                  * Work around bios bug - acpi _PTS turns off the wireless led
937                  * during suspend.  Normally it restores it on resume, but
938                  * we should kick it ourselves in case hibernation is aborted.
939                  */
940                 wlan = get_acpi(eeepc, CM_ASL_WLAN);
941                 set_acpi(eeepc, CM_ASL_WLAN, wlan);
942         }
943
944         return 0;
945 }
946
947 static int eeepc_hotk_restore(struct device *device)
948 {
949         struct eeepc_laptop *eeepc = dev_get_drvdata(device);
950
951         /* Refresh both wlan rfkill state and pci hotplug */
952         if (eeepc->wlan_rfkill) {
953                 eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5");
954                 eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6");
955                 eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7");
956         }
957
958         if (eeepc->bluetooth_rfkill)
959                 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
960                                     get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
961         if (eeepc->wwan3g_rfkill)
962                 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
963                                     get_acpi(eeepc, CM_ASL_3G) != 1);
964         if (eeepc->wimax_rfkill)
965                 rfkill_set_sw_state(eeepc->wimax_rfkill,
966                                     get_acpi(eeepc, CM_ASL_WIMAX) != 1);
967
968         return 0;
969 }
970
971 static const struct dev_pm_ops eeepc_pm_ops = {
972         .thaw = eeepc_hotk_thaw,
973         .restore = eeepc_hotk_restore,
974 };
975
976 static struct platform_driver platform_driver = {
977         .driver = {
978                 .name = EEEPC_LAPTOP_FILE,
979                 .owner = THIS_MODULE,
980                 .pm = &eeepc_pm_ops,
981         }
982 };
983
984 /*
985  * Hwmon device
986  */
987
988 #define EEEPC_EC_SC00      0x61
989 #define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
990 #define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
991 #define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
992
993 #define EEEPC_EC_SFB0      0xD0
994 #define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
995
996 static int eeepc_get_fan_pwm(void)
997 {
998         u8 value = 0;
999
1000         ec_read(EEEPC_EC_FAN_PWM, &value);
1001         return value * 255 / 100;
1002 }
1003
1004 static void eeepc_set_fan_pwm(int value)
1005 {
1006         value = clamp_val(value, 0, 255);
1007         value = value * 100 / 255;
1008         ec_write(EEEPC_EC_FAN_PWM, value);
1009 }
1010
1011 static int eeepc_get_fan_rpm(void)
1012 {
1013         u8 high = 0;
1014         u8 low = 0;
1015
1016         ec_read(EEEPC_EC_FAN_HRPM, &high);
1017         ec_read(EEEPC_EC_FAN_LRPM, &low);
1018         return high << 8 | low;
1019 }
1020
1021 static int eeepc_get_fan_ctrl(void)
1022 {
1023         u8 value = 0;
1024
1025         ec_read(EEEPC_EC_FAN_CTRL, &value);
1026         if (value & 0x02)
1027                 return 1; /* manual */
1028         else
1029                 return 2; /* automatic */
1030 }
1031
1032 static void eeepc_set_fan_ctrl(int manual)
1033 {
1034         u8 value = 0;
1035
1036         ec_read(EEEPC_EC_FAN_CTRL, &value);
1037         if (manual == 1)
1038                 value |= 0x02;
1039         else
1040                 value &= ~0x02;
1041         ec_write(EEEPC_EC_FAN_CTRL, value);
1042 }
1043
1044 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1045 {
1046         int rv, value;
1047
1048         rv = parse_arg(buf, count, &value);
1049         if (rv > 0)
1050                 set(value);
1051         return rv;
1052 }
1053
1054 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1055 {
1056         return sprintf(buf, "%d\n", get());
1057 }
1058
1059 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)              \
1060         static ssize_t show_##_name(struct device *dev,                 \
1061                                     struct device_attribute *attr,      \
1062                                     char *buf)                          \
1063         {                                                               \
1064                 return show_sys_hwmon(_set, buf);                       \
1065         }                                                               \
1066         static ssize_t store_##_name(struct device *dev,                \
1067                                      struct device_attribute *attr,     \
1068                                      const char *buf, size_t count)     \
1069         {                                                               \
1070                 return store_sys_hwmon(_get, buf, count);               \
1071         }                                                               \
1072         static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
1073
1074 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
1075 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
1076                          eeepc_get_fan_pwm, eeepc_set_fan_pwm);
1077 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
1078                          eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
1079
1080 static ssize_t
1081 show_name(struct device *dev, struct device_attribute *attr, char *buf)
1082 {
1083         return sprintf(buf, "eeepc\n");
1084 }
1085 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
1086
1087 static struct attribute *hwmon_attributes[] = {
1088         &sensor_dev_attr_pwm1.dev_attr.attr,
1089         &sensor_dev_attr_fan1_input.dev_attr.attr,
1090         &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1091         &sensor_dev_attr_name.dev_attr.attr,
1092         NULL
1093 };
1094
1095 static struct attribute_group hwmon_attribute_group = {
1096         .attrs = hwmon_attributes
1097 };
1098
1099 static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
1100 {
1101         struct device *hwmon;
1102
1103         hwmon = eeepc->hwmon_device;
1104         if (!hwmon)
1105                 return;
1106         sysfs_remove_group(&hwmon->kobj,
1107                            &hwmon_attribute_group);
1108         hwmon_device_unregister(hwmon);
1109         eeepc->hwmon_device = NULL;
1110 }
1111
1112 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1113 {
1114         struct device *hwmon;
1115         int result;
1116
1117         hwmon = hwmon_device_register(&eeepc->platform_device->dev);
1118         if (IS_ERR(hwmon)) {
1119                 pr_err("Could not register eeepc hwmon device\n");
1120                 eeepc->hwmon_device = NULL;
1121                 return PTR_ERR(hwmon);
1122         }
1123         eeepc->hwmon_device = hwmon;
1124         result = sysfs_create_group(&hwmon->kobj,
1125                                     &hwmon_attribute_group);
1126         if (result)
1127                 eeepc_hwmon_exit(eeepc);
1128         return result;
1129 }
1130
1131 /*
1132  * Backlight device
1133  */
1134 static int read_brightness(struct backlight_device *bd)
1135 {
1136         struct eeepc_laptop *eeepc = bl_get_data(bd);
1137
1138         return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1139 }
1140
1141 static int set_brightness(struct backlight_device *bd, int value)
1142 {
1143         struct eeepc_laptop *eeepc = bl_get_data(bd);
1144
1145         return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1146 }
1147
1148 static int update_bl_status(struct backlight_device *bd)
1149 {
1150         return set_brightness(bd, bd->props.brightness);
1151 }
1152
1153 static const struct backlight_ops eeepcbl_ops = {
1154         .get_brightness = read_brightness,
1155         .update_status = update_bl_status,
1156 };
1157
1158 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1159 {
1160         struct backlight_device *bd = eeepc->backlight_device;
1161         int old = bd->props.brightness;
1162
1163         backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1164
1165         return old;
1166 }
1167
1168 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1169 {
1170         struct backlight_properties props;
1171         struct backlight_device *bd;
1172
1173         memset(&props, 0, sizeof(struct backlight_properties));
1174         props.type = BACKLIGHT_PLATFORM;
1175         props.max_brightness = 15;
1176         bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1177                                        &eeepc->platform_device->dev, eeepc,
1178                                        &eeepcbl_ops, &props);
1179         if (IS_ERR(bd)) {
1180                 pr_err("Could not register eeepc backlight device\n");
1181                 eeepc->backlight_device = NULL;
1182                 return PTR_ERR(bd);
1183         }
1184         eeepc->backlight_device = bd;
1185         bd->props.brightness = read_brightness(bd);
1186         bd->props.power = FB_BLANK_UNBLANK;
1187         backlight_update_status(bd);
1188         return 0;
1189 }
1190
1191 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1192 {
1193         if (eeepc->backlight_device)
1194                 backlight_device_unregister(eeepc->backlight_device);
1195         eeepc->backlight_device = NULL;
1196 }
1197
1198
1199 /*
1200  * Input device (i.e. hotkeys)
1201  */
1202 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1203 {
1204         struct input_dev *input;
1205         int error;
1206
1207         input = input_allocate_device();
1208         if (!input)
1209                 return -ENOMEM;
1210
1211         input->name = "Asus EeePC extra buttons";
1212         input->phys = EEEPC_LAPTOP_FILE "/input0";
1213         input->id.bustype = BUS_HOST;
1214         input->dev.parent = &eeepc->platform_device->dev;
1215
1216         error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1217         if (error) {
1218                 pr_err("Unable to setup input device keymap\n");
1219                 goto err_free_dev;
1220         }
1221
1222         error = input_register_device(input);
1223         if (error) {
1224                 pr_err("Unable to register input device\n");
1225                 goto err_free_keymap;
1226         }
1227
1228         eeepc->inputdev = input;
1229         return 0;
1230
1231 err_free_keymap:
1232         sparse_keymap_free(input);
1233 err_free_dev:
1234         input_free_device(input);
1235         return error;
1236 }
1237
1238 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1239 {
1240         if (eeepc->inputdev) {
1241                 sparse_keymap_free(eeepc->inputdev);
1242                 input_unregister_device(eeepc->inputdev);
1243         }
1244         eeepc->inputdev = NULL;
1245 }
1246
1247 /*
1248  * ACPI driver
1249  */
1250 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1251 {
1252         if (!eeepc->inputdev)
1253                 return ;
1254         if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
1255                 pr_info("Unknown key %x pressed\n", event);
1256 }
1257
1258 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1259 {
1260         struct eeepc_laptop *eeepc = acpi_driver_data(device);
1261         u16 count;
1262
1263         if (event > ACPI_MAX_SYS_NOTIFY)
1264                 return;
1265         count = eeepc->event_count[event % 128]++;
1266         acpi_bus_generate_netlink_event(device->pnp.device_class,
1267                                         dev_name(&device->dev), event,
1268                                         count);
1269
1270         /* Brightness events are special */
1271         if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
1272
1273                 /* Ignore them completely if the acpi video driver is used */
1274                 if (eeepc->backlight_device != NULL) {
1275                         int old_brightness, new_brightness;
1276
1277                         /* Update the backlight device. */
1278                         old_brightness = eeepc_backlight_notify(eeepc);
1279
1280                         /* Convert event to keypress (obsolescent hack) */
1281                         new_brightness = event - NOTIFY_BRN_MIN;
1282
1283                         if (new_brightness < old_brightness) {
1284                                 event = NOTIFY_BRN_MIN; /* brightness down */
1285                         } else if (new_brightness > old_brightness) {
1286                                 event = NOTIFY_BRN_MAX; /* brightness up */
1287                         } else {
1288                                 /*
1289                                 * no change in brightness - already at min/max,
1290                                 * event will be desired value (or else ignored)
1291                                 */
1292                         }
1293                         eeepc_input_notify(eeepc, event);
1294                 }
1295         } else {
1296                 /* Everything else is a bona-fide keypress event */
1297                 eeepc_input_notify(eeepc, event);
1298         }
1299 }
1300
1301 static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1302 {
1303         const char *model;
1304
1305         model = dmi_get_system_info(DMI_PRODUCT_NAME);
1306         if (!model)
1307                 return;
1308
1309         /*
1310          * Blacklist for setting cpufv (cpu speed).
1311          *
1312          * EeePC 4G ("701") implements CFVS, but it is not supported
1313          * by the pre-installed OS, and the original option to change it
1314          * in the BIOS setup screen was removed in later versions.
1315          *
1316          * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1317          * this applies to all "701" models (4G/4G Surf/2G Surf).
1318          *
1319          * So Asus made a deliberate decision not to support it on this model.
1320          * We have several reports that using it can cause the system to hang
1321          *
1322          * The hang has also been reported on a "702" (Model name "8G"?).
1323          *
1324          * We avoid dmi_check_system() / dmi_match(), because they use
1325          * substring matching.  We don't want to affect the "701SD"
1326          * and "701SDX" models, because they do support S.H.E.
1327          */
1328         if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1329                 eeepc->cpufv_disabled = true;
1330                 pr_info("model %s does not officially support setting cpu "
1331                         "speed\n", model);
1332                 pr_info("cpufv disabled to avoid instability\n");
1333         }
1334
1335         /*
1336          * Blacklist for wlan hotplug
1337          *
1338          * Eeepc 1005HA doesn't work like others models and don't need the
1339          * hotplug code. In fact, current hotplug code seems to unplug another
1340          * device...
1341          */
1342         if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1343             strcmp(model, "1005PE") == 0) {
1344                 eeepc->hotplug_disabled = true;
1345                 pr_info("wlan hotplug disabled\n");
1346         }
1347 }
1348
1349 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1350 {
1351         int dummy;
1352
1353         /* Some BIOSes do not report cm although it is available.
1354            Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1355         if (!(eeepc->cm_supported & (1 << cm))
1356             && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1357                 pr_info("%s (%x) not reported by BIOS,"
1358                         " enabling anyway\n", name, 1 << cm);
1359                 eeepc->cm_supported |= 1 << cm;
1360         }
1361 }
1362
1363 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1364 {
1365         cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1366         cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1367         cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1368         cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1369 }
1370
1371 static int eeepc_acpi_init(struct eeepc_laptop *eeepc)
1372 {
1373         unsigned int init_flags;
1374         int result;
1375
1376         result = acpi_bus_get_status(eeepc->device);
1377         if (result)
1378                 return result;
1379         if (!eeepc->device->status.present) {
1380                 pr_err("Hotkey device not present, aborting\n");
1381                 return -ENODEV;
1382         }
1383
1384         init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1385         pr_notice("Hotkey init flags 0x%x\n", init_flags);
1386
1387         if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1388                 pr_err("Hotkey initialization failed\n");
1389                 return -ENODEV;
1390         }
1391
1392         /* get control methods supported */
1393         if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1394                 pr_err("Get control methods supported failed\n");
1395                 return -ENODEV;
1396         }
1397         cmsg_quirks(eeepc);
1398         pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1399
1400         return 0;
1401 }
1402
1403 static void eeepc_enable_camera(struct eeepc_laptop *eeepc)
1404 {
1405         /*
1406          * If the following call to set_acpi() fails, it's because there's no
1407          * camera so we can ignore the error.
1408          */
1409         if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1410                 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1411 }
1412
1413 static bool eeepc_device_present;
1414
1415 static int eeepc_acpi_add(struct acpi_device *device)
1416 {
1417         struct eeepc_laptop *eeepc;
1418         int result;
1419
1420         pr_notice(EEEPC_LAPTOP_NAME "\n");
1421         eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1422         if (!eeepc)
1423                 return -ENOMEM;
1424         eeepc->handle = device->handle;
1425         strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1426         strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1427         device->driver_data = eeepc;
1428         eeepc->device = device;
1429
1430         eeepc->hotplug_disabled = hotplug_disabled;
1431
1432         eeepc_dmi_check(eeepc);
1433
1434         result = eeepc_acpi_init(eeepc);
1435         if (result)
1436                 goto fail_platform;
1437         eeepc_enable_camera(eeepc);
1438
1439         /*
1440          * Register the platform device first.  It is used as a parent for the
1441          * sub-devices below.
1442          *
1443          * Note that if there are multiple instances of this ACPI device it
1444          * will bail out, because the platform device is registered with a
1445          * fixed name.  Of course it doesn't make sense to have more than one,
1446          * and machine-specific scripts find the fixed name convenient.  But
1447          * It's also good for us to exclude multiple instances because both
1448          * our hwmon and our wlan rfkill subdevice use global ACPI objects
1449          * (the EC and the wlan PCI slot respectively).
1450          */
1451         result = eeepc_platform_init(eeepc);
1452         if (result)
1453                 goto fail_platform;
1454
1455         if (!acpi_video_backlight_support()) {
1456                 result = eeepc_backlight_init(eeepc);
1457                 if (result)
1458                         goto fail_backlight;
1459         } else
1460                 pr_info("Backlight controlled by ACPI video driver\n");
1461
1462         result = eeepc_input_init(eeepc);
1463         if (result)
1464                 goto fail_input;
1465
1466         result = eeepc_hwmon_init(eeepc);
1467         if (result)
1468                 goto fail_hwmon;
1469
1470         result = eeepc_led_init(eeepc);
1471         if (result)
1472                 goto fail_led;
1473
1474         result = eeepc_rfkill_init(eeepc);
1475         if (result)
1476                 goto fail_rfkill;
1477
1478         eeepc_device_present = true;
1479         return 0;
1480
1481 fail_rfkill:
1482         eeepc_led_exit(eeepc);
1483 fail_led:
1484         eeepc_hwmon_exit(eeepc);
1485 fail_hwmon:
1486         eeepc_input_exit(eeepc);
1487 fail_input:
1488         eeepc_backlight_exit(eeepc);
1489 fail_backlight:
1490         eeepc_platform_exit(eeepc);
1491 fail_platform:
1492         kfree(eeepc);
1493
1494         return result;
1495 }
1496
1497 static int eeepc_acpi_remove(struct acpi_device *device)
1498 {
1499         struct eeepc_laptop *eeepc = acpi_driver_data(device);
1500
1501         eeepc_backlight_exit(eeepc);
1502         eeepc_rfkill_exit(eeepc);
1503         eeepc_input_exit(eeepc);
1504         eeepc_hwmon_exit(eeepc);
1505         eeepc_led_exit(eeepc);
1506         eeepc_platform_exit(eeepc);
1507
1508         kfree(eeepc);
1509         return 0;
1510 }
1511
1512
1513 static const struct acpi_device_id eeepc_device_ids[] = {
1514         {EEEPC_ACPI_HID, 0},
1515         {"", 0},
1516 };
1517 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1518
1519 static struct acpi_driver eeepc_acpi_driver = {
1520         .name = EEEPC_LAPTOP_NAME,
1521         .class = EEEPC_ACPI_CLASS,
1522         .owner = THIS_MODULE,
1523         .ids = eeepc_device_ids,
1524         .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1525         .ops = {
1526                 .add = eeepc_acpi_add,
1527                 .remove = eeepc_acpi_remove,
1528                 .notify = eeepc_acpi_notify,
1529         },
1530 };
1531
1532
1533 static int __init eeepc_laptop_init(void)
1534 {
1535         int result;
1536
1537         result = platform_driver_register(&platform_driver);
1538         if (result < 0)
1539                 return result;
1540
1541         result = acpi_bus_register_driver(&eeepc_acpi_driver);
1542         if (result < 0)
1543                 goto fail_acpi_driver;
1544
1545         if (!eeepc_device_present) {
1546                 result = -ENODEV;
1547                 goto fail_no_device;
1548         }
1549
1550         return 0;
1551
1552 fail_no_device:
1553         acpi_bus_unregister_driver(&eeepc_acpi_driver);
1554 fail_acpi_driver:
1555         platform_driver_unregister(&platform_driver);
1556         return result;
1557 }
1558
1559 static void __exit eeepc_laptop_exit(void)
1560 {
1561         acpi_bus_unregister_driver(&eeepc_acpi_driver);
1562         platform_driver_unregister(&platform_driver);
1563 }
1564
1565 module_init(eeepc_laptop_init);
1566 module_exit(eeepc_laptop_exit);