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