2 * eepc-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"
41 #define EEEPC_HOTK_NAME "Eee PC Hotkey Driver"
42 #define EEEPC_HOTK_FILE "eeepc"
43 #define EEEPC_HOTK_CLASS "hotkey"
44 #define EEEPC_HOTK_DEVICE_NAME "Hotkey"
45 #define EEEPC_HOTK_HID "ASUS010"
49 * Definitions for Asus EeePC
51 #define NOTIFY_WLAN_ON 0x10
52 #define NOTIFY_BRN_MIN 0x20
53 #define NOTIFY_BRN_MAX 0x2f
56 DISABLE_ASL_WLAN = 0x0001,
57 DISABLE_ASL_BLUETOOTH = 0x0002,
58 DISABLE_ASL_IRDA = 0x0004,
59 DISABLE_ASL_CAMERA = 0x0008,
60 DISABLE_ASL_TV = 0x0010,
61 DISABLE_ASL_GPS = 0x0020,
62 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
63 DISABLE_ASL_MODEM = 0x0080,
64 DISABLE_ASL_CARDREADER = 0x0100,
65 DISABLE_ASL_3G = 0x0200,
66 DISABLE_ASL_WIMAX = 0x0400,
67 DISABLE_ASL_HWCF = 0x0800
84 CM_ASL_CPUTEMPERATURE,
97 CM_ASL_PANELPOWER, /*P901*/
101 static const char *cm_getv[] = {
102 "WLDG", "BTHG", NULL, NULL,
103 "CAMG", NULL, NULL, NULL,
104 NULL, "PBLG", NULL, NULL,
105 "CFVG", NULL, NULL, NULL,
106 "USBG", NULL, NULL, "MODG",
107 "CRDG", "M3GG", "WIMG", "HWCF",
108 "LIDG", "TYPE", "PBPG", "TPDG"
111 static const char *cm_setv[] = {
112 "WLDS", "BTHS", NULL, NULL,
113 "CAMS", NULL, NULL, NULL,
114 "SDSP", "PBLS", "HDPS", NULL,
115 "CFVS", NULL, NULL, NULL,
116 "USBG", NULL, NULL, "MODS",
117 "CRDS", "M3GS", "WIMS", NULL,
118 NULL, NULL, "PBPS", "TPDS"
121 #define EEEPC_EC "\\_SB.PCI0.SBRG.EC0."
123 #define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */
124 #define EEEPC_EC_SC02 0x63
125 #define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */
126 #define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */
127 #define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */
128 #define EEEPC_EC_SFB3 0xD3
131 * This is the main structure, we can use it to store useful information
132 * about the hotk device
135 struct acpi_device *device; /* the device we are in */
136 acpi_handle handle; /* the handle of the hotk device */
137 u32 cm_supported; /* the control methods supported
139 uint init_flag; /* Init flags */
140 u16 event_count[128]; /* count for each event */
141 struct input_dev *inputdev;
143 struct rfkill *wlan_rfkill;
144 struct rfkill *bluetooth_rfkill;
145 struct rfkill *wwan3g_rfkill;
146 struct rfkill *wimax_rfkill;
147 struct hotplug_slot *hotplug_slot;
148 struct mutex hotplug_lock;
151 /* The actual device the driver binds to */
152 static struct eeepc_hotk *ehotk;
154 /* Platform device/driver */
155 static int eeepc_hotk_thaw(struct device *device);
156 static int eeepc_hotk_restore(struct device *device);
158 static struct dev_pm_ops eeepc_pm_ops = {
159 .thaw = eeepc_hotk_thaw,
160 .restore = eeepc_hotk_restore,
163 static struct platform_driver platform_driver = {
165 .name = EEEPC_HOTK_FILE,
166 .owner = THIS_MODULE,
171 static struct platform_device *platform_device;
179 enum { KE_KEY, KE_END };
181 static struct key_entry eeepc_keymap[] = {
182 /* Sleep already handled via generic ACPI code */
183 {KE_KEY, 0x10, KEY_WLAN },
184 {KE_KEY, 0x11, KEY_WLAN },
185 {KE_KEY, 0x12, KEY_PROG1 },
186 {KE_KEY, 0x13, KEY_MUTE },
187 {KE_KEY, 0x14, KEY_VOLUMEDOWN },
188 {KE_KEY, 0x15, KEY_VOLUMEUP },
189 {KE_KEY, 0x1a, KEY_COFFEE },
190 {KE_KEY, 0x1b, KEY_ZOOM },
191 {KE_KEY, 0x1c, KEY_PROG2 },
192 {KE_KEY, 0x1d, KEY_PROG3 },
193 {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
194 {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP },
195 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
196 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
197 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
202 * The hotkey driver declaration
204 static int eeepc_hotk_add(struct acpi_device *device);
205 static int eeepc_hotk_remove(struct acpi_device *device, int type);
206 static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
208 static const struct acpi_device_id eeepc_device_ids[] = {
212 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
214 static struct acpi_driver eeepc_hotk_driver = {
215 .name = EEEPC_HOTK_NAME,
216 .class = EEEPC_HOTK_CLASS,
217 .owner = THIS_MODULE,
218 .ids = eeepc_device_ids,
219 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
221 .add = eeepc_hotk_add,
222 .remove = eeepc_hotk_remove,
223 .notify = eeepc_hotk_notify,
227 /* PCI hotplug ops */
228 static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
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,
236 /* The backlight device /sys/class/backlight */
237 static struct backlight_device *eeepc_backlight_device;
239 /* The hwmon device */
240 static struct device *eeepc_hwmon_device;
243 * The backlight class declaration
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,
252 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
253 MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
254 MODULE_LICENSE("GPL");
259 static int write_acpi_int(acpi_handle handle, const char *method, int val,
260 struct acpi_buffer *output)
262 struct acpi_object_list params;
263 union acpi_object in_obj;
267 params.pointer = &in_obj;
268 in_obj.type = ACPI_TYPE_INTEGER;
269 in_obj.integer.value = val;
271 status = acpi_evaluate_object(handle, (char *)method, ¶ms, output);
272 return (status == AE_OK ? 0 : -1);
275 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
278 unsigned long long result;
280 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
281 if (ACPI_FAILURE(status)) {
290 static int set_acpi(int cm, int value)
292 const char *method = cm_setv[cm];
296 if ((ehotk->cm_supported & (0x1 << cm)) == 0)
299 if (write_acpi_int(ehotk->handle, method, value, NULL))
300 pr_warning("Error writing %s\n", method);
304 static int get_acpi(int cm)
306 const char *method = cm_getv[cm];
311 if ((ehotk->cm_supported & (0x1 << cm)) == 0)
314 if (read_acpi_int(ehotk->handle, method, &value))
315 pr_warning("Error reading %s\n", method);
322 static int read_brightness(struct backlight_device *bd)
324 return get_acpi(CM_ASL_PANELBRIGHT);
327 static int set_brightness(struct backlight_device *bd, int value)
329 value = max(0, min(15, value));
330 return set_acpi(CM_ASL_PANELBRIGHT, value);
333 static int update_bl_status(struct backlight_device *bd)
335 return set_brightness(bd, bd->props.brightness);
342 static bool eeepc_wlan_rfkill_blocked(void)
344 if (get_acpi(CM_ASL_WLAN) == 1)
349 static int eeepc_rfkill_set(void *data, bool blocked)
351 unsigned long asl = (unsigned long)data;
352 return set_acpi(asl, !blocked);
355 static const struct rfkill_ops eeepc_rfkill_ops = {
356 .set_block = eeepc_rfkill_set,
359 static void __devinit eeepc_enable_camera(void)
362 * If the following call to set_acpi() fails, it's because there's no
363 * camera so we can ignore the error.
365 if (get_acpi(CM_ASL_CAMERA) == 0)
366 set_acpi(CM_ASL_CAMERA, 1);
372 static int parse_arg(const char *buf, unsigned long count, int *val)
376 if (sscanf(buf, "%i", val) != 1)
381 static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
385 rv = parse_arg(buf, count, &value);
387 value = set_acpi(cm, value);
393 static ssize_t show_sys_acpi(int cm, char *buf)
395 int value = get_acpi(cm);
399 return sprintf(buf, "%d\n", value);
402 #define EEEPC_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
403 static ssize_t show_##_name(struct device *dev, \
404 struct device_attribute *attr, \
407 return show_sys_acpi(_cm, buf); \
409 static ssize_t store_##_name(struct device *dev, \
410 struct device_attribute *attr, \
411 const char *buf, size_t count) \
413 return store_sys_acpi(_cm, buf, count); \
415 static struct device_attribute dev_attr_##_name = { \
417 .name = __stringify(_name), \
419 .show = show_##_name, \
420 .store = store_##_name, \
423 EEEPC_CREATE_DEVICE_ATTR(camera, 0644, CM_ASL_CAMERA);
424 EEEPC_CREATE_DEVICE_ATTR(cardr, 0644, CM_ASL_CARDREADER);
425 EEEPC_CREATE_DEVICE_ATTR(disp, 0200, CM_ASL_DISPLAYSWITCH);
432 static int get_cpufv(struct eeepc_cpufv *c)
434 c->cur = get_acpi(CM_ASL_CPUFV);
435 c->num = (c->cur >> 8) & 0xff;
437 if (c->cur < 0 || c->num <= 0 || c->num > 12)
442 static ssize_t show_available_cpufv(struct device *dev,
443 struct device_attribute *attr,
446 struct eeepc_cpufv c;
452 for (i = 0; i < c.num; i++)
453 len += sprintf(buf + len, "%d ", i);
454 len += sprintf(buf + len, "\n");
458 static ssize_t show_cpufv(struct device *dev,
459 struct device_attribute *attr,
462 struct eeepc_cpufv c;
466 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
469 static ssize_t store_cpufv(struct device *dev,
470 struct device_attribute *attr,
471 const char *buf, size_t count)
473 struct eeepc_cpufv c;
478 rv = parse_arg(buf, count, &value);
481 if (!rv || value < 0 || value >= c.num)
483 set_acpi(CM_ASL_CPUFV, value);
487 static struct device_attribute dev_attr_cpufv = {
495 static struct device_attribute dev_attr_available_cpufv = {
497 .name = "available_cpufv",
499 .show = show_available_cpufv
502 static struct attribute *platform_attributes[] = {
503 &dev_attr_camera.attr,
504 &dev_attr_cardr.attr,
506 &dev_attr_cpufv.attr,
507 &dev_attr_available_cpufv.attr,
511 static struct attribute_group platform_attribute_group = {
512 .attrs = platform_attributes
519 * These functions actually update the LED's, and are called from a
520 * workqueue. By doing this as separate work rather than when the LED
521 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
522 * potentially bad time, such as a timer interrupt.
524 static int tpd_led_wk;
526 static void tpd_led_update(struct work_struct *ignored)
528 int value = tpd_led_wk;
529 set_acpi(CM_ASL_TPD, value);
532 static struct workqueue_struct *led_workqueue;
533 static DECLARE_WORK(tpd_led_work, tpd_led_update);
535 static void tpd_led_set(struct led_classdev *led_cdev,
536 enum led_brightness value)
538 tpd_led_wk = (value > 0) ? 1 : 0;
539 queue_work(led_workqueue, &tpd_led_work);
542 static struct led_classdev tpd_led = {
543 .name = "eeepc::touchpad",
544 .brightness_set = tpd_led_set,
551 static struct key_entry *eepc_get_entry_by_scancode(int code)
553 struct key_entry *key;
555 for (key = eeepc_keymap; key->type != KE_END; key++)
556 if (code == key->code)
562 static struct key_entry *eepc_get_entry_by_keycode(int code)
564 struct key_entry *key;
566 for (key = eeepc_keymap; key->type != KE_END; key++)
567 if (code == key->keycode && key->type == KE_KEY)
573 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
575 struct key_entry *key = eepc_get_entry_by_scancode(scancode);
577 if (key && key->type == KE_KEY) {
578 *keycode = key->keycode;
585 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
587 struct key_entry *key;
590 if (keycode < 0 || keycode > KEY_MAX)
593 key = eepc_get_entry_by_scancode(scancode);
594 if (key && key->type == KE_KEY) {
595 old_keycode = key->keycode;
596 key->keycode = keycode;
597 set_bit(keycode, dev->keybit);
598 if (!eepc_get_entry_by_keycode(old_keycode))
599 clear_bit(old_keycode, dev->keybit);
606 static void cmsg_quirk(int cm, const char *name)
610 /* Some BIOSes do not report cm although it is avaliable.
611 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
612 if (!(ehotk->cm_supported & (1 << cm))
613 && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) {
614 pr_info("%s (%x) not reported by BIOS,"
615 " enabling anyway\n", name, 1 << cm);
616 ehotk->cm_supported |= 1 << cm;
620 static void cmsg_quirks(void)
622 cmsg_quirk(CM_ASL_LID, "LID");
623 cmsg_quirk(CM_ASL_TYPE, "TYPE");
624 cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER");
625 cmsg_quirk(CM_ASL_TPD, "TPD");
628 static int eeepc_hotk_check(void)
630 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
633 result = acpi_bus_get_status(ehotk->device);
636 if (ehotk->device->status.present) {
637 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
639 pr_err("Hotkey initialization failed\n");
642 pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
644 /* get control methods supported */
645 if (read_acpi_int(ehotk->handle, "CMSG"
646 , &ehotk->cm_supported)) {
647 pr_err("Get control methods supported failed\n");
651 pr_info("Get control methods supported: 0x%x\n",
652 ehotk->cm_supported);
655 pr_err("Hotkey device not present, aborting\n");
661 static int notify_brn(void)
663 /* returns the *previous* brightness, or -1 */
664 struct backlight_device *bd = eeepc_backlight_device;
666 int old = bd->props.brightness;
667 backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
673 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
676 int val = get_acpi(CM_ASL_WLAN);
678 if (val == 1 || val == 0)
686 static void eeepc_rfkill_hotplug(void)
690 bool blocked = eeepc_wlan_rfkill_blocked();
692 if (ehotk->wlan_rfkill)
693 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
695 mutex_lock(&ehotk->hotplug_lock);
697 if (ehotk->hotplug_slot) {
698 bus = pci_find_bus(0, 1);
700 pr_warning("Unable to find PCI bus 1?\n");
705 dev = pci_get_slot(bus, 0);
707 /* Device already present */
711 dev = pci_scan_single_device(bus, 0);
713 pci_bus_assign_resources(bus);
714 if (pci_bus_add_device(dev))
715 pr_err("Unable to hotplug wifi\n");
718 dev = pci_get_slot(bus, 0);
720 pci_remove_bus_device(dev);
727 mutex_unlock(&ehotk->hotplug_lock);
730 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
732 if (event != ACPI_NOTIFY_BUS_CHECK)
735 eeepc_rfkill_hotplug();
738 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
740 static struct key_entry *key;
746 if (event > ACPI_MAX_SYS_NOTIFY)
748 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
750 count = ehotk->event_count[event % 128]++;
751 acpi_bus_generate_proc_event(ehotk->device, event, count);
752 acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
753 dev_name(&ehotk->device->dev), event,
755 if (ehotk->inputdev) {
756 if (brn != -ENODEV) {
757 /* brightness-change events need special
758 * handling for conversion to key events
763 brn += NOTIFY_BRN_MIN;
765 event = NOTIFY_BRN_MIN; /* brightness down */
766 else if (event > brn)
767 event = NOTIFY_BRN_MIN + 2; /* ... up */
769 event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
771 key = eepc_get_entry_by_scancode(event);
775 input_report_key(ehotk->inputdev, key->keycode,
777 input_sync(ehotk->inputdev);
778 input_report_key(ehotk->inputdev, key->keycode,
780 input_sync(ehotk->inputdev);
787 static int eeepc_register_rfkill_notifier(char *node)
789 acpi_status status = AE_OK;
792 status = acpi_get_handle(NULL, node, &handle);
794 if (ACPI_SUCCESS(status)) {
795 status = acpi_install_notify_handler(handle,
799 if (ACPI_FAILURE(status))
800 pr_warning("Failed to register notify on %s\n", node);
807 static void eeepc_unregister_rfkill_notifier(char *node)
809 acpi_status status = AE_OK;
812 status = acpi_get_handle(NULL, node, &handle);
814 if (ACPI_SUCCESS(status)) {
815 status = acpi_remove_notify_handler(handle,
817 eeepc_rfkill_notify);
818 if (ACPI_FAILURE(status))
819 pr_err("Error removing rfkill notify handler %s\n",
824 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
826 kfree(hotplug_slot->info);
830 static int eeepc_setup_pci_hotplug(void)
833 struct pci_bus *bus = pci_find_bus(0, 1);
836 pr_err("Unable to find wifi PCI bus\n");
840 ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
841 if (!ehotk->hotplug_slot)
844 ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
846 if (!ehotk->hotplug_slot->info)
849 ehotk->hotplug_slot->private = ehotk;
850 ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
851 ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
852 eeepc_get_adapter_status(ehotk->hotplug_slot,
853 &ehotk->hotplug_slot->info->adapter_status);
855 ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
857 pr_err("Unable to register hotplug slot - %d\n", ret);
864 kfree(ehotk->hotplug_slot->info);
866 kfree(ehotk->hotplug_slot);
867 ehotk->hotplug_slot = NULL;
872 static int eeepc_hotk_thaw(struct device *device)
874 if (ehotk->wlan_rfkill) {
878 * Work around bios bug - acpi _PTS turns off the wireless led
879 * during suspend. Normally it restores it on resume, but
880 * we should kick it ourselves in case hibernation is aborted.
882 wlan = get_acpi(CM_ASL_WLAN);
883 set_acpi(CM_ASL_WLAN, wlan);
889 static int eeepc_hotk_restore(struct device *device)
891 /* Refresh both wlan rfkill state and pci hotplug */
892 if (ehotk->wlan_rfkill)
893 eeepc_rfkill_hotplug();
895 if (ehotk->bluetooth_rfkill)
896 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
897 get_acpi(CM_ASL_BLUETOOTH) != 1);
898 if (ehotk->wwan3g_rfkill)
899 rfkill_set_sw_state(ehotk->wwan3g_rfkill,
900 get_acpi(CM_ASL_3G) != 1);
901 if (ehotk->wimax_rfkill)
902 rfkill_set_sw_state(ehotk->wimax_rfkill,
903 get_acpi(CM_ASL_WIMAX) != 1);
911 static int eeepc_get_fan_pwm(void)
915 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
916 value = value * 255 / 100;
920 static void eeepc_set_fan_pwm(int value)
922 value = SENSORS_LIMIT(value, 0, 255);
923 value = value * 100 / 255;
924 ec_write(EEEPC_EC_SC02, value);
927 static int eeepc_get_fan_rpm(void)
932 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
933 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
934 return (high << 8 | low);
937 static int eeepc_get_fan_ctrl(void)
941 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
943 return 1; /* manual */
945 return 2; /* automatic */
948 static void eeepc_set_fan_ctrl(int manual)
952 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
957 ec_write(EEEPC_EC_SFB3, value);
960 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
964 rv = parse_arg(buf, count, &value);
970 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
972 return sprintf(buf, "%d\n", get());
975 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
976 static ssize_t show_##_name(struct device *dev, \
977 struct device_attribute *attr, \
980 return show_sys_hwmon(_set, buf); \
982 static ssize_t store_##_name(struct device *dev, \
983 struct device_attribute *attr, \
984 const char *buf, size_t count) \
986 return store_sys_hwmon(_get, buf, count); \
988 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
990 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
991 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
992 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
993 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
994 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
997 show_name(struct device *dev, struct device_attribute *attr, char *buf)
999 return sprintf(buf, "eeepc\n");
1001 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
1003 static struct attribute *hwmon_attributes[] = {
1004 &sensor_dev_attr_pwm1.dev_attr.attr,
1005 &sensor_dev_attr_fan1_input.dev_attr.attr,
1006 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1007 &sensor_dev_attr_name.dev_attr.attr,
1011 static struct attribute_group hwmon_attribute_group = {
1012 .attrs = hwmon_attributes
1018 static void eeepc_backlight_exit(void)
1020 if (eeepc_backlight_device)
1021 backlight_device_unregister(eeepc_backlight_device);
1022 eeepc_backlight_device = NULL;
1025 static void eeepc_rfkill_exit(void)
1027 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5");
1028 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
1029 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
1030 if (ehotk->wlan_rfkill) {
1031 rfkill_unregister(ehotk->wlan_rfkill);
1032 rfkill_destroy(ehotk->wlan_rfkill);
1033 ehotk->wlan_rfkill = NULL;
1036 * Refresh pci hotplug in case the rfkill state was changed after
1037 * eeepc_unregister_rfkill_notifier()
1039 eeepc_rfkill_hotplug();
1040 if (ehotk->hotplug_slot)
1041 pci_hp_deregister(ehotk->hotplug_slot);
1043 if (ehotk->bluetooth_rfkill) {
1044 rfkill_unregister(ehotk->bluetooth_rfkill);
1045 rfkill_destroy(ehotk->bluetooth_rfkill);
1046 ehotk->bluetooth_rfkill = NULL;
1048 if (ehotk->wwan3g_rfkill) {
1049 rfkill_unregister(ehotk->wwan3g_rfkill);
1050 rfkill_destroy(ehotk->wwan3g_rfkill);
1051 ehotk->wwan3g_rfkill = NULL;
1053 if (ehotk->wimax_rfkill) {
1054 rfkill_unregister(ehotk->wimax_rfkill);
1055 rfkill_destroy(ehotk->wimax_rfkill);
1056 ehotk->wimax_rfkill = NULL;
1060 static void eeepc_input_exit(void)
1062 if (ehotk->inputdev)
1063 input_unregister_device(ehotk->inputdev);
1066 static void eeepc_hwmon_exit(void)
1068 struct device *hwmon;
1070 hwmon = eeepc_hwmon_device;
1073 sysfs_remove_group(&hwmon->kobj,
1074 &hwmon_attribute_group);
1075 hwmon_device_unregister(hwmon);
1076 eeepc_hwmon_device = NULL;
1079 static void eeepc_led_exit(void)
1082 led_classdev_unregister(&tpd_led);
1084 destroy_workqueue(led_workqueue);
1087 static int eeepc_new_rfkill(struct rfkill **rfkill,
1088 const char *name, struct device *dev,
1089 enum rfkill_type type, int cm)
1093 result = get_acpi(cm);
1097 *rfkill = rfkill_alloc(name, dev, type,
1098 &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1103 rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1104 result = rfkill_register(*rfkill);
1106 rfkill_destroy(*rfkill);
1114 static int eeepc_rfkill_init(struct device *dev)
1118 mutex_init(&ehotk->hotplug_lock);
1120 result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1122 RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1124 if (result && result != -ENODEV)
1127 result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1128 "eeepc-bluetooth", dev,
1129 RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1131 if (result && result != -ENODEV)
1134 result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill,
1135 "eeepc-wwan3g", dev,
1136 RFKILL_TYPE_WWAN, CM_ASL_3G);
1138 if (result && result != -ENODEV)
1141 result = eeepc_new_rfkill(&ehotk->wimax_rfkill,
1143 RFKILL_TYPE_WIMAX, CM_ASL_WIMAX);
1145 if (result && result != -ENODEV)
1148 result = eeepc_setup_pci_hotplug();
1150 * If we get -EBUSY then something else is handling the PCI hotplug -
1151 * don't fail in this case
1153 if (result == -EBUSY)
1156 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P5");
1157 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1158 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1160 * Refresh pci hotplug in case the rfkill state was changed during
1163 eeepc_rfkill_hotplug();
1166 if (result && result != -ENODEV)
1167 eeepc_rfkill_exit();
1171 static int eeepc_backlight_init(struct device *dev)
1173 struct backlight_device *bd;
1175 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1176 NULL, &eeepcbl_ops);
1178 pr_err("Could not register eeepc backlight device\n");
1179 eeepc_backlight_device = NULL;
1182 eeepc_backlight_device = bd;
1183 bd->props.max_brightness = 15;
1184 bd->props.brightness = read_brightness(NULL);
1185 bd->props.power = FB_BLANK_UNBLANK;
1186 backlight_update_status(bd);
1190 static int eeepc_hwmon_init(struct device *dev)
1192 struct device *hwmon;
1195 hwmon = hwmon_device_register(dev);
1196 if (IS_ERR(hwmon)) {
1197 pr_err("Could not register eeepc hwmon device\n");
1198 eeepc_hwmon_device = NULL;
1199 return PTR_ERR(hwmon);
1201 eeepc_hwmon_device = hwmon;
1202 result = sysfs_create_group(&hwmon->kobj,
1203 &hwmon_attribute_group);
1209 static int eeepc_input_init(struct device *dev)
1211 const struct key_entry *key;
1214 ehotk->inputdev = input_allocate_device();
1215 if (!ehotk->inputdev) {
1216 pr_info("Unable to allocate input device\n");
1219 ehotk->inputdev->name = "Asus EeePC extra buttons";
1220 ehotk->inputdev->dev.parent = dev;
1221 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
1222 ehotk->inputdev->id.bustype = BUS_HOST;
1223 ehotk->inputdev->getkeycode = eeepc_getkeycode;
1224 ehotk->inputdev->setkeycode = eeepc_setkeycode;
1226 for (key = eeepc_keymap; key->type != KE_END; key++) {
1227 switch (key->type) {
1229 set_bit(EV_KEY, ehotk->inputdev->evbit);
1230 set_bit(key->keycode, ehotk->inputdev->keybit);
1234 result = input_register_device(ehotk->inputdev);
1236 pr_info("Unable to register input device\n");
1237 input_free_device(ehotk->inputdev);
1243 static int eeepc_led_init(struct device *dev)
1247 if (get_acpi(CM_ASL_TPD) == -ENODEV)
1250 led_workqueue = create_singlethread_workqueue("led_workqueue");
1254 rv = led_classdev_register(dev, &tpd_led);
1256 destroy_workqueue(led_workqueue);
1263 static int __devinit eeepc_hotk_add(struct acpi_device *device)
1268 pr_notice(EEEPC_HOTK_NAME "\n");
1269 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
1272 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1273 ehotk->handle = device->handle;
1274 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
1275 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
1276 device->driver_data = ehotk;
1277 ehotk->device = device;
1279 result = eeepc_hotk_check();
1281 goto fail_platform_driver;
1282 eeepc_enable_camera();
1284 /* Register platform stuff */
1285 result = platform_driver_register(&platform_driver);
1287 goto fail_platform_driver;
1288 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1289 if (!platform_device) {
1291 goto fail_platform_device1;
1293 result = platform_device_add(platform_device);
1295 goto fail_platform_device2;
1296 result = sysfs_create_group(&platform_device->dev.kobj,
1297 &platform_attribute_group);
1301 dev = &platform_device->dev;
1303 if (!acpi_video_backlight_support()) {
1304 result = eeepc_backlight_init(dev);
1306 goto fail_backlight;
1308 pr_info("Backlight controlled by ACPI video "
1311 result = eeepc_input_init(dev);
1315 result = eeepc_hwmon_init(dev);
1319 result = eeepc_led_init(dev);
1323 result = eeepc_rfkill_init(dev);
1336 eeepc_backlight_exit();
1338 sysfs_remove_group(&platform_device->dev.kobj,
1339 &platform_attribute_group);
1341 platform_device_del(platform_device);
1342 fail_platform_device2:
1343 platform_device_put(platform_device);
1344 fail_platform_device1:
1345 platform_driver_unregister(&platform_driver);
1346 fail_platform_driver:
1352 static int eeepc_hotk_remove(struct acpi_device *device, int type)
1354 eeepc_backlight_exit();
1355 eeepc_rfkill_exit();
1359 sysfs_remove_group(&platform_device->dev.kobj,
1360 &platform_attribute_group);
1361 platform_device_unregister(platform_device);
1362 platform_driver_unregister(&platform_driver);
1368 static int __init eeepc_laptop_init(void)
1372 result = acpi_bus_register_driver(&eeepc_hotk_driver);
1376 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1382 static void __exit eeepc_laptop_exit(void)
1384 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1387 module_init(eeepc_laptop_init);
1388 module_exit(eeepc_laptop_exit);