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 hotplug_slot *hotplug_slot;
146 struct work_struct hotplug_work;
149 /* The actual device the driver binds to */
150 static struct eeepc_hotk *ehotk;
152 /* Platform device/driver */
153 static struct platform_driver platform_driver = {
155 .name = EEEPC_HOTK_FILE,
156 .owner = THIS_MODULE,
160 static struct platform_device *platform_device;
168 enum { KE_KEY, KE_END };
170 static struct key_entry eeepc_keymap[] = {
171 /* Sleep already handled via generic ACPI code */
172 {KE_KEY, 0x10, KEY_WLAN },
173 {KE_KEY, 0x11, KEY_WLAN },
174 {KE_KEY, 0x12, KEY_PROG1 },
175 {KE_KEY, 0x13, KEY_MUTE },
176 {KE_KEY, 0x14, KEY_VOLUMEDOWN },
177 {KE_KEY, 0x15, KEY_VOLUMEUP },
178 {KE_KEY, 0x1a, KEY_COFFEE },
179 {KE_KEY, 0x1b, KEY_ZOOM },
180 {KE_KEY, 0x1c, KEY_PROG2 },
181 {KE_KEY, 0x1d, KEY_PROG3 },
182 {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
183 {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP },
184 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
185 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
186 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
191 * The hotkey driver declaration
193 static int eeepc_hotk_add(struct acpi_device *device);
194 static int eeepc_hotk_remove(struct acpi_device *device, int type);
195 static int eeepc_hotk_resume(struct acpi_device *device);
196 static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
198 static const struct acpi_device_id eeepc_device_ids[] = {
202 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
204 static struct acpi_driver eeepc_hotk_driver = {
205 .name = EEEPC_HOTK_NAME,
206 .class = EEEPC_HOTK_CLASS,
207 .ids = eeepc_device_ids,
208 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
210 .add = eeepc_hotk_add,
211 .remove = eeepc_hotk_remove,
212 .resume = eeepc_hotk_resume,
213 .notify = eeepc_hotk_notify,
217 /* PCI hotplug ops */
218 static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
220 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
221 .owner = THIS_MODULE,
222 .get_adapter_status = eeepc_get_adapter_status,
223 .get_power_status = eeepc_get_adapter_status,
226 /* The backlight device /sys/class/backlight */
227 static struct backlight_device *eeepc_backlight_device;
229 /* The hwmon device */
230 static struct device *eeepc_hwmon_device;
233 * The backlight class declaration
235 static int read_brightness(struct backlight_device *bd);
236 static int update_bl_status(struct backlight_device *bd);
237 static struct backlight_ops eeepcbl_ops = {
238 .get_brightness = read_brightness,
239 .update_status = update_bl_status,
242 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
243 MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
244 MODULE_LICENSE("GPL");
249 static int write_acpi_int(acpi_handle handle, const char *method, int val,
250 struct acpi_buffer *output)
252 struct acpi_object_list params;
253 union acpi_object in_obj;
257 params.pointer = &in_obj;
258 in_obj.type = ACPI_TYPE_INTEGER;
259 in_obj.integer.value = val;
261 status = acpi_evaluate_object(handle, (char *)method, ¶ms, output);
262 return (status == AE_OK ? 0 : -1);
265 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
268 unsigned long long result;
270 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
271 if (ACPI_FAILURE(status)) {
280 static int set_acpi(int cm, int value)
282 if (ehotk->cm_supported & (0x1 << cm)) {
283 const char *method = cm_setv[cm];
286 if (write_acpi_int(ehotk->handle, method, value, NULL))
287 pr_warning("Error writing %s\n", method);
292 static int get_acpi(int cm)
295 if ((ehotk->cm_supported & (0x1 << cm))) {
296 const char *method = cm_getv[cm];
299 if (read_acpi_int(ehotk->handle, method, &value))
300 pr_warning("Error reading %s\n", method);
308 static int read_brightness(struct backlight_device *bd)
310 return get_acpi(CM_ASL_PANELBRIGHT);
313 static int set_brightness(struct backlight_device *bd, int value)
315 value = max(0, min(15, value));
316 return set_acpi(CM_ASL_PANELBRIGHT, value);
319 static int update_bl_status(struct backlight_device *bd)
321 return set_brightness(bd, bd->props.brightness);
328 static bool eeepc_wlan_rfkill_blocked(void)
330 if (get_acpi(CM_ASL_WLAN) == 1)
335 static int eeepc_rfkill_set(void *data, bool blocked)
337 unsigned long asl = (unsigned long)data;
338 return set_acpi(asl, !blocked);
341 static const struct rfkill_ops eeepc_rfkill_ops = {
342 .set_block = eeepc_rfkill_set,
345 static void __init eeepc_enable_camera(void)
348 * If the following call to set_acpi() fails, it's because there's no
349 * camera so we can ignore the error.
351 set_acpi(CM_ASL_CAMERA, 1);
357 static int parse_arg(const char *buf, unsigned long count, int *val)
361 if (sscanf(buf, "%i", val) != 1)
366 static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
370 rv = parse_arg(buf, count, &value);
372 value = set_acpi(cm, value);
378 static ssize_t show_sys_acpi(int cm, char *buf)
380 int value = get_acpi(cm);
384 return sprintf(buf, "%d\n", value);
387 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
388 static ssize_t show_##_name(struct device *dev, \
389 struct device_attribute *attr, \
392 return show_sys_acpi(_cm, buf); \
394 static ssize_t store_##_name(struct device *dev, \
395 struct device_attribute *attr, \
396 const char *buf, size_t count) \
398 return store_sys_acpi(_cm, buf, count); \
400 static struct device_attribute dev_attr_##_name = { \
402 .name = __stringify(_name), \
404 .show = show_##_name, \
405 .store = store_##_name, \
408 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
409 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
410 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
417 static int get_cpufv(struct eeepc_cpufv *c)
419 c->cur = get_acpi(CM_ASL_CPUFV);
420 c->num = (c->cur >> 8) & 0xff;
422 if (c->cur < 0 || c->num <= 0 || c->num > 12)
427 static ssize_t show_available_cpufv(struct device *dev,
428 struct device_attribute *attr,
431 struct eeepc_cpufv c;
437 for (i = 0; i < c.num; i++)
438 len += sprintf(buf + len, "%d ", i);
439 len += sprintf(buf + len, "\n");
443 static ssize_t show_cpufv(struct device *dev,
444 struct device_attribute *attr,
447 struct eeepc_cpufv c;
451 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
454 static ssize_t store_cpufv(struct device *dev,
455 struct device_attribute *attr,
456 const char *buf, size_t count)
458 struct eeepc_cpufv c;
463 rv = parse_arg(buf, count, &value);
466 if (!rv || value < 0 || value >= c.num)
468 set_acpi(CM_ASL_CPUFV, value);
472 static struct device_attribute dev_attr_cpufv = {
480 static struct device_attribute dev_attr_available_cpufv = {
482 .name = "available_cpufv",
484 .show = show_available_cpufv
487 static struct attribute *platform_attributes[] = {
488 &dev_attr_camera.attr,
489 &dev_attr_cardr.attr,
491 &dev_attr_cpufv.attr,
492 &dev_attr_available_cpufv.attr,
496 static struct attribute_group platform_attribute_group = {
497 .attrs = platform_attributes
503 static struct key_entry *eepc_get_entry_by_scancode(int code)
505 struct key_entry *key;
507 for (key = eeepc_keymap; key->type != KE_END; key++)
508 if (code == key->code)
514 static struct key_entry *eepc_get_entry_by_keycode(int code)
516 struct key_entry *key;
518 for (key = eeepc_keymap; key->type != KE_END; key++)
519 if (code == key->keycode && key->type == KE_KEY)
525 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
527 struct key_entry *key = eepc_get_entry_by_scancode(scancode);
529 if (key && key->type == KE_KEY) {
530 *keycode = key->keycode;
537 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
539 struct key_entry *key;
542 if (keycode < 0 || keycode > KEY_MAX)
545 key = eepc_get_entry_by_scancode(scancode);
546 if (key && key->type == KE_KEY) {
547 old_keycode = key->keycode;
548 key->keycode = keycode;
549 set_bit(keycode, dev->keybit);
550 if (!eepc_get_entry_by_keycode(old_keycode))
551 clear_bit(old_keycode, dev->keybit);
558 static void cmsg_quirk(int cm, const char *name)
562 /* Some BIOSes do not report cm although it is avaliable.
563 Check if cm_getv[cm] works and, if yes, assume cm should be set. */
564 if (!(ehotk->cm_supported & (1 << cm))
565 && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) {
566 pr_info("%s (%x) not reported by BIOS,"
567 " enabling anyway\n", name, 1 << cm);
568 ehotk->cm_supported |= 1 << cm;
572 static void cmsg_quirks(void)
574 cmsg_quirk(CM_ASL_LID, "LID");
575 cmsg_quirk(CM_ASL_TYPE, "TYPE");
576 cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER");
577 cmsg_quirk(CM_ASL_TPD, "TPD");
580 static int eeepc_hotk_check(void)
582 const struct key_entry *key;
583 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
586 result = acpi_bus_get_status(ehotk->device);
589 if (ehotk->device->status.present) {
590 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
592 pr_err("Hotkey initialization failed\n");
595 pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
597 /* get control methods supported */
598 if (read_acpi_int(ehotk->handle, "CMSG"
599 , &ehotk->cm_supported)) {
600 pr_err("Get control methods supported failed\n");
604 pr_info("Get control methods supported: 0x%x\n",
605 ehotk->cm_supported);
607 ehotk->inputdev = input_allocate_device();
608 if (!ehotk->inputdev) {
609 pr_info("Unable to allocate input device\n");
612 ehotk->inputdev->name = "Asus EeePC extra buttons";
613 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
614 ehotk->inputdev->id.bustype = BUS_HOST;
615 ehotk->inputdev->getkeycode = eeepc_getkeycode;
616 ehotk->inputdev->setkeycode = eeepc_setkeycode;
618 for (key = eeepc_keymap; key->type != KE_END; key++) {
621 set_bit(EV_KEY, ehotk->inputdev->evbit);
622 set_bit(key->keycode, ehotk->inputdev->keybit);
626 result = input_register_device(ehotk->inputdev);
628 pr_info("Unable to register input device\n");
629 input_free_device(ehotk->inputdev);
633 pr_err("Hotkey device not present, aborting\n");
639 static int notify_brn(void)
641 /* returns the *previous* brightness, or -1 */
642 struct backlight_device *bd = eeepc_backlight_device;
644 int old = bd->props.brightness;
645 bd->props.brightness = read_brightness(bd);
651 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
654 int val = get_acpi(CM_ASL_WLAN);
656 if (val == 1 || val == 0)
664 static void eeepc_hotplug_work(struct work_struct *work)
667 struct pci_bus *bus = pci_find_bus(0, 1);
671 pr_warning("Unable to find PCI bus 1?\n");
675 blocked = eeepc_wlan_rfkill_blocked();
677 dev = pci_get_slot(bus, 0);
679 /* Device already present */
683 dev = pci_scan_single_device(bus, 0);
685 pci_bus_assign_resources(bus);
686 if (pci_bus_add_device(dev))
687 pr_err("Unable to hotplug wifi\n");
690 dev = pci_get_slot(bus, 0);
692 pci_remove_bus_device(dev);
697 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
700 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
702 if (event != ACPI_NOTIFY_BUS_CHECK)
705 schedule_work(&ehotk->hotplug_work);
708 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
710 static struct key_entry *key;
716 if (event > ACPI_MAX_SYS_NOTIFY)
718 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
720 count = ehotk->event_count[event % 128]++;
721 acpi_bus_generate_proc_event(ehotk->device, event, count);
722 acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
723 dev_name(&ehotk->device->dev), event,
725 if (ehotk->inputdev) {
726 if (brn != -ENODEV) {
727 /* brightness-change events need special
728 * handling for conversion to key events
733 brn += NOTIFY_BRN_MIN;
735 event = NOTIFY_BRN_MIN; /* brightness down */
736 else if (event > brn)
737 event = NOTIFY_BRN_MIN + 2; /* ... up */
739 event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
741 key = eepc_get_entry_by_scancode(event);
745 input_report_key(ehotk->inputdev, key->keycode,
747 input_sync(ehotk->inputdev);
748 input_report_key(ehotk->inputdev, key->keycode,
750 input_sync(ehotk->inputdev);
757 static int eeepc_register_rfkill_notifier(char *node)
759 acpi_status status = AE_OK;
762 status = acpi_get_handle(NULL, node, &handle);
764 if (ACPI_SUCCESS(status)) {
765 status = acpi_install_notify_handler(handle,
769 if (ACPI_FAILURE(status))
770 pr_warning("Failed to register notify on %s\n", node);
777 static void eeepc_unregister_rfkill_notifier(char *node)
779 acpi_status status = AE_OK;
782 status = acpi_get_handle(NULL, node, &handle);
784 if (ACPI_SUCCESS(status)) {
785 status = acpi_remove_notify_handler(handle,
787 eeepc_rfkill_notify);
788 if (ACPI_FAILURE(status))
789 pr_err("Error removing rfkill notify handler %s\n",
794 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
796 kfree(hotplug_slot->info);
800 static int eeepc_setup_pci_hotplug(void)
803 struct pci_bus *bus = pci_find_bus(0, 1);
806 pr_err("Unable to find wifi PCI bus\n");
810 ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
811 if (!ehotk->hotplug_slot)
814 ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
816 if (!ehotk->hotplug_slot->info)
819 ehotk->hotplug_slot->private = ehotk;
820 ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
821 ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
822 eeepc_get_adapter_status(ehotk->hotplug_slot,
823 &ehotk->hotplug_slot->info->adapter_status);
825 ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
827 pr_err("Unable to register hotplug slot - %d\n", ret);
834 kfree(ehotk->hotplug_slot->info);
836 kfree(ehotk->hotplug_slot);
837 ehotk->hotplug_slot = NULL;
842 static int eeepc_hotk_add(struct acpi_device *device)
848 pr_notice(EEEPC_HOTK_NAME "\n");
849 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
852 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
853 ehotk->handle = device->handle;
854 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
855 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
856 device->driver_data = ehotk;
857 ehotk->device = device;
858 result = eeepc_hotk_check();
871 static int eeepc_hotk_remove(struct acpi_device *device, int type)
873 if (!device || !acpi_driver_data(device))
880 static int eeepc_hotk_resume(struct acpi_device *device)
882 if (ehotk->wlan_rfkill) {
885 /* Workaround - it seems that _PTS disables the wireless
886 without notification or changing the value read by WLAN.
887 Normally this is fine because the correct value is restored
888 from the non-volatile storage on resume, but we need to do
889 it ourself if case suspend is aborted, or we lose wireless.
891 wlan = get_acpi(CM_ASL_WLAN);
892 set_acpi(CM_ASL_WLAN, wlan);
894 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
896 schedule_work(&ehotk->hotplug_work);
899 if (ehotk->bluetooth_rfkill)
900 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
901 get_acpi(CM_ASL_BLUETOOTH) != 1);
909 static int eeepc_get_fan_pwm(void)
913 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
914 value = value * 255 / 100;
918 static void eeepc_set_fan_pwm(int value)
920 value = SENSORS_LIMIT(value, 0, 255);
921 value = value * 100 / 255;
922 ec_write(EEEPC_EC_SC02, value);
925 static int eeepc_get_fan_rpm(void)
930 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
931 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
932 return (high << 8 | low);
935 static int eeepc_get_fan_ctrl(void)
939 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
940 return ((value & 0x02 ? 1 : 0));
943 static void eeepc_set_fan_ctrl(int manual)
947 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
952 ec_write(EEEPC_EC_SFB3, value);
955 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
959 rv = parse_arg(buf, count, &value);
965 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
967 return sprintf(buf, "%d\n", get());
970 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
971 static ssize_t show_##_name(struct device *dev, \
972 struct device_attribute *attr, \
975 return show_sys_hwmon(_set, buf); \
977 static ssize_t store_##_name(struct device *dev, \
978 struct device_attribute *attr, \
979 const char *buf, size_t count) \
981 return store_sys_hwmon(_get, buf, count); \
983 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
985 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
986 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
987 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
988 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
989 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
992 show_name(struct device *dev, struct device_attribute *attr, char *buf)
994 return sprintf(buf, "eeepc\n");
996 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
998 static struct attribute *hwmon_attributes[] = {
999 &sensor_dev_attr_pwm1.dev_attr.attr,
1000 &sensor_dev_attr_fan1_input.dev_attr.attr,
1001 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1002 &sensor_dev_attr_name.dev_attr.attr,
1006 static struct attribute_group hwmon_attribute_group = {
1007 .attrs = hwmon_attributes
1013 static void eeepc_backlight_exit(void)
1015 if (eeepc_backlight_device)
1016 backlight_device_unregister(eeepc_backlight_device);
1017 eeepc_backlight_device = NULL;
1020 static void eeepc_rfkill_exit(void)
1022 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
1023 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
1024 if (ehotk->wlan_rfkill)
1025 rfkill_unregister(ehotk->wlan_rfkill);
1026 if (ehotk->bluetooth_rfkill)
1027 rfkill_unregister(ehotk->bluetooth_rfkill);
1028 if (ehotk->wwan3g_rfkill)
1029 rfkill_unregister(ehotk->wwan3g_rfkill);
1030 if (ehotk->hotplug_slot)
1031 pci_hp_deregister(ehotk->hotplug_slot);
1034 static void eeepc_input_exit(void)
1036 if (ehotk->inputdev)
1037 input_unregister_device(ehotk->inputdev);
1040 static void eeepc_hwmon_exit(void)
1042 struct device *hwmon;
1044 hwmon = eeepc_hwmon_device;
1047 sysfs_remove_group(&hwmon->kobj,
1048 &hwmon_attribute_group);
1049 hwmon_device_unregister(hwmon);
1050 eeepc_hwmon_device = NULL;
1053 static void __exit eeepc_laptop_exit(void)
1055 eeepc_backlight_exit();
1056 eeepc_rfkill_exit();
1059 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1060 sysfs_remove_group(&platform_device->dev.kobj,
1061 &platform_attribute_group);
1062 platform_device_unregister(platform_device);
1063 platform_driver_unregister(&platform_driver);
1066 static int eeepc_new_rfkill(struct rfkill **rfkill,
1067 const char *name, struct device *dev,
1068 enum rfkill_type type, int cm)
1072 result = get_acpi(cm);
1076 *rfkill = rfkill_alloc(name, dev, type,
1077 &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1082 rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1083 result = rfkill_register(*rfkill);
1085 rfkill_destroy(*rfkill);
1093 static int eeepc_rfkill_init(struct device *dev)
1097 INIT_WORK(&ehotk->hotplug_work, eeepc_hotplug_work);
1099 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1100 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1102 result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1104 RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1106 if (result && result != -ENODEV)
1109 result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1110 "eeepc-bluetooth", dev,
1111 RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1113 if (result && result != -ENODEV)
1116 result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill,
1117 "eeepc-wwan3g", dev,
1118 RFKILL_TYPE_WWAN, CM_ASL_3G);
1120 if (result && result != -ENODEV)
1123 result = eeepc_setup_pci_hotplug();
1125 * If we get -EBUSY then something else is handling the PCI hotplug -
1126 * don't fail in this case
1128 if (result == -EBUSY)
1132 if (result && result != -ENODEV)
1133 eeepc_rfkill_exit();
1137 static int eeepc_backlight_init(struct device *dev)
1139 struct backlight_device *bd;
1141 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1142 NULL, &eeepcbl_ops);
1144 pr_err("Could not register eeepc backlight device\n");
1145 eeepc_backlight_device = NULL;
1148 eeepc_backlight_device = bd;
1149 bd->props.max_brightness = 15;
1150 bd->props.brightness = read_brightness(NULL);
1151 bd->props.power = FB_BLANK_UNBLANK;
1152 backlight_update_status(bd);
1156 static int eeepc_hwmon_init(struct device *dev)
1158 struct device *hwmon;
1161 hwmon = hwmon_device_register(dev);
1162 if (IS_ERR(hwmon)) {
1163 pr_err("Could not register eeepc hwmon device\n");
1164 eeepc_hwmon_device = NULL;
1165 return PTR_ERR(hwmon);
1167 eeepc_hwmon_device = hwmon;
1168 result = sysfs_create_group(&hwmon->kobj,
1169 &hwmon_attribute_group);
1175 static int __init eeepc_laptop_init(void)
1182 result = acpi_bus_register_driver(&eeepc_hotk_driver);
1186 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1190 eeepc_enable_camera();
1192 /* Register platform stuff */
1193 result = platform_driver_register(&platform_driver);
1195 goto fail_platform_driver;
1196 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1197 if (!platform_device) {
1199 goto fail_platform_device1;
1201 result = platform_device_add(platform_device);
1203 goto fail_platform_device2;
1204 result = sysfs_create_group(&platform_device->dev.kobj,
1205 &platform_attribute_group);
1209 dev = &platform_device->dev;
1211 if (!acpi_video_backlight_support()) {
1212 result = eeepc_backlight_init(dev);
1214 goto fail_backlight;
1216 pr_info("Backlight controlled by ACPI video "
1219 result = eeepc_hwmon_init(dev);
1223 result = eeepc_rfkill_init(dev);
1231 eeepc_backlight_exit();
1233 sysfs_remove_group(&platform_device->dev.kobj,
1234 &platform_attribute_group);
1236 platform_device_del(platform_device);
1237 fail_platform_device2:
1238 platform_device_put(platform_device);
1239 fail_platform_device1:
1240 platform_driver_unregister(&platform_driver);
1241 fail_platform_driver:
1246 module_init(eeepc_laptop_init);
1247 module_exit(eeepc_laptop_exit);