eeepc-laptop: rfkill refactoring
[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 *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 = -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->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         return 0;
832
833  ehotk_fail:
834         kfree(ehotk);
835         ehotk = NULL;
836
837         return result;
838 }
839
840 static int eeepc_hotk_remove(struct acpi_device *device, int type)
841 {
842         if (!device || !acpi_driver_data(device))
843                  return -EINVAL;
844
845         kfree(ehotk);
846         return 0;
847 }
848
849 static int eeepc_hotk_resume(struct acpi_device *device)
850 {
851         if (ehotk->wlan_rfkill) {
852                 bool wlan;
853
854                 /* Workaround - it seems that _PTS disables the wireless
855                    without notification or changing the value read by WLAN.
856                    Normally this is fine because the correct value is restored
857                    from the non-volatile storage on resume, but we need to do
858                    it ourself if case suspend is aborted, or we lose wireless.
859                  */
860                 wlan = get_acpi(CM_ASL_WLAN);
861                 set_acpi(CM_ASL_WLAN, wlan);
862
863                 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
864
865                 eeepc_rfkill_hotplug();
866         }
867
868         if (ehotk->bluetooth_rfkill)
869                 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
870                                     get_acpi(CM_ASL_BLUETOOTH) != 1);
871
872         return 0;
873 }
874
875 /*
876  * Hwmon
877  */
878 static int eeepc_get_fan_pwm(void)
879 {
880         int value = 0;
881
882         read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
883         value = value * 255 / 100;
884         return (value);
885 }
886
887 static void eeepc_set_fan_pwm(int value)
888 {
889         value = SENSORS_LIMIT(value, 0, 255);
890         value = value * 100 / 255;
891         ec_write(EEEPC_EC_SC02, value);
892 }
893
894 static int eeepc_get_fan_rpm(void)
895 {
896         int high = 0;
897         int low = 0;
898
899         read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
900         read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
901         return (high << 8 | low);
902 }
903
904 static int eeepc_get_fan_ctrl(void)
905 {
906         int value = 0;
907
908         read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
909         return ((value & 0x02 ? 1 : 0));
910 }
911
912 static void eeepc_set_fan_ctrl(int manual)
913 {
914         int value = 0;
915
916         read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
917         if (manual)
918                 value |= 0x02;
919         else
920                 value &= ~0x02;
921         ec_write(EEEPC_EC_SFB3, value);
922 }
923
924 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
925 {
926         int rv, value;
927
928         rv = parse_arg(buf, count, &value);
929         if (rv > 0)
930                 set(value);
931         return rv;
932 }
933
934 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
935 {
936         return sprintf(buf, "%d\n", get());
937 }
938
939 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)              \
940         static ssize_t show_##_name(struct device *dev,                 \
941                                     struct device_attribute *attr,      \
942                                     char *buf)                          \
943         {                                                               \
944                 return show_sys_hwmon(_set, buf);                       \
945         }                                                               \
946         static ssize_t store_##_name(struct device *dev,                \
947                                      struct device_attribute *attr,     \
948                                      const char *buf, size_t count)     \
949         {                                                               \
950                 return store_sys_hwmon(_get, buf, count);               \
951         }                                                               \
952         static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
953
954 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
955 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
956                          eeepc_get_fan_pwm, eeepc_set_fan_pwm);
957 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
958                          eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
959
960 static ssize_t
961 show_name(struct device *dev, struct device_attribute *attr, char *buf)
962 {
963         return sprintf(buf, "eeepc\n");
964 }
965 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
966
967 static struct attribute *hwmon_attributes[] = {
968         &sensor_dev_attr_pwm1.dev_attr.attr,
969         &sensor_dev_attr_fan1_input.dev_attr.attr,
970         &sensor_dev_attr_pwm1_enable.dev_attr.attr,
971         &sensor_dev_attr_name.dev_attr.attr,
972         NULL
973 };
974
975 static struct attribute_group hwmon_attribute_group = {
976         .attrs = hwmon_attributes
977 };
978
979 /*
980  * exit/init
981  */
982 static void eeepc_backlight_exit(void)
983 {
984         if (eeepc_backlight_device)
985                 backlight_device_unregister(eeepc_backlight_device);
986         eeepc_backlight_device = NULL;
987 }
988
989 static void eeepc_rfkill_exit(void)
990 {
991         eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
992         eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
993         if (ehotk->wlan_rfkill)
994                 rfkill_unregister(ehotk->wlan_rfkill);
995         if (ehotk->bluetooth_rfkill)
996                 rfkill_unregister(ehotk->bluetooth_rfkill);
997         if (ehotk->hotplug_slot)
998                 pci_hp_deregister(ehotk->hotplug_slot);
999 }
1000
1001 static void eeepc_input_exit(void)
1002 {
1003         if (ehotk->inputdev)
1004                 input_unregister_device(ehotk->inputdev);
1005 }
1006
1007 static void eeepc_hwmon_exit(void)
1008 {
1009         struct device *hwmon;
1010
1011         hwmon = eeepc_hwmon_device;
1012         if (!hwmon)
1013                 return ;
1014         sysfs_remove_group(&hwmon->kobj,
1015                            &hwmon_attribute_group);
1016         hwmon_device_unregister(hwmon);
1017         eeepc_hwmon_device = NULL;
1018 }
1019
1020 static void __exit eeepc_laptop_exit(void)
1021 {
1022         eeepc_backlight_exit();
1023         eeepc_rfkill_exit();
1024         eeepc_input_exit();
1025         eeepc_hwmon_exit();
1026         acpi_bus_unregister_driver(&eeepc_hotk_driver);
1027         sysfs_remove_group(&platform_device->dev.kobj,
1028                            &platform_attribute_group);
1029         platform_device_unregister(platform_device);
1030         platform_driver_unregister(&platform_driver);
1031 }
1032
1033 static int eeepc_new_rfkill(struct rfkill **rfkill,
1034                             const char *name, struct device *dev,
1035                             enum rfkill_type type, int cm)
1036 {
1037         int result;
1038
1039         if (get_acpi(cm) == -1)
1040                 return -ENODEV;
1041
1042         *rfkill = rfkill_alloc(name, dev, type,
1043                                &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1044
1045         if (!*rfkill)
1046                 return -EINVAL;
1047
1048         rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1049         result = rfkill_register(*rfkill);
1050         if (result) {
1051                 rfkill_destroy(*rfkill);
1052                 *rfkill = NULL;
1053                 return result;
1054         }
1055         return 0;
1056 }
1057
1058
1059 static int eeepc_rfkill_init(struct device *dev)
1060 {
1061         int result = 0;
1062
1063         eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1064         eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1065
1066         result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1067                                   "eeepc-wlan", dev,
1068                                   RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1069
1070         if (result && result != -ENODEV)
1071                 goto exit;
1072
1073         result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1074                                   "eeepc-bluetooth", dev,
1075                                   RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1076
1077         if (result && result != -ENODEV)
1078                 goto exit;
1079
1080         result = eeepc_setup_pci_hotplug();
1081         /*
1082          * If we get -EBUSY then something else is handling the PCI hotplug -
1083          * don't fail in this case
1084          */
1085         if (result == -EBUSY)
1086                 result = 0;
1087
1088 exit:
1089         if (result && result != -ENODEV)
1090                 eeepc_rfkill_exit();
1091         return result;
1092 }
1093
1094 static int eeepc_backlight_init(struct device *dev)
1095 {
1096         struct backlight_device *bd;
1097
1098         bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1099                                        NULL, &eeepcbl_ops);
1100         if (IS_ERR(bd)) {
1101                 pr_err("Could not register eeepc backlight device\n");
1102                 eeepc_backlight_device = NULL;
1103                 return PTR_ERR(bd);
1104         }
1105         eeepc_backlight_device = bd;
1106         bd->props.max_brightness = 15;
1107         bd->props.brightness = read_brightness(NULL);
1108         bd->props.power = FB_BLANK_UNBLANK;
1109         backlight_update_status(bd);
1110         return 0;
1111 }
1112
1113 static int eeepc_hwmon_init(struct device *dev)
1114 {
1115         struct device *hwmon;
1116         int result;
1117
1118         hwmon = hwmon_device_register(dev);
1119         if (IS_ERR(hwmon)) {
1120                 pr_err("Could not register eeepc hwmon device\n");
1121                 eeepc_hwmon_device = NULL;
1122                 return PTR_ERR(hwmon);
1123         }
1124         eeepc_hwmon_device = hwmon;
1125         result = sysfs_create_group(&hwmon->kobj,
1126                                     &hwmon_attribute_group);
1127         if (result)
1128                 eeepc_hwmon_exit();
1129         return result;
1130 }
1131
1132 static int __init eeepc_laptop_init(void)
1133 {
1134         struct device *dev;
1135         int result;
1136
1137         if (acpi_disabled)
1138                 return -ENODEV;
1139         result = acpi_bus_register_driver(&eeepc_hotk_driver);
1140         if (result < 0)
1141                 return result;
1142         if (!ehotk) {
1143                 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1144                 return -ENODEV;
1145         }
1146         dev = acpi_get_physical_device(ehotk->device->handle);
1147
1148         if (!acpi_video_backlight_support()) {
1149                 result = eeepc_backlight_init(dev);
1150                 if (result)
1151                         goto fail_backlight;
1152         } else
1153                 pr_info("Backlight controlled by ACPI video driver\n");
1154
1155         result = eeepc_hwmon_init(dev);
1156         if (result)
1157                 goto fail_hwmon;
1158
1159         eeepc_enable_camera();
1160
1161         /* Register platform stuff */
1162         result = platform_driver_register(&platform_driver);
1163         if (result)
1164                 goto fail_platform_driver;
1165         platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1166         if (!platform_device) {
1167                 result = -ENOMEM;
1168                 goto fail_platform_device1;
1169         }
1170         result = platform_device_add(platform_device);
1171         if (result)
1172                 goto fail_platform_device2;
1173         result = sysfs_create_group(&platform_device->dev.kobj,
1174                                     &platform_attribute_group);
1175         if (result)
1176                 goto fail_sysfs;
1177
1178         result = eeepc_rfkill_init(dev);
1179         if (result)
1180                 goto fail_rfkill;
1181
1182         return 0;
1183 fail_rfkill:
1184         sysfs_remove_group(&platform_device->dev.kobj,
1185                            &platform_attribute_group);
1186 fail_sysfs:
1187         platform_device_del(platform_device);
1188 fail_platform_device2:
1189         platform_device_put(platform_device);
1190 fail_platform_device1:
1191         platform_driver_unregister(&platform_driver);
1192 fail_platform_driver:
1193         eeepc_hwmon_exit();
1194 fail_hwmon:
1195         eeepc_backlight_exit();
1196 fail_backlight:
1197         eeepc_input_exit();
1198         return result;
1199 }
1200
1201 module_init(eeepc_laptop_init);
1202 module_exit(eeepc_laptop_exit);