Merge tag 'platform-drivers-x86-v3.19-1' of git://git.infradead.org/users/dvhart...
[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_ACPI_SHOW_FUNC(_name, _cm) \
299 static ssize_t _name##_show(struct device *dev, \
300 struct device_attribute *attr, \
301 char *buf) \
302 { \
303 return show_sys_acpi(dev, _cm, buf); \
304 }
305
306 #define EEEPC_ACPI_STORE_FUNC(_name, _cm) \
307 static ssize_t _name##_store(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
314 #define EEEPC_CREATE_DEVICE_ATTR_RW(_name, _cm) \
315 EEEPC_ACPI_SHOW_FUNC(_name, _cm) \
316 EEEPC_ACPI_STORE_FUNC(_name, _cm) \
317 static DEVICE_ATTR_RW(_name)
318
319 #define EEEPC_CREATE_DEVICE_ATTR_WO(_name, _cm) \
320 EEEPC_ACPI_STORE_FUNC(_name, _cm) \
321 static DEVICE_ATTR_WO(_name)
322
323 EEEPC_CREATE_DEVICE_ATTR_RW(camera, CM_ASL_CAMERA);
324 EEEPC_CREATE_DEVICE_ATTR_RW(cardr, CM_ASL_CARDREADER);
325 EEEPC_CREATE_DEVICE_ATTR_WO(disp, CM_ASL_DISPLAYSWITCH);
326
327 struct eeepc_cpufv {
328 int num;
329 int cur;
330 };
331
332 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
333 {
334 c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
335 if (c->cur < 0)
336 return -ENODEV;
337
338 c->num = (c->cur >> 8) & 0xff;
339 c->cur &= 0xff;
340 if (c->num == 0 || c->num > 12)
341 return -ENODEV;
342 return 0;
343 }
344
345 static ssize_t available_cpufv_show(struct device *dev,
346 struct device_attribute *attr,
347 char *buf)
348 {
349 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
350 struct eeepc_cpufv c;
351 int i;
352 ssize_t len = 0;
353
354 if (get_cpufv(eeepc, &c))
355 return -ENODEV;
356 for (i = 0; i < c.num; i++)
357 len += sprintf(buf + len, "%d ", i);
358 len += sprintf(buf + len, "\n");
359 return len;
360 }
361
362 static ssize_t cpufv_show(struct device *dev,
363 struct device_attribute *attr,
364 char *buf)
365 {
366 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
367 struct eeepc_cpufv c;
368
369 if (get_cpufv(eeepc, &c))
370 return -ENODEV;
371 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
372 }
373
374 static ssize_t cpufv_store(struct device *dev,
375 struct device_attribute *attr,
376 const char *buf, size_t count)
377 {
378 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
379 struct eeepc_cpufv c;
380 int rv, value;
381
382 if (eeepc->cpufv_disabled)
383 return -EPERM;
384 if (get_cpufv(eeepc, &c))
385 return -ENODEV;
386 rv = parse_arg(buf, &value);
387 if (rv < 0)
388 return rv;
389 if (value < 0 || value >= c.num)
390 return -EINVAL;
391 rv = set_acpi(eeepc, CM_ASL_CPUFV, value);
392 if (rv)
393 return rv;
394 return count;
395 }
396
397 static ssize_t cpufv_disabled_show(struct device *dev,
398 struct device_attribute *attr,
399 char *buf)
400 {
401 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
402
403 return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
404 }
405
406 static ssize_t cpufv_disabled_store(struct device *dev,
407 struct device_attribute *attr,
408 const char *buf, size_t count)
409 {
410 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
411 int rv, value;
412
413 rv = parse_arg(buf, &value);
414 if (rv < 0)
415 return rv;
416
417 switch (value) {
418 case 0:
419 if (eeepc->cpufv_disabled)
420 pr_warn("cpufv enabled (not officially supported on this model)\n");
421 eeepc->cpufv_disabled = false;
422 return count;
423 case 1:
424 return -EPERM;
425 default:
426 return -EINVAL;
427 }
428 }
429
430
431 static DEVICE_ATTR_RW(cpufv);
432 static DEVICE_ATTR_RO(available_cpufv);
433 static DEVICE_ATTR_RW(cpufv_disabled);
434
435 static struct attribute *platform_attributes[] = {
436 &dev_attr_camera.attr,
437 &dev_attr_cardr.attr,
438 &dev_attr_disp.attr,
439 &dev_attr_cpufv.attr,
440 &dev_attr_available_cpufv.attr,
441 &dev_attr_cpufv_disabled.attr,
442 NULL
443 };
444
445 static struct attribute_group platform_attribute_group = {
446 .attrs = platform_attributes
447 };
448
449 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
450 {
451 int result;
452
453 eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
454 if (!eeepc->platform_device)
455 return -ENOMEM;
456 platform_set_drvdata(eeepc->platform_device, eeepc);
457
458 result = platform_device_add(eeepc->platform_device);
459 if (result)
460 goto fail_platform_device;
461
462 result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
463 &platform_attribute_group);
464 if (result)
465 goto fail_sysfs;
466 return 0;
467
468 fail_sysfs:
469 platform_device_del(eeepc->platform_device);
470 fail_platform_device:
471 platform_device_put(eeepc->platform_device);
472 return result;
473 }
474
475 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
476 {
477 sysfs_remove_group(&eeepc->platform_device->dev.kobj,
478 &platform_attribute_group);
479 platform_device_unregister(eeepc->platform_device);
480 }
481
482 /*
483 * LEDs
484 */
485 /*
486 * These functions actually update the LED's, and are called from a
487 * workqueue. By doing this as separate work rather than when the LED
488 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
489 * potentially bad time, such as a timer interrupt.
490 */
491 static void tpd_led_update(struct work_struct *work)
492 {
493 struct eeepc_laptop *eeepc;
494
495 eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
496
497 set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
498 }
499
500 static void tpd_led_set(struct led_classdev *led_cdev,
501 enum led_brightness value)
502 {
503 struct eeepc_laptop *eeepc;
504
505 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
506
507 eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
508 queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
509 }
510
511 static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
512 {
513 struct eeepc_laptop *eeepc;
514
515 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
516
517 return get_acpi(eeepc, CM_ASL_TPD);
518 }
519
520 static int eeepc_led_init(struct eeepc_laptop *eeepc)
521 {
522 int rv;
523
524 if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
525 return 0;
526
527 eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
528 if (!eeepc->led_workqueue)
529 return -ENOMEM;
530 INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
531
532 eeepc->tpd_led.name = "eeepc::touchpad";
533 eeepc->tpd_led.brightness_set = tpd_led_set;
534 if (get_acpi(eeepc, CM_ASL_TPD) >= 0) /* if method is available */
535 eeepc->tpd_led.brightness_get = tpd_led_get;
536 eeepc->tpd_led.max_brightness = 1;
537
538 rv = led_classdev_register(&eeepc->platform_device->dev,
539 &eeepc->tpd_led);
540 if (rv) {
541 destroy_workqueue(eeepc->led_workqueue);
542 return rv;
543 }
544
545 return 0;
546 }
547
548 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
549 {
550 if (!IS_ERR_OR_NULL(eeepc->tpd_led.dev))
551 led_classdev_unregister(&eeepc->tpd_led);
552 if (eeepc->led_workqueue)
553 destroy_workqueue(eeepc->led_workqueue);
554 }
555
556
557 /*
558 * PCI hotplug (for wlan rfkill)
559 */
560 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
561 {
562 if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
563 return false;
564 return true;
565 }
566
567 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
568 {
569 struct pci_dev *port;
570 struct pci_dev *dev;
571 struct pci_bus *bus;
572 bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
573 bool absent;
574 u32 l;
575
576 if (eeepc->wlan_rfkill)
577 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
578
579 mutex_lock(&eeepc->hotplug_lock);
580 pci_lock_rescan_remove();
581
582 if (!eeepc->hotplug_slot)
583 goto out_unlock;
584
585 port = acpi_get_pci_dev(handle);
586 if (!port) {
587 pr_warning("Unable to find port\n");
588 goto out_unlock;
589 }
590
591 bus = port->subordinate;
592
593 if (!bus) {
594 pr_warn("Unable to find PCI bus 1?\n");
595 goto out_put_dev;
596 }
597
598 if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
599 pr_err("Unable to read PCI config space?\n");
600 goto out_put_dev;
601 }
602
603 absent = (l == 0xffffffff);
604
605 if (blocked != absent) {
606 pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n",
607 blocked ? "blocked" : "unblocked",
608 absent ? "absent" : "present");
609 pr_warn("skipped wireless hotplug as probably inappropriate for this model\n");
610 goto out_put_dev;
611 }
612
613 if (!blocked) {
614 dev = pci_get_slot(bus, 0);
615 if (dev) {
616 /* Device already present */
617 pci_dev_put(dev);
618 goto out_put_dev;
619 }
620 dev = pci_scan_single_device(bus, 0);
621 if (dev) {
622 pci_bus_assign_resources(bus);
623 pci_bus_add_device(dev);
624 }
625 } else {
626 dev = pci_get_slot(bus, 0);
627 if (dev) {
628 pci_stop_and_remove_bus_device(dev);
629 pci_dev_put(dev);
630 }
631 }
632 out_put_dev:
633 pci_dev_put(port);
634
635 out_unlock:
636 pci_unlock_rescan_remove();
637 mutex_unlock(&eeepc->hotplug_lock);
638 }
639
640 static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node)
641 {
642 acpi_status status = AE_OK;
643 acpi_handle handle;
644
645 status = acpi_get_handle(NULL, node, &handle);
646
647 if (ACPI_SUCCESS(status))
648 eeepc_rfkill_hotplug(eeepc, handle);
649 }
650
651 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
652 {
653 struct eeepc_laptop *eeepc = data;
654
655 if (event != ACPI_NOTIFY_BUS_CHECK)
656 return;
657
658 eeepc_rfkill_hotplug(eeepc, handle);
659 }
660
661 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
662 char *node)
663 {
664 acpi_status status;
665 acpi_handle handle;
666
667 status = acpi_get_handle(NULL, node, &handle);
668
669 if (ACPI_FAILURE(status))
670 return -ENODEV;
671
672 status = acpi_install_notify_handler(handle,
673 ACPI_SYSTEM_NOTIFY,
674 eeepc_rfkill_notify,
675 eeepc);
676 if (ACPI_FAILURE(status))
677 pr_warn("Failed to register notify on %s\n", node);
678
679 /*
680 * Refresh pci hotplug in case the rfkill state was
681 * changed during setup.
682 */
683 eeepc_rfkill_hotplug(eeepc, handle);
684 return 0;
685 }
686
687 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
688 char *node)
689 {
690 acpi_status status = AE_OK;
691 acpi_handle handle;
692
693 status = acpi_get_handle(NULL, node, &handle);
694
695 if (ACPI_FAILURE(status))
696 return;
697
698 status = acpi_remove_notify_handler(handle,
699 ACPI_SYSTEM_NOTIFY,
700 eeepc_rfkill_notify);
701 if (ACPI_FAILURE(status))
702 pr_err("Error removing rfkill notify handler %s\n",
703 node);
704 /*
705 * Refresh pci hotplug in case the rfkill
706 * state was changed after
707 * eeepc_unregister_rfkill_notifier()
708 */
709 eeepc_rfkill_hotplug(eeepc, handle);
710 }
711
712 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
713 u8 *value)
714 {
715 struct eeepc_laptop *eeepc = hotplug_slot->private;
716 int val = get_acpi(eeepc, CM_ASL_WLAN);
717
718 if (val == 1 || val == 0)
719 *value = val;
720 else
721 return -EINVAL;
722
723 return 0;
724 }
725
726 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
727 {
728 kfree(hotplug_slot->info);
729 kfree(hotplug_slot);
730 }
731
732 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
733 .owner = THIS_MODULE,
734 .get_adapter_status = eeepc_get_adapter_status,
735 .get_power_status = eeepc_get_adapter_status,
736 };
737
738 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
739 {
740 int ret = -ENOMEM;
741 struct pci_bus *bus = pci_find_bus(0, 1);
742
743 if (!bus) {
744 pr_err("Unable to find wifi PCI bus\n");
745 return -ENODEV;
746 }
747
748 eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
749 if (!eeepc->hotplug_slot)
750 goto error_slot;
751
752 eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
753 GFP_KERNEL);
754 if (!eeepc->hotplug_slot->info)
755 goto error_info;
756
757 eeepc->hotplug_slot->private = eeepc;
758 eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
759 eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
760 eeepc_get_adapter_status(eeepc->hotplug_slot,
761 &eeepc->hotplug_slot->info->adapter_status);
762
763 ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
764 if (ret) {
765 pr_err("Unable to register hotplug slot - %d\n", ret);
766 goto error_register;
767 }
768
769 return 0;
770
771 error_register:
772 kfree(eeepc->hotplug_slot->info);
773 error_info:
774 kfree(eeepc->hotplug_slot);
775 eeepc->hotplug_slot = NULL;
776 error_slot:
777 return ret;
778 }
779
780 /*
781 * Rfkill devices
782 */
783 static int eeepc_rfkill_set(void *data, bool blocked)
784 {
785 acpi_handle handle = data;
786
787 return write_acpi_int(handle, NULL, !blocked);
788 }
789
790 static const struct rfkill_ops eeepc_rfkill_ops = {
791 .set_block = eeepc_rfkill_set,
792 };
793
794 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
795 struct rfkill **rfkill,
796 const char *name,
797 enum rfkill_type type, int cm)
798 {
799 acpi_handle handle;
800 int result;
801
802 result = acpi_setter_handle(eeepc, cm, &handle);
803 if (result < 0)
804 return result;
805
806 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
807 &eeepc_rfkill_ops, handle);
808
809 if (!*rfkill)
810 return -EINVAL;
811
812 rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
813 result = rfkill_register(*rfkill);
814 if (result) {
815 rfkill_destroy(*rfkill);
816 *rfkill = NULL;
817 return result;
818 }
819 return 0;
820 }
821
822 static char EEEPC_RFKILL_NODE_1[] = "\\_SB.PCI0.P0P5";
823 static char EEEPC_RFKILL_NODE_2[] = "\\_SB.PCI0.P0P6";
824 static char EEEPC_RFKILL_NODE_3[] = "\\_SB.PCI0.P0P7";
825
826 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
827 {
828 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
829 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
830 eeepc_unregister_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
831 if (eeepc->wlan_rfkill) {
832 rfkill_unregister(eeepc->wlan_rfkill);
833 rfkill_destroy(eeepc->wlan_rfkill);
834 eeepc->wlan_rfkill = NULL;
835 }
836
837 if (eeepc->hotplug_slot)
838 pci_hp_deregister(eeepc->hotplug_slot);
839
840 if (eeepc->bluetooth_rfkill) {
841 rfkill_unregister(eeepc->bluetooth_rfkill);
842 rfkill_destroy(eeepc->bluetooth_rfkill);
843 eeepc->bluetooth_rfkill = NULL;
844 }
845 if (eeepc->wwan3g_rfkill) {
846 rfkill_unregister(eeepc->wwan3g_rfkill);
847 rfkill_destroy(eeepc->wwan3g_rfkill);
848 eeepc->wwan3g_rfkill = NULL;
849 }
850 if (eeepc->wimax_rfkill) {
851 rfkill_unregister(eeepc->wimax_rfkill);
852 rfkill_destroy(eeepc->wimax_rfkill);
853 eeepc->wimax_rfkill = NULL;
854 }
855 }
856
857 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
858 {
859 int result = 0;
860
861 mutex_init(&eeepc->hotplug_lock);
862
863 result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
864 "eeepc-wlan", RFKILL_TYPE_WLAN,
865 CM_ASL_WLAN);
866
867 if (result && result != -ENODEV)
868 goto exit;
869
870 result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
871 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
872 CM_ASL_BLUETOOTH);
873
874 if (result && result != -ENODEV)
875 goto exit;
876
877 result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
878 "eeepc-wwan3g", RFKILL_TYPE_WWAN,
879 CM_ASL_3G);
880
881 if (result && result != -ENODEV)
882 goto exit;
883
884 result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
885 "eeepc-wimax", RFKILL_TYPE_WIMAX,
886 CM_ASL_WIMAX);
887
888 if (result && result != -ENODEV)
889 goto exit;
890
891 if (eeepc->hotplug_disabled)
892 return 0;
893
894 result = eeepc_setup_pci_hotplug(eeepc);
895 /*
896 * If we get -EBUSY then something else is handling the PCI hotplug -
897 * don't fail in this case
898 */
899 if (result == -EBUSY)
900 result = 0;
901
902 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_1);
903 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_2);
904 eeepc_register_rfkill_notifier(eeepc, EEEPC_RFKILL_NODE_3);
905
906 exit:
907 if (result && result != -ENODEV)
908 eeepc_rfkill_exit(eeepc);
909 return result;
910 }
911
912 /*
913 * Platform driver - hibernate/resume callbacks
914 */
915 static int eeepc_hotk_thaw(struct device *device)
916 {
917 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
918
919 if (eeepc->wlan_rfkill) {
920 int wlan;
921
922 /*
923 * Work around bios bug - acpi _PTS turns off the wireless led
924 * during suspend. Normally it restores it on resume, but
925 * we should kick it ourselves in case hibernation is aborted.
926 */
927 wlan = get_acpi(eeepc, CM_ASL_WLAN);
928 if (wlan >= 0)
929 set_acpi(eeepc, CM_ASL_WLAN, wlan);
930 }
931
932 return 0;
933 }
934
935 static int eeepc_hotk_restore(struct device *device)
936 {
937 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
938
939 /* Refresh both wlan rfkill state and pci hotplug */
940 if (eeepc->wlan_rfkill) {
941 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_1);
942 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_2);
943 eeepc_rfkill_hotplug_update(eeepc, EEEPC_RFKILL_NODE_3);
944 }
945
946 if (eeepc->bluetooth_rfkill)
947 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
948 get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
949 if (eeepc->wwan3g_rfkill)
950 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
951 get_acpi(eeepc, CM_ASL_3G) != 1);
952 if (eeepc->wimax_rfkill)
953 rfkill_set_sw_state(eeepc->wimax_rfkill,
954 get_acpi(eeepc, CM_ASL_WIMAX) != 1);
955
956 return 0;
957 }
958
959 static const struct dev_pm_ops eeepc_pm_ops = {
960 .thaw = eeepc_hotk_thaw,
961 .restore = eeepc_hotk_restore,
962 };
963
964 static struct platform_driver platform_driver = {
965 .driver = {
966 .name = EEEPC_LAPTOP_FILE,
967 .pm = &eeepc_pm_ops,
968 }
969 };
970
971 /*
972 * Hwmon device
973 */
974
975 #define EEEPC_EC_SC00 0x61
976 #define EEEPC_EC_FAN_PWM (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
977 #define EEEPC_EC_FAN_HRPM (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
978 #define EEEPC_EC_FAN_LRPM (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
979
980 #define EEEPC_EC_SFB0 0xD0
981 #define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */
982
983 static inline int eeepc_pwm_to_lmsensors(int value)
984 {
985 return value * 255 / 100;
986 }
987
988 static inline int eeepc_lmsensors_to_pwm(int value)
989 {
990 value = clamp_val(value, 0, 255);
991 return value * 100 / 255;
992 }
993
994 static int eeepc_get_fan_pwm(void)
995 {
996 u8 value = 0;
997
998 ec_read(EEEPC_EC_FAN_PWM, &value);
999 return eeepc_pwm_to_lmsensors(value);
1000 }
1001
1002 static void eeepc_set_fan_pwm(int value)
1003 {
1004 value = eeepc_lmsensors_to_pwm(value);
1005 ec_write(EEEPC_EC_FAN_PWM, value);
1006 }
1007
1008 static int eeepc_get_fan_rpm(void)
1009 {
1010 u8 high = 0;
1011 u8 low = 0;
1012
1013 ec_read(EEEPC_EC_FAN_HRPM, &high);
1014 ec_read(EEEPC_EC_FAN_LRPM, &low);
1015 return high << 8 | low;
1016 }
1017
1018 #define EEEPC_EC_FAN_CTRL_BIT 0x02
1019 #define EEEPC_FAN_CTRL_MANUAL 1
1020 #define EEEPC_FAN_CTRL_AUTO 2
1021
1022 static int eeepc_get_fan_ctrl(void)
1023 {
1024 u8 value = 0;
1025
1026 ec_read(EEEPC_EC_FAN_CTRL, &value);
1027 if (value & EEEPC_EC_FAN_CTRL_BIT)
1028 return EEEPC_FAN_CTRL_MANUAL;
1029 else
1030 return EEEPC_FAN_CTRL_AUTO;
1031 }
1032
1033 static void eeepc_set_fan_ctrl(int manual)
1034 {
1035 u8 value = 0;
1036
1037 ec_read(EEEPC_EC_FAN_CTRL, &value);
1038 if (manual == EEEPC_FAN_CTRL_MANUAL)
1039 value |= EEEPC_EC_FAN_CTRL_BIT;
1040 else
1041 value &= ~EEEPC_EC_FAN_CTRL_BIT;
1042 ec_write(EEEPC_EC_FAN_CTRL, value);
1043 }
1044
1045 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
1046 {
1047 int rv, value;
1048
1049 rv = parse_arg(buf, &value);
1050 if (rv < 0)
1051 return rv;
1052 set(value);
1053 return count;
1054 }
1055
1056 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1057 {
1058 return sprintf(buf, "%d\n", get());
1059 }
1060
1061 #define EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1062 static ssize_t _name##_show(struct device *dev, \
1063 struct device_attribute *attr, \
1064 char *buf) \
1065 { \
1066 return show_sys_hwmon(_get, buf); \
1067 }
1068
1069 #define EEEPC_SENSOR_STORE_FUNC(_name, _set) \
1070 static ssize_t _name##_store(struct device *dev, \
1071 struct device_attribute *attr, \
1072 const char *buf, size_t count) \
1073 { \
1074 return store_sys_hwmon(_set, buf, count); \
1075 }
1076
1077 #define EEEPC_CREATE_SENSOR_ATTR_RW(_name, _get, _set) \
1078 EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1079 EEEPC_SENSOR_STORE_FUNC(_name, _set) \
1080 static DEVICE_ATTR_RW(_name)
1081
1082 #define EEEPC_CREATE_SENSOR_ATTR_RO(_name, _get) \
1083 EEEPC_SENSOR_SHOW_FUNC(_name, _get) \
1084 static DEVICE_ATTR_RO(_name)
1085
1086 EEEPC_CREATE_SENSOR_ATTR_RO(fan1_input, eeepc_get_fan_rpm);
1087 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1, eeepc_get_fan_pwm,
1088 eeepc_set_fan_pwm);
1089 EEEPC_CREATE_SENSOR_ATTR_RW(pwm1_enable, eeepc_get_fan_ctrl,
1090 eeepc_set_fan_ctrl);
1091
1092 static struct attribute *hwmon_attrs[] = {
1093 &dev_attr_pwm1.attr,
1094 &dev_attr_fan1_input.attr,
1095 &dev_attr_pwm1_enable.attr,
1096 NULL
1097 };
1098 ATTRIBUTE_GROUPS(hwmon);
1099
1100 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1101 {
1102 struct device *dev = &eeepc->platform_device->dev;
1103 struct device *hwmon;
1104
1105 hwmon = devm_hwmon_device_register_with_groups(dev, "eeepc", NULL,
1106 hwmon_groups);
1107 if (IS_ERR(hwmon)) {
1108 pr_err("Could not register eeepc hwmon device\n");
1109 return PTR_ERR(hwmon);
1110 }
1111 return 0;
1112 }
1113
1114 /*
1115 * Backlight device
1116 */
1117 static int read_brightness(struct backlight_device *bd)
1118 {
1119 struct eeepc_laptop *eeepc = bl_get_data(bd);
1120
1121 return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1122 }
1123
1124 static int set_brightness(struct backlight_device *bd, int value)
1125 {
1126 struct eeepc_laptop *eeepc = bl_get_data(bd);
1127
1128 return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1129 }
1130
1131 static int update_bl_status(struct backlight_device *bd)
1132 {
1133 return set_brightness(bd, bd->props.brightness);
1134 }
1135
1136 static const struct backlight_ops eeepcbl_ops = {
1137 .get_brightness = read_brightness,
1138 .update_status = update_bl_status,
1139 };
1140
1141 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1142 {
1143 struct backlight_device *bd = eeepc->backlight_device;
1144 int old = bd->props.brightness;
1145
1146 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1147
1148 return old;
1149 }
1150
1151 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1152 {
1153 struct backlight_properties props;
1154 struct backlight_device *bd;
1155
1156 memset(&props, 0, sizeof(struct backlight_properties));
1157 props.type = BACKLIGHT_PLATFORM;
1158 props.max_brightness = 15;
1159 bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1160 &eeepc->platform_device->dev, eeepc,
1161 &eeepcbl_ops, &props);
1162 if (IS_ERR(bd)) {
1163 pr_err("Could not register eeepc backlight device\n");
1164 eeepc->backlight_device = NULL;
1165 return PTR_ERR(bd);
1166 }
1167 eeepc->backlight_device = bd;
1168 bd->props.brightness = read_brightness(bd);
1169 bd->props.power = FB_BLANK_UNBLANK;
1170 backlight_update_status(bd);
1171 return 0;
1172 }
1173
1174 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1175 {
1176 backlight_device_unregister(eeepc->backlight_device);
1177 eeepc->backlight_device = NULL;
1178 }
1179
1180
1181 /*
1182 * Input device (i.e. hotkeys)
1183 */
1184 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1185 {
1186 struct input_dev *input;
1187 int error;
1188
1189 input = input_allocate_device();
1190 if (!input)
1191 return -ENOMEM;
1192
1193 input->name = "Asus EeePC extra buttons";
1194 input->phys = EEEPC_LAPTOP_FILE "/input0";
1195 input->id.bustype = BUS_HOST;
1196 input->dev.parent = &eeepc->platform_device->dev;
1197
1198 error = sparse_keymap_setup(input, eeepc_keymap, NULL);
1199 if (error) {
1200 pr_err("Unable to setup input device keymap\n");
1201 goto err_free_dev;
1202 }
1203
1204 error = input_register_device(input);
1205 if (error) {
1206 pr_err("Unable to register input device\n");
1207 goto err_free_keymap;
1208 }
1209
1210 eeepc->inputdev = input;
1211 return 0;
1212
1213 err_free_keymap:
1214 sparse_keymap_free(input);
1215 err_free_dev:
1216 input_free_device(input);
1217 return error;
1218 }
1219
1220 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1221 {
1222 if (eeepc->inputdev) {
1223 sparse_keymap_free(eeepc->inputdev);
1224 input_unregister_device(eeepc->inputdev);
1225 }
1226 eeepc->inputdev = NULL;
1227 }
1228
1229 /*
1230 * ACPI driver
1231 */
1232 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1233 {
1234 if (!eeepc->inputdev)
1235 return;
1236 if (!sparse_keymap_report_event(eeepc->inputdev, event, 1, true))
1237 pr_info("Unknown key %x pressed\n", event);
1238 }
1239
1240 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1241 {
1242 struct eeepc_laptop *eeepc = acpi_driver_data(device);
1243 int old_brightness, new_brightness;
1244 u16 count;
1245
1246 if (event > ACPI_MAX_SYS_NOTIFY)
1247 return;
1248 count = eeepc->event_count[event % 128]++;
1249 acpi_bus_generate_netlink_event(device->pnp.device_class,
1250 dev_name(&device->dev), event,
1251 count);
1252
1253 /* Brightness events are special */
1254 if (event < NOTIFY_BRN_MIN || event > NOTIFY_BRN_MAX) {
1255 eeepc_input_notify(eeepc, event);
1256 return;
1257 }
1258
1259 /* Ignore them completely if the acpi video driver is used */
1260 if (!eeepc->backlight_device)
1261 return;
1262
1263 /* Update the backlight device. */
1264 old_brightness = eeepc_backlight_notify(eeepc);
1265
1266 /* Convert event to keypress (obsolescent hack) */
1267 new_brightness = event - NOTIFY_BRN_MIN;
1268
1269 if (new_brightness < old_brightness) {
1270 event = NOTIFY_BRN_MIN; /* brightness down */
1271 } else if (new_brightness > old_brightness) {
1272 event = NOTIFY_BRN_MAX; /* brightness up */
1273 } else {
1274 /*
1275 * no change in brightness - already at min/max,
1276 * event will be desired value (or else ignored)
1277 */
1278 }
1279 eeepc_input_notify(eeepc, event);
1280 }
1281
1282 static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1283 {
1284 const char *model;
1285
1286 model = dmi_get_system_info(DMI_PRODUCT_NAME);
1287 if (!model)
1288 return;
1289
1290 /*
1291 * Blacklist for setting cpufv (cpu speed).
1292 *
1293 * EeePC 4G ("701") implements CFVS, but it is not supported
1294 * by the pre-installed OS, and the original option to change it
1295 * in the BIOS setup screen was removed in later versions.
1296 *
1297 * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1298 * this applies to all "701" models (4G/4G Surf/2G Surf).
1299 *
1300 * So Asus made a deliberate decision not to support it on this model.
1301 * We have several reports that using it can cause the system to hang
1302 *
1303 * The hang has also been reported on a "702" (Model name "8G"?).
1304 *
1305 * We avoid dmi_check_system() / dmi_match(), because they use
1306 * substring matching. We don't want to affect the "701SD"
1307 * and "701SDX" models, because they do support S.H.E.
1308 */
1309 if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1310 eeepc->cpufv_disabled = true;
1311 pr_info("model %s does not officially support setting cpu speed\n",
1312 model);
1313 pr_info("cpufv disabled to avoid instability\n");
1314 }
1315
1316 /*
1317 * Blacklist for wlan hotplug
1318 *
1319 * Eeepc 1005HA doesn't work like others models and don't need the
1320 * hotplug code. In fact, current hotplug code seems to unplug another
1321 * device...
1322 */
1323 if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
1324 strcmp(model, "1005PE") == 0) {
1325 eeepc->hotplug_disabled = true;
1326 pr_info("wlan hotplug disabled\n");
1327 }
1328 }
1329
1330 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1331 {
1332 int dummy;
1333
1334 /* Some BIOSes do not report cm although it is available.
1335 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1336 if (!(eeepc->cm_supported & (1 << cm))
1337 && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1338 pr_info("%s (%x) not reported by BIOS, enabling anyway\n",
1339 name, 1 << cm);
1340 eeepc->cm_supported |= 1 << cm;
1341 }
1342 }
1343
1344 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1345 {
1346 cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1347 cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1348 cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1349 cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1350 }
1351
1352 static int eeepc_acpi_init(struct eeepc_laptop *eeepc)
1353 {
1354 unsigned int init_flags;
1355 int result;
1356
1357 result = acpi_bus_get_status(eeepc->device);
1358 if (result)
1359 return result;
1360 if (!eeepc->device->status.present) {
1361 pr_err("Hotkey device not present, aborting\n");
1362 return -ENODEV;
1363 }
1364
1365 init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1366 pr_notice("Hotkey init flags 0x%x\n", init_flags);
1367
1368 if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1369 pr_err("Hotkey initialization failed\n");
1370 return -ENODEV;
1371 }
1372
1373 /* get control methods supported */
1374 if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1375 pr_err("Get control methods supported failed\n");
1376 return -ENODEV;
1377 }
1378 cmsg_quirks(eeepc);
1379 pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1380
1381 return 0;
1382 }
1383
1384 static void eeepc_enable_camera(struct eeepc_laptop *eeepc)
1385 {
1386 /*
1387 * If the following call to set_acpi() fails, it's because there's no
1388 * camera so we can ignore the error.
1389 */
1390 if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1391 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1392 }
1393
1394 static bool eeepc_device_present;
1395
1396 static int eeepc_acpi_add(struct acpi_device *device)
1397 {
1398 struct eeepc_laptop *eeepc;
1399 int result;
1400
1401 pr_notice(EEEPC_LAPTOP_NAME "\n");
1402 eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1403 if (!eeepc)
1404 return -ENOMEM;
1405 eeepc->handle = device->handle;
1406 strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1407 strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1408 device->driver_data = eeepc;
1409 eeepc->device = device;
1410
1411 eeepc->hotplug_disabled = hotplug_disabled;
1412
1413 eeepc_dmi_check(eeepc);
1414
1415 result = eeepc_acpi_init(eeepc);
1416 if (result)
1417 goto fail_platform;
1418 eeepc_enable_camera(eeepc);
1419
1420 /*
1421 * Register the platform device first. It is used as a parent for the
1422 * sub-devices below.
1423 *
1424 * Note that if there are multiple instances of this ACPI device it
1425 * will bail out, because the platform device is registered with a
1426 * fixed name. Of course it doesn't make sense to have more than one,
1427 * and machine-specific scripts find the fixed name convenient. But
1428 * It's also good for us to exclude multiple instances because both
1429 * our hwmon and our wlan rfkill subdevice use global ACPI objects
1430 * (the EC and the wlan PCI slot respectively).
1431 */
1432 result = eeepc_platform_init(eeepc);
1433 if (result)
1434 goto fail_platform;
1435
1436 if (!acpi_video_backlight_support()) {
1437 result = eeepc_backlight_init(eeepc);
1438 if (result)
1439 goto fail_backlight;
1440 } else {
1441 pr_info("Backlight controlled by ACPI video driver\n");
1442 }
1443
1444 result = eeepc_input_init(eeepc);
1445 if (result)
1446 goto fail_input;
1447
1448 result = eeepc_hwmon_init(eeepc);
1449 if (result)
1450 goto fail_hwmon;
1451
1452 result = eeepc_led_init(eeepc);
1453 if (result)
1454 goto fail_led;
1455
1456 result = eeepc_rfkill_init(eeepc);
1457 if (result)
1458 goto fail_rfkill;
1459
1460 eeepc_device_present = true;
1461 return 0;
1462
1463 fail_rfkill:
1464 eeepc_led_exit(eeepc);
1465 fail_led:
1466 fail_hwmon:
1467 eeepc_input_exit(eeepc);
1468 fail_input:
1469 eeepc_backlight_exit(eeepc);
1470 fail_backlight:
1471 eeepc_platform_exit(eeepc);
1472 fail_platform:
1473 kfree(eeepc);
1474
1475 return result;
1476 }
1477
1478 static int eeepc_acpi_remove(struct acpi_device *device)
1479 {
1480 struct eeepc_laptop *eeepc = acpi_driver_data(device);
1481
1482 eeepc_backlight_exit(eeepc);
1483 eeepc_rfkill_exit(eeepc);
1484 eeepc_input_exit(eeepc);
1485 eeepc_led_exit(eeepc);
1486 eeepc_platform_exit(eeepc);
1487
1488 kfree(eeepc);
1489 return 0;
1490 }
1491
1492
1493 static const struct acpi_device_id eeepc_device_ids[] = {
1494 {EEEPC_ACPI_HID, 0},
1495 {"", 0},
1496 };
1497 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1498
1499 static struct acpi_driver eeepc_acpi_driver = {
1500 .name = EEEPC_LAPTOP_NAME,
1501 .class = EEEPC_ACPI_CLASS,
1502 .owner = THIS_MODULE,
1503 .ids = eeepc_device_ids,
1504 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1505 .ops = {
1506 .add = eeepc_acpi_add,
1507 .remove = eeepc_acpi_remove,
1508 .notify = eeepc_acpi_notify,
1509 },
1510 };
1511
1512
1513 static int __init eeepc_laptop_init(void)
1514 {
1515 int result;
1516
1517 result = platform_driver_register(&platform_driver);
1518 if (result < 0)
1519 return result;
1520
1521 result = acpi_bus_register_driver(&eeepc_acpi_driver);
1522 if (result < 0)
1523 goto fail_acpi_driver;
1524
1525 if (!eeepc_device_present) {
1526 result = -ENODEV;
1527 goto fail_no_device;
1528 }
1529
1530 return 0;
1531
1532 fail_no_device:
1533 acpi_bus_unregister_driver(&eeepc_acpi_driver);
1534 fail_acpi_driver:
1535 platform_driver_unregister(&platform_driver);
1536 return result;
1537 }
1538
1539 static void __exit eeepc_laptop_exit(void)
1540 {
1541 acpi_bus_unregister_driver(&eeepc_acpi_driver);
1542 platform_driver_unregister(&platform_driver);
1543 }
1544
1545 module_init(eeepc_laptop_init);
1546 module_exit(eeepc_laptop_exit);
This page took 0.110716 seconds and 5 git commands to generate.