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