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>
38 #define EEEPC_LAPTOP_VERSION "0.1"
40 #define EEEPC_HOTK_NAME "Eee PC Hotkey Driver"
41 #define EEEPC_HOTK_FILE "eeepc"
42 #define EEEPC_HOTK_CLASS "hotkey"
43 #define EEEPC_HOTK_DEVICE_NAME "Hotkey"
44 #define EEEPC_HOTK_HID "ASUS010"
48 * Definitions for Asus EeePC
50 #define NOTIFY_WLAN_ON 0x10
51 #define NOTIFY_BRN_MIN 0x20
52 #define NOTIFY_BRN_MAX 0x2f
55 DISABLE_ASL_WLAN = 0x0001,
56 DISABLE_ASL_BLUETOOTH = 0x0002,
57 DISABLE_ASL_IRDA = 0x0004,
58 DISABLE_ASL_CAMERA = 0x0008,
59 DISABLE_ASL_TV = 0x0010,
60 DISABLE_ASL_GPS = 0x0020,
61 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
62 DISABLE_ASL_MODEM = 0x0080,
63 DISABLE_ASL_CARDREADER = 0x0100,
64 DISABLE_ASL_3G = 0x0200,
65 DISABLE_ASL_WIMAX = 0x0400,
66 DISABLE_ASL_HWCF = 0x0800
83 CM_ASL_CPUTEMPERATURE,
96 CM_ASL_PANELPOWER, /*P901*/
100 static const char *cm_getv[] = {
101 "WLDG", "BTHG", NULL, NULL,
102 "CAMG", NULL, NULL, NULL,
103 NULL, "PBLG", NULL, NULL,
104 "CFVG", NULL, NULL, NULL,
105 "USBG", NULL, NULL, "MODG",
106 "CRDG", "M3GG", "WIMG", "HWCF",
107 "LIDG", "TYPE", "PBPG", "TPDG"
110 static const char *cm_setv[] = {
111 "WLDS", "BTHS", NULL, NULL,
112 "CAMS", NULL, NULL, NULL,
113 "SDSP", "PBLS", "HDPS", NULL,
114 "CFVS", NULL, NULL, NULL,
115 "USBG", NULL, NULL, "MODS",
116 "CRDS", "M3GS", "WIMS", NULL,
117 NULL, NULL, "PBPS", "TPDS"
120 #define EEEPC_EC "\\_SB.PCI0.SBRG.EC0."
122 #define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */
123 #define EEEPC_EC_SC02 0x63
124 #define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */
125 #define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */
126 #define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */
127 #define EEEPC_EC_SFB3 0xD3
130 * This is the main structure, we can use it to store useful information
131 * about the hotk device
134 struct acpi_device *device; /* the device we are in */
135 acpi_handle handle; /* the handle of the hotk device */
136 u32 cm_supported; /* the control methods supported
138 uint init_flag; /* Init flags */
139 u16 event_count[128]; /* count for each event */
140 struct input_dev *inputdev;
142 struct rfkill *wlan_rfkill;
143 struct rfkill *bluetooth_rfkill;
144 struct rfkill *wwan3g_rfkill;
145 struct rfkill *wimax_rfkill;
146 struct hotplug_slot *hotplug_slot;
147 struct mutex hotplug_lock;
150 /* The actual device the driver binds to */
151 static struct eeepc_hotk *ehotk;
153 /* Platform device/driver */
154 static int eeepc_hotk_thaw(struct device *device);
155 static int eeepc_hotk_restore(struct device *device);
157 static struct dev_pm_ops eeepc_pm_ops = {
158 .thaw = eeepc_hotk_thaw,
159 .restore = eeepc_hotk_restore,
162 static struct platform_driver platform_driver = {
164 .name = EEEPC_HOTK_FILE,
165 .owner = THIS_MODULE,
170 static struct platform_device *platform_device;
178 enum { KE_KEY, KE_END };
180 static struct key_entry eeepc_keymap[] = {
181 /* Sleep already handled via generic ACPI code */
182 {KE_KEY, 0x10, KEY_WLAN },
183 {KE_KEY, 0x11, KEY_WLAN },
184 {KE_KEY, 0x12, KEY_PROG1 },
185 {KE_KEY, 0x13, KEY_MUTE },
186 {KE_KEY, 0x14, KEY_VOLUMEDOWN },
187 {KE_KEY, 0x15, KEY_VOLUMEUP },
188 {KE_KEY, 0x1a, KEY_COFFEE },
189 {KE_KEY, 0x1b, KEY_ZOOM },
190 {KE_KEY, 0x1c, KEY_PROG2 },
191 {KE_KEY, 0x1d, KEY_PROG3 },
192 {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
193 {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP },
194 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
195 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
196 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
201 * The hotkey driver declaration
203 static int eeepc_hotk_add(struct acpi_device *device);
204 static int eeepc_hotk_remove(struct acpi_device *device, int type);
205 static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
207 static const struct acpi_device_id eeepc_device_ids[] = {
211 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
213 static struct acpi_driver eeepc_hotk_driver = {
214 .name = EEEPC_HOTK_NAME,
215 .class = EEEPC_HOTK_CLASS,
216 .ids = eeepc_device_ids,
217 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
219 .add = eeepc_hotk_add,
220 .remove = eeepc_hotk_remove,
221 .notify = eeepc_hotk_notify,
225 /* PCI hotplug ops */
226 static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
228 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
229 .owner = THIS_MODULE,
230 .get_adapter_status = eeepc_get_adapter_status,
231 .get_power_status = eeepc_get_adapter_status,
234 /* The backlight device /sys/class/backlight */
235 static struct backlight_device *eeepc_backlight_device;
237 /* The hwmon device */
238 static struct device *eeepc_hwmon_device;
241 * The backlight class declaration
243 static int read_brightness(struct backlight_device *bd);
244 static int update_bl_status(struct backlight_device *bd);
245 static struct backlight_ops eeepcbl_ops = {
246 .get_brightness = read_brightness,
247 .update_status = update_bl_status,
250 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
251 MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
252 MODULE_LICENSE("GPL");
257 static int write_acpi_int(acpi_handle handle, const char *method, int val,
258 struct acpi_buffer *output)
260 struct acpi_object_list params;
261 union acpi_object in_obj;
265 params.pointer = &in_obj;
266 in_obj.type = ACPI_TYPE_INTEGER;
267 in_obj.integer.value = val;
269 status = acpi_evaluate_object(handle, (char *)method, ¶ms, output);
270 return (status == AE_OK ? 0 : -1);
273 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
276 unsigned long long result;
278 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
279 if (ACPI_FAILURE(status)) {
288 static int set_acpi(int cm, int value)
290 if (ehotk->cm_supported & (0x1 << cm)) {
291 const char *method = cm_setv[cm];
294 if (write_acpi_int(ehotk->handle, method, value, NULL))
295 pr_warning("Error writing %s\n", method);
300 static int get_acpi(int cm)
303 if ((ehotk->cm_supported & (0x1 << cm))) {
304 const char *method = cm_getv[cm];
307 if (read_acpi_int(ehotk->handle, method, &value))
308 pr_warning("Error reading %s\n", method);
316 static int read_brightness(struct backlight_device *bd)
318 return get_acpi(CM_ASL_PANELBRIGHT);
321 static int set_brightness(struct backlight_device *bd, int value)
323 value = max(0, min(15, value));
324 return set_acpi(CM_ASL_PANELBRIGHT, value);
327 static int update_bl_status(struct backlight_device *bd)
329 return set_brightness(bd, bd->props.brightness);
336 static bool eeepc_wlan_rfkill_blocked(void)
338 if (get_acpi(CM_ASL_WLAN) == 1)
343 static int eeepc_rfkill_set(void *data, bool blocked)
345 unsigned long asl = (unsigned long)data;
346 return set_acpi(asl, !blocked);
349 static const struct rfkill_ops eeepc_rfkill_ops = {
350 .set_block = eeepc_rfkill_set,
353 static void __init eeepc_enable_camera(void)
356 * If the following call to set_acpi() fails, it's because there's no
357 * camera so we can ignore the error.
359 set_acpi(CM_ASL_CAMERA, 1);
365 static int parse_arg(const char *buf, unsigned long count, int *val)
369 if (sscanf(buf, "%i", val) != 1)
374 static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
378 rv = parse_arg(buf, count, &value);
380 value = set_acpi(cm, value);
386 static ssize_t show_sys_acpi(int cm, char *buf)
388 int value = get_acpi(cm);
392 return sprintf(buf, "%d\n", value);
395 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
396 static ssize_t show_##_name(struct device *dev, \
397 struct device_attribute *attr, \
400 return show_sys_acpi(_cm, buf); \
402 static ssize_t store_##_name(struct device *dev, \
403 struct device_attribute *attr, \
404 const char *buf, size_t count) \
406 return store_sys_acpi(_cm, buf, count); \
408 static struct device_attribute dev_attr_##_name = { \
410 .name = __stringify(_name), \
412 .show = show_##_name, \
413 .store = store_##_name, \
416 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
417 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
418 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
425 static int get_cpufv(struct eeepc_cpufv *c)
427 c->cur = get_acpi(CM_ASL_CPUFV);
428 c->num = (c->cur >> 8) & 0xff;
430 if (c->cur < 0 || c->num <= 0 || c->num > 12)
435 static ssize_t show_available_cpufv(struct device *dev,
436 struct device_attribute *attr,
439 struct eeepc_cpufv c;
445 for (i = 0; i < c.num; i++)
446 len += sprintf(buf + len, "%d ", i);
447 len += sprintf(buf + len, "\n");
451 static ssize_t show_cpufv(struct device *dev,
452 struct device_attribute *attr,
455 struct eeepc_cpufv c;
459 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
462 static ssize_t store_cpufv(struct device *dev,
463 struct device_attribute *attr,
464 const char *buf, size_t count)
466 struct eeepc_cpufv c;
471 rv = parse_arg(buf, count, &value);
474 if (!rv || value < 0 || value >= c.num)
476 set_acpi(CM_ASL_CPUFV, value);
480 static struct device_attribute dev_attr_cpufv = {
488 static struct device_attribute dev_attr_available_cpufv = {
490 .name = "available_cpufv",
492 .show = show_available_cpufv
495 static struct attribute *platform_attributes[] = {
496 &dev_attr_camera.attr,
497 &dev_attr_cardr.attr,
499 &dev_attr_cpufv.attr,
500 &dev_attr_available_cpufv.attr,
504 static struct attribute_group platform_attribute_group = {
505 .attrs = platform_attributes
511 static struct key_entry *eepc_get_entry_by_scancode(int code)
513 struct key_entry *key;
515 for (key = eeepc_keymap; key->type != KE_END; key++)
516 if (code == key->code)
522 static struct key_entry *eepc_get_entry_by_keycode(int code)
524 struct key_entry *key;
526 for (key = eeepc_keymap; key->type != KE_END; key++)
527 if (code == key->keycode && key->type == KE_KEY)
533 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
535 struct key_entry *key = eepc_get_entry_by_scancode(scancode);
537 if (key && key->type == KE_KEY) {
538 *keycode = key->keycode;
545 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
547 struct key_entry *key;
550 if (keycode < 0 || keycode > KEY_MAX)
553 key = eepc_get_entry_by_scancode(scancode);
554 if (key && key->type == KE_KEY) {
555 old_keycode = key->keycode;
556 key->keycode = keycode;
557 set_bit(keycode, dev->keybit);
558 if (!eepc_get_entry_by_keycode(old_keycode))
559 clear_bit(old_keycode, dev->keybit);
566 static void cmsg_quirk(int cm, const char *name)
570 /* Some BIOSes do not report cm although it is avaliable.
571 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
572 if (!(ehotk->cm_supported & (1 << cm))
573 && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) {
574 pr_info("%s (%x) not reported by BIOS,"
575 " enabling anyway\n", name, 1 << cm);
576 ehotk->cm_supported |= 1 << cm;
580 static void cmsg_quirks(void)
582 cmsg_quirk(CM_ASL_LID, "LID");
583 cmsg_quirk(CM_ASL_TYPE, "TYPE");
584 cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER");
585 cmsg_quirk(CM_ASL_TPD, "TPD");
588 static int eeepc_hotk_check(void)
590 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
593 result = acpi_bus_get_status(ehotk->device);
596 if (ehotk->device->status.present) {
597 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
599 pr_err("Hotkey initialization failed\n");
602 pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
604 /* get control methods supported */
605 if (read_acpi_int(ehotk->handle, "CMSG"
606 , &ehotk->cm_supported)) {
607 pr_err("Get control methods supported failed\n");
611 pr_info("Get control methods supported: 0x%x\n",
612 ehotk->cm_supported);
615 pr_err("Hotkey device not present, aborting\n");
621 static int notify_brn(void)
623 /* returns the *previous* brightness, or -1 */
624 struct backlight_device *bd = eeepc_backlight_device;
626 int old = bd->props.brightness;
627 bd->props.brightness = read_brightness(bd);
633 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
636 int val = get_acpi(CM_ASL_WLAN);
638 if (val == 1 || val == 0)
646 static void eeepc_rfkill_hotplug(void)
650 bool blocked = eeepc_wlan_rfkill_blocked();
652 if (ehotk->wlan_rfkill)
653 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
655 mutex_lock(&ehotk->hotplug_lock);
657 if (ehotk->hotplug_slot) {
658 bus = pci_find_bus(0, 1);
660 pr_warning("Unable to find PCI bus 1?\n");
665 dev = pci_get_slot(bus, 0);
667 /* Device already present */
671 dev = pci_scan_single_device(bus, 0);
673 pci_bus_assign_resources(bus);
674 if (pci_bus_add_device(dev))
675 pr_err("Unable to hotplug wifi\n");
678 dev = pci_get_slot(bus, 0);
680 pci_remove_bus_device(dev);
687 mutex_unlock(&ehotk->hotplug_lock);
690 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
692 if (event != ACPI_NOTIFY_BUS_CHECK)
695 eeepc_rfkill_hotplug();
698 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
700 static struct key_entry *key;
706 if (event > ACPI_MAX_SYS_NOTIFY)
708 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
710 count = ehotk->event_count[event % 128]++;
711 acpi_bus_generate_proc_event(ehotk->device, event, count);
712 acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
713 dev_name(&ehotk->device->dev), event,
715 if (ehotk->inputdev) {
716 if (brn != -ENODEV) {
717 /* brightness-change events need special
718 * handling for conversion to key events
723 brn += NOTIFY_BRN_MIN;
725 event = NOTIFY_BRN_MIN; /* brightness down */
726 else if (event > brn)
727 event = NOTIFY_BRN_MIN + 2; /* ... up */
729 event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
731 key = eepc_get_entry_by_scancode(event);
735 input_report_key(ehotk->inputdev, key->keycode,
737 input_sync(ehotk->inputdev);
738 input_report_key(ehotk->inputdev, key->keycode,
740 input_sync(ehotk->inputdev);
747 static int eeepc_register_rfkill_notifier(char *node)
749 acpi_status status = AE_OK;
752 status = acpi_get_handle(NULL, node, &handle);
754 if (ACPI_SUCCESS(status)) {
755 status = acpi_install_notify_handler(handle,
759 if (ACPI_FAILURE(status))
760 pr_warning("Failed to register notify on %s\n", node);
767 static void eeepc_unregister_rfkill_notifier(char *node)
769 acpi_status status = AE_OK;
772 status = acpi_get_handle(NULL, node, &handle);
774 if (ACPI_SUCCESS(status)) {
775 status = acpi_remove_notify_handler(handle,
777 eeepc_rfkill_notify);
778 if (ACPI_FAILURE(status))
779 pr_err("Error removing rfkill notify handler %s\n",
784 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
786 kfree(hotplug_slot->info);
790 static int eeepc_setup_pci_hotplug(void)
793 struct pci_bus *bus = pci_find_bus(0, 1);
796 pr_err("Unable to find wifi PCI bus\n");
800 ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
801 if (!ehotk->hotplug_slot)
804 ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
806 if (!ehotk->hotplug_slot->info)
809 ehotk->hotplug_slot->private = ehotk;
810 ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
811 ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
812 eeepc_get_adapter_status(ehotk->hotplug_slot,
813 &ehotk->hotplug_slot->info->adapter_status);
815 ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
817 pr_err("Unable to register hotplug slot - %d\n", ret);
824 kfree(ehotk->hotplug_slot->info);
826 kfree(ehotk->hotplug_slot);
827 ehotk->hotplug_slot = NULL;
832 static int eeepc_hotk_thaw(struct device *device)
834 if (ehotk->wlan_rfkill) {
838 * Work around bios bug - acpi _PTS turns off the wireless led
839 * during suspend. Normally it restores it on resume, but
840 * we should kick it ourselves in case hibernation is aborted.
842 wlan = get_acpi(CM_ASL_WLAN);
843 set_acpi(CM_ASL_WLAN, wlan);
849 static int eeepc_hotk_restore(struct device *device)
851 /* Refresh both wlan rfkill state and pci hotplug */
852 if (ehotk->wlan_rfkill)
853 eeepc_rfkill_hotplug();
855 if (ehotk->bluetooth_rfkill)
856 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
857 get_acpi(CM_ASL_BLUETOOTH) != 1);
858 if (ehotk->wwan3g_rfkill)
859 rfkill_set_sw_state(ehotk->wwan3g_rfkill,
860 get_acpi(CM_ASL_3G) != 1);
861 if (ehotk->wimax_rfkill)
862 rfkill_set_sw_state(ehotk->wimax_rfkill,
863 get_acpi(CM_ASL_WIMAX) != 1);
871 static int eeepc_get_fan_pwm(void)
875 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
876 value = value * 255 / 100;
880 static void eeepc_set_fan_pwm(int value)
882 value = SENSORS_LIMIT(value, 0, 255);
883 value = value * 100 / 255;
884 ec_write(EEEPC_EC_SC02, value);
887 static int eeepc_get_fan_rpm(void)
892 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
893 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
894 return (high << 8 | low);
897 static int eeepc_get_fan_ctrl(void)
901 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
902 return ((value & 0x02 ? 1 : 0));
905 static void eeepc_set_fan_ctrl(int manual)
909 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
914 ec_write(EEEPC_EC_SFB3, value);
917 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
921 rv = parse_arg(buf, count, &value);
927 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
929 return sprintf(buf, "%d\n", get());
932 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
933 static ssize_t show_##_name(struct device *dev, \
934 struct device_attribute *attr, \
937 return show_sys_hwmon(_set, buf); \
939 static ssize_t store_##_name(struct device *dev, \
940 struct device_attribute *attr, \
941 const char *buf, size_t count) \
943 return store_sys_hwmon(_get, buf, count); \
945 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
947 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
948 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
949 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
950 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
951 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
954 show_name(struct device *dev, struct device_attribute *attr, char *buf)
956 return sprintf(buf, "eeepc\n");
958 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
960 static struct attribute *hwmon_attributes[] = {
961 &sensor_dev_attr_pwm1.dev_attr.attr,
962 &sensor_dev_attr_fan1_input.dev_attr.attr,
963 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
964 &sensor_dev_attr_name.dev_attr.attr,
968 static struct attribute_group hwmon_attribute_group = {
969 .attrs = hwmon_attributes
975 static void eeepc_backlight_exit(void)
977 if (eeepc_backlight_device)
978 backlight_device_unregister(eeepc_backlight_device);
979 eeepc_backlight_device = NULL;
982 static void eeepc_rfkill_exit(void)
984 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5");
985 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
986 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
987 if (ehotk->wlan_rfkill) {
988 rfkill_unregister(ehotk->wlan_rfkill);
989 rfkill_destroy(ehotk->wlan_rfkill);
990 ehotk->wlan_rfkill = NULL;
993 * Refresh pci hotplug in case the rfkill state was changed after
994 * eeepc_unregister_rfkill_notifier()
996 eeepc_rfkill_hotplug();
997 if (ehotk->hotplug_slot)
998 pci_hp_deregister(ehotk->hotplug_slot);
1000 if (ehotk->bluetooth_rfkill) {
1001 rfkill_unregister(ehotk->bluetooth_rfkill);
1002 rfkill_destroy(ehotk->bluetooth_rfkill);
1003 ehotk->bluetooth_rfkill = NULL;
1005 if (ehotk->wwan3g_rfkill) {
1006 rfkill_unregister(ehotk->wwan3g_rfkill);
1007 rfkill_destroy(ehotk->wwan3g_rfkill);
1008 ehotk->wwan3g_rfkill = NULL;
1010 if (ehotk->wimax_rfkill) {
1011 rfkill_unregister(ehotk->wimax_rfkill);
1012 rfkill_destroy(ehotk->wimax_rfkill);
1013 ehotk->wimax_rfkill = NULL;
1017 static void eeepc_input_exit(void)
1019 if (ehotk->inputdev)
1020 input_unregister_device(ehotk->inputdev);
1023 static void eeepc_hwmon_exit(void)
1025 struct device *hwmon;
1027 hwmon = eeepc_hwmon_device;
1030 sysfs_remove_group(&hwmon->kobj,
1031 &hwmon_attribute_group);
1032 hwmon_device_unregister(hwmon);
1033 eeepc_hwmon_device = NULL;
1036 static int eeepc_new_rfkill(struct rfkill **rfkill,
1037 const char *name, struct device *dev,
1038 enum rfkill_type type, int cm)
1042 result = get_acpi(cm);
1046 *rfkill = rfkill_alloc(name, dev, type,
1047 &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1052 rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1053 result = rfkill_register(*rfkill);
1055 rfkill_destroy(*rfkill);
1063 static int eeepc_rfkill_init(struct device *dev)
1067 mutex_init(&ehotk->hotplug_lock);
1069 result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1071 RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1073 if (result && result != -ENODEV)
1076 result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1077 "eeepc-bluetooth", dev,
1078 RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1080 if (result && result != -ENODEV)
1083 result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill,
1084 "eeepc-wwan3g", dev,
1085 RFKILL_TYPE_WWAN, CM_ASL_3G);
1087 if (result && result != -ENODEV)
1090 result = eeepc_new_rfkill(&ehotk->wimax_rfkill,
1092 RFKILL_TYPE_WIMAX, CM_ASL_WIMAX);
1094 if (result && result != -ENODEV)
1097 result = eeepc_setup_pci_hotplug();
1099 * If we get -EBUSY then something else is handling the PCI hotplug -
1100 * don't fail in this case
1102 if (result == -EBUSY)
1105 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P5");
1106 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1107 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1109 * Refresh pci hotplug in case the rfkill state was changed during
1112 eeepc_rfkill_hotplug();
1115 if (result && result != -ENODEV)
1116 eeepc_rfkill_exit();
1120 static int eeepc_backlight_init(struct device *dev)
1122 struct backlight_device *bd;
1124 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1125 NULL, &eeepcbl_ops);
1127 pr_err("Could not register eeepc backlight device\n");
1128 eeepc_backlight_device = NULL;
1131 eeepc_backlight_device = bd;
1132 bd->props.max_brightness = 15;
1133 bd->props.brightness = read_brightness(NULL);
1134 bd->props.power = FB_BLANK_UNBLANK;
1135 backlight_update_status(bd);
1139 static int eeepc_hwmon_init(struct device *dev)
1141 struct device *hwmon;
1144 hwmon = hwmon_device_register(dev);
1145 if (IS_ERR(hwmon)) {
1146 pr_err("Could not register eeepc hwmon device\n");
1147 eeepc_hwmon_device = NULL;
1148 return PTR_ERR(hwmon);
1150 eeepc_hwmon_device = hwmon;
1151 result = sysfs_create_group(&hwmon->kobj,
1152 &hwmon_attribute_group);
1158 static int eeepc_input_init(struct device *dev)
1160 const struct key_entry *key;
1163 ehotk->inputdev = input_allocate_device();
1164 if (!ehotk->inputdev) {
1165 pr_info("Unable to allocate input device\n");
1168 ehotk->inputdev->name = "Asus EeePC extra buttons";
1169 ehotk->inputdev->dev.parent = dev;
1170 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
1171 ehotk->inputdev->id.bustype = BUS_HOST;
1172 ehotk->inputdev->getkeycode = eeepc_getkeycode;
1173 ehotk->inputdev->setkeycode = eeepc_setkeycode;
1175 for (key = eeepc_keymap; key->type != KE_END; key++) {
1176 switch (key->type) {
1178 set_bit(EV_KEY, ehotk->inputdev->evbit);
1179 set_bit(key->keycode, ehotk->inputdev->keybit);
1183 result = input_register_device(ehotk->inputdev);
1185 pr_info("Unable to register input device\n");
1186 input_free_device(ehotk->inputdev);
1192 static int eeepc_hotk_add(struct acpi_device *device)
1199 pr_notice(EEEPC_HOTK_NAME "\n");
1200 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
1203 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
1204 ehotk->handle = device->handle;
1205 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
1206 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
1207 device->driver_data = ehotk;
1208 ehotk->device = device;
1210 result = eeepc_hotk_check();
1212 goto fail_platform_driver;
1213 eeepc_enable_camera();
1215 /* Register platform stuff */
1216 result = platform_driver_register(&platform_driver);
1218 goto fail_platform_driver;
1219 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1220 if (!platform_device) {
1222 goto fail_platform_device1;
1224 result = platform_device_add(platform_device);
1226 goto fail_platform_device2;
1227 result = sysfs_create_group(&platform_device->dev.kobj,
1228 &platform_attribute_group);
1232 dev = &platform_device->dev;
1234 if (!acpi_video_backlight_support()) {
1235 result = eeepc_backlight_init(dev);
1237 goto fail_backlight;
1239 pr_info("Backlight controlled by ACPI video "
1242 result = eeepc_input_init(dev);
1246 result = eeepc_hwmon_init(dev);
1250 result = eeepc_rfkill_init(dev);
1261 eeepc_backlight_exit();
1263 sysfs_remove_group(&platform_device->dev.kobj,
1264 &platform_attribute_group);
1266 platform_device_del(platform_device);
1267 fail_platform_device2:
1268 platform_device_put(platform_device);
1269 fail_platform_device1:
1270 platform_driver_unregister(&platform_driver);
1271 fail_platform_driver:
1277 static int eeepc_hotk_remove(struct acpi_device *device, int type)
1279 if (!device || !acpi_driver_data(device))
1282 eeepc_backlight_exit();
1283 eeepc_rfkill_exit();
1286 sysfs_remove_group(&platform_device->dev.kobj,
1287 &platform_attribute_group);
1288 platform_device_unregister(platform_device);
1289 platform_driver_unregister(&platform_driver);
1295 static int __init eeepc_laptop_init(void)
1301 result = acpi_bus_register_driver(&eeepc_hotk_driver);
1305 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1311 static void __exit eeepc_laptop_exit(void)
1313 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1316 module_init(eeepc_laptop_init);
1317 module_exit(eeepc_laptop_exit);