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>
39 #define EEEPC_LAPTOP_VERSION "0.1"
40 #define EEEPC_LAPTOP_NAME "Eee PC Hotkey Driver"
41 #define EEEPC_LAPTOP_FILE "eeepc"
43 #define EEEPC_ACPI_CLASS "hotkey"
44 #define EEEPC_ACPI_DEVICE_NAME "Hotkey"
45 #define EEEPC_ACPI_HID "ASUS010"
47 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
48 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
49 MODULE_LICENSE("GPL");
52 * Definitions for Asus EeePC
54 #define NOTIFY_BRN_MIN 0x20
55 #define NOTIFY_BRN_MAX 0x2f
58 DISABLE_ASL_WLAN = 0x0001,
59 DISABLE_ASL_BLUETOOTH = 0x0002,
60 DISABLE_ASL_IRDA = 0x0004,
61 DISABLE_ASL_CAMERA = 0x0008,
62 DISABLE_ASL_TV = 0x0010,
63 DISABLE_ASL_GPS = 0x0020,
64 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
65 DISABLE_ASL_MODEM = 0x0080,
66 DISABLE_ASL_CARDREADER = 0x0100,
67 DISABLE_ASL_3G = 0x0200,
68 DISABLE_ASL_WIMAX = 0x0400,
69 DISABLE_ASL_HWCF = 0x0800
86 CM_ASL_CPUTEMPERATURE,
99 CM_ASL_PANELPOWER, /*P901*/
103 static const char *cm_getv[] = {
104 "WLDG", "BTHG", NULL, NULL,
105 "CAMG", NULL, NULL, NULL,
106 NULL, "PBLG", NULL, NULL,
107 "CFVG", NULL, NULL, NULL,
108 "USBG", NULL, NULL, "MODG",
109 "CRDG", "M3GG", "WIMG", "HWCF",
110 "LIDG", "TYPE", "PBPG", "TPDG"
113 static const char *cm_setv[] = {
114 "WLDS", "BTHS", NULL, NULL,
115 "CAMS", NULL, NULL, NULL,
116 "SDSP", "PBLS", "HDPS", NULL,
117 "CFVS", NULL, NULL, NULL,
118 "USBG", NULL, NULL, "MODS",
119 "CRDS", "M3GS", "WIMS", NULL,
120 NULL, NULL, "PBPS", "TPDS"
129 enum { KE_KEY, KE_END };
131 static const struct key_entry eeepc_keymap[] = {
132 /* Sleep already handled via generic ACPI code */
133 {KE_KEY, 0x10, KEY_WLAN },
134 {KE_KEY, 0x11, KEY_WLAN },
135 {KE_KEY, 0x12, KEY_PROG1 },
136 {KE_KEY, 0x13, KEY_MUTE },
137 {KE_KEY, 0x14, KEY_VOLUMEDOWN },
138 {KE_KEY, 0x15, KEY_VOLUMEUP },
139 {KE_KEY, 0x1a, KEY_COFFEE },
140 {KE_KEY, 0x1b, KEY_ZOOM },
141 {KE_KEY, 0x1c, KEY_PROG2 },
142 {KE_KEY, 0x1d, KEY_PROG3 },
143 {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
144 {KE_KEY, NOTIFY_BRN_MAX, KEY_BRIGHTNESSUP },
145 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
146 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
147 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
153 * This is the main structure, we can use it to store useful information
155 struct eeepc_laptop {
156 acpi_handle handle; /* the handle of the acpi device */
157 u32 cm_supported; /* the control methods supported
159 u16 event_count[128]; /* count for each event */
161 struct platform_device *platform_device;
162 struct device *hwmon_device;
163 struct backlight_device *backlight_device;
165 struct input_dev *inputdev;
166 struct key_entry *keymap;
168 struct rfkill *wlan_rfkill;
169 struct rfkill *bluetooth_rfkill;
170 struct rfkill *wwan3g_rfkill;
171 struct rfkill *wimax_rfkill;
173 struct hotplug_slot *hotplug_slot;
174 struct mutex hotplug_lock;
176 struct led_classdev tpd_led;
178 struct workqueue_struct *led_workqueue;
179 struct work_struct tpd_led_work;
185 static int write_acpi_int(acpi_handle handle, const char *method, int val)
187 struct acpi_object_list params;
188 union acpi_object in_obj;
192 params.pointer = &in_obj;
193 in_obj.type = ACPI_TYPE_INTEGER;
194 in_obj.integer.value = val;
196 status = acpi_evaluate_object(handle, (char *)method, ¶ms, NULL);
197 return (status == AE_OK ? 0 : -1);
200 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
203 unsigned long long result;
205 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
206 if (ACPI_FAILURE(status)) {
215 static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value)
217 const char *method = cm_setv[cm];
221 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
224 if (write_acpi_int(eeepc->handle, method, value))
225 pr_warning("Error writing %s\n", method);
229 static int get_acpi(struct eeepc_laptop *eeepc, int cm)
231 const char *method = cm_getv[cm];
236 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
239 if (read_acpi_int(eeepc->handle, method, &value))
240 pr_warning("Error reading %s\n", method);
244 static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm, acpi_handle *handle)
246 const char *method = cm_setv[cm];
251 if ((eeepc->cm_supported & (0x1 << cm)) == 0)
254 status = acpi_get_handle(eeepc->handle, (char *)method,
256 if (status != AE_OK) {
257 pr_warning("Error finding %s\n", method);
267 static int parse_arg(const char *buf, unsigned long count, int *val)
271 if (sscanf(buf, "%i", val) != 1)
276 static ssize_t store_sys_acpi(struct device *dev, int cm,
277 const char *buf, size_t count)
279 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
282 rv = parse_arg(buf, count, &value);
284 value = set_acpi(eeepc, cm, value);
290 static ssize_t show_sys_acpi(struct device *dev, int cm, char *buf)
292 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
293 int value = get_acpi(eeepc, cm);
297 return sprintf(buf, "%d\n", value);
300 #define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
301 static ssize_t show_##_name(struct device *dev, \
302 struct device_attribute *attr, \
305 return show_sys_acpi(dev, _cm, buf); \
307 static ssize_t store_##_name(struct device *dev, \
308 struct device_attribute *attr, \
309 const char *buf, size_t count) \
311 return store_sys_acpi(dev, _cm, buf, count); \
313 static struct device_attribute dev_attr_##_name = { \
315 .name = __stringify(_name), \
317 .show = show_##_name, \
318 .store = store_##_name, \
321 EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA);
322 EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER);
323 EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH);
330 static int get_cpufv(struct eeepc_laptop *eeepc, struct eeepc_cpufv *c)
332 c->cur = get_acpi(eeepc, CM_ASL_CPUFV);
333 c->num = (c->cur >> 8) & 0xff;
335 if (c->cur < 0 || c->num <= 0 || c->num > 12)
340 static ssize_t show_available_cpufv(struct device *dev,
341 struct device_attribute *attr,
344 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
345 struct eeepc_cpufv c;
349 if (get_cpufv(eeepc, &c))
351 for (i = 0; i < c.num; i++)
352 len += sprintf(buf + len, "%d ", i);
353 len += sprintf(buf + len, "\n");
357 static ssize_t show_cpufv(struct device *dev,
358 struct device_attribute *attr,
361 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
362 struct eeepc_cpufv c;
364 if (get_cpufv(eeepc, &c))
366 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
369 static ssize_t store_cpufv(struct device *dev,
370 struct device_attribute *attr,
371 const char *buf, size_t count)
373 struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
374 struct eeepc_cpufv c;
377 if (get_cpufv(eeepc, &c))
379 rv = parse_arg(buf, count, &value);
382 if (!rv || value < 0 || value >= c.num)
384 set_acpi(eeepc, CM_ASL_CPUFV, value);
388 static struct device_attribute dev_attr_cpufv = {
396 static struct device_attribute dev_attr_available_cpufv = {
398 .name = "available_cpufv",
400 .show = show_available_cpufv
403 static struct attribute *platform_attributes[] = {
404 &dev_attr_camera.attr,
405 &dev_attr_cardr.attr,
407 &dev_attr_cpufv.attr,
408 &dev_attr_available_cpufv.attr,
412 static struct attribute_group platform_attribute_group = {
413 .attrs = platform_attributes
416 static int eeepc_platform_init(struct eeepc_laptop *eeepc)
420 eeepc->platform_device = platform_device_alloc(EEEPC_LAPTOP_FILE, -1);
421 if (!eeepc->platform_device)
423 platform_set_drvdata(eeepc->platform_device, eeepc);
425 result = platform_device_add(eeepc->platform_device);
427 goto fail_platform_device;
429 result = sysfs_create_group(&eeepc->platform_device->dev.kobj,
430 &platform_attribute_group);
436 platform_device_del(eeepc->platform_device);
437 fail_platform_device:
438 platform_device_put(eeepc->platform_device);
442 static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
444 sysfs_remove_group(&eeepc->platform_device->dev.kobj,
445 &platform_attribute_group);
446 platform_device_unregister(eeepc->platform_device);
453 * These functions actually update the LED's, and are called from a
454 * workqueue. By doing this as separate work rather than when the LED
455 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
456 * potentially bad time, such as a timer interrupt.
458 static void tpd_led_update(struct work_struct *work)
460 struct eeepc_laptop *eeepc;
462 eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
464 set_acpi(eeepc, CM_ASL_TPD, eeepc->tpd_led_wk);
467 static void tpd_led_set(struct led_classdev *led_cdev,
468 enum led_brightness value)
470 struct eeepc_laptop *eeepc;
472 eeepc = container_of(led_cdev, struct eeepc_laptop, tpd_led);
474 eeepc->tpd_led_wk = (value > 0) ? 1 : 0;
475 queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
478 static int eeepc_led_init(struct eeepc_laptop *eeepc)
482 if (get_acpi(eeepc, CM_ASL_TPD) == -ENODEV)
485 eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
486 if (!eeepc->led_workqueue)
488 INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
490 eeepc->tpd_led.name = "eeepc::touchpad";
491 eeepc->tpd_led.brightness_set = tpd_led_set;
492 eeepc->tpd_led.max_brightness = 1;
494 rv = led_classdev_register(&eeepc->platform_device->dev,
497 destroy_workqueue(eeepc->led_workqueue);
504 static void eeepc_led_exit(struct eeepc_laptop *eeepc)
506 if (eeepc->tpd_led.dev)
507 led_classdev_unregister(&eeepc->tpd_led);
508 if (eeepc->led_workqueue)
509 destroy_workqueue(eeepc->led_workqueue);
514 * PCI hotplug (for wlan rfkill)
516 static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc)
518 if (get_acpi(eeepc, CM_ASL_WLAN) == 1)
523 static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
527 bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
529 if (eeepc->wlan_rfkill)
530 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
532 mutex_lock(&eeepc->hotplug_lock);
534 if (eeepc->hotplug_slot) {
535 bus = pci_find_bus(0, 1);
537 pr_warning("Unable to find PCI bus 1?\n");
542 dev = pci_get_slot(bus, 0);
544 /* Device already present */
548 dev = pci_scan_single_device(bus, 0);
550 pci_bus_assign_resources(bus);
551 if (pci_bus_add_device(dev))
552 pr_err("Unable to hotplug wifi\n");
555 dev = pci_get_slot(bus, 0);
557 pci_remove_bus_device(dev);
564 mutex_unlock(&eeepc->hotplug_lock);
567 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
569 struct eeepc_laptop *eeepc = data;
571 if (event != ACPI_NOTIFY_BUS_CHECK)
574 eeepc_rfkill_hotplug(eeepc);
577 static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc,
583 status = acpi_get_handle(NULL, node, &handle);
585 if (ACPI_SUCCESS(status)) {
586 status = acpi_install_notify_handler(handle,
590 if (ACPI_FAILURE(status))
591 pr_warning("Failed to register notify on %s\n", node);
598 static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc,
601 acpi_status status = AE_OK;
604 status = acpi_get_handle(NULL, node, &handle);
606 if (ACPI_SUCCESS(status)) {
607 status = acpi_remove_notify_handler(handle,
609 eeepc_rfkill_notify);
610 if (ACPI_FAILURE(status))
611 pr_err("Error removing rfkill notify handler %s\n",
616 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
619 struct eeepc_laptop *eeepc = hotplug_slot->private;
620 int val = get_acpi(eeepc, CM_ASL_WLAN);
622 if (val == 1 || val == 0)
630 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
632 kfree(hotplug_slot->info);
636 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
637 .owner = THIS_MODULE,
638 .get_adapter_status = eeepc_get_adapter_status,
639 .get_power_status = eeepc_get_adapter_status,
642 static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc)
645 struct pci_bus *bus = pci_find_bus(0, 1);
648 pr_err("Unable to find wifi PCI bus\n");
652 eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
653 if (!eeepc->hotplug_slot)
656 eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
658 if (!eeepc->hotplug_slot->info)
661 eeepc->hotplug_slot->private = eeepc;
662 eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
663 eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
664 eeepc_get_adapter_status(eeepc->hotplug_slot,
665 &eeepc->hotplug_slot->info->adapter_status);
667 ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi");
669 pr_err("Unable to register hotplug slot - %d\n", ret);
676 kfree(eeepc->hotplug_slot->info);
678 kfree(eeepc->hotplug_slot);
679 eeepc->hotplug_slot = NULL;
687 static int eeepc_rfkill_set(void *data, bool blocked)
689 acpi_handle handle = data;
691 return write_acpi_int(handle, NULL, !blocked);
694 static const struct rfkill_ops eeepc_rfkill_ops = {
695 .set_block = eeepc_rfkill_set,
698 static int eeepc_new_rfkill(struct eeepc_laptop *eeepc,
699 struct rfkill **rfkill,
701 enum rfkill_type type, int cm)
706 result = acpi_setter_handle(eeepc, cm, &handle);
710 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
711 &eeepc_rfkill_ops, handle);
716 rfkill_init_sw_state(*rfkill, get_acpi(eeepc, cm) != 1);
717 result = rfkill_register(*rfkill);
719 rfkill_destroy(*rfkill);
726 static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc)
728 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
729 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
730 eeepc_unregister_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
731 if (eeepc->wlan_rfkill) {
732 rfkill_unregister(eeepc->wlan_rfkill);
733 rfkill_destroy(eeepc->wlan_rfkill);
734 eeepc->wlan_rfkill = NULL;
737 * Refresh pci hotplug in case the rfkill state was changed after
738 * eeepc_unregister_rfkill_notifier()
740 eeepc_rfkill_hotplug(eeepc);
741 if (eeepc->hotplug_slot)
742 pci_hp_deregister(eeepc->hotplug_slot);
744 if (eeepc->bluetooth_rfkill) {
745 rfkill_unregister(eeepc->bluetooth_rfkill);
746 rfkill_destroy(eeepc->bluetooth_rfkill);
747 eeepc->bluetooth_rfkill = NULL;
749 if (eeepc->wwan3g_rfkill) {
750 rfkill_unregister(eeepc->wwan3g_rfkill);
751 rfkill_destroy(eeepc->wwan3g_rfkill);
752 eeepc->wwan3g_rfkill = NULL;
754 if (eeepc->wimax_rfkill) {
755 rfkill_unregister(eeepc->wimax_rfkill);
756 rfkill_destroy(eeepc->wimax_rfkill);
757 eeepc->wimax_rfkill = NULL;
761 static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
765 mutex_init(&eeepc->hotplug_lock);
767 result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
768 "eeepc-wlan", RFKILL_TYPE_WLAN,
771 if (result && result != -ENODEV)
774 result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
775 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
778 if (result && result != -ENODEV)
781 result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
782 "eeepc-wwan3g", RFKILL_TYPE_WWAN,
785 if (result && result != -ENODEV)
788 result = eeepc_new_rfkill(eeepc, &eeepc->wimax_rfkill,
789 "eeepc-wimax", RFKILL_TYPE_WIMAX,
792 if (result && result != -ENODEV)
795 result = eeepc_setup_pci_hotplug(eeepc);
797 * If we get -EBUSY then something else is handling the PCI hotplug -
798 * don't fail in this case
800 if (result == -EBUSY)
803 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5");
804 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6");
805 eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7");
807 * Refresh pci hotplug in case the rfkill state was changed during
810 eeepc_rfkill_hotplug(eeepc);
813 if (result && result != -ENODEV)
814 eeepc_rfkill_exit(eeepc);
819 * Platform driver - hibernate/resume callbacks
821 static int eeepc_hotk_thaw(struct device *device)
823 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
825 if (eeepc->wlan_rfkill) {
829 * Work around bios bug - acpi _PTS turns off the wireless led
830 * during suspend. Normally it restores it on resume, but
831 * we should kick it ourselves in case hibernation is aborted.
833 wlan = get_acpi(eeepc, CM_ASL_WLAN);
834 set_acpi(eeepc, CM_ASL_WLAN, wlan);
840 static int eeepc_hotk_restore(struct device *device)
842 struct eeepc_laptop *eeepc = dev_get_drvdata(device);
844 /* Refresh both wlan rfkill state and pci hotplug */
845 if (eeepc->wlan_rfkill)
846 eeepc_rfkill_hotplug(eeepc);
848 if (eeepc->bluetooth_rfkill)
849 rfkill_set_sw_state(eeepc->bluetooth_rfkill,
850 get_acpi(eeepc, CM_ASL_BLUETOOTH) != 1);
851 if (eeepc->wwan3g_rfkill)
852 rfkill_set_sw_state(eeepc->wwan3g_rfkill,
853 get_acpi(eeepc, CM_ASL_3G) != 1);
854 if (eeepc->wimax_rfkill)
855 rfkill_set_sw_state(eeepc->wimax_rfkill,
856 get_acpi(eeepc, CM_ASL_WIMAX) != 1);
861 static struct dev_pm_ops eeepc_pm_ops = {
862 .thaw = eeepc_hotk_thaw,
863 .restore = eeepc_hotk_restore,
866 static struct platform_driver platform_driver = {
868 .name = EEEPC_LAPTOP_FILE,
869 .owner = THIS_MODULE,
878 #define EEEPC_EC_SC00 0x61
879 #define EEEPC_EC_FAN_PWM (EEEPC_EC_SC00 + 2) /* Fan PWM duty cycle (%) */
880 #define EEEPC_EC_FAN_HRPM (EEEPC_EC_SC00 + 5) /* High byte, fan speed (RPM) */
881 #define EEEPC_EC_FAN_LRPM (EEEPC_EC_SC00 + 6) /* Low byte, fan speed (RPM) */
883 #define EEEPC_EC_SFB0 0xD0
884 #define EEEPC_EC_FAN_CTRL (EEEPC_EC_SFB0 + 3) /* Byte containing SF25 */
886 static int eeepc_get_fan_pwm(void)
890 ec_read(EEEPC_EC_FAN_PWM, &value);
891 return value * 255 / 100;
894 static void eeepc_set_fan_pwm(int value)
896 value = SENSORS_LIMIT(value, 0, 255);
897 value = value * 100 / 255;
898 ec_write(EEEPC_EC_FAN_PWM, value);
901 static int eeepc_get_fan_rpm(void)
906 ec_read(EEEPC_EC_FAN_HRPM, &high);
907 ec_read(EEEPC_EC_FAN_LRPM, &low);
908 return high << 8 | low;
911 static int eeepc_get_fan_ctrl(void)
915 ec_read(EEEPC_EC_FAN_CTRL, &value);
917 return 1; /* manual */
919 return 2; /* automatic */
922 static void eeepc_set_fan_ctrl(int manual)
926 ec_read(EEEPC_EC_FAN_CTRL, &value);
931 ec_write(EEEPC_EC_FAN_CTRL, value);
934 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
938 rv = parse_arg(buf, count, &value);
944 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
946 return sprintf(buf, "%d\n", get());
949 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
950 static ssize_t show_##_name(struct device *dev, \
951 struct device_attribute *attr, \
954 return show_sys_hwmon(_set, buf); \
956 static ssize_t store_##_name(struct device *dev, \
957 struct device_attribute *attr, \
958 const char *buf, size_t count) \
960 return store_sys_hwmon(_get, buf, count); \
962 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
964 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
965 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
966 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
967 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
968 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
971 show_name(struct device *dev, struct device_attribute *attr, char *buf)
973 return sprintf(buf, "eeepc\n");
975 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
977 static struct attribute *hwmon_attributes[] = {
978 &sensor_dev_attr_pwm1.dev_attr.attr,
979 &sensor_dev_attr_fan1_input.dev_attr.attr,
980 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
981 &sensor_dev_attr_name.dev_attr.attr,
985 static struct attribute_group hwmon_attribute_group = {
986 .attrs = hwmon_attributes
989 static void eeepc_hwmon_exit(struct eeepc_laptop *eeepc)
991 struct device *hwmon;
993 hwmon = eeepc->hwmon_device;
996 sysfs_remove_group(&hwmon->kobj,
997 &hwmon_attribute_group);
998 hwmon_device_unregister(hwmon);
999 eeepc->hwmon_device = NULL;
1002 static int eeepc_hwmon_init(struct eeepc_laptop *eeepc)
1004 struct device *hwmon;
1007 hwmon = hwmon_device_register(&eeepc->platform_device->dev);
1008 if (IS_ERR(hwmon)) {
1009 pr_err("Could not register eeepc hwmon device\n");
1010 eeepc->hwmon_device = NULL;
1011 return PTR_ERR(hwmon);
1013 eeepc->hwmon_device = hwmon;
1014 result = sysfs_create_group(&hwmon->kobj,
1015 &hwmon_attribute_group);
1017 eeepc_hwmon_exit(eeepc);
1024 static int read_brightness(struct backlight_device *bd)
1026 struct eeepc_laptop *eeepc = bl_get_data(bd);
1028 return get_acpi(eeepc, CM_ASL_PANELBRIGHT);
1031 static int set_brightness(struct backlight_device *bd, int value)
1033 struct eeepc_laptop *eeepc = bl_get_data(bd);
1035 return set_acpi(eeepc, CM_ASL_PANELBRIGHT, value);
1038 static int update_bl_status(struct backlight_device *bd)
1040 return set_brightness(bd, bd->props.brightness);
1043 static struct backlight_ops eeepcbl_ops = {
1044 .get_brightness = read_brightness,
1045 .update_status = update_bl_status,
1048 static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
1050 struct backlight_device *bd = eeepc->backlight_device;
1051 int old = bd->props.brightness;
1053 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1058 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
1060 struct backlight_device *bd;
1062 bd = backlight_device_register(EEEPC_LAPTOP_FILE,
1063 &eeepc->platform_device->dev,
1064 eeepc, &eeepcbl_ops);
1066 pr_err("Could not register eeepc backlight device\n");
1067 eeepc->backlight_device = NULL;
1070 eeepc->backlight_device = bd;
1071 bd->props.max_brightness = 15;
1072 bd->props.brightness = read_brightness(bd);
1073 bd->props.power = FB_BLANK_UNBLANK;
1074 backlight_update_status(bd);
1078 static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
1080 if (eeepc->backlight_device)
1081 backlight_device_unregister(eeepc->backlight_device);
1082 eeepc->backlight_device = NULL;
1087 * Input device (i.e. hotkeys)
1089 static struct key_entry *eeepc_get_entry_by_scancode(
1090 struct eeepc_laptop *eeepc,
1093 struct key_entry *key;
1095 for (key = eeepc->keymap; key->type != KE_END; key++)
1096 if (code == key->code)
1102 static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
1104 static struct key_entry *key;
1106 key = eeepc_get_entry_by_scancode(eeepc, event);
1108 switch (key->type) {
1110 input_report_key(eeepc->inputdev, key->keycode,
1112 input_sync(eeepc->inputdev);
1113 input_report_key(eeepc->inputdev, key->keycode,
1115 input_sync(eeepc->inputdev);
1121 static struct key_entry *eeepc_get_entry_by_keycode(
1122 struct eeepc_laptop *eeepc, int code)
1124 struct key_entry *key;
1126 for (key = eeepc->keymap; key->type != KE_END; key++)
1127 if (code == key->keycode && key->type == KE_KEY)
1133 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
1135 struct eeepc_laptop *eeepc = input_get_drvdata(dev);
1136 struct key_entry *key = eeepc_get_entry_by_scancode(eeepc, scancode);
1138 if (key && key->type == KE_KEY) {
1139 *keycode = key->keycode;
1146 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
1148 struct eeepc_laptop *eeepc = input_get_drvdata(dev);
1149 struct key_entry *key;
1152 if (keycode < 0 || keycode > KEY_MAX)
1155 key = eeepc_get_entry_by_scancode(eeepc, scancode);
1156 if (key && key->type == KE_KEY) {
1157 old_keycode = key->keycode;
1158 key->keycode = keycode;
1159 set_bit(keycode, dev->keybit);
1160 if (!eeepc_get_entry_by_keycode(eeepc, old_keycode))
1161 clear_bit(old_keycode, dev->keybit);
1168 static int eeepc_input_init(struct eeepc_laptop *eeepc)
1170 const struct key_entry *key;
1173 eeepc->inputdev = input_allocate_device();
1174 if (!eeepc->inputdev) {
1175 pr_info("Unable to allocate input device\n");
1178 eeepc->inputdev->name = "Asus EeePC extra buttons";
1179 eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
1180 eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0";
1181 eeepc->inputdev->id.bustype = BUS_HOST;
1182 eeepc->inputdev->getkeycode = eeepc_getkeycode;
1183 eeepc->inputdev->setkeycode = eeepc_setkeycode;
1184 input_set_drvdata(eeepc->inputdev, eeepc);
1186 eeepc->keymap = kmemdup(eeepc_keymap, sizeof(eeepc_keymap),
1188 for (key = eeepc_keymap; key->type != KE_END; key++) {
1189 switch (key->type) {
1191 set_bit(EV_KEY, eeepc->inputdev->evbit);
1192 set_bit(key->keycode, eeepc->inputdev->keybit);
1196 result = input_register_device(eeepc->inputdev);
1198 pr_info("Unable to register input device\n");
1199 input_free_device(eeepc->inputdev);
1205 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
1207 if (eeepc->inputdev) {
1208 input_unregister_device(eeepc->inputdev);
1209 kfree(eeepc->keymap);
1216 static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
1218 struct eeepc_laptop *eeepc = acpi_driver_data(device);
1221 if (event > ACPI_MAX_SYS_NOTIFY)
1223 count = eeepc->event_count[event % 128]++;
1224 acpi_bus_generate_proc_event(device, event, count);
1225 acpi_bus_generate_netlink_event(device->pnp.device_class,
1226 dev_name(&device->dev), event,
1229 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) {
1230 int old_brightness, new_brightness;
1232 /* Update backlight device. */
1233 old_brightness = eeepc_backlight_notify(eeepc);
1235 /* Convert brightness event to keypress (obsolescent hack). */
1236 new_brightness = event - NOTIFY_BRN_MIN;
1238 if (new_brightness < old_brightness) {
1239 event = NOTIFY_BRN_MIN; /* brightness down */
1240 } else if (new_brightness > old_brightness) {
1241 event = NOTIFY_BRN_MAX; /* brightness up */
1244 * no change in brightness - already at min/max,
1245 * event will be desired value (or else ignored).
1249 eeepc_input_notify(eeepc, event);
1252 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
1256 /* Some BIOSes do not report cm although it is avaliable.
1257 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
1258 if (!(eeepc->cm_supported & (1 << cm))
1259 && !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
1260 pr_info("%s (%x) not reported by BIOS,"
1261 " enabling anyway\n", name, 1 << cm);
1262 eeepc->cm_supported |= 1 << cm;
1266 static void cmsg_quirks(struct eeepc_laptop *eeepc)
1268 cmsg_quirk(eeepc, CM_ASL_LID, "LID");
1269 cmsg_quirk(eeepc, CM_ASL_TYPE, "TYPE");
1270 cmsg_quirk(eeepc, CM_ASL_PANELPOWER, "PANELPOWER");
1271 cmsg_quirk(eeepc, CM_ASL_TPD, "TPD");
1274 static int eeepc_acpi_init(struct eeepc_laptop *eeepc, struct acpi_device *device)
1276 unsigned int init_flags;
1279 result = acpi_bus_get_status(device);
1282 if (!device->status.present) {
1283 pr_err("Hotkey device not present, aborting\n");
1287 init_flags = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1288 pr_notice("Hotkey init flags 0x%x\n", init_flags);
1290 if (write_acpi_int(eeepc->handle, "INIT", init_flags)) {
1291 pr_err("Hotkey initialization failed\n");
1295 /* get control methods supported */
1296 if (read_acpi_int(eeepc->handle, "CMSG", &eeepc->cm_supported)) {
1297 pr_err("Get control methods supported failed\n");
1301 pr_info("Get control methods supported: 0x%x\n", eeepc->cm_supported);
1306 static void __devinit eeepc_enable_camera(struct eeepc_laptop *eeepc)
1309 * If the following call to set_acpi() fails, it's because there's no
1310 * camera so we can ignore the error.
1312 if (get_acpi(eeepc, CM_ASL_CAMERA) == 0)
1313 set_acpi(eeepc, CM_ASL_CAMERA, 1);
1316 static bool eeepc_device_present;
1318 static int __devinit eeepc_acpi_add(struct acpi_device *device)
1320 struct eeepc_laptop *eeepc;
1323 pr_notice(EEEPC_LAPTOP_NAME "\n");
1324 eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL);
1327 eeepc->handle = device->handle;
1328 strcpy(acpi_device_name(device), EEEPC_ACPI_DEVICE_NAME);
1329 strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
1330 device->driver_data = eeepc;
1332 result = eeepc_acpi_init(eeepc, device);
1335 eeepc_enable_camera(eeepc);
1338 * Register the platform device first. It is used as a parent for the
1339 * sub-devices below.
1341 * Note that if there are multiple instances of this ACPI device it
1342 * will bail out, because the platform device is registered with a
1343 * fixed name. Of course it doesn't make sense to have more than one,
1344 * and machine-specific scripts find the fixed name convenient. But
1345 * It's also good for us to exclude multiple instances because both
1346 * our hwmon and our wlan rfkill subdevice use global ACPI objects
1347 * (the EC and the wlan PCI slot respectively).
1349 result = eeepc_platform_init(eeepc);
1353 if (!acpi_video_backlight_support()) {
1354 result = eeepc_backlight_init(eeepc);
1356 goto fail_backlight;
1358 pr_info("Backlight controlled by ACPI video driver\n");
1360 result = eeepc_input_init(eeepc);
1364 result = eeepc_hwmon_init(eeepc);
1368 result = eeepc_led_init(eeepc);
1372 result = eeepc_rfkill_init(eeepc);
1376 eeepc_device_present = true;
1380 eeepc_led_exit(eeepc);
1382 eeepc_hwmon_exit(eeepc);
1384 eeepc_input_exit(eeepc);
1386 eeepc_backlight_exit(eeepc);
1388 eeepc_platform_exit(eeepc);
1395 static int eeepc_acpi_remove(struct acpi_device *device, int type)
1397 struct eeepc_laptop *eeepc = acpi_driver_data(device);
1399 eeepc_backlight_exit(eeepc);
1400 eeepc_rfkill_exit(eeepc);
1401 eeepc_input_exit(eeepc);
1402 eeepc_hwmon_exit(eeepc);
1403 eeepc_led_exit(eeepc);
1404 eeepc_platform_exit(eeepc);
1411 static const struct acpi_device_id eeepc_device_ids[] = {
1412 {EEEPC_ACPI_HID, 0},
1415 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
1417 static struct acpi_driver eeepc_acpi_driver = {
1418 .name = EEEPC_LAPTOP_NAME,
1419 .class = EEEPC_ACPI_CLASS,
1420 .owner = THIS_MODULE,
1421 .ids = eeepc_device_ids,
1422 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
1424 .add = eeepc_acpi_add,
1425 .remove = eeepc_acpi_remove,
1426 .notify = eeepc_acpi_notify,
1431 static int __init eeepc_laptop_init(void)
1435 result = platform_driver_register(&platform_driver);
1439 result = acpi_bus_register_driver(&eeepc_acpi_driver);
1441 goto fail_acpi_driver;
1442 if (!eeepc_device_present) {
1444 goto fail_no_device;
1449 acpi_bus_unregister_driver(&eeepc_acpi_driver);
1451 platform_driver_unregister(&platform_driver);
1455 static void __exit eeepc_laptop_exit(void)
1457 acpi_bus_unregister_driver(&eeepc_acpi_driver);
1458 platform_driver_unregister(&platform_driver);
1461 module_init(eeepc_laptop_init);
1462 module_exit(eeepc_laptop_exit);