d14f7149cb1312c2a9ff8760054d11f22649c4ad
[linux-2.6.git] / 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 *eeepc_wlan_rfkill;
143         struct rfkill *eeepc_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 = -1;
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                 set_acpi(cm, value);
371         return rv;
372 }
373
374 static ssize_t show_sys_acpi(int cm, char *buf)
375 {
376         return sprintf(buf, "%d\n", get_acpi(cm));
377 }
378
379 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm)                            \
380         static ssize_t show_##_name(struct device *dev,                 \
381                                     struct device_attribute *attr,      \
382                                     char *buf)                          \
383         {                                                               \
384                 return show_sys_acpi(_cm, buf);                         \
385         }                                                               \
386         static ssize_t store_##_name(struct device *dev,                \
387                                      struct device_attribute *attr,     \
388                                      const char *buf, size_t count)     \
389         {                                                               \
390                 return store_sys_acpi(_cm, buf, count);                 \
391         }                                                               \
392         static struct device_attribute dev_attr_##_name = {             \
393                 .attr = {                                               \
394                         .name = __stringify(_name),                     \
395                         .mode = 0644 },                                 \
396                 .show   = show_##_name,                                 \
397                 .store  = store_##_name,                                \
398         }
399
400 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
401 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
402 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
403
404 struct eeepc_cpufv {
405         int num;
406         int cur;
407 };
408
409 static int get_cpufv(struct eeepc_cpufv *c)
410 {
411         c->cur = get_acpi(CM_ASL_CPUFV);
412         c->num = (c->cur >> 8) & 0xff;
413         c->cur &= 0xff;
414         if (c->cur < 0 || c->num <= 0 || c->num > 12)
415                 return -ENODEV;
416         return 0;
417 }
418
419 static ssize_t show_available_cpufv(struct device *dev,
420                                     struct device_attribute *attr,
421                                     char *buf)
422 {
423         struct eeepc_cpufv c;
424         int i;
425         ssize_t len = 0;
426
427         if (get_cpufv(&c))
428                 return -ENODEV;
429         for (i = 0; i < c.num; i++)
430                 len += sprintf(buf + len, "%d ", i);
431         len += sprintf(buf + len, "\n");
432         return len;
433 }
434
435 static ssize_t show_cpufv(struct device *dev,
436                           struct device_attribute *attr,
437                           char *buf)
438 {
439         struct eeepc_cpufv c;
440
441         if (get_cpufv(&c))
442                 return -ENODEV;
443         return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
444 }
445
446 static ssize_t store_cpufv(struct device *dev,
447                            struct device_attribute *attr,
448                            const char *buf, size_t count)
449 {
450         struct eeepc_cpufv c;
451         int rv, value;
452
453         if (get_cpufv(&c))
454                 return -ENODEV;
455         rv = parse_arg(buf, count, &value);
456         if (rv < 0)
457                 return rv;
458         if (!rv || value < 0 || value >= c.num)
459                 return -EINVAL;
460         set_acpi(CM_ASL_CPUFV, value);
461         return rv;
462 }
463
464 static struct device_attribute dev_attr_cpufv = {
465         .attr = {
466                 .name = "cpufv",
467                 .mode = 0644 },
468         .show   = show_cpufv,
469         .store  = store_cpufv
470 };
471
472 static struct device_attribute dev_attr_available_cpufv = {
473         .attr = {
474                 .name = "available_cpufv",
475                 .mode = 0444 },
476         .show   = show_available_cpufv
477 };
478
479 static struct attribute *platform_attributes[] = {
480         &dev_attr_camera.attr,
481         &dev_attr_cardr.attr,
482         &dev_attr_disp.attr,
483         &dev_attr_cpufv.attr,
484         &dev_attr_available_cpufv.attr,
485         NULL
486 };
487
488 static struct attribute_group platform_attribute_group = {
489         .attrs = platform_attributes
490 };
491
492 /*
493  * Hotkey functions
494  */
495 static struct key_entry *eepc_get_entry_by_scancode(int code)
496 {
497         struct key_entry *key;
498
499         for (key = eeepc_keymap; key->type != KE_END; key++)
500                 if (code == key->code)
501                         return key;
502
503         return NULL;
504 }
505
506 static struct key_entry *eepc_get_entry_by_keycode(int code)
507 {
508         struct key_entry *key;
509
510         for (key = eeepc_keymap; key->type != KE_END; key++)
511                 if (code == key->keycode && key->type == KE_KEY)
512                         return key;
513
514         return NULL;
515 }
516
517 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
518 {
519         struct key_entry *key = eepc_get_entry_by_scancode(scancode);
520
521         if (key && key->type == KE_KEY) {
522                 *keycode = key->keycode;
523                 return 0;
524         }
525
526         return -EINVAL;
527 }
528
529 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
530 {
531         struct key_entry *key;
532         int old_keycode;
533
534         if (keycode < 0 || keycode > KEY_MAX)
535                 return -EINVAL;
536
537         key = eepc_get_entry_by_scancode(scancode);
538         if (key && key->type == KE_KEY) {
539                 old_keycode = key->keycode;
540                 key->keycode = keycode;
541                 set_bit(keycode, dev->keybit);
542                 if (!eepc_get_entry_by_keycode(old_keycode))
543                         clear_bit(old_keycode, dev->keybit);
544                 return 0;
545         }
546
547         return -EINVAL;
548 }
549
550 static int eeepc_hotk_check(void)
551 {
552         const struct key_entry *key;
553         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
554         int result;
555
556         result = acpi_bus_get_status(ehotk->device);
557         if (result)
558                 return result;
559         if (ehotk->device->status.present) {
560                 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
561                                     &buffer)) {
562                         pr_err("Hotkey initialization failed\n");
563                         return -ENODEV;
564                 } else {
565                         pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
566                 }
567                 /* get control methods supported */
568                 if (read_acpi_int(ehotk->handle, "CMSG"
569                                    , &ehotk->cm_supported)) {
570                         pr_err("Get control methods supported failed\n");
571                         return -ENODEV;
572                 } else {
573                         pr_info("Get control methods supported: 0x%x\n",
574                                 ehotk->cm_supported);
575                 }
576                 ehotk->inputdev = input_allocate_device();
577                 if (!ehotk->inputdev) {
578                         pr_info("Unable to allocate input device\n");
579                         return 0;
580                 }
581                 ehotk->inputdev->name = "Asus EeePC extra buttons";
582                 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
583                 ehotk->inputdev->id.bustype = BUS_HOST;
584                 ehotk->inputdev->getkeycode = eeepc_getkeycode;
585                 ehotk->inputdev->setkeycode = eeepc_setkeycode;
586
587                 for (key = eeepc_keymap; key->type != KE_END; key++) {
588                         switch (key->type) {
589                         case KE_KEY:
590                                 set_bit(EV_KEY, ehotk->inputdev->evbit);
591                                 set_bit(key->keycode, ehotk->inputdev->keybit);
592                                 break;
593                         }
594                 }
595                 result = input_register_device(ehotk->inputdev);
596                 if (result) {
597                         pr_info("Unable to register input device\n");
598                         input_free_device(ehotk->inputdev);
599                         return 0;
600                 }
601         } else {
602                 pr_err("Hotkey device not present, aborting\n");
603                 return -EINVAL;
604         }
605         return 0;
606 }
607
608 static int notify_brn(void)
609 {
610         /* returns the *previous* brightness, or -1 */
611         struct backlight_device *bd = eeepc_backlight_device;
612         if (bd) {
613                 int old = bd->props.brightness;
614                 bd->props.brightness = read_brightness(bd);
615                 return old;
616         }
617         return -1;
618 }
619
620 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
621                                     u8 *value)
622 {
623         int val = get_acpi(CM_ASL_WLAN);
624
625         if (val == 1 || val == 0)
626                 *value = val;
627         else
628                 return -EINVAL;
629
630         return 0;
631 }
632
633 static void eeepc_rfkill_hotplug(void)
634 {
635         struct pci_dev *dev;
636         struct pci_bus *bus = pci_find_bus(0, 1);
637         bool blocked;
638
639         if (!bus) {
640                 pr_warning("Unable to find PCI bus 1?\n");
641                 return;
642         }
643
644         blocked = eeepc_wlan_rfkill_blocked();
645         if (!blocked) {
646                 dev = pci_get_slot(bus, 0);
647                 if (dev) {
648                         /* Device already present */
649                         pci_dev_put(dev);
650                         return;
651                 }
652                 dev = pci_scan_single_device(bus, 0);
653                 if (dev) {
654                         pci_bus_assign_resources(bus);
655                         if (pci_bus_add_device(dev))
656                                 pr_err("Unable to hotplug wifi\n");
657                 }
658         } else {
659                 dev = pci_get_slot(bus, 0);
660                 if (dev) {
661                         pci_remove_bus_device(dev);
662                         pci_dev_put(dev);
663                 }
664         }
665
666         rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked);
667 }
668
669 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
670 {
671         if (event != ACPI_NOTIFY_BUS_CHECK)
672                 return;
673
674         eeepc_rfkill_hotplug();
675 }
676
677 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
678 {
679         static struct key_entry *key;
680         u16 count;
681         int brn = -ENODEV;
682
683         if (!ehotk)
684                 return;
685         if (event > ACPI_MAX_SYS_NOTIFY)
686                 return;
687         if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
688                 brn = notify_brn();
689         count = ehotk->event_count[event % 128]++;
690         acpi_bus_generate_proc_event(ehotk->device, event, count);
691         acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
692                                         dev_name(&ehotk->device->dev), event,
693                                         count);
694         if (ehotk->inputdev) {
695                 if (brn != -ENODEV) {
696                         /* brightness-change events need special
697                          * handling for conversion to key events
698                          */
699                         if (brn < 0)
700                                 brn = event;
701                         else
702                                 brn += NOTIFY_BRN_MIN;
703                         if (event < brn)
704                                 event = NOTIFY_BRN_MIN; /* brightness down */
705                         else if (event > brn)
706                                 event = NOTIFY_BRN_MIN + 2; /* ... up */
707                         else
708                                 event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
709                 }
710                 key = eepc_get_entry_by_scancode(event);
711                 if (key) {
712                         switch (key->type) {
713                         case KE_KEY:
714                                 input_report_key(ehotk->inputdev, key->keycode,
715                                                  1);
716                                 input_sync(ehotk->inputdev);
717                                 input_report_key(ehotk->inputdev, key->keycode,
718                                                  0);
719                                 input_sync(ehotk->inputdev);
720                                 break;
721                         }
722                 }
723         }
724 }
725
726 static int eeepc_register_rfkill_notifier(char *node)
727 {
728         acpi_status status = AE_OK;
729         acpi_handle handle;
730
731         status = acpi_get_handle(NULL, node, &handle);
732
733         if (ACPI_SUCCESS(status)) {
734                 status = acpi_install_notify_handler(handle,
735                                                      ACPI_SYSTEM_NOTIFY,
736                                                      eeepc_rfkill_notify,
737                                                      NULL);
738                 if (ACPI_FAILURE(status))
739                         pr_warning("Failed to register notify on %s\n", node);
740         } else
741                 return -ENODEV;
742
743         return 0;
744 }
745
746 static void eeepc_unregister_rfkill_notifier(char *node)
747 {
748         acpi_status status = AE_OK;
749         acpi_handle handle;
750
751         status = acpi_get_handle(NULL, node, &handle);
752
753         if (ACPI_SUCCESS(status)) {
754                 status = acpi_remove_notify_handler(handle,
755                                                      ACPI_SYSTEM_NOTIFY,
756                                                      eeepc_rfkill_notify);
757                 if (ACPI_FAILURE(status))
758                         pr_err("Error removing rfkill notify handler %s\n",
759                                 node);
760         }
761 }
762
763 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
764 {
765         kfree(hotplug_slot->info);
766         kfree(hotplug_slot);
767 }
768
769 static int eeepc_setup_pci_hotplug(void)
770 {
771         int ret = -ENOMEM;
772         struct pci_bus *bus = pci_find_bus(0, 1);
773
774         if (!bus) {
775                 pr_err("Unable to find wifi PCI bus\n");
776                 return -ENODEV;
777         }
778
779         ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
780         if (!ehotk->hotplug_slot)
781                 goto error_slot;
782
783         ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
784                                             GFP_KERNEL);
785         if (!ehotk->hotplug_slot->info)
786                 goto error_info;
787
788         ehotk->hotplug_slot->private = ehotk;
789         ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
790         ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
791         eeepc_get_adapter_status(ehotk->hotplug_slot,
792                                  &ehotk->hotplug_slot->info->adapter_status);
793
794         ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
795         if (ret) {
796                 pr_err("Unable to register hotplug slot - %d\n", ret);
797                 goto error_register;
798         }
799
800         return 0;
801
802 error_register:
803         kfree(ehotk->hotplug_slot->info);
804 error_info:
805         kfree(ehotk->hotplug_slot);
806         ehotk->hotplug_slot = NULL;
807 error_slot:
808         return ret;
809 }
810
811 static int eeepc_hotk_add(struct acpi_device *device)
812 {
813         int result;
814
815         if (!device)
816                  return -EINVAL;
817         pr_notice(EEEPC_HOTK_NAME "\n");
818         ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
819         if (!ehotk)
820                 return -ENOMEM;
821         ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
822         ehotk->handle = device->handle;
823         strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
824         strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
825         device->driver_data = ehotk;
826         ehotk->device = device;
827         result = eeepc_hotk_check();
828         if (result)
829                 goto ehotk_fail;
830
831         eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
832         eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
833
834         if (get_acpi(CM_ASL_WLAN) != -1) {
835                 ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
836                                                         &device->dev,
837                                                         RFKILL_TYPE_WLAN,
838                                                         &eeepc_rfkill_ops,
839                                                         (void *)CM_ASL_WLAN);
840
841                 if (!ehotk->eeepc_wlan_rfkill)
842                         goto wlan_fail;
843
844                 rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill,
845                                      get_acpi(CM_ASL_WLAN) != 1);
846                 result = rfkill_register(ehotk->eeepc_wlan_rfkill);
847                 if (result)
848                         goto wlan_fail;
849         }
850
851         if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
852                 ehotk->eeepc_bluetooth_rfkill =
853                         rfkill_alloc("eeepc-bluetooth",
854                                      &device->dev,
855                                      RFKILL_TYPE_BLUETOOTH,
856                                      &eeepc_rfkill_ops,
857                                      (void *)CM_ASL_BLUETOOTH);
858
859                 if (!ehotk->eeepc_bluetooth_rfkill)
860                         goto bluetooth_fail;
861
862                 rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill,
863                                      get_acpi(CM_ASL_BLUETOOTH) != 1);
864                 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
865                 if (result)
866                         goto bluetooth_fail;
867         }
868
869         result = eeepc_setup_pci_hotplug();
870         /*
871          * If we get -EBUSY then something else is handling the PCI hotplug -
872          * don't fail in this case
873          */
874         if (result == -EBUSY)
875                 return 0;
876         else if (result)
877                 goto pci_fail;
878
879         return 0;
880
881  pci_fail:
882         if (ehotk->eeepc_bluetooth_rfkill)
883                 rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
884  bluetooth_fail:
885         rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
886         rfkill_unregister(ehotk->eeepc_wlan_rfkill);
887  wlan_fail:
888         rfkill_destroy(ehotk->eeepc_wlan_rfkill);
889         eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
890         eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
891  ehotk_fail:
892         kfree(ehotk);
893         ehotk = NULL;
894
895         return result;
896 }
897
898 static int eeepc_hotk_remove(struct acpi_device *device, int type)
899 {
900         if (!device || !acpi_driver_data(device))
901                  return -EINVAL;
902
903         eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
904         eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
905         if (ehotk->hotplug_slot)
906                 pci_hp_deregister(ehotk->hotplug_slot);
907
908         kfree(ehotk);
909         return 0;
910 }
911
912 static int eeepc_hotk_resume(struct acpi_device *device)
913 {
914         if (ehotk->eeepc_wlan_rfkill) {
915                 bool wlan;
916
917                 /* Workaround - it seems that _PTS disables the wireless
918                    without notification or changing the value read by WLAN.
919                    Normally this is fine because the correct value is restored
920                    from the non-volatile storage on resume, but we need to do
921                    it ourself if case suspend is aborted, or we lose wireless.
922                  */
923                 wlan = get_acpi(CM_ASL_WLAN);
924                 set_acpi(CM_ASL_WLAN, wlan);
925
926                 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill,
927                                     wlan != 1);
928
929                 eeepc_rfkill_hotplug();
930         }
931
932         if (ehotk->eeepc_bluetooth_rfkill)
933                 rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill,
934                                     get_acpi(CM_ASL_BLUETOOTH) != 1);
935
936         return 0;
937 }
938
939 /*
940  * Hwmon
941  */
942 static int eeepc_get_fan_pwm(void)
943 {
944         int value = 0;
945
946         read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
947         value = value * 255 / 100;
948         return (value);
949 }
950
951 static void eeepc_set_fan_pwm(int value)
952 {
953         value = SENSORS_LIMIT(value, 0, 255);
954         value = value * 100 / 255;
955         ec_write(EEEPC_EC_SC02, value);
956 }
957
958 static int eeepc_get_fan_rpm(void)
959 {
960         int high = 0;
961         int low = 0;
962
963         read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
964         read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
965         return (high << 8 | low);
966 }
967
968 static int eeepc_get_fan_ctrl(void)
969 {
970         int value = 0;
971
972         read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
973         return ((value & 0x02 ? 1 : 0));
974 }
975
976 static void eeepc_set_fan_ctrl(int manual)
977 {
978         int value = 0;
979
980         read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
981         if (manual)
982                 value |= 0x02;
983         else
984                 value &= ~0x02;
985         ec_write(EEEPC_EC_SFB3, value);
986 }
987
988 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
989 {
990         int rv, value;
991
992         rv = parse_arg(buf, count, &value);
993         if (rv > 0)
994                 set(value);
995         return rv;
996 }
997
998 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
999 {
1000         return sprintf(buf, "%d\n", get());
1001 }
1002
1003 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)              \
1004         static ssize_t show_##_name(struct device *dev,                 \
1005                                     struct device_attribute *attr,      \
1006                                     char *buf)                          \
1007         {                                                               \
1008                 return show_sys_hwmon(_set, buf);                       \
1009         }                                                               \
1010         static ssize_t store_##_name(struct device *dev,                \
1011                                      struct device_attribute *attr,     \
1012                                      const char *buf, size_t count)     \
1013         {                                                               \
1014                 return store_sys_hwmon(_get, buf, count);               \
1015         }                                                               \
1016         static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
1017
1018 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
1019 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
1020                          eeepc_get_fan_pwm, eeepc_set_fan_pwm);
1021 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
1022                          eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
1023
1024 static ssize_t
1025 show_name(struct device *dev, struct device_attribute *attr, char *buf)
1026 {
1027         return sprintf(buf, "eeepc\n");
1028 }
1029 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
1030
1031 static struct attribute *hwmon_attributes[] = {
1032         &sensor_dev_attr_pwm1.dev_attr.attr,
1033         &sensor_dev_attr_fan1_input.dev_attr.attr,
1034         &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1035         &sensor_dev_attr_name.dev_attr.attr,
1036         NULL
1037 };
1038
1039 static struct attribute_group hwmon_attribute_group = {
1040         .attrs = hwmon_attributes
1041 };
1042
1043 /*
1044  * exit/init
1045  */
1046 static void eeepc_backlight_exit(void)
1047 {
1048         if (eeepc_backlight_device)
1049                 backlight_device_unregister(eeepc_backlight_device);
1050         eeepc_backlight_device = NULL;
1051 }
1052
1053 static void eeepc_rfkill_exit(void)
1054 {
1055         if (ehotk->eeepc_wlan_rfkill)
1056                 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
1057         if (ehotk->eeepc_bluetooth_rfkill)
1058                 rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
1059 }
1060
1061 static void eeepc_input_exit(void)
1062 {
1063         if (ehotk->inputdev)
1064                 input_unregister_device(ehotk->inputdev);
1065 }
1066
1067 static void eeepc_hwmon_exit(void)
1068 {
1069         struct device *hwmon;
1070
1071         hwmon = eeepc_hwmon_device;
1072         if (!hwmon)
1073                 return ;
1074         sysfs_remove_group(&hwmon->kobj,
1075                            &hwmon_attribute_group);
1076         hwmon_device_unregister(hwmon);
1077         eeepc_hwmon_device = NULL;
1078 }
1079
1080 static void __exit eeepc_laptop_exit(void)
1081 {
1082         eeepc_backlight_exit();
1083         eeepc_rfkill_exit();
1084         eeepc_input_exit();
1085         eeepc_hwmon_exit();
1086         acpi_bus_unregister_driver(&eeepc_hotk_driver);
1087         sysfs_remove_group(&platform_device->dev.kobj,
1088                            &platform_attribute_group);
1089         platform_device_unregister(platform_device);
1090         platform_driver_unregister(&platform_driver);
1091 }
1092
1093 static int eeepc_backlight_init(struct device *dev)
1094 {
1095         struct backlight_device *bd;
1096
1097         bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1098                                        NULL, &eeepcbl_ops);
1099         if (IS_ERR(bd)) {
1100                 pr_err("Could not register eeepc backlight device\n");
1101                 eeepc_backlight_device = NULL;
1102                 return PTR_ERR(bd);
1103         }
1104         eeepc_backlight_device = bd;
1105         bd->props.max_brightness = 15;
1106         bd->props.brightness = read_brightness(NULL);
1107         bd->props.power = FB_BLANK_UNBLANK;
1108         backlight_update_status(bd);
1109         return 0;
1110 }
1111
1112 static int eeepc_hwmon_init(struct device *dev)
1113 {
1114         struct device *hwmon;
1115         int result;
1116
1117         hwmon = hwmon_device_register(dev);
1118         if (IS_ERR(hwmon)) {
1119                 pr_err("Could not register eeepc hwmon device\n");
1120                 eeepc_hwmon_device = NULL;
1121                 return PTR_ERR(hwmon);
1122         }
1123         eeepc_hwmon_device = hwmon;
1124         result = sysfs_create_group(&hwmon->kobj,
1125                                     &hwmon_attribute_group);
1126         if (result)
1127                 eeepc_hwmon_exit();
1128         return result;
1129 }
1130
1131 static int __init eeepc_laptop_init(void)
1132 {
1133         struct device *dev;
1134         int result;
1135
1136         if (acpi_disabled)
1137                 return -ENODEV;
1138         result = acpi_bus_register_driver(&eeepc_hotk_driver);
1139         if (result < 0)
1140                 return result;
1141         if (!ehotk) {
1142                 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1143                 return -ENODEV;
1144         }
1145         dev = acpi_get_physical_device(ehotk->device->handle);
1146
1147         if (!acpi_video_backlight_support()) {
1148                 result = eeepc_backlight_init(dev);
1149                 if (result)
1150                         goto fail_backlight;
1151         } else
1152                 pr_info("Backlight controlled by ACPI video driver\n");
1153
1154         result = eeepc_hwmon_init(dev);
1155         if (result)
1156                 goto fail_hwmon;
1157
1158         eeepc_enable_camera();
1159
1160         /* Register platform stuff */
1161         result = platform_driver_register(&platform_driver);
1162         if (result)
1163                 goto fail_platform_driver;
1164         platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1165         if (!platform_device) {
1166                 result = -ENOMEM;
1167                 goto fail_platform_device1;
1168         }
1169         result = platform_device_add(platform_device);
1170         if (result)
1171                 goto fail_platform_device2;
1172         result = sysfs_create_group(&platform_device->dev.kobj,
1173                                     &platform_attribute_group);
1174         if (result)
1175                 goto fail_sysfs;
1176         return 0;
1177 fail_sysfs:
1178         platform_device_del(platform_device);
1179 fail_platform_device2:
1180         platform_device_put(platform_device);
1181 fail_platform_device1:
1182         platform_driver_unregister(&platform_driver);
1183 fail_platform_driver:
1184         eeepc_hwmon_exit();
1185 fail_hwmon:
1186         eeepc_backlight_exit();
1187 fail_backlight:
1188         eeepc_input_exit();
1189         eeepc_rfkill_exit();
1190         return result;
1191 }
1192
1193 module_init(eeepc_laptop_init);
1194 module_exit(eeepc_laptop_exit);