eeepc-laptop: makes get_acpi() returns -ENODEV
[safe/jmp/linux-2.6] / drivers / platform / x86 / eeepc-laptop.c
1 /*
2  *  eepc-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 <acpi/acpi_drivers.h>
31 #include <acpi/acpi_bus.h>
32 #include <linux/uaccess.h>
33 #include <linux/input.h>
34 #include <linux/rfkill.h>
35 #include <linux/pci.h>
36 #include <linux/pci_hotplug.h>
37
38 #define EEEPC_LAPTOP_VERSION    "0.1"
39
40 #define EEEPC_HOTK_NAME         "Eee PC Hotkey Driver"
41 #define EEEPC_HOTK_FILE         "eeepc"
42 #define EEEPC_HOTK_CLASS        "hotkey"
43 #define EEEPC_HOTK_DEVICE_NAME  "Hotkey"
44 #define EEEPC_HOTK_HID          "ASUS010"
45
46
47 /*
48  * Definitions for Asus EeePC
49  */
50 #define NOTIFY_WLAN_ON  0x10
51 #define NOTIFY_BRN_MIN  0x20
52 #define NOTIFY_BRN_MAX  0x2f
53
54 enum {
55         DISABLE_ASL_WLAN = 0x0001,
56         DISABLE_ASL_BLUETOOTH = 0x0002,
57         DISABLE_ASL_IRDA = 0x0004,
58         DISABLE_ASL_CAMERA = 0x0008,
59         DISABLE_ASL_TV = 0x0010,
60         DISABLE_ASL_GPS = 0x0020,
61         DISABLE_ASL_DISPLAYSWITCH = 0x0040,
62         DISABLE_ASL_MODEM = 0x0080,
63         DISABLE_ASL_CARDREADER = 0x0100,
64         DISABLE_ASL_3G = 0x0200,
65         DISABLE_ASL_WIMAX = 0x0400,
66         DISABLE_ASL_HWCF = 0x0800
67 };
68
69 enum {
70         CM_ASL_WLAN = 0,
71         CM_ASL_BLUETOOTH,
72         CM_ASL_IRDA,
73         CM_ASL_1394,
74         CM_ASL_CAMERA,
75         CM_ASL_TV,
76         CM_ASL_GPS,
77         CM_ASL_DVDROM,
78         CM_ASL_DISPLAYSWITCH,
79         CM_ASL_PANELBRIGHT,
80         CM_ASL_BIOSFLASH,
81         CM_ASL_ACPIFLASH,
82         CM_ASL_CPUFV,
83         CM_ASL_CPUTEMPERATURE,
84         CM_ASL_FANCPU,
85         CM_ASL_FANCHASSIS,
86         CM_ASL_USBPORT1,
87         CM_ASL_USBPORT2,
88         CM_ASL_USBPORT3,
89         CM_ASL_MODEM,
90         CM_ASL_CARDREADER,
91         CM_ASL_3G,
92         CM_ASL_WIMAX,
93         CM_ASL_HWCF,
94         CM_ASL_LID,
95         CM_ASL_TYPE,
96         CM_ASL_PANELPOWER,      /*P901*/
97         CM_ASL_TPD
98 };
99
100 static const char *cm_getv[] = {
101         "WLDG", "BTHG", NULL, NULL,
102         "CAMG", NULL, NULL, NULL,
103         NULL, "PBLG", NULL, NULL,
104         "CFVG", NULL, NULL, NULL,
105         "USBG", NULL, NULL, "MODG",
106         "CRDG", "M3GG", "WIMG", "HWCF",
107         "LIDG", "TYPE", "PBPG", "TPDG"
108 };
109
110 static const char *cm_setv[] = {
111         "WLDS", "BTHS", NULL, NULL,
112         "CAMS", NULL, NULL, NULL,
113         "SDSP", "PBLS", "HDPS", NULL,
114         "CFVS", NULL, NULL, NULL,
115         "USBG", NULL, NULL, "MODS",
116         "CRDS", "M3GS", "WIMS", NULL,
117         NULL, NULL, "PBPS", "TPDS"
118 };
119
120 #define EEEPC_EC        "\\_SB.PCI0.SBRG.EC0."
121
122 #define EEEPC_EC_FAN_PWM        EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */
123 #define EEEPC_EC_SC02           0x63
124 #define EEEPC_EC_FAN_HRPM       EEEPC_EC "SC05" /* High byte, fan speed (RPM) */
125 #define EEEPC_EC_FAN_LRPM       EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */
126 #define EEEPC_EC_FAN_CTRL       EEEPC_EC "SFB3" /* Byte containing SF25  */
127 #define EEEPC_EC_SFB3           0xD3
128
129 /*
130  * This is the main structure, we can use it to store useful information
131  * about the hotk device
132  */
133 struct eeepc_hotk {
134         struct acpi_device *device;     /* the device we are in */
135         acpi_handle handle;             /* the handle of the hotk device */
136         u32 cm_supported;               /* the control methods supported
137                                            by this BIOS */
138         uint init_flag;                 /* Init flags */
139         u16 event_count[128];           /* count for each event */
140         struct input_dev *inputdev;
141         u16 *keycode_map;
142         struct rfkill *wlan_rfkill;
143         struct rfkill *bluetooth_rfkill;
144         struct hotplug_slot *hotplug_slot;
145 };
146
147 /* The actual device the driver binds to */
148 static struct eeepc_hotk *ehotk;
149
150 /* Platform device/driver */
151 static struct platform_driver platform_driver = {
152         .driver = {
153                 .name = EEEPC_HOTK_FILE,
154                 .owner = THIS_MODULE,
155         }
156 };
157
158 static struct platform_device *platform_device;
159
160 struct key_entry {
161         char type;
162         u8 code;
163         u16 keycode;
164 };
165
166 enum { KE_KEY, KE_END };
167
168 static struct key_entry eeepc_keymap[] = {
169         /* Sleep already handled via generic ACPI code */
170         {KE_KEY, 0x10, KEY_WLAN },
171         {KE_KEY, 0x11, KEY_WLAN },
172         {KE_KEY, 0x12, KEY_PROG1 },
173         {KE_KEY, 0x13, KEY_MUTE },
174         {KE_KEY, 0x14, KEY_VOLUMEDOWN },
175         {KE_KEY, 0x15, KEY_VOLUMEUP },
176         {KE_KEY, 0x1a, KEY_COFFEE },
177         {KE_KEY, 0x1b, KEY_ZOOM },
178         {KE_KEY, 0x1c, KEY_PROG2 },
179         {KE_KEY, 0x1d, KEY_PROG3 },
180         {KE_KEY, NOTIFY_BRN_MIN,     KEY_BRIGHTNESSDOWN },
181         {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP },
182         {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
183         {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
184         {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
185         {KE_END, 0},
186 };
187
188 /*
189  * The hotkey driver declaration
190  */
191 static int eeepc_hotk_add(struct acpi_device *device);
192 static int eeepc_hotk_remove(struct acpi_device *device, int type);
193 static int eeepc_hotk_resume(struct acpi_device *device);
194 static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
195
196 static const struct acpi_device_id eeepc_device_ids[] = {
197         {EEEPC_HOTK_HID, 0},
198         {"", 0},
199 };
200 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
201
202 static struct acpi_driver eeepc_hotk_driver = {
203         .name = EEEPC_HOTK_NAME,
204         .class = EEEPC_HOTK_CLASS,
205         .ids = eeepc_device_ids,
206         .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
207         .ops = {
208                 .add = eeepc_hotk_add,
209                 .remove = eeepc_hotk_remove,
210                 .resume = eeepc_hotk_resume,
211                 .notify = eeepc_hotk_notify,
212         },
213 };
214
215 /* PCI hotplug ops */
216 static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
217
218 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
219         .owner = THIS_MODULE,
220         .get_adapter_status = eeepc_get_adapter_status,
221         .get_power_status = eeepc_get_adapter_status,
222 };
223
224 /* The backlight device /sys/class/backlight */
225 static struct backlight_device *eeepc_backlight_device;
226
227 /* The hwmon device */
228 static struct device *eeepc_hwmon_device;
229
230 /*
231  * The backlight class declaration
232  */
233 static int read_brightness(struct backlight_device *bd);
234 static int update_bl_status(struct backlight_device *bd);
235 static struct backlight_ops eeepcbl_ops = {
236         .get_brightness = read_brightness,
237         .update_status = update_bl_status,
238 };
239
240 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
241 MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
242 MODULE_LICENSE("GPL");
243
244 /*
245  * ACPI Helpers
246  */
247 static int write_acpi_int(acpi_handle handle, const char *method, int val,
248                           struct acpi_buffer *output)
249 {
250         struct acpi_object_list params;
251         union acpi_object in_obj;
252         acpi_status status;
253
254         params.count = 1;
255         params.pointer = &in_obj;
256         in_obj.type = ACPI_TYPE_INTEGER;
257         in_obj.integer.value = val;
258
259         status = acpi_evaluate_object(handle, (char *)method, &params, output);
260         return (status == AE_OK ? 0 : -1);
261 }
262
263 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
264 {
265         acpi_status status;
266         unsigned long long result;
267
268         status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
269         if (ACPI_FAILURE(status)) {
270                 *val = -1;
271                 return -1;
272         } else {
273                 *val = result;
274                 return 0;
275         }
276 }
277
278 static int set_acpi(int cm, int value)
279 {
280         if (ehotk->cm_supported & (0x1 << cm)) {
281                 const char *method = cm_setv[cm];
282                 if (method == NULL)
283                         return -ENODEV;
284                 if (write_acpi_int(ehotk->handle, method, value, NULL))
285                         pr_warning("Error writing %s\n", method);
286         }
287         return 0;
288 }
289
290 static int get_acpi(int cm)
291 {
292         int value = -ENODEV;
293         if ((ehotk->cm_supported & (0x1 << cm))) {
294                 const char *method = cm_getv[cm];
295                 if (method == NULL)
296                         return -ENODEV;
297                 if (read_acpi_int(ehotk->handle, method, &value))
298                         pr_warning("Error reading %s\n", method);
299         }
300         return value;
301 }
302
303 /*
304  * Backlight
305  */
306 static int read_brightness(struct backlight_device *bd)
307 {
308         return get_acpi(CM_ASL_PANELBRIGHT);
309 }
310
311 static int set_brightness(struct backlight_device *bd, int value)
312 {
313         value = max(0, min(15, value));
314         return set_acpi(CM_ASL_PANELBRIGHT, value);
315 }
316
317 static int update_bl_status(struct backlight_device *bd)
318 {
319         return set_brightness(bd, bd->props.brightness);
320 }
321
322 /*
323  * Rfkill helpers
324  */
325
326 static bool eeepc_wlan_rfkill_blocked(void)
327 {
328         if (get_acpi(CM_ASL_WLAN) == 1)
329                 return false;
330         return true;
331 }
332
333 static int eeepc_rfkill_set(void *data, bool blocked)
334 {
335         unsigned long asl = (unsigned long)data;
336         return set_acpi(asl, !blocked);
337 }
338
339 static const struct rfkill_ops eeepc_rfkill_ops = {
340         .set_block = eeepc_rfkill_set,
341 };
342
343 static void __init eeepc_enable_camera(void)
344 {
345         /*
346          * If the following call to set_acpi() fails, it's because there's no
347          * camera so we can ignore the error.
348          */
349         set_acpi(CM_ASL_CAMERA, 1);
350 }
351
352 /*
353  * Sys helpers
354  */
355 static int parse_arg(const char *buf, unsigned long count, int *val)
356 {
357         if (!count)
358                 return 0;
359         if (sscanf(buf, "%i", val) != 1)
360                 return -EINVAL;
361         return count;
362 }
363
364 static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
365 {
366         int rv, value;
367
368         rv = parse_arg(buf, count, &value);
369         if (rv > 0)
370                 value = set_acpi(cm, value);
371         if (value < 0)
372                 return value;
373         return rv;
374 }
375
376 static ssize_t show_sys_acpi(int cm, char *buf)
377 {
378         int value = get_acpi(cm);
379
380         if (value < 0)
381                 return value;
382         return sprintf(buf, "%d\n", value);
383 }
384
385 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm)                            \
386         static ssize_t show_##_name(struct device *dev,                 \
387                                     struct device_attribute *attr,      \
388                                     char *buf)                          \
389         {                                                               \
390                 return show_sys_acpi(_cm, buf);                         \
391         }                                                               \
392         static ssize_t store_##_name(struct device *dev,                \
393                                      struct device_attribute *attr,     \
394                                      const char *buf, size_t count)     \
395         {                                                               \
396                 return store_sys_acpi(_cm, buf, count);                 \
397         }                                                               \
398         static struct device_attribute dev_attr_##_name = {             \
399                 .attr = {                                               \
400                         .name = __stringify(_name),                     \
401                         .mode = 0644 },                                 \
402                 .show   = show_##_name,                                 \
403                 .store  = store_##_name,                                \
404         }
405
406 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
407 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
408 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
409
410 struct eeepc_cpufv {
411         int num;
412         int cur;
413 };
414
415 static int get_cpufv(struct eeepc_cpufv *c)
416 {
417         c->cur = get_acpi(CM_ASL_CPUFV);
418         c->num = (c->cur >> 8) & 0xff;
419         c->cur &= 0xff;
420         if (c->cur < 0 || c->num <= 0 || c->num > 12)
421                 return -ENODEV;
422         return 0;
423 }
424
425 static ssize_t show_available_cpufv(struct device *dev,
426                                     struct device_attribute *attr,
427                                     char *buf)
428 {
429         struct eeepc_cpufv c;
430         int i;
431         ssize_t len = 0;
432
433         if (get_cpufv(&c))
434                 return -ENODEV;
435         for (i = 0; i < c.num; i++)
436                 len += sprintf(buf + len, "%d ", i);
437         len += sprintf(buf + len, "\n");
438         return len;
439 }
440
441 static ssize_t show_cpufv(struct device *dev,
442                           struct device_attribute *attr,
443                           char *buf)
444 {
445         struct eeepc_cpufv c;
446
447         if (get_cpufv(&c))
448                 return -ENODEV;
449         return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
450 }
451
452 static ssize_t store_cpufv(struct device *dev,
453                            struct device_attribute *attr,
454                            const char *buf, size_t count)
455 {
456         struct eeepc_cpufv c;
457         int rv, value;
458
459         if (get_cpufv(&c))
460                 return -ENODEV;
461         rv = parse_arg(buf, count, &value);
462         if (rv < 0)
463                 return rv;
464         if (!rv || value < 0 || value >= c.num)
465                 return -EINVAL;
466         set_acpi(CM_ASL_CPUFV, value);
467         return rv;
468 }
469
470 static struct device_attribute dev_attr_cpufv = {
471         .attr = {
472                 .name = "cpufv",
473                 .mode = 0644 },
474         .show   = show_cpufv,
475         .store  = store_cpufv
476 };
477
478 static struct device_attribute dev_attr_available_cpufv = {
479         .attr = {
480                 .name = "available_cpufv",
481                 .mode = 0444 },
482         .show   = show_available_cpufv
483 };
484
485 static struct attribute *platform_attributes[] = {
486         &dev_attr_camera.attr,
487         &dev_attr_cardr.attr,
488         &dev_attr_disp.attr,
489         &dev_attr_cpufv.attr,
490         &dev_attr_available_cpufv.attr,
491         NULL
492 };
493
494 static struct attribute_group platform_attribute_group = {
495         .attrs = platform_attributes
496 };
497
498 /*
499  * Hotkey functions
500  */
501 static struct key_entry *eepc_get_entry_by_scancode(int code)
502 {
503         struct key_entry *key;
504
505         for (key = eeepc_keymap; key->type != KE_END; key++)
506                 if (code == key->code)
507                         return key;
508
509         return NULL;
510 }
511
512 static struct key_entry *eepc_get_entry_by_keycode(int code)
513 {
514         struct key_entry *key;
515
516         for (key = eeepc_keymap; key->type != KE_END; key++)
517                 if (code == key->keycode && key->type == KE_KEY)
518                         return key;
519
520         return NULL;
521 }
522
523 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
524 {
525         struct key_entry *key = eepc_get_entry_by_scancode(scancode);
526
527         if (key && key->type == KE_KEY) {
528                 *keycode = key->keycode;
529                 return 0;
530         }
531
532         return -EINVAL;
533 }
534
535 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
536 {
537         struct key_entry *key;
538         int old_keycode;
539
540         if (keycode < 0 || keycode > KEY_MAX)
541                 return -EINVAL;
542
543         key = eepc_get_entry_by_scancode(scancode);
544         if (key && key->type == KE_KEY) {
545                 old_keycode = key->keycode;
546                 key->keycode = keycode;
547                 set_bit(keycode, dev->keybit);
548                 if (!eepc_get_entry_by_keycode(old_keycode))
549                         clear_bit(old_keycode, dev->keybit);
550                 return 0;
551         }
552
553         return -EINVAL;
554 }
555
556 static int eeepc_hotk_check(void)
557 {
558         const struct key_entry *key;
559         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
560         int result;
561
562         result = acpi_bus_get_status(ehotk->device);
563         if (result)
564                 return result;
565         if (ehotk->device->status.present) {
566                 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
567                                     &buffer)) {
568                         pr_err("Hotkey initialization failed\n");
569                         return -ENODEV;
570                 } else {
571                         pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
572                 }
573                 /* get control methods supported */
574                 if (read_acpi_int(ehotk->handle, "CMSG"
575                                    , &ehotk->cm_supported)) {
576                         pr_err("Get control methods supported failed\n");
577                         return -ENODEV;
578                 } else {
579                         pr_info("Get control methods supported: 0x%x\n",
580                                 ehotk->cm_supported);
581                 }
582                 ehotk->inputdev = input_allocate_device();
583                 if (!ehotk->inputdev) {
584                         pr_info("Unable to allocate input device\n");
585                         return 0;
586                 }
587                 ehotk->inputdev->name = "Asus EeePC extra buttons";
588                 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
589                 ehotk->inputdev->id.bustype = BUS_HOST;
590                 ehotk->inputdev->getkeycode = eeepc_getkeycode;
591                 ehotk->inputdev->setkeycode = eeepc_setkeycode;
592
593                 for (key = eeepc_keymap; key->type != KE_END; key++) {
594                         switch (key->type) {
595                         case KE_KEY:
596                                 set_bit(EV_KEY, ehotk->inputdev->evbit);
597                                 set_bit(key->keycode, ehotk->inputdev->keybit);
598                                 break;
599                         }
600                 }
601                 result = input_register_device(ehotk->inputdev);
602                 if (result) {
603                         pr_info("Unable to register input device\n");
604                         input_free_device(ehotk->inputdev);
605                         return 0;
606                 }
607         } else {
608                 pr_err("Hotkey device not present, aborting\n");
609                 return -EINVAL;
610         }
611         return 0;
612 }
613
614 static int notify_brn(void)
615 {
616         /* returns the *previous* brightness, or -1 */
617         struct backlight_device *bd = eeepc_backlight_device;
618         if (bd) {
619                 int old = bd->props.brightness;
620                 bd->props.brightness = read_brightness(bd);
621                 return old;
622         }
623         return -1;
624 }
625
626 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
627                                     u8 *value)
628 {
629         int val = get_acpi(CM_ASL_WLAN);
630
631         if (val == 1 || val == 0)
632                 *value = val;
633         else
634                 return -EINVAL;
635
636         return 0;
637 }
638
639 static void eeepc_rfkill_hotplug(void)
640 {
641         struct pci_dev *dev;
642         struct pci_bus *bus = pci_find_bus(0, 1);
643         bool blocked;
644
645         if (!bus) {
646                 pr_warning("Unable to find PCI bus 1?\n");
647                 return;
648         }
649
650         blocked = eeepc_wlan_rfkill_blocked();
651         if (!blocked) {
652                 dev = pci_get_slot(bus, 0);
653                 if (dev) {
654                         /* Device already present */
655                         pci_dev_put(dev);
656                         return;
657                 }
658                 dev = pci_scan_single_device(bus, 0);
659                 if (dev) {
660                         pci_bus_assign_resources(bus);
661                         if (pci_bus_add_device(dev))
662                                 pr_err("Unable to hotplug wifi\n");
663                 }
664         } else {
665                 dev = pci_get_slot(bus, 0);
666                 if (dev) {
667                         pci_remove_bus_device(dev);
668                         pci_dev_put(dev);
669                 }
670         }
671
672         rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
673 }
674
675 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
676 {
677         if (event != ACPI_NOTIFY_BUS_CHECK)
678                 return;
679
680         eeepc_rfkill_hotplug();
681 }
682
683 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
684 {
685         static struct key_entry *key;
686         u16 count;
687         int brn = -ENODEV;
688
689         if (!ehotk)
690                 return;
691         if (event > ACPI_MAX_SYS_NOTIFY)
692                 return;
693         if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
694                 brn = notify_brn();
695         count = ehotk->event_count[event % 128]++;
696         acpi_bus_generate_proc_event(ehotk->device, event, count);
697         acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
698                                         dev_name(&ehotk->device->dev), event,
699                                         count);
700         if (ehotk->inputdev) {
701                 if (brn != -ENODEV) {
702                         /* brightness-change events need special
703                          * handling for conversion to key events
704                          */
705                         if (brn < 0)
706                                 brn = event;
707                         else
708                                 brn += NOTIFY_BRN_MIN;
709                         if (event < brn)
710                                 event = NOTIFY_BRN_MIN; /* brightness down */
711                         else if (event > brn)
712                                 event = NOTIFY_BRN_MIN + 2; /* ... up */
713                         else
714                                 event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
715                 }
716                 key = eepc_get_entry_by_scancode(event);
717                 if (key) {
718                         switch (key->type) {
719                         case KE_KEY:
720                                 input_report_key(ehotk->inputdev, key->keycode,
721                                                  1);
722                                 input_sync(ehotk->inputdev);
723                                 input_report_key(ehotk->inputdev, key->keycode,
724                                                  0);
725                                 input_sync(ehotk->inputdev);
726                                 break;
727                         }
728                 }
729         }
730 }
731
732 static int eeepc_register_rfkill_notifier(char *node)
733 {
734         acpi_status status = AE_OK;
735         acpi_handle handle;
736
737         status = acpi_get_handle(NULL, node, &handle);
738
739         if (ACPI_SUCCESS(status)) {
740                 status = acpi_install_notify_handler(handle,
741                                                      ACPI_SYSTEM_NOTIFY,
742                                                      eeepc_rfkill_notify,
743                                                      NULL);
744                 if (ACPI_FAILURE(status))
745                         pr_warning("Failed to register notify on %s\n", node);
746         } else
747                 return -ENODEV;
748
749         return 0;
750 }
751
752 static void eeepc_unregister_rfkill_notifier(char *node)
753 {
754         acpi_status status = AE_OK;
755         acpi_handle handle;
756
757         status = acpi_get_handle(NULL, node, &handle);
758
759         if (ACPI_SUCCESS(status)) {
760                 status = acpi_remove_notify_handler(handle,
761                                                      ACPI_SYSTEM_NOTIFY,
762                                                      eeepc_rfkill_notify);
763                 if (ACPI_FAILURE(status))
764                         pr_err("Error removing rfkill notify handler %s\n",
765                                 node);
766         }
767 }
768
769 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
770 {
771         kfree(hotplug_slot->info);
772         kfree(hotplug_slot);
773 }
774
775 static int eeepc_setup_pci_hotplug(void)
776 {
777         int ret = -ENOMEM;
778         struct pci_bus *bus = pci_find_bus(0, 1);
779
780         if (!bus) {
781                 pr_err("Unable to find wifi PCI bus\n");
782                 return -ENODEV;
783         }
784
785         ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
786         if (!ehotk->hotplug_slot)
787                 goto error_slot;
788
789         ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
790                                             GFP_KERNEL);
791         if (!ehotk->hotplug_slot->info)
792                 goto error_info;
793
794         ehotk->hotplug_slot->private = ehotk;
795         ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
796         ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
797         eeepc_get_adapter_status(ehotk->hotplug_slot,
798                                  &ehotk->hotplug_slot->info->adapter_status);
799
800         ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
801         if (ret) {
802                 pr_err("Unable to register hotplug slot - %d\n", ret);
803                 goto error_register;
804         }
805
806         return 0;
807
808 error_register:
809         kfree(ehotk->hotplug_slot->info);
810 error_info:
811         kfree(ehotk->hotplug_slot);
812         ehotk->hotplug_slot = NULL;
813 error_slot:
814         return ret;
815 }
816
817 static int eeepc_hotk_add(struct acpi_device *device)
818 {
819         int result;
820
821         if (!device)
822                  return -EINVAL;
823         pr_notice(EEEPC_HOTK_NAME "\n");
824         ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
825         if (!ehotk)
826                 return -ENOMEM;
827         ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
828         ehotk->handle = device->handle;
829         strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
830         strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
831         device->driver_data = ehotk;
832         ehotk->device = device;
833         result = eeepc_hotk_check();
834         if (result)
835                 goto ehotk_fail;
836
837         return 0;
838
839  ehotk_fail:
840         kfree(ehotk);
841         ehotk = NULL;
842
843         return result;
844 }
845
846 static int eeepc_hotk_remove(struct acpi_device *device, int type)
847 {
848         if (!device || !acpi_driver_data(device))
849                  return -EINVAL;
850
851         kfree(ehotk);
852         return 0;
853 }
854
855 static int eeepc_hotk_resume(struct acpi_device *device)
856 {
857         if (ehotk->wlan_rfkill) {
858                 bool wlan;
859
860                 /* Workaround - it seems that _PTS disables the wireless
861                    without notification or changing the value read by WLAN.
862                    Normally this is fine because the correct value is restored
863                    from the non-volatile storage on resume, but we need to do
864                    it ourself if case suspend is aborted, or we lose wireless.
865                  */
866                 wlan = get_acpi(CM_ASL_WLAN);
867                 set_acpi(CM_ASL_WLAN, wlan);
868
869                 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
870
871                 eeepc_rfkill_hotplug();
872         }
873
874         if (ehotk->bluetooth_rfkill)
875                 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
876                                     get_acpi(CM_ASL_BLUETOOTH) != 1);
877
878         return 0;
879 }
880
881 /*
882  * Hwmon
883  */
884 static int eeepc_get_fan_pwm(void)
885 {
886         int value = 0;
887
888         read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
889         value = value * 255 / 100;
890         return (value);
891 }
892
893 static void eeepc_set_fan_pwm(int value)
894 {
895         value = SENSORS_LIMIT(value, 0, 255);
896         value = value * 100 / 255;
897         ec_write(EEEPC_EC_SC02, value);
898 }
899
900 static int eeepc_get_fan_rpm(void)
901 {
902         int high = 0;
903         int low = 0;
904
905         read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
906         read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
907         return (high << 8 | low);
908 }
909
910 static int eeepc_get_fan_ctrl(void)
911 {
912         int value = 0;
913
914         read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
915         return ((value & 0x02 ? 1 : 0));
916 }
917
918 static void eeepc_set_fan_ctrl(int manual)
919 {
920         int value = 0;
921
922         read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
923         if (manual)
924                 value |= 0x02;
925         else
926                 value &= ~0x02;
927         ec_write(EEEPC_EC_SFB3, value);
928 }
929
930 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
931 {
932         int rv, value;
933
934         rv = parse_arg(buf, count, &value);
935         if (rv > 0)
936                 set(value);
937         return rv;
938 }
939
940 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
941 {
942         return sprintf(buf, "%d\n", get());
943 }
944
945 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)              \
946         static ssize_t show_##_name(struct device *dev,                 \
947                                     struct device_attribute *attr,      \
948                                     char *buf)                          \
949         {                                                               \
950                 return show_sys_hwmon(_set, buf);                       \
951         }                                                               \
952         static ssize_t store_##_name(struct device *dev,                \
953                                      struct device_attribute *attr,     \
954                                      const char *buf, size_t count)     \
955         {                                                               \
956                 return store_sys_hwmon(_get, buf, count);               \
957         }                                                               \
958         static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
959
960 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
961 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
962                          eeepc_get_fan_pwm, eeepc_set_fan_pwm);
963 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
964                          eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
965
966 static ssize_t
967 show_name(struct device *dev, struct device_attribute *attr, char *buf)
968 {
969         return sprintf(buf, "eeepc\n");
970 }
971 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
972
973 static struct attribute *hwmon_attributes[] = {
974         &sensor_dev_attr_pwm1.dev_attr.attr,
975         &sensor_dev_attr_fan1_input.dev_attr.attr,
976         &sensor_dev_attr_pwm1_enable.dev_attr.attr,
977         &sensor_dev_attr_name.dev_attr.attr,
978         NULL
979 };
980
981 static struct attribute_group hwmon_attribute_group = {
982         .attrs = hwmon_attributes
983 };
984
985 /*
986  * exit/init
987  */
988 static void eeepc_backlight_exit(void)
989 {
990         if (eeepc_backlight_device)
991                 backlight_device_unregister(eeepc_backlight_device);
992         eeepc_backlight_device = NULL;
993 }
994
995 static void eeepc_rfkill_exit(void)
996 {
997         eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
998         eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
999         if (ehotk->wlan_rfkill)
1000                 rfkill_unregister(ehotk->wlan_rfkill);
1001         if (ehotk->bluetooth_rfkill)
1002                 rfkill_unregister(ehotk->bluetooth_rfkill);
1003         if (ehotk->hotplug_slot)
1004                 pci_hp_deregister(ehotk->hotplug_slot);
1005 }
1006
1007 static void eeepc_input_exit(void)
1008 {
1009         if (ehotk->inputdev)
1010                 input_unregister_device(ehotk->inputdev);
1011 }
1012
1013 static void eeepc_hwmon_exit(void)
1014 {
1015         struct device *hwmon;
1016
1017         hwmon = eeepc_hwmon_device;
1018         if (!hwmon)
1019                 return ;
1020         sysfs_remove_group(&hwmon->kobj,
1021                            &hwmon_attribute_group);
1022         hwmon_device_unregister(hwmon);
1023         eeepc_hwmon_device = NULL;
1024 }
1025
1026 static void __exit eeepc_laptop_exit(void)
1027 {
1028         eeepc_backlight_exit();
1029         eeepc_rfkill_exit();
1030         eeepc_input_exit();
1031         eeepc_hwmon_exit();
1032         acpi_bus_unregister_driver(&eeepc_hotk_driver);
1033         sysfs_remove_group(&platform_device->dev.kobj,
1034                            &platform_attribute_group);
1035         platform_device_unregister(platform_device);
1036         platform_driver_unregister(&platform_driver);
1037 }
1038
1039 static int eeepc_new_rfkill(struct rfkill **rfkill,
1040                             const char *name, struct device *dev,
1041                             enum rfkill_type type, int cm)
1042 {
1043         int result;
1044
1045         result = get_acpi(cm);
1046         if (result < 0)
1047                 return result;
1048
1049         *rfkill = rfkill_alloc(name, dev, type,
1050                                &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1051
1052         if (!*rfkill)
1053                 return -EINVAL;
1054
1055         rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1056         result = rfkill_register(*rfkill);
1057         if (result) {
1058                 rfkill_destroy(*rfkill);
1059                 *rfkill = NULL;
1060                 return result;
1061         }
1062         return 0;
1063 }
1064
1065
1066 static int eeepc_rfkill_init(struct device *dev)
1067 {
1068         int result = 0;
1069
1070         eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1071         eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1072
1073         result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1074                                   "eeepc-wlan", dev,
1075                                   RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1076
1077         if (result && result != -ENODEV)
1078                 goto exit;
1079
1080         result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1081                                   "eeepc-bluetooth", dev,
1082                                   RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1083
1084         if (result && result != -ENODEV)
1085                 goto exit;
1086
1087         result = eeepc_setup_pci_hotplug();
1088         /*
1089          * If we get -EBUSY then something else is handling the PCI hotplug -
1090          * don't fail in this case
1091          */
1092         if (result == -EBUSY)
1093                 result = 0;
1094
1095 exit:
1096         if (result && result != -ENODEV)
1097                 eeepc_rfkill_exit();
1098         return result;
1099 }
1100
1101 static int eeepc_backlight_init(struct device *dev)
1102 {
1103         struct backlight_device *bd;
1104
1105         bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1106                                        NULL, &eeepcbl_ops);
1107         if (IS_ERR(bd)) {
1108                 pr_err("Could not register eeepc backlight device\n");
1109                 eeepc_backlight_device = NULL;
1110                 return PTR_ERR(bd);
1111         }
1112         eeepc_backlight_device = bd;
1113         bd->props.max_brightness = 15;
1114         bd->props.brightness = read_brightness(NULL);
1115         bd->props.power = FB_BLANK_UNBLANK;
1116         backlight_update_status(bd);
1117         return 0;
1118 }
1119
1120 static int eeepc_hwmon_init(struct device *dev)
1121 {
1122         struct device *hwmon;
1123         int result;
1124
1125         hwmon = hwmon_device_register(dev);
1126         if (IS_ERR(hwmon)) {
1127                 pr_err("Could not register eeepc hwmon device\n");
1128                 eeepc_hwmon_device = NULL;
1129                 return PTR_ERR(hwmon);
1130         }
1131         eeepc_hwmon_device = hwmon;
1132         result = sysfs_create_group(&hwmon->kobj,
1133                                     &hwmon_attribute_group);
1134         if (result)
1135                 eeepc_hwmon_exit();
1136         return result;
1137 }
1138
1139 static int __init eeepc_laptop_init(void)
1140 {
1141         struct device *dev;
1142         int result;
1143
1144         if (acpi_disabled)
1145                 return -ENODEV;
1146         result = acpi_bus_register_driver(&eeepc_hotk_driver);
1147         if (result < 0)
1148                 return result;
1149         if (!ehotk) {
1150                 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1151                 return -ENODEV;
1152         }
1153
1154         eeepc_enable_camera();
1155
1156         /* Register platform stuff */
1157         result = platform_driver_register(&platform_driver);
1158         if (result)
1159                 goto fail_platform_driver;
1160         platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1161         if (!platform_device) {
1162                 result = -ENOMEM;
1163                 goto fail_platform_device1;
1164         }
1165         result = platform_device_add(platform_device);
1166         if (result)
1167                 goto fail_platform_device2;
1168         result = sysfs_create_group(&platform_device->dev.kobj,
1169                                     &platform_attribute_group);
1170         if (result)
1171                 goto fail_sysfs;
1172
1173         dev = &platform_device->dev;
1174
1175         if (!acpi_video_backlight_support()) {
1176                 result = eeepc_backlight_init(dev);
1177                 if (result)
1178                         goto fail_backlight;
1179         } else
1180                 pr_info("Backlight controlled by ACPI video "
1181                         "driver\n");
1182
1183         result = eeepc_hwmon_init(dev);
1184         if (result)
1185                 goto fail_hwmon;
1186
1187         result = eeepc_rfkill_init(dev);
1188         if (result)
1189                 goto fail_rfkill;
1190
1191         return 0;
1192 fail_rfkill:
1193         eeepc_hwmon_exit();
1194 fail_hwmon:
1195         eeepc_backlight_exit();
1196 fail_backlight:
1197         sysfs_remove_group(&platform_device->dev.kobj,
1198                            &platform_attribute_group);
1199 fail_sysfs:
1200         platform_device_del(platform_device);
1201 fail_platform_device2:
1202         platform_device_put(platform_device);
1203 fail_platform_device1:
1204         platform_driver_unregister(&platform_driver);
1205 fail_platform_driver:
1206         eeepc_input_exit();
1207         return result;
1208 }
1209
1210 module_init(eeepc_laptop_init);
1211 module_exit(eeepc_laptop_exit);