Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/platform/x86/eeepc-laptop.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us