OSDN Git Service

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