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