Version:  2.0.40 2.2.26 2.4.37 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2

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

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