2 * eeepc-laptop.c - Asus Eee PC extras
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
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.
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.
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
28 #include <linux/hwmon.h>
29 #include <linux/hwmon-sysfs.h>
30 #include <acpi/acpi_drivers.h>
31 #include <acpi/acpi_bus.h>
32 #include <linux/uaccess.h>
33 #include <linux/input.h>
34 #include <linux/rfkill.h>
35 #include <linux/pci.h>
36 #include <linux/pci_hotplug.h>
37 #include <linux/leds.h>
38 #include <linux/dmi.h>
40 #define EEEPC_LAPTOP_VERSION "0.1"
41 #define EEEPC_LAPTOP_NAME "Eee PC Hotkey Driver"
42 #define EEEPC_LAPTOP_FILE "eeepc"
44 #define EEEPC_ACPI_CLASS "hotkey"
45 #define EEEPC_ACPI_DEVICE_NAME "Hotkey"
46 #define EEEPC_ACPI_HID "ASUS010"
48 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
49 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
50 MODULE_LICENSE("GPL");
53 * Definitions for Asus EeePC
55 #define NOTIFY_BRN_MIN 0x20
56 #define NOTIFY_BRN_MAX 0x2f
59 DISABLE_ASL_WLAN = 0x0001,
60 DISABLE_ASL_BLUETOOTH = 0x0002,
61 DISABLE_ASL_IRDA = 0x0004,
62 DISABLE_ASL_CAMERA = 0x0008,
63 DISABLE_ASL_TV = 0x0010,
64 DISABLE_ASL_GPS = 0x0020,
65 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
66 DISABLE_ASL_MODEM = 0x0080,
67 DISABLE_ASL_CARDREADER = 0x0100,
68 DISABLE_ASL_3G = 0x0200,
69 DISABLE_ASL_WIMAX = 0x0400,
70 DISABLE_ASL_HWCF = 0x0800
87 CM_ASL_CPUTEMPERATURE,
100 CM_ASL_PANELPOWER, /*P901*/
104 static const char *cm_getv[] = {
105 "WLDG", "BTHG", NULL, NULL,
106 "CAMG", NULL, NULL, NULL,
107 NULL, "PBLG", NULL, NULL,
108 "CFVG", NULL, NULL, NULL,
109 "USBG", NULL, NULL, "MODG",
110 "CRDG", "M3GG", "WIMG", "HWCF",
111 "LIDG", "TYPE", "PBPG", "TPDG"
114 static const char *cm_setv[] = {
115 "WLDS", "BTHS", NULL, NULL,
116 "CAMS", NULL, NULL, NULL,
117 "SDSP", "PBLS", "HDPS", NULL,
118 "CFVS", NULL, NULL, NULL,
119 "USBG", NULL, NULL, "MODS",
120 "CRDS", "M3GS", "WIMS", NULL,
121 NULL, NULL, "PBPS", "TPDS"
130 enum { KE_KEY, KE_END };
132 static const struct key_entry eeepc_keymap[] = {
133 /* Sleep already handled via generic ACPI code */
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 },
157 * This is the main structure, we can use it to store useful information
159 struct eeepc_laptop {
160 acpi_handle handle; /* the handle of the acpi device */
161 u32 cm_supported; /* the control methods supported
164 bool hotplug_disabled;
165 u16 event_count[128]; /* count for each event */
167 struct platform_device *platform_device;
168 struct device *hwmon_device;
169 struct backlight_device *backlight_device;
171 struct input_dev *inputdev;
172 struct key_entry *keymap;
174 struct rfkill *wlan_rfkill;
175 struct rfkill *bluetooth_rfkill;
176 struct rfkill *wwan3g_rfkill;
177 struct rfkill *wimax_rfkill;
179 struct hotplug_slot *hotplug_slot;
180 struct mutex hotplug_lock;
182 struct led_classdev tpd_led;
184 struct workqueue_struct *led_workqueue;
185 struct work_struct tpd_led_work;
191 static int write_acpi_int(acpi_handle handle, const char *method, int val)
193 struct acpi_object_list params;
194 union acpi_object in_obj;
198 params.pointer = &in_obj;
199 in_obj.type = ACPI_TYPE_INTEGER;
200 in_obj.integer.value = val;
202 status = acpi_evaluate_object(handle, (char *)method, ¶ms, NULL);
203 return (status == AE_OK ? 0 : -1);
206 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
209 unsigned long long result;
211 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
212 if (ACPI_FAILURE(status)) {
221 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
223 const char *method = cm_setv[cm];
227 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
230 if (write_acpi_int(eeepc->handle, method, value))
231 pr_warning("Error writing %s\n", method);
235 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
237 const char *method = cm_getv[cm];
242 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
245 if (read_acpi_int(eeepc->handle, method, &value))
246 pr_warning("Error reading %s\n", method);
250 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm,
253 const char *method = cm_setv[cm];
258 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
261 status = acpi_get_handle(eeepc->handle, (char *)method,
263 if (status != AE_OK) {
264 pr_warning("Error finding %s\n", method);
274 static int parse_arg(const char *buf, unsigned long count, int *val)
278 if (sscanf(buf, "%i", val) != 1)
283 static ssize_t store_sys_acpi(struct device *dev, int cm,
284 const char *buf, size_t count)
286 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
289 rv = parse_arg(buf, count, &value);
291 value = set_acpi(eeepc, cm, value);
297 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
299 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
300 int value = get_acpi(eeepc, cm);
304 return sprintf(buf, "%d\n", value);
307 #define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
308 static ssize_t show_##_name(struct device *dev, \
309 struct device_attribute *attr, \
312 return show_sys_acpi(dev, _cm, buf); \
314 static ssize_t store_##_name(struct device *dev, \
315 struct device_attribute *attr, \
316 const char *buf, size_t count) \
318 return store_sys_acpi(dev, _cm, buf, count); \
320 static struct device_attribute dev_attr_##_name = { \
322 .name = __stringify(_name), \
324 .show = show_##_name, \
325 .store = store_##_name, \
328 EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA);
329 EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER);
330 EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH);
337 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
339 c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
340 c->num = (c->cur >> 8) & 0xff;
342 if (c->cur < 0 || c->num <= 0 || c->num > 12)
347 static ssize_t show_available_cpufv(struct device *dev,
348 struct device_attribute *attr,
351 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
352 struct eeepc_cpufv c;
356 if (get_cpufv(eeepc, &c))
358 for (i = 0; i < c.num; i++)
359 len += sprintf(buf + len, "%d ", i);
360 len += sprintf(buf + len, "\n");
364 static ssize_t show_cpufv(struct device *dev,
365 struct device_attribute *attr,
368 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
369 struct eeepc_cpufv c;
371 if (get_cpufv(eeepc, &c))
373 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
376 static ssize_t store_cpufv(struct device *dev,
377 struct device_attribute *attr,
378 const char *buf, size_t count)
380 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
381 struct eeepc_cpufv c;
384 if (eeepc->cpufv_disabled)
386 if (get_cpufv(eeepc, &c))
388 rv = parse_arg(buf, count, &value);
391 if (!rv || value < 0 || value >= c.num)
393 set_acpi(eeepc, CM_ASL_CPUFV, value);
397 static ssize_t show_cpufv_disabled(struct device *dev,
398 struct device_attribute *attr,
401 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
403 return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
406 static ssize_t store_cpufv_disabled(struct device *dev,
407 struct device_attribute *attr,
408 const char *buf, size_t count)
410 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
413 rv = parse_arg(buf, count, &value);
419 if (eeepc->cpufv_disabled)
420 pr_warning("cpufv enabled (not officially supported "
422 eeepc->cpufv_disabled = false;
432 static struct device_attribute dev_attr_cpufv = {
440 static struct device_attribute dev_attr_available_cpufv = {
442 .name = "available_cpufv",
444 .show = show_available_cpufv
447 static struct device_attribute dev_attr_cpufv_disabled = {
449 .name = "cpufv_disabled",
451 .show = show_cpufv_disabled,
452 .store = store_cpufv_disabled
456 static struct attribute *platform_attributes[] = {
457 &dev_attr_camera.attr,
458 &dev_attr_cardr.attr,
460 &dev_attr_cpufv.attr,
461 &dev_attr_available_cpufv.attr,
462 &dev_attr_cpufv_disabled.attr,
466 static struct attribute_group platform_attribute_group = {
467 .attrs = platform_attributes
470 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
474 eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
475 if (!eeepc->platform_device)
477 platform_set_drvdata(eeepc->platform_device, eeepc);
479 result = platform_device_add(eeepc->platform_device);
481 goto fail_platform_device;
483 result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
484 &platform_attribute_group);
490 platform_device_del(eeepc->platform_device);
491 fail_platform_device:
492 platform_device_put(eeepc->platform_device);
496 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
498 sysfs_remove_group(&eeepc->platform_device->dev.kobj,
499 &platform_attribute_group);
500 platform_device_unregister(eeepc->platform_device);
507 * These functions actually update the LED's, and are called from a
508 * workqueue. By doing this as separate work rather than when the LED
509 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
510 * potentially bad time, such as a timer interrupt.
512 static void tpd_led_update(struct work_struct *work)
514 struct eeepc_laptop *eeepc;
516 eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
518 set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
521 static void tpd_led_set(struct led_classdev *led_cdev,
522 enum led_brightness value)
524 struct eeepc_laptop *eeepc;
526 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
528 eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
529 queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
532 static int eeepc_led_init(struct eeepc_laptop *eeepc)
536 if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
539 eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
540 if (!eeepc->led_workqueue)
542 INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
544 eeepc->tpd_led.name = "eeepc::touchpad";
545 eeepc->tpd_led.brightness_set = tpd_led_set;
546 eeepc->tpd_led.max_brightness = 1;
548 rv = led_classdev_register(&eeepc->platform_device->dev,
551 destroy_workqueue(eeepc->led_workqueue);
558 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
560 if (eeepc->tpd_led.dev)
561 led_classdev_unregister(&eeepc->tpd_led);
562 if (eeepc->led_workqueue)
563 destroy_workqueue(eeepc->led_workqueue);
568 * PCI hotplug (for wlan rfkill)
570 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
572 if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
577 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
581 bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
583 if (eeepc->wlan_rfkill)
584 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
586 mutex_lock(&eeepc->hotplug_lock);
588 if (eeepc->hotplug_slot) {
589 bus = pci_find_bus(0, 1);
591 pr_warning("Unable to find PCI bus 1?\n");
596 dev = pci_get_slot(bus, 0);
598 /* Device already present */
602 dev = pci_scan_single_device(bus, 0);
604 pci_bus_assign_resources(bus);
605 if (pci_bus_add_device(dev))
606 pr_err("Unable to hotplug wifi\n");
609 dev = pci_get_slot(bus, 0);
611 pci_remove_bus_device(dev);
618 mutex_unlock(&eeepc->hotplug_lock);
621 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
623 struct eeepc_laptop *eeepc = data;
625 if (event != ACPI_NOTIFY_BUS_CHECK)
628 eeepc_rfkill_hotplug(eeepc);
631 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
637 status = acpi_get_handle(NULL, node, &handle);
639 if (ACPI_SUCCESS(status)) {
640 status = acpi_install_notify_handler(handle,
644 if (ACPI_FAILURE(status))
645 pr_warning("Failed to register notify on %s\n", node);
652 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
655 acpi_status status = AE_OK;
658 status = acpi_get_handle(NULL, node, &handle);
660 if (ACPI_SUCCESS(status)) {
661 status = acpi_remove_notify_handler(handle,
663 eeepc_rfkill_notify);
664 if (ACPI_FAILURE(status))
665 pr_err("Error removing rfkill notify handler %s\n",
670 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
673 struct eeepc_laptop *eeepc = hotplug_slot->private;
674 int val = get_acpi(eeepc, CM_ASL_WLAN);
676 if (val == 1 || val == 0)
684 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
686 kfree(hotplug_slot->info);
690 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
691 .owner = THIS_MODULE,
692 .get_adapter_status = eeepc_get_adapter_status,
693 .get_power_status = eeepc_get_adapter_status,
696 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
699 struct pci_bus *bus = pci_find_bus(0, 1);
702 pr_err("Unable to find wifi PCI bus\n");
706 eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
707 if (!eeepc->hotplug_slot)
710 eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
712 if (!eeepc->hotplug_slot->info)
715 eeepc->hotplug_slot->private = eeepc;
716 eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
717 eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
718 eeepc_get_adapter_status(eeepc->hotplug_slot,
719 &eeepc->hotplug_slot->info->adapter_status);
721 ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
723 pr_err("Unable to register hotplug slot - %d\n", ret);
730 kfree(eeepc->hotplug_slot->info);
732 kfree(eeepc->hotplug_slot);
733 eeepc->hotplug_slot = NULL;
741 static int eeepc_rfkill_set(void *data, bool blocked)
743 acpi_handle handle = data;
745 return write_acpi_int(handle, NULL, !blocked);
748 static const struct rfkill_ops eeepc_rfkill_ops = {
749 .set_block = eeepc_rfkill_set,
752 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
753 struct rfkill **rfkill,
755 enum rfkill_type type, int cm)
760 result = acpi_setter_handle(eeepc, cm, &handle);
764 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
765 &eeepc_rfkill_ops, handle);
770 rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
771 result = rfkill_register(*rfkill);
773 rfkill_destroy(*rfkill);
780 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
782 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
783 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
784 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
785 if (eeepc->wlan_rfkill) {
786 rfkill_unregister(eeepc->wlan_rfkill);
787 rfkill_destroy(eeepc->wlan_rfkill);
788 eeepc->wlan_rfkill = NULL;
791 * Refresh pci hotplug in case the rfkill state was changed after
792 * eeepc_unregister_rfkill_notifier()
794 eeepc_rfkill_hotplug(eeepc);
795 if (eeepc->hotplug_slot)
796 pci_hp_deregister(eeepc->hotplug_slot);
798 if (eeepc->bluetooth_rfkill) {
799 rfkill_unregister(eeepc->bluetooth_rfkill);
800 rfkill_destroy(eeepc->bluetooth_rfkill);
801 eeepc->bluetooth_rfkill = NULL;
803 if (eeepc->wwan3g_rfkill) {
804 rfkill_unregister(eeepc->wwan3g_rfkill);
805 rfkill_destroy(eeepc->wwan3g_rfkill);
806 eeepc->wwan3g_rfkill = NULL;
808 if (eeepc->wimax_rfkill) {
809 rfkill_unregister(eeepc->wimax_rfkill);
810 rfkill_destroy(eeepc->wimax_rfkill);
811 eeepc->wimax_rfkill = NULL;
815 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
819 mutex_init(&eeepc->hotplug_lock);
821 result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
822 "eeepc-wlan", RFKILL_TYPE_WLAN,
825 if (result && result != -ENODEV)
828 result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
829 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
832 if (result && result != -ENODEV)
835 result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
836 "eeepc-wwan3g", RFKILL_TYPE_WWAN,
839 if (result && result != -ENODEV)
842 result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
843 "eeepc-wimax", RFKILL_TYPE_WIMAX,
846 if (result && result != -ENODEV)
849 if (eeepc->hotplug_disabled)
852 result = eeepc_setup_pci_hotplug(eeepc);
854 * If we get -EBUSY then something else is handling the PCI hotplug -
855 * don't fail in this case
857 if (result == -EBUSY)
860 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
861 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
862 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
864 * Refresh pci hotplug in case the rfkill state was changed during
867 eeepc_rfkill_hotplug(eeepc);
870 if (result && result != -ENODEV)
871 eeepc_rfkill_exit(eeepc);
876 * Platform driver - hibernate/resume callbacks
878 static int eeepc_hotk_thaw(struct device *device)
880 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
882 if (eeepc->wlan_rfkill) {
886 * Work around bios bug - acpi _PTS turns off the wireless led
887 * during suspend. Normally it restores it on resume, but
888 * we should kick it ourselves in case hibernation is aborted.
890 wlan = get_acpi(eeepc, CM_ASL_WLAN);
891 set_acpi(eeepc, CM_ASL_WLAN, wlan);
897 static int eeepc_hotk_restore(struct device *device)
899 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
901 /* Refresh both wlan rfkill state and pci hotplug */
902 if (eeepc->wlan_rfkill)
903 eeepc_rfkill_hotplug(eeepc);
905 if (eeepc->bluetooth_rfkill)
906 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
907 get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
908 if (eeepc->wwan3g_rfkill)
909 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
910 get_acpi(eeepc, CM_ASL_3G) != 1);
911 if (eeepc->wimax_rfkill)
912 rfkill_set_sw_state(eeepc->wimax_rfkill,
913 get_acpi(eeepc, CM_ASL_WIMAX) != 1);
918 static const struct dev_pm_ops eeepc_pm_ops = {
919 .thaw = eeepc_hotk_thaw,
920 .restore = eeepc_hotk_restore,
923 static struct platform_driver platform_driver = {
925 .name = EEEPC_LAPTOP_FILE,
926 .owner = THIS_MODULE,
935 #define EEEPC_EC_SC00 0x61
936 #define EEEPC_EC_FAN_PWM (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
937 #define EEEPC_EC_FAN_HRPM (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
938 #define EEEPC_EC_FAN_LRPM (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
940 #define EEEPC_EC_SFB0 0xD0
941 #define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */
943 static int eeepc_get_fan_pwm(void)
947 ec_read(EEEPC_EC_FAN_PWM, &value);
948 return value * 255 / 100;
951 static void eeepc_set_fan_pwm(int value)
953 value = SENSORS_LIMIT(value, 0, 255);
954 value = value * 100 / 255;
955 ec_write(EEEPC_EC_FAN_PWM, value);
958 static int eeepc_get_fan_rpm(void)
963 ec_read(EEEPC_EC_FAN_HRPM, &high);
964 ec_read(EEEPC_EC_FAN_LRPM, &low);
965 return high << 8 | low;
968 static int eeepc_get_fan_ctrl(void)
972 ec_read(EEEPC_EC_FAN_CTRL, &value);
974 return 1; /* manual */
976 return 2; /* automatic */
979 static void eeepc_set_fan_ctrl(int manual)
983 ec_read(EEEPC_EC_FAN_CTRL, &value);
988 ec_write(EEEPC_EC_FAN_CTRL, value);
991 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
995 rv = parse_arg(buf, count, &value);
1001 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
1003 return sprintf(buf, "%d\n", get());
1006 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
1007 static ssize_t show_##_name(struct device *dev, \
1008 struct device_attribute *attr, \
1011 return show_sys_hwmon(_set, buf); \
1013 static ssize_t store_##_name(struct device *dev, \
1014 struct device_attribute *attr, \
1015 const char *buf, size_t count) \
1017 return store_sys_hwmon(_get, buf, count); \
1019 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
1021 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
1022 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
1023 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
1024 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
1025 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
1028 show_name(struct device *dev, struct device_attribute *attr, char *buf)
1030 return sprintf(buf, "eeepc\n");
1032 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
1034 static struct attribute *hwmon_attributes[] = {
1035 &sensor_dev_attr_pwm1.dev_attr.attr,
1036 &sensor_dev_attr_fan1_input.dev_attr.attr,
1037 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1038 &sensor_dev_attr_name.dev_attr.attr,
1042 static struct attribute_group hwmon_attribute_group = {
1043 .attrs = hwmon_attributes
1046 static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
1048 struct device *hwmon;
1050 hwmon = eeepc->hwmon_device;
1053 sysfs_remove_group(&hwmon->kobj,
1054 &hwmon_attribute_group);
1055 hwmon_device_unregister(hwmon);
1056 eeepc->hwmon_device = NULL;
1059 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1061 struct device *hwmon;
1064 hwmon = hwmon_device_register(&eeepc->platform_device->dev);
1065 if (IS_ERR(hwmon)) {
1066 pr_err("Could not register eeepc hwmon device\n");
1067 eeepc->hwmon_device = NULL;
1068 return PTR_ERR(hwmon);
1070 eeepc->hwmon_device = hwmon;
1071 result = sysfs_create_group(&hwmon->kobj,
1072 &hwmon_attribute_group);
1074 eeepc_hwmon_exit(eeepc);
1081 static int read_brightness(struct backlight_device *bd)
1083 struct eeepc_laptop *eeepc = bl_get_data(bd);
1085 return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1088 static int set_brightness(struct backlight_device *bd, int value)
1090 struct eeepc_laptop *eeepc = bl_get_data(bd);
1092 return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1095 static int update_bl_status(struct backlight_device *bd)
1097 return set_brightness(bd, bd->props.brightness);
1100 static struct backlight_ops eeepcbl_ops = {
1101 .get_brightness = read_brightness,
1102 .update_status = update_bl_status,
1105 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1107 struct backlight_device *bd = eeepc->backlight_device;
1108 int old = bd->props.brightness;
1110 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1115 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1117 struct backlight_device *bd;
1119 bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1120 &eeepc->platform_device->dev,
1121 eeepc, &eeepcbl_ops);
1123 pr_err("Could not register eeepc backlight device\n");
1124 eeepc->backlight_device = NULL;
1127 eeepc->backlight_device = bd;
1128 bd->props.max_brightness = 15;
1129 bd->props.brightness = read_brightness(bd);
1130 bd->props.power = FB_BLANK_UNBLANK;
1131 backlight_update_status(bd);
1135 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1137 if (eeepc->backlight_device)
1138 backlight_device_unregister(eeepc->backlight_device);
1139 eeepc->backlight_device = NULL;
1144 * Input device (i.e. hotkeys)
1146 static struct key_entry *eeepc_get_entry_by_scancode(
1147 struct eeepc_laptop *eeepc,
1150 struct key_entry *key;
1152 for (key = eeepc->keymap; key->type != KE_END; key++)
1153 if (code == key->code)
1159 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1161 static struct key_entry *key;
1163 key = eeepc_get_entry_by_scancode(eeepc, event);
1165 switch (key->type) {
1167 input_report_key(eeepc->inputdev, key->keycode,
1169 input_sync(eeepc->inputdev);
1170 input_report_key(eeepc->inputdev, key->keycode,
1172 input_sync(eeepc->inputdev);
1178 static struct key_entry *eeepc_get_entry_by_keycode(
1179 struct eeepc_laptop *eeepc, int code)
1181 struct key_entry *key;
1183 for (key = eeepc->keymap; key->type != KE_END; key++)
1184 if (code == key->keycode && key->type == KE_KEY)
1190 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
1192 struct eeepc_laptop *eeepc = input_get_drvdata(dev);
1193 struct key_entry *key = eeepc_get_entry_by_scancode(eeepc, scancode);
1195 if (key && key->type == KE_KEY) {
1196 *keycode = key->keycode;
1203 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
1205 struct eeepc_laptop *eeepc = input_get_drvdata(dev);
1206 struct key_entry *key;
1209 if (keycode < 0 || keycode > KEY_MAX)
1212 key = eeepc_get_entry_by_scancode(eeepc, scancode);
1213 if (key && key->type == KE_KEY) {
1214 old_keycode = key->keycode;
1215 key->keycode = keycode;
1216 set_bit(keycode, dev->keybit);
1217 if (!eeepc_get_entry_by_keycode(eeepc, old_keycode))
1218 clear_bit(old_keycode, dev->keybit);
1225 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1227 const struct key_entry *key;
1230 eeepc->inputdev = input_allocate_device();
1231 if (!eeepc->inputdev) {
1232 pr_info("Unable to allocate input device\n");
1235 eeepc->inputdev->name = "Asus EeePC extra buttons";
1236 eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
1237 eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0";
1238 eeepc->inputdev->id.bustype = BUS_HOST;
1239 eeepc->inputdev->getkeycode = eeepc_getkeycode;
1240 eeepc->inputdev->setkeycode = eeepc_setkeycode;
1241 input_set_drvdata(eeepc->inputdev, eeepc);
1243 eeepc->keymap = kmemdup(eeepc_keymap, sizeof(eeepc_keymap),
1245 for (key = eeepc_keymap; key->type != KE_END; key++) {
1246 switch (key->type) {
1248 set_bit(EV_KEY, eeepc->inputdev->evbit);
1249 set_bit(key->keycode, eeepc->inputdev->keybit);
1253 result = input_register_device(eeepc->inputdev);
1255 pr_info("Unable to register input device\n");
1256 input_free_device(eeepc->inputdev);
1262 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1264 if (eeepc->inputdev) {
1265 input_unregister_device(eeepc->inputdev);
1266 kfree(eeepc->keymap);
1273 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1275 struct eeepc_laptop *eeepc = acpi_driver_data(device);
1278 if (event > ACPI_MAX_SYS_NOTIFY)
1280 count = eeepc->event_count[event % 128]++;
1281 acpi_bus_generate_proc_event(device, event, count);
1282 acpi_bus_generate_netlink_event(device->pnp.device_class,
1283 dev_name(&device->dev), event,
1286 /* Brightness events are special */
1287 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
1289 /* Ignore them completely if the acpi video driver is used */
1290 if (eeepc->backlight_device != NULL) {
1291 int old_brightness, new_brightness;
1293 /* Update the backlight device. */
1294 old_brightness = eeepc_backlight_notify(eeepc);
1296 /* Convert event to keypress (obsolescent hack) */
1297 new_brightness = event - NOTIFY_BRN_MIN;
1299 if (new_brightness < old_brightness) {
1300 event = NOTIFY_BRN_MIN; /* brightness down */
1301 } else if (new_brightness > old_brightness) {
1302 event = NOTIFY_BRN_MAX; /* brightness up */
1305 * no change in brightness - already at min/max,
1306 * event will be desired value (or else ignored)
1309 eeepc_input_notify(eeepc, event);
1312 /* Everything else is a bona-fide keypress event */
1313 eeepc_input_notify(eeepc, event);
1317 static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
1321 model = dmi_get_system_info(DMI_PRODUCT_NAME);
1326 * Blacklist for setting cpufv (cpu speed).
1328 * EeePC 4G ("701") implements CFVS, but it is not supported
1329 * by the pre-installed OS, and the original option to change it
1330 * in the BIOS setup screen was removed in later versions.
1332 * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
1333 * this applies to all "701" models (4G/4G Surf/2G Surf).
1335 * So Asus made a deliberate decision not to support it on this model.
1336 * We have several reports that using it can cause the system to hang
1338 * The hang has also been reported on a "702" (Model name "8G"?).
1340 * We avoid dmi_check_system() / dmi_match(), because they use
1341 * substring matching. We don't want to affect the "701SD"
1342 * and "701SDX" models, because they do support S.H.E.
1344 if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
1345 eeepc->cpufv_disabled = true;
1346 pr_info("model %s does not officially support setting cpu "
1348 pr_info("cpufv disabled to avoid instability\n");
1352 * Blacklist for wlan hotplug
1354 * Eeepc 1005HA doesn't work like others models and don't need the
1355 * hotplug code. In fact, current hotplug code seems to unplug another
1358 if (strcmp(model, "1005HA") == 0) {
1359 eeepc->hotplug_disabled = true;
1360 pr_info("wlan hotplug disabled\n");
1364 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1368 /* Some BIOSes do not report cm although it is avaliable.
1369 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1370 if (!(eeepc->cm_supported & (1 << cm))
1371 && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1372 pr_info("%s (%x) not reported by BIOS,"
1373 " enabling anyway\n", name, 1 << cm);
1374 eeepc->cm_supported |= 1 << cm;
1378 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1380 cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1381 cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1382 cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1383 cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1386 static int eeepc_acpi_init(struct eeepc_laptop *eeepc,
1387 struct acpi_device *device)
1389 unsigned int init_flags;
1392 result = acpi_bus_get_status(device);
1395 if (!device->status.present) {
1396 pr_err("Hotkey device not present, aborting\n");
1400 init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1401 pr_notice("Hotkey init flags 0x%x\n", init_flags);
1403 if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1404 pr_err("Hotkey initialization failed\n");
1408 /* get control methods supported */
1409 if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1410 pr_err("Get control methods supported failed\n");
1414 pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1419 static void __devinit eeepc_enable_camera(struct eeepc_laptop *eeepc)
1422 * If the following call to set_acpi() fails, it's because there's no
1423 * camera so we can ignore the error.
1425 if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1426 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1429 static bool eeepc_device_present;
1431 static int __devinit eeepc_acpi_add(struct acpi_device *device)
1433 struct eeepc_laptop *eeepc;
1436 pr_notice(EEEPC_LAPTOP_NAME "\n");
1437 eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1440 eeepc->handle = device->handle;
1441 strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1442 strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1443 device->driver_data = eeepc;
1445 eeepc_dmi_check(eeepc);
1447 result = eeepc_acpi_init(eeepc, device);
1450 eeepc_enable_camera(eeepc);
1453 * Register the platform device first. It is used as a parent for the
1454 * sub-devices below.
1456 * Note that if there are multiple instances of this ACPI device it
1457 * will bail out, because the platform device is registered with a
1458 * fixed name. Of course it doesn't make sense to have more than one,
1459 * and machine-specific scripts find the fixed name convenient. But
1460 * It's also good for us to exclude multiple instances because both
1461 * our hwmon and our wlan rfkill subdevice use global ACPI objects
1462 * (the EC and the wlan PCI slot respectively).
1464 result = eeepc_platform_init(eeepc);
1468 if (!acpi_video_backlight_support()) {
1469 result = eeepc_backlight_init(eeepc);
1471 goto fail_backlight;
1473 pr_info("Backlight controlled by ACPI video driver\n");
1475 result = eeepc_input_init(eeepc);
1479 result = eeepc_hwmon_init(eeepc);
1483 result = eeepc_led_init(eeepc);
1487 result = eeepc_rfkill_init(eeepc);
1491 eeepc_device_present = true;
1495 eeepc_led_exit(eeepc);
1497 eeepc_hwmon_exit(eeepc);
1499 eeepc_input_exit(eeepc);
1501 eeepc_backlight_exit(eeepc);
1503 eeepc_platform_exit(eeepc);
1510 static int eeepc_acpi_remove(struct acpi_device *device, int type)
1512 struct eeepc_laptop *eeepc = acpi_driver_data(device);
1514 eeepc_backlight_exit(eeepc);
1515 eeepc_rfkill_exit(eeepc);
1516 eeepc_input_exit(eeepc);
1517 eeepc_hwmon_exit(eeepc);
1518 eeepc_led_exit(eeepc);
1519 eeepc_platform_exit(eeepc);
1526 static const struct acpi_device_id eeepc_device_ids[] = {
1527 {EEEPC_ACPI_HID, 0},
1530 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1532 static struct acpi_driver eeepc_acpi_driver = {
1533 .name = EEEPC_LAPTOP_NAME,
1534 .class = EEEPC_ACPI_CLASS,
1535 .owner = THIS_MODULE,
1536 .ids = eeepc_device_ids,
1537 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1539 .add = eeepc_acpi_add,
1540 .remove = eeepc_acpi_remove,
1541 .notify = eeepc_acpi_notify,
1546 static int __init eeepc_laptop_init(void)
1550 result = platform_driver_register(&platform_driver);
1554 result = acpi_bus_register_driver(&eeepc_acpi_driver);
1556 goto fail_acpi_driver;
1557 if (!eeepc_device_present) {
1559 goto fail_no_device;
1564 acpi_bus_unregister_driver(&eeepc_acpi_driver);
1566 platform_driver_unregister(&platform_driver);
1570 static void __exit eeepc_laptop_exit(void)
1572 acpi_bus_unregister_driver(&eeepc_acpi_driver);
1573 platform_driver_unregister(&platform_driver);
1576 module_init(eeepc_laptop_init);
1577 module_exit(eeepc_laptop_exit);