eeepc-laptop: callbacks should use "driver data" parameter or field
[safe/jmp/linux-2.6] / drivers / platform / x86 / eeepc-laptop.c
1 /*
2  *  eeepc-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 #include <linux/leds.h>
38
39 #define EEEPC_LAPTOP_VERSION    "0.1"
40 #define EEEPC_LAPTOP_NAME       "Eee PC Hotkey Driver"
41 #define EEEPC_LAPTOP_FILE       "eeepc"
42
43 #define EEEPC_ACPI_CLASS        "hotkey"
44 #define EEEPC_ACPI_DEVICE_NAME  "Hotkey"
45 #define EEEPC_ACPI_HID          "ASUS010"
46
47 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
48 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
49 MODULE_LICENSE("GPL");
50
51 /*
52  * Definitions for Asus EeePC
53  */
54 #define NOTIFY_BRN_MIN  0x20
55 #define NOTIFY_BRN_MAX  0x2f
56
57 enum {
58         DISABLE_ASL_WLAN = 0x0001,
59         DISABLE_ASL_BLUETOOTH = 0x0002,
60         DISABLE_ASL_IRDA = 0x0004,
61         DISABLE_ASL_CAMERA = 0x0008,
62         DISABLE_ASL_TV = 0x0010,
63         DISABLE_ASL_GPS = 0x0020,
64         DISABLE_ASL_DISPLAYSWITCH = 0x0040,
65         DISABLE_ASL_MODEM = 0x0080,
66         DISABLE_ASL_CARDREADER = 0x0100,
67         DISABLE_ASL_3G = 0x0200,
68         DISABLE_ASL_WIMAX = 0x0400,
69         DISABLE_ASL_HWCF = 0x0800
70 };
71
72 enum {
73         CM_ASL_WLAN = 0,
74         CM_ASL_BLUETOOTH,
75         CM_ASL_IRDA,
76         CM_ASL_1394,
77         CM_ASL_CAMERA,
78         CM_ASL_TV,
79         CM_ASL_GPS,
80         CM_ASL_DVDROM,
81         CM_ASL_DISPLAYSWITCH,
82         CM_ASL_PANELBRIGHT,
83         CM_ASL_BIOSFLASH,
84         CM_ASL_ACPIFLASH,
85         CM_ASL_CPUFV,
86         CM_ASL_CPUTEMPERATURE,
87         CM_ASL_FANCPU,
88         CM_ASL_FANCHASSIS,
89         CM_ASL_USBPORT1,
90         CM_ASL_USBPORT2,
91         CM_ASL_USBPORT3,
92         CM_ASL_MODEM,
93         CM_ASL_CARDREADER,
94         CM_ASL_3G,
95         CM_ASL_WIMAX,
96         CM_ASL_HWCF,
97         CM_ASL_LID,
98         CM_ASL_TYPE,
99         CM_ASL_PANELPOWER,      /*P901*/
100         CM_ASL_TPD
101 };
102
103 static const char *cm_getv[] = {
104         "WLDG", "BTHG", NULL, NULL,
105         "CAMG", NULL, NULL, NULL,
106         NULL, "PBLG", NULL, NULL,
107         "CFVG", NULL, NULL, NULL,
108         "USBG", NULL, NULL, "MODG",
109         "CRDG", "M3GG", "WIMG", "HWCF",
110         "LIDG", "TYPE", "PBPG", "TPDG"
111 };
112
113 static const char *cm_setv[] = {
114         "WLDS", "BTHS", NULL, NULL,
115         "CAMS", NULL, NULL, NULL,
116         "SDSP", "PBLS", "HDPS", NULL,
117         "CFVS", NULL, NULL, NULL,
118         "USBG", NULL, NULL, "MODS",
119         "CRDS", "M3GS", "WIMS", NULL,
120         NULL, NULL, "PBPS", "TPDS"
121 };
122
123 struct key_entry {
124         char type;
125         u8 code;
126         u16 keycode;
127 };
128
129 enum { KE_KEY, KE_END };
130
131 static const struct key_entry eeepc_keymap[] = {
132         /* Sleep already handled via generic ACPI code */
133         {KE_KEY, 0x10, KEY_WLAN },
134         {KE_KEY, 0x11, KEY_WLAN },
135         {KE_KEY, 0x12, KEY_PROG1 },
136         {KE_KEY, 0x13, KEY_MUTE },
137         {KE_KEY, 0x14, KEY_VOLUMEDOWN },
138         {KE_KEY, 0x15, KEY_VOLUMEUP },
139         {KE_KEY, 0x1a, KEY_COFFEE },
140         {KE_KEY, 0x1b, KEY_ZOOM },
141         {KE_KEY, 0x1c, KEY_PROG2 },
142         {KE_KEY, 0x1d, KEY_PROG3 },
143         {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
144         {KE_KEY, NOTIFY_BRN_MAX, KEY_BRIGHTNESSUP },
145         {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
146         {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
147         {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
148         {KE_END, 0},
149 };
150
151
152 /*
153  * This is the main structure, we can use it to store useful information
154  */
155 struct eeepc_laptop {
156         acpi_handle handle;             /* the handle of the acpi device */
157         u32 cm_supported;               /* the control methods supported
158                                            by this BIOS */
159         u16 event_count[128];           /* count for each event */
160
161         struct platform_device *platform_device;
162         struct device *hwmon_device;
163         struct backlight_device *backlight_device;
164
165         struct input_dev *inputdev;
166         struct key_entry *keymap;
167
168         struct rfkill *wlan_rfkill;
169         struct rfkill *bluetooth_rfkill;
170         struct rfkill *wwan3g_rfkill;
171         struct rfkill *wimax_rfkill;
172
173         struct hotplug_slot *hotplug_slot;
174         struct mutex hotplug_lock;
175
176         struct led_classdev tpd_led;
177         int tpd_led_wk;
178         struct workqueue_struct *led_workqueue;
179         struct work_struct tpd_led_work;
180 };
181
182 /*
183  * ACPI Helpers
184  */
185 static int write_acpi_int(acpi_handle handle, const char *method, int val)
186 {
187         struct acpi_object_list params;
188         union acpi_object in_obj;
189         acpi_status status;
190
191         params.count = 1;
192         params.pointer = &in_obj;
193         in_obj.type = ACPI_TYPE_INTEGER;
194         in_obj.integer.value = val;
195
196         status = acpi_evaluate_object(handle, (char *)method, &params, NULL);
197         return (status == AE_OK ? 0 : -1);
198 }
199
200 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
201 {
202         acpi_status status;
203         unsigned long long result;
204
205         status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
206         if (ACPI_FAILURE(status)) {
207                 *val = -1;
208                 return -1;
209         } else {
210                 *val = result;
211                 return 0;
212         }
213 }
214
215 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
216 {
217         const char *method = cm_setv[cm];
218
219         if (method == NULL)
220                 return -ENODEV;
221         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
222                 return -ENODEV;
223
224         if (write_acpi_int(eeepc->handle, method, value))
225                 pr_warning("Error writing %s\n", method);
226         return 0;
227 }
228
229 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
230 {
231         const char *method = cm_getv[cm];
232         int value;
233
234         if (method == NULL)
235                 return -ENODEV;
236         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
237                 return -ENODEV;
238
239         if (read_acpi_int(eeepc->handle, method, &value))
240                 pr_warning("Error reading %s\n", method);
241         return value;
242 }
243
244 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm, acpi_handle *handle)
245 {
246         const char *method = cm_setv[cm];
247         acpi_status status;
248
249         if (method == NULL)
250                 return -ENODEV;
251         if ((eeepc->cm_supported & (0x1 << cm)) == 0)
252                 return -ENODEV;
253
254         status = acpi_get_handle(eeepc->handle, (char *)method,
255                                  handle);
256         if (status != AE_OK) {
257                 pr_warning("Error finding %s\n", method);
258                 return -ENODEV;
259         }
260         return 0;
261 }
262
263
264 /*
265  * Sys helpers
266  */
267 static int parse_arg(const char *buf, unsigned long count, int *val)
268 {
269         if (!count)
270                 return 0;
271         if (sscanf(buf, "%i", val) != 1)
272                 return -EINVAL;
273         return count;
274 }
275
276 static ssize_t store_sys_acpi(struct device *dev, int cm,
277                               const char *buf, size_t count)
278 {
279         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
280         int rv, value;
281
282         rv = parse_arg(buf, count, &value);
283         if (rv > 0)
284                 value = set_acpi(eeepc, cm, value);
285         if (value < 0)
286                 return -EIO;
287         return rv;
288 }
289
290 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
291 {
292         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
293         int value = get_acpi(eeepc, cm);
294
295         if (value < 0)
296                 return -EIO;
297         return sprintf(buf, "%d\n", value);
298 }
299
300 #define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm)                     \
301         static ssize_t show_##_name(struct device *dev,                 \
302                                     struct device_attribute *attr,      \
303                                     char *buf)                          \
304         {                                                               \
305                 return show_sys_acpi(dev, _cm, buf);                    \
306         }                                                               \
307         static ssize_t store_##_name(struct device *dev,                \
308                                      struct device_attribute *attr,     \
309                                      const char *buf, size_t count)     \
310         {                                                               \
311                 return store_sys_acpi(dev, _cm, buf, count);            \
312         }                                                               \
313         static struct device_attribute dev_attr_##_name = {             \
314                 .attr = {                                               \
315                         .name = __stringify(_name),                     \
316                         .mode = _mode },                                \
317                 .show   = show_##_name,                                 \
318                 .store  = store_##_name,                                \
319         }
320
321 EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA);
322 EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER);
323 EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH);
324
325 struct eeepc_cpufv {
326         int num;
327         int cur;
328 };
329
330 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
331 {
332         c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
333         c->num = (c->cur >> 8) & 0xff;
334         c->cur &= 0xff;
335         if (c->cur < 0 || c->num <= 0 || c->num > 12)
336                 return -ENODEV;
337         return 0;
338 }
339
340 static ssize_t show_available_cpufv(struct device *dev,
341                                     struct device_attribute *attr,
342                                     char *buf)
343 {
344         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
345         struct eeepc_cpufv c;
346         int i;
347         ssize_t len = 0;
348
349         if (get_cpufv(eeepc, &c))
350                 return -ENODEV;
351         for (i = 0; i < c.num; i++)
352                 len += sprintf(buf + len, "%d ", i);
353         len += sprintf(buf + len, "\n");
354         return len;
355 }
356
357 static ssize_t show_cpufv(struct device *dev,
358                           struct device_attribute *attr,
359                           char *buf)
360 {
361         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
362         struct eeepc_cpufv c;
363
364         if (get_cpufv(eeepc, &c))
365                 return -ENODEV;
366         return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
367 }
368
369 static ssize_t store_cpufv(struct device *dev,
370                            struct device_attribute *attr,
371                            const char *buf, size_t count)
372 {
373         struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
374         struct eeepc_cpufv c;
375         int rv, value;
376
377         if (get_cpufv(eeepc, &c))
378                 return -ENODEV;
379         rv = parse_arg(buf, count, &value);
380         if (rv < 0)
381                 return rv;
382         if (!rv || value < 0 || value >= c.num)
383                 return -EINVAL;
384         set_acpi(eeepc, CM_ASL_CPUFV, value);
385         return rv;
386 }
387
388 static struct device_attribute dev_attr_cpufv = {
389         .attr = {
390                 .name = "cpufv",
391                 .mode = 0644 },
392         .show   = show_cpufv,
393         .store  = store_cpufv
394 };
395
396 static struct device_attribute dev_attr_available_cpufv = {
397         .attr = {
398                 .name = "available_cpufv",
399                 .mode = 0444 },
400         .show   = show_available_cpufv
401 };
402
403 static struct attribute *platform_attributes[] = {
404         &dev_attr_camera.attr,
405         &dev_attr_cardr.attr,
406         &dev_attr_disp.attr,
407         &dev_attr_cpufv.attr,
408         &dev_attr_available_cpufv.attr,
409         NULL
410 };
411
412 static struct attribute_group platform_attribute_group = {
413         .attrs = platform_attributes
414 };
415
416 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
417 {
418         int result;
419
420         eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
421         if (!eeepc->platform_device)
422                 return -ENOMEM;
423         platform_set_drvdata(eeepc->platform_device, eeepc);
424
425         result = platform_device_add(eeepc->platform_device);
426         if (result)
427                 goto fail_platform_device;
428
429         result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
430                                     &platform_attribute_group);
431         if (result)
432                 goto fail_sysfs;
433         return 0;
434
435 fail_sysfs:
436         platform_device_del(eeepc->platform_device);
437 fail_platform_device:
438         platform_device_put(eeepc->platform_device);
439         return result;
440 }
441
442 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
443 {
444         sysfs_remove_group(&eeepc->platform_device->dev.kobj,
445                            &platform_attribute_group);
446         platform_device_unregister(eeepc->platform_device);
447 }
448
449 /*
450  * LEDs
451  */
452 /*
453  * These functions actually update the LED's, and are called from a
454  * workqueue. By doing this as separate work rather than when the LED
455  * subsystem asks, we avoid messing with the Asus ACPI stuff during a
456  * potentially bad time, such as a timer interrupt.
457  */
458 static void tpd_led_update(struct work_struct *work)
459  {
460         struct eeepc_laptop *eeepc;
461
462         eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
463
464         set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
465 }
466
467 static void tpd_led_set(struct led_classdev *led_cdev,
468                         enum led_brightness value)
469 {
470         struct eeepc_laptop *eeepc;
471
472         eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
473
474         eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
475         queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
476 }
477
478 static int eeepc_led_init(struct eeepc_laptop *eeepc)
479 {
480         int rv;
481
482         if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
483                 return 0;
484
485         eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
486         if (!eeepc->led_workqueue)
487                 return -ENOMEM;
488         INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
489
490         eeepc->tpd_led.name = "eeepc::touchpad";
491         eeepc->tpd_led.brightness_set = tpd_led_set;
492         eeepc->tpd_led.max_brightness = 1;
493
494         rv = led_classdev_register(&eeepc->platform_device->dev,
495                                    &eeepc->tpd_led);
496         if (rv) {
497                 destroy_workqueue(eeepc->led_workqueue);
498                 return rv;
499         }
500
501         return 0;
502 }
503
504 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
505 {
506         if (eeepc->tpd_led.dev)
507                 led_classdev_unregister(&eeepc->tpd_led);
508         if (eeepc->led_workqueue)
509                 destroy_workqueue(eeepc->led_workqueue);
510 }
511
512
513 /*
514  * PCI hotplug (for wlan rfkill)
515  */
516 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
517 {
518         if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
519                 return false;
520         return true;
521 }
522
523 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
524 {
525         struct pci_dev *dev;
526         struct pci_bus *bus;
527         bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
528
529         if (eeepc->wlan_rfkill)
530                 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
531
532         mutex_lock(&eeepc->hotplug_lock);
533
534         if (eeepc->hotplug_slot) {
535                 bus = pci_find_bus(0, 1);
536                 if (!bus) {
537                         pr_warning("Unable to find PCI bus 1?\n");
538                         goto out_unlock;
539                 }
540
541                 if (!blocked) {
542                         dev = pci_get_slot(bus, 0);
543                         if (dev) {
544                                 /* Device already present */
545                                 pci_dev_put(dev);
546                                 goto out_unlock;
547                         }
548                         dev = pci_scan_single_device(bus, 0);
549                         if (dev) {
550                                 pci_bus_assign_resources(bus);
551                                 if (pci_bus_add_device(dev))
552                                         pr_err("Unable to hotplug wifi\n");
553                         }
554                 } else {
555                         dev = pci_get_slot(bus, 0);
556                         if (dev) {
557                                 pci_remove_bus_device(dev);
558                                 pci_dev_put(dev);
559                         }
560                 }
561         }
562
563 out_unlock:
564         mutex_unlock(&eeepc->hotplug_lock);
565 }
566
567 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
568 {
569         struct eeepc_laptop *eeepc = data;
570
571         if (event != ACPI_NOTIFY_BUS_CHECK)
572                 return;
573
574         eeepc_rfkill_hotplug(eeepc);
575 }
576
577 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
578                                           char *node)
579 {
580         acpi_status status;
581         acpi_handle handle;
582
583         status = acpi_get_handle(NULL, node, &handle);
584
585         if (ACPI_SUCCESS(status)) {
586                 status = acpi_install_notify_handler(handle,
587                                                      ACPI_SYSTEM_NOTIFY,
588                                                      eeepc_rfkill_notify,
589                                                      eeepc);
590                 if (ACPI_FAILURE(status))
591                         pr_warning("Failed to register notify on %s\n", node);
592         } else
593                 return -ENODEV;
594
595         return 0;
596 }
597
598 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
599                                              char *node)
600 {
601         acpi_status status = AE_OK;
602         acpi_handle handle;
603
604         status = acpi_get_handle(NULL, node, &handle);
605
606         if (ACPI_SUCCESS(status)) {
607                 status = acpi_remove_notify_handler(handle,
608                                                      ACPI_SYSTEM_NOTIFY,
609                                                      eeepc_rfkill_notify);
610                 if (ACPI_FAILURE(status))
611                         pr_err("Error removing rfkill notify handler %s\n",
612                                 node);
613         }
614 }
615
616 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
617                                     u8 *value)
618 {
619         struct eeepc_laptop *eeepc = hotplug_slot->private;
620         int val = get_acpi(eeepc, CM_ASL_WLAN);
621
622         if (val == 1 || val == 0)
623                 *value = val;
624         else
625                 return -EINVAL;
626
627         return 0;
628 }
629
630 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
631 {
632         kfree(hotplug_slot->info);
633         kfree(hotplug_slot);
634 }
635
636 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
637         .owner = THIS_MODULE,
638         .get_adapter_status = eeepc_get_adapter_status,
639         .get_power_status = eeepc_get_adapter_status,
640 };
641
642 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
643 {
644         int ret = -ENOMEM;
645         struct pci_bus *bus = pci_find_bus(0, 1);
646
647         if (!bus) {
648                 pr_err("Unable to find wifi PCI bus\n");
649                 return -ENODEV;
650         }
651
652         eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
653         if (!eeepc->hotplug_slot)
654                 goto error_slot;
655
656         eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
657                                             GFP_KERNEL);
658         if (!eeepc->hotplug_slot->info)
659                 goto error_info;
660
661         eeepc->hotplug_slot->private = eeepc;
662         eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
663         eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
664         eeepc_get_adapter_status(eeepc->hotplug_slot,
665                                  &eeepc->hotplug_slot->info->adapter_status);
666
667         ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
668         if (ret) {
669                 pr_err("Unable to register hotplug slot - %d\n", ret);
670                 goto error_register;
671         }
672
673         return 0;
674
675 error_register:
676         kfree(eeepc->hotplug_slot->info);
677 error_info:
678         kfree(eeepc->hotplug_slot);
679         eeepc->hotplug_slot = NULL;
680 error_slot:
681         return ret;
682 }
683
684 /*
685  * Rfkill devices
686  */
687 static int eeepc_rfkill_set(void *data, bool blocked)
688 {
689         acpi_handle handle = data;
690
691         return write_acpi_int(handle, NULL, !blocked);
692 }
693
694 static const struct rfkill_ops eeepc_rfkill_ops = {
695         .set_block = eeepc_rfkill_set,
696 };
697
698 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
699                             struct rfkill **rfkill,
700                             const char *name,
701                             enum rfkill_type type, int cm)
702 {
703         acpi_handle handle;
704         int result;
705
706         result = acpi_setter_handle(eeepc, cm, &handle);
707         if (result < 0)
708                 return result;
709
710         *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
711                                &eeepc_rfkill_ops, handle);
712
713         if (!*rfkill)
714                 return -EINVAL;
715
716         rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
717         result = rfkill_register(*rfkill);
718         if (result) {
719                 rfkill_destroy(*rfkill);
720                 *rfkill = NULL;
721                 return result;
722         }
723         return 0;
724 }
725
726 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
727 {
728         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
729         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
730         eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
731         if (eeepc->wlan_rfkill) {
732                 rfkill_unregister(eeepc->wlan_rfkill);
733                 rfkill_destroy(eeepc->wlan_rfkill);
734                 eeepc->wlan_rfkill = NULL;
735         }
736         /*
737          * Refresh pci hotplug in case the rfkill state was changed after
738          * eeepc_unregister_rfkill_notifier()
739          */
740         eeepc_rfkill_hotplug(eeepc);
741         if (eeepc->hotplug_slot)
742                 pci_hp_deregister(eeepc->hotplug_slot);
743
744         if (eeepc->bluetooth_rfkill) {
745                 rfkill_unregister(eeepc->bluetooth_rfkill);
746                 rfkill_destroy(eeepc->bluetooth_rfkill);
747                 eeepc->bluetooth_rfkill = NULL;
748         }
749         if (eeepc->wwan3g_rfkill) {
750                 rfkill_unregister(eeepc->wwan3g_rfkill);
751                 rfkill_destroy(eeepc->wwan3g_rfkill);
752                 eeepc->wwan3g_rfkill = NULL;
753         }
754         if (eeepc->wimax_rfkill) {
755                 rfkill_unregister(eeepc->wimax_rfkill);
756                 rfkill_destroy(eeepc->wimax_rfkill);
757                 eeepc->wimax_rfkill = NULL;
758         }
759 }
760
761 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
762 {
763         int result = 0;
764
765         mutex_init(&eeepc->hotplug_lock);
766
767         result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
768                                   "eeepc-wlan", RFKILL_TYPE_WLAN,
769                                   CM_ASL_WLAN);
770
771         if (result && result != -ENODEV)
772                 goto exit;
773
774         result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
775                                   "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
776                                   CM_ASL_BLUETOOTH);
777
778         if (result && result != -ENODEV)
779                 goto exit;
780
781         result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
782                                   "eeepc-wwan3g", RFKILL_TYPE_WWAN,
783                                   CM_ASL_3G);
784
785         if (result && result != -ENODEV)
786                 goto exit;
787
788         result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
789                                   "eeepc-wimax", RFKILL_TYPE_WIMAX,
790                                   CM_ASL_WIMAX);
791
792         if (result && result != -ENODEV)
793                 goto exit;
794
795         result = eeepc_setup_pci_hotplug(eeepc);
796         /*
797          * If we get -EBUSY then something else is handling the PCI hotplug -
798          * don't fail in this case
799          */
800         if (result == -EBUSY)
801                 result = 0;
802
803         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
804         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
805         eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
806         /*
807          * Refresh pci hotplug in case the rfkill state was changed during
808          * setup.
809          */
810         eeepc_rfkill_hotplug(eeepc);
811
812 exit:
813         if (result && result != -ENODEV)
814                 eeepc_rfkill_exit(eeepc);
815         return result;
816 }
817
818 /*
819  * Platform driver - hibernate/resume callbacks
820  */
821 static int eeepc_hotk_thaw(struct device *device)
822 {
823         struct eeepc_laptop *eeepc = dev_get_drvdata(device);
824
825         if (eeepc->wlan_rfkill) {
826                 bool wlan;
827
828                 /*
829                  * Work around bios bug - acpi _PTS turns off the wireless led
830                  * during suspend.  Normally it restores it on resume, but
831                  * we should kick it ourselves in case hibernation is aborted.
832                  */
833                 wlan = get_acpi(eeepc, CM_ASL_WLAN);
834                 set_acpi(eeepc, CM_ASL_WLAN, wlan);
835         }
836
837         return 0;
838 }
839
840 static int eeepc_hotk_restore(struct device *device)
841 {
842         struct eeepc_laptop *eeepc = dev_get_drvdata(device);
843
844         /* Refresh both wlan rfkill state and pci hotplug */
845         if (eeepc->wlan_rfkill)
846                 eeepc_rfkill_hotplug(eeepc);
847
848         if (eeepc->bluetooth_rfkill)
849                 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
850                                     get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
851         if (eeepc->wwan3g_rfkill)
852                 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
853                                     get_acpi(eeepc, CM_ASL_3G) != 1);
854         if (eeepc->wimax_rfkill)
855                 rfkill_set_sw_state(eeepc->wimax_rfkill,
856                                     get_acpi(eeepc, CM_ASL_WIMAX) != 1);
857
858         return 0;
859 }
860
861 static struct dev_pm_ops eeepc_pm_ops = {
862         .thaw = eeepc_hotk_thaw,
863         .restore = eeepc_hotk_restore,
864 };
865
866 static struct platform_driver platform_driver = {
867         .driver = {
868                 .name = EEEPC_LAPTOP_FILE,
869                 .owner = THIS_MODULE,
870                 .pm = &eeepc_pm_ops,
871         }
872 };
873
874 /*
875  * Hwmon device
876  */
877
878 #define EEEPC_EC_SC00      0x61
879 #define EEEPC_EC_FAN_PWM   (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
880 #define EEEPC_EC_FAN_HRPM  (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
881 #define EEEPC_EC_FAN_LRPM  (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
882
883 #define EEEPC_EC_SFB0      0xD0
884 #define EEEPC_EC_FAN_CTRL  (EEEPC_EC_SFB0 + 3) /* Byte containing SF25  */
885
886 static int eeepc_get_fan_pwm(void)
887 {
888         u8 value = 0;
889
890         ec_read(EEEPC_EC_FAN_PWM, &value);
891         return value * 255 / 100;
892 }
893
894 static void eeepc_set_fan_pwm(int value)
895 {
896         value = SENSORS_LIMIT(value, 0, 255);
897         value = value * 100 / 255;
898         ec_write(EEEPC_EC_FAN_PWM, value);
899 }
900
901 static int eeepc_get_fan_rpm(void)
902 {
903         u8 high = 0;
904         u8 low = 0;
905
906         ec_read(EEEPC_EC_FAN_HRPM, &high);
907         ec_read(EEEPC_EC_FAN_LRPM, &low);
908         return high << 8 | low;
909 }
910
911 static int eeepc_get_fan_ctrl(void)
912 {
913         u8 value = 0;
914
915         ec_read(EEEPC_EC_FAN_CTRL, &value);
916         if (value & 0x02)
917                 return 1; /* manual */
918         else
919                 return 2; /* automatic */
920 }
921
922 static void eeepc_set_fan_ctrl(int manual)
923 {
924         u8 value = 0;
925
926         ec_read(EEEPC_EC_FAN_CTRL, &value);
927         if (manual == 1)
928                 value |= 0x02;
929         else
930                 value &= ~0x02;
931         ec_write(EEEPC_EC_FAN_CTRL, value);
932 }
933
934 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
935 {
936         int rv, value;
937
938         rv = parse_arg(buf, count, &value);
939         if (rv > 0)
940                 set(value);
941         return rv;
942 }
943
944 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
945 {
946         return sprintf(buf, "%d\n", get());
947 }
948
949 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get)              \
950         static ssize_t show_##_name(struct device *dev,                 \
951                                     struct device_attribute *attr,      \
952                                     char *buf)                          \
953         {                                                               \
954                 return show_sys_hwmon(_set, buf);                       \
955         }                                                               \
956         static ssize_t store_##_name(struct device *dev,                \
957                                      struct device_attribute *attr,     \
958                                      const char *buf, size_t count)     \
959         {                                                               \
960                 return store_sys_hwmon(_get, buf, count);               \
961         }                                                               \
962         static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
963
964 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
965 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
966                          eeepc_get_fan_pwm, eeepc_set_fan_pwm);
967 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
968                          eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
969
970 static ssize_t
971 show_name(struct device *dev, struct device_attribute *attr, char *buf)
972 {
973         return sprintf(buf, "eeepc\n");
974 }
975 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
976
977 static struct attribute *hwmon_attributes[] = {
978         &sensor_dev_attr_pwm1.dev_attr.attr,
979         &sensor_dev_attr_fan1_input.dev_attr.attr,
980         &sensor_dev_attr_pwm1_enable.dev_attr.attr,
981         &sensor_dev_attr_name.dev_attr.attr,
982         NULL
983 };
984
985 static struct attribute_group hwmon_attribute_group = {
986         .attrs = hwmon_attributes
987 };
988
989 static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
990 {
991         struct device *hwmon;
992
993         hwmon = eeepc->hwmon_device;
994         if (!hwmon)
995                 return;
996         sysfs_remove_group(&hwmon->kobj,
997                            &hwmon_attribute_group);
998         hwmon_device_unregister(hwmon);
999         eeepc->hwmon_device = NULL;
1000 }
1001
1002 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1003 {
1004         struct device *hwmon;
1005         int result;
1006
1007         hwmon = hwmon_device_register(&eeepc->platform_device->dev);
1008         if (IS_ERR(hwmon)) {
1009                 pr_err("Could not register eeepc hwmon device\n");
1010                 eeepc->hwmon_device = NULL;
1011                 return PTR_ERR(hwmon);
1012         }
1013         eeepc->hwmon_device = hwmon;
1014         result = sysfs_create_group(&hwmon->kobj,
1015                                     &hwmon_attribute_group);
1016         if (result)
1017                 eeepc_hwmon_exit(eeepc);
1018         return result;
1019 }
1020
1021 /*
1022  * Backlight device
1023  */
1024 static int read_brightness(struct backlight_device *bd)
1025 {
1026         struct eeepc_laptop *eeepc = bl_get_data(bd);
1027
1028         return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1029 }
1030
1031 static int set_brightness(struct backlight_device *bd, int value)
1032 {
1033         struct eeepc_laptop *eeepc = bl_get_data(bd);
1034
1035         return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1036 }
1037
1038 static int update_bl_status(struct backlight_device *bd)
1039 {
1040         return set_brightness(bd, bd->props.brightness);
1041 }
1042
1043 static struct backlight_ops eeepcbl_ops = {
1044         .get_brightness = read_brightness,
1045         .update_status = update_bl_status,
1046 };
1047
1048 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1049 {
1050         struct backlight_device *bd = eeepc->backlight_device;
1051         int old = bd->props.brightness;
1052
1053         backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1054
1055         return old;
1056 }
1057
1058 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1059 {
1060         struct backlight_device *bd;
1061
1062         bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1063                                        &eeepc->platform_device->dev,
1064                                        eeepc, &eeepcbl_ops);
1065         if (IS_ERR(bd)) {
1066                 pr_err("Could not register eeepc backlight device\n");
1067                 eeepc->backlight_device = NULL;
1068                 return PTR_ERR(bd);
1069         }
1070         eeepc->backlight_device = bd;
1071         bd->props.max_brightness = 15;
1072         bd->props.brightness = read_brightness(bd);
1073         bd->props.power = FB_BLANK_UNBLANK;
1074         backlight_update_status(bd);
1075         return 0;
1076 }
1077
1078 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1079 {
1080         if (eeepc->backlight_device)
1081                 backlight_device_unregister(eeepc->backlight_device);
1082         eeepc->backlight_device = NULL;
1083 }
1084
1085
1086 /*
1087  * Input device (i.e. hotkeys)
1088  */
1089 static struct key_entry *eeepc_get_entry_by_scancode(
1090         struct eeepc_laptop *eeepc,
1091         int code)
1092 {
1093         struct key_entry *key;
1094
1095         for (key = eeepc->keymap; key->type != KE_END; key++)
1096                 if (code == key->code)
1097                         return key;
1098
1099         return NULL;
1100 }
1101
1102 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1103 {
1104         static struct key_entry *key;
1105
1106         key = eeepc_get_entry_by_scancode(eeepc, event);
1107         if (key) {
1108                 switch (key->type) {
1109                 case KE_KEY:
1110                         input_report_key(eeepc->inputdev, key->keycode,
1111                                                 1);
1112                         input_sync(eeepc->inputdev);
1113                         input_report_key(eeepc->inputdev, key->keycode,
1114                                                 0);
1115                         input_sync(eeepc->inputdev);
1116                         break;
1117                 }
1118         }
1119 }
1120
1121 static struct key_entry *eeepc_get_entry_by_keycode(
1122         struct eeepc_laptop *eeepc, int code)
1123 {
1124         struct key_entry *key;
1125
1126         for (key = eeepc->keymap; key->type != KE_END; key++)
1127                 if (code == key->keycode && key->type == KE_KEY)
1128                         return key;
1129
1130         return NULL;
1131 }
1132
1133 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
1134 {
1135         struct eeepc_laptop *eeepc = input_get_drvdata(dev);
1136         struct key_entry *key = eeepc_get_entry_by_scancode(eeepc, scancode);
1137
1138         if (key && key->type == KE_KEY) {
1139                 *keycode = key->keycode;
1140                 return 0;
1141         }
1142
1143         return -EINVAL;
1144 }
1145
1146 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
1147 {
1148         struct eeepc_laptop *eeepc = input_get_drvdata(dev);
1149         struct key_entry *key;
1150         int old_keycode;
1151
1152         if (keycode < 0 || keycode > KEY_MAX)
1153                 return -EINVAL;
1154
1155         key = eeepc_get_entry_by_scancode(eeepc, scancode);
1156         if (key && key->type == KE_KEY) {
1157                 old_keycode = key->keycode;
1158                 key->keycode = keycode;
1159                 set_bit(keycode, dev->keybit);
1160                 if (!eeepc_get_entry_by_keycode(eeepc, old_keycode))
1161                         clear_bit(old_keycode, dev->keybit);
1162                 return 0;
1163         }
1164
1165         return -EINVAL;
1166 }
1167
1168 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1169 {
1170         const struct key_entry *key;
1171         int result;
1172
1173         eeepc->inputdev = input_allocate_device();
1174         if (!eeepc->inputdev) {
1175                 pr_info("Unable to allocate input device\n");
1176                 return -ENOMEM;
1177         }
1178         eeepc->inputdev->name = "Asus EeePC extra buttons";
1179         eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
1180         eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0";
1181         eeepc->inputdev->id.bustype = BUS_HOST;
1182         eeepc->inputdev->getkeycode = eeepc_getkeycode;
1183         eeepc->inputdev->setkeycode = eeepc_setkeycode;
1184         input_set_drvdata(eeepc->inputdev, eeepc);
1185
1186         eeepc->keymap = kmemdup(eeepc_keymap, sizeof(eeepc_keymap),
1187                                 GFP_KERNEL);
1188         for (key = eeepc_keymap; key->type != KE_END; key++) {
1189                 switch (key->type) {
1190                 case KE_KEY:
1191                         set_bit(EV_KEY, eeepc->inputdev->evbit);
1192                         set_bit(key->keycode, eeepc->inputdev->keybit);
1193                         break;
1194                 }
1195         }
1196         result = input_register_device(eeepc->inputdev);
1197         if (result) {
1198                 pr_info("Unable to register input device\n");
1199                 input_free_device(eeepc->inputdev);
1200                 return result;
1201         }
1202         return 0;
1203 }
1204
1205 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1206 {
1207         if (eeepc->inputdev) {
1208                 input_unregister_device(eeepc->inputdev);
1209                 kfree(eeepc->keymap);
1210         }
1211 }
1212
1213 /*
1214  * ACPI driver
1215  */
1216 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1217 {
1218         struct eeepc_laptop *eeepc = acpi_driver_data(device);
1219         u16 count;
1220
1221         if (event > ACPI_MAX_SYS_NOTIFY)
1222                 return;
1223         count = eeepc->event_count[event % 128]++;
1224         acpi_bus_generate_proc_event(device, event, count);
1225         acpi_bus_generate_netlink_event(device->pnp.device_class,
1226                                         dev_name(&device->dev), event,
1227                                         count);
1228
1229         if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
1230                 int old_brightness, new_brightness;
1231
1232                 /* Update backlight device. */
1233                 old_brightness = eeepc_backlight_notify(eeepc);
1234
1235                 /* Convert brightness event to keypress (obsolescent hack). */
1236                 new_brightness = event - NOTIFY_BRN_MIN;
1237
1238                 if (new_brightness < old_brightness) {
1239                         event = NOTIFY_BRN_MIN; /* brightness down */
1240                 } else if (new_brightness > old_brightness) {
1241                         event = NOTIFY_BRN_MAX; /* brightness up */
1242                 } else {
1243                         /*
1244                          * no change in brightness - already at min/max,
1245                          * event will be desired value (or else ignored).
1246                          */
1247                 }
1248         }
1249         eeepc_input_notify(eeepc, event);
1250 }
1251
1252 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1253 {
1254         int dummy;
1255
1256         /* Some BIOSes do not report cm although it is avaliable.
1257            Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1258         if (!(eeepc->cm_supported & (1 << cm))
1259             && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1260                 pr_info("%s (%x) not reported by BIOS,"
1261                         " enabling anyway\n", name, 1 << cm);
1262                 eeepc->cm_supported |= 1 << cm;
1263         }
1264 }
1265
1266 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1267 {
1268         cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1269         cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1270         cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1271         cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1272 }
1273
1274 static int eeepc_acpi_init(struct eeepc_laptop *eeepc, struct acpi_device *device)
1275 {
1276         unsigned int init_flags;
1277         int result;
1278
1279         result = acpi_bus_get_status(device);
1280         if (result)
1281                 return result;
1282         if (!device->status.present) {
1283                 pr_err("Hotkey device not present, aborting\n");
1284                 return -ENODEV;
1285         }
1286
1287         init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1288         pr_notice("Hotkey init flags 0x%x\n", init_flags);
1289
1290         if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1291                 pr_err("Hotkey initialization failed\n");
1292                 return -ENODEV;
1293         }
1294
1295         /* get control methods supported */
1296         if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1297                 pr_err("Get control methods supported failed\n");
1298                 return -ENODEV;
1299         }
1300         cmsg_quirks(eeepc);
1301         pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1302
1303         return 0;
1304 }
1305
1306 static void __devinit eeepc_enable_camera(struct eeepc_laptop *eeepc)
1307 {
1308         /*
1309          * If the following call to set_acpi() fails, it's because there's no
1310          * camera so we can ignore the error.
1311          */
1312         if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1313                 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1314 }
1315
1316 static bool eeepc_device_present;
1317
1318 static int __devinit eeepc_acpi_add(struct acpi_device *device)
1319 {
1320         struct eeepc_laptop *eeepc;
1321         int result;
1322
1323         pr_notice(EEEPC_LAPTOP_NAME "\n");
1324         eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1325         if (!eeepc)
1326                 return -ENOMEM;
1327         eeepc->handle = device->handle;
1328         strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1329         strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1330         device->driver_data = eeepc;
1331
1332         result = eeepc_acpi_init(eeepc, device);
1333         if (result)
1334                 goto fail_platform;
1335         eeepc_enable_camera(eeepc);
1336
1337         /*
1338          * Register the platform device first.  It is used as a parent for the
1339          * sub-devices below.
1340          *
1341          * Note that if there are multiple instances of this ACPI device it
1342          * will bail out, because the platform device is registered with a
1343          * fixed name.  Of course it doesn't make sense to have more than one,
1344          * and machine-specific scripts find the fixed name convenient.  But
1345          * It's also good for us to exclude multiple instances because both
1346          * our hwmon and our wlan rfkill subdevice use global ACPI objects
1347          * (the EC and the wlan PCI slot respectively).
1348          */
1349         result = eeepc_platform_init(eeepc);
1350         if (result)
1351                 goto fail_platform;
1352
1353         if (!acpi_video_backlight_support()) {
1354                 result = eeepc_backlight_init(eeepc);
1355                 if (result)
1356                         goto fail_backlight;
1357         } else
1358                 pr_info("Backlight controlled by ACPI video driver\n");
1359
1360         result = eeepc_input_init(eeepc);
1361         if (result)
1362                 goto fail_input;
1363
1364         result = eeepc_hwmon_init(eeepc);
1365         if (result)
1366                 goto fail_hwmon;
1367
1368         result = eeepc_led_init(eeepc);
1369         if (result)
1370                 goto fail_led;
1371
1372         result = eeepc_rfkill_init(eeepc);
1373         if (result)
1374                 goto fail_rfkill;
1375
1376         eeepc_device_present = true;
1377         return 0;
1378
1379 fail_rfkill:
1380         eeepc_led_exit(eeepc);
1381 fail_led:
1382         eeepc_hwmon_exit(eeepc);
1383 fail_hwmon:
1384         eeepc_input_exit(eeepc);
1385 fail_input:
1386         eeepc_backlight_exit(eeepc);
1387 fail_backlight:
1388         eeepc_platform_exit(eeepc);
1389 fail_platform:
1390         kfree(eeepc);
1391
1392         return result;
1393 }
1394
1395 static int eeepc_acpi_remove(struct acpi_device *device, int type)
1396 {
1397         struct eeepc_laptop *eeepc = acpi_driver_data(device);
1398
1399         eeepc_backlight_exit(eeepc);
1400         eeepc_rfkill_exit(eeepc);
1401         eeepc_input_exit(eeepc);
1402         eeepc_hwmon_exit(eeepc);
1403         eeepc_led_exit(eeepc);
1404         eeepc_platform_exit(eeepc);
1405
1406         kfree(eeepc);
1407         return 0;
1408 }
1409
1410
1411 static const struct acpi_device_id eeepc_device_ids[] = {
1412         {EEEPC_ACPI_HID, 0},
1413         {"", 0},
1414 };
1415 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1416
1417 static struct acpi_driver eeepc_acpi_driver = {
1418         .name = EEEPC_LAPTOP_NAME,
1419         .class = EEEPC_ACPI_CLASS,
1420         .owner = THIS_MODULE,
1421         .ids = eeepc_device_ids,
1422         .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1423         .ops = {
1424                 .add = eeepc_acpi_add,
1425                 .remove = eeepc_acpi_remove,
1426                 .notify = eeepc_acpi_notify,
1427         },
1428 };
1429
1430
1431 static int __init eeepc_laptop_init(void)
1432 {
1433         int result;
1434
1435         result = platform_driver_register(&platform_driver);
1436         if (result < 0)
1437                 return result;
1438
1439         result = acpi_bus_register_driver(&eeepc_acpi_driver);
1440         if (result < 0)
1441                 goto fail_acpi_driver;
1442         if (!eeepc_device_present) {
1443                 result = -ENODEV;
1444                 goto fail_no_device;
1445         }
1446         return 0;
1447
1448 fail_no_device:
1449         acpi_bus_unregister_driver(&eeepc_acpi_driver);
1450 fail_acpi_driver:
1451         platform_driver_unregister(&platform_driver);
1452         return result;
1453 }
1454
1455 static void __exit eeepc_laptop_exit(void)
1456 {
1457         acpi_bus_unregister_driver(&eeepc_acpi_driver);
1458         platform_driver_unregister(&platform_driver);
1459 }
1460
1461 module_init(eeepc_laptop_init);
1462 module_exit(eeepc_laptop_exit);