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