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