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