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