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 hotplug_slot *hotplug_slot;
147 /* The actual device the driver binds to */
148 static struct eeepc_hotk *ehotk;
150 /* Platform device/driver */
151 static struct platform_driver platform_driver = {
153 .name = EEEPC_HOTK_FILE,
154 .owner = THIS_MODULE,
158 static struct platform_device *platform_device;
166 enum { KE_KEY, KE_END };
168 static struct key_entry eeepc_keymap[] = {
169 /* Sleep already handled via generic ACPI code */
170 {KE_KEY, 0x10, KEY_WLAN },
171 {KE_KEY, 0x11, KEY_WLAN },
172 {KE_KEY, 0x12, KEY_PROG1 },
173 {KE_KEY, 0x13, KEY_MUTE },
174 {KE_KEY, 0x14, KEY_VOLUMEDOWN },
175 {KE_KEY, 0x15, KEY_VOLUMEUP },
176 {KE_KEY, 0x1a, KEY_COFFEE },
177 {KE_KEY, 0x1b, KEY_ZOOM },
178 {KE_KEY, 0x1c, KEY_PROG2 },
179 {KE_KEY, 0x1d, KEY_PROG3 },
180 {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
181 {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP },
182 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
183 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
184 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
189 * The hotkey driver declaration
191 static int eeepc_hotk_add(struct acpi_device *device);
192 static int eeepc_hotk_remove(struct acpi_device *device, int type);
193 static int eeepc_hotk_resume(struct acpi_device *device);
194 static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
196 static const struct acpi_device_id eeepc_device_ids[] = {
200 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
202 static struct acpi_driver eeepc_hotk_driver = {
203 .name = EEEPC_HOTK_NAME,
204 .class = EEEPC_HOTK_CLASS,
205 .ids = eeepc_device_ids,
206 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
208 .add = eeepc_hotk_add,
209 .remove = eeepc_hotk_remove,
210 .resume = eeepc_hotk_resume,
211 .notify = eeepc_hotk_notify,
215 /* PCI hotplug ops */
216 static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value);
218 static struct hotplug_slot_ops eeepc_hotplug_slot_ops = {
219 .owner = THIS_MODULE,
220 .get_adapter_status = eeepc_get_adapter_status,
221 .get_power_status = eeepc_get_adapter_status,
224 /* The backlight device /sys/class/backlight */
225 static struct backlight_device *eeepc_backlight_device;
227 /* The hwmon device */
228 static struct device *eeepc_hwmon_device;
231 * The backlight class declaration
233 static int read_brightness(struct backlight_device *bd);
234 static int update_bl_status(struct backlight_device *bd);
235 static struct backlight_ops eeepcbl_ops = {
236 .get_brightness = read_brightness,
237 .update_status = update_bl_status,
240 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
241 MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
242 MODULE_LICENSE("GPL");
247 static int write_acpi_int(acpi_handle handle, const char *method, int val,
248 struct acpi_buffer *output)
250 struct acpi_object_list params;
251 union acpi_object in_obj;
255 params.pointer = &in_obj;
256 in_obj.type = ACPI_TYPE_INTEGER;
257 in_obj.integer.value = val;
259 status = acpi_evaluate_object(handle, (char *)method, ¶ms, output);
260 return (status == AE_OK ? 0 : -1);
263 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
266 unsigned long long result;
268 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
269 if (ACPI_FAILURE(status)) {
278 static int set_acpi(int cm, int value)
280 if (ehotk->cm_supported & (0x1 << cm)) {
281 const char *method = cm_setv[cm];
284 if (write_acpi_int(ehotk->handle, method, value, NULL))
285 pr_warning("Error writing %s\n", method);
290 static int get_acpi(int cm)
293 if ((ehotk->cm_supported & (0x1 << cm))) {
294 const char *method = cm_getv[cm];
297 if (read_acpi_int(ehotk->handle, method, &value))
298 pr_warning("Error reading %s\n", method);
306 static int read_brightness(struct backlight_device *bd)
308 return get_acpi(CM_ASL_PANELBRIGHT);
311 static int set_brightness(struct backlight_device *bd, int value)
313 value = max(0, min(15, value));
314 return set_acpi(CM_ASL_PANELBRIGHT, value);
317 static int update_bl_status(struct backlight_device *bd)
319 return set_brightness(bd, bd->props.brightness);
326 static bool eeepc_wlan_rfkill_blocked(void)
328 if (get_acpi(CM_ASL_WLAN) == 1)
333 static int eeepc_rfkill_set(void *data, bool blocked)
335 unsigned long asl = (unsigned long)data;
336 return set_acpi(asl, !blocked);
339 static const struct rfkill_ops eeepc_rfkill_ops = {
340 .set_block = eeepc_rfkill_set,
343 static void __init eeepc_enable_camera(void)
346 * If the following call to set_acpi() fails, it's because there's no
347 * camera so we can ignore the error.
349 set_acpi(CM_ASL_CAMERA, 1);
355 static int parse_arg(const char *buf, unsigned long count, int *val)
359 if (sscanf(buf, "%i", val) != 1)
364 static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
368 rv = parse_arg(buf, count, &value);
370 value = set_acpi(cm, value);
376 static ssize_t show_sys_acpi(int cm, char *buf)
378 int value = get_acpi(cm);
382 return sprintf(buf, "%d\n", value);
385 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
386 static ssize_t show_##_name(struct device *dev, \
387 struct device_attribute *attr, \
390 return show_sys_acpi(_cm, buf); \
392 static ssize_t store_##_name(struct device *dev, \
393 struct device_attribute *attr, \
394 const char *buf, size_t count) \
396 return store_sys_acpi(_cm, buf, count); \
398 static struct device_attribute dev_attr_##_name = { \
400 .name = __stringify(_name), \
402 .show = show_##_name, \
403 .store = store_##_name, \
406 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
407 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
408 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
415 static int get_cpufv(struct eeepc_cpufv *c)
417 c->cur = get_acpi(CM_ASL_CPUFV);
418 c->num = (c->cur >> 8) & 0xff;
420 if (c->cur < 0 || c->num <= 0 || c->num > 12)
425 static ssize_t show_available_cpufv(struct device *dev,
426 struct device_attribute *attr,
429 struct eeepc_cpufv c;
435 for (i = 0; i < c.num; i++)
436 len += sprintf(buf + len, "%d ", i);
437 len += sprintf(buf + len, "\n");
441 static ssize_t show_cpufv(struct device *dev,
442 struct device_attribute *attr,
445 struct eeepc_cpufv c;
449 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
452 static ssize_t store_cpufv(struct device *dev,
453 struct device_attribute *attr,
454 const char *buf, size_t count)
456 struct eeepc_cpufv c;
461 rv = parse_arg(buf, count, &value);
464 if (!rv || value < 0 || value >= c.num)
466 set_acpi(CM_ASL_CPUFV, value);
470 static struct device_attribute dev_attr_cpufv = {
478 static struct device_attribute dev_attr_available_cpufv = {
480 .name = "available_cpufv",
482 .show = show_available_cpufv
485 static struct attribute *platform_attributes[] = {
486 &dev_attr_camera.attr,
487 &dev_attr_cardr.attr,
489 &dev_attr_cpufv.attr,
490 &dev_attr_available_cpufv.attr,
494 static struct attribute_group platform_attribute_group = {
495 .attrs = platform_attributes
501 static struct key_entry *eepc_get_entry_by_scancode(int code)
503 struct key_entry *key;
505 for (key = eeepc_keymap; key->type != KE_END; key++)
506 if (code == key->code)
512 static struct key_entry *eepc_get_entry_by_keycode(int code)
514 struct key_entry *key;
516 for (key = eeepc_keymap; key->type != KE_END; key++)
517 if (code == key->keycode && key->type == KE_KEY)
523 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
525 struct key_entry *key = eepc_get_entry_by_scancode(scancode);
527 if (key && key->type == KE_KEY) {
528 *keycode = key->keycode;
535 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
537 struct key_entry *key;
540 if (keycode < 0 || keycode > KEY_MAX)
543 key = eepc_get_entry_by_scancode(scancode);
544 if (key && key->type == KE_KEY) {
545 old_keycode = key->keycode;
546 key->keycode = keycode;
547 set_bit(keycode, dev->keybit);
548 if (!eepc_get_entry_by_keycode(old_keycode))
549 clear_bit(old_keycode, dev->keybit);
556 static int eeepc_hotk_check(void)
558 const struct key_entry *key;
559 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
562 result = acpi_bus_get_status(ehotk->device);
565 if (ehotk->device->status.present) {
566 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
568 pr_err("Hotkey initialization failed\n");
571 pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
573 /* get control methods supported */
574 if (read_acpi_int(ehotk->handle, "CMSG"
575 , &ehotk->cm_supported)) {
576 pr_err("Get control methods supported failed\n");
579 pr_info("Get control methods supported: 0x%x\n",
580 ehotk->cm_supported);
582 ehotk->inputdev = input_allocate_device();
583 if (!ehotk->inputdev) {
584 pr_info("Unable to allocate input device\n");
587 ehotk->inputdev->name = "Asus EeePC extra buttons";
588 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
589 ehotk->inputdev->id.bustype = BUS_HOST;
590 ehotk->inputdev->getkeycode = eeepc_getkeycode;
591 ehotk->inputdev->setkeycode = eeepc_setkeycode;
593 for (key = eeepc_keymap; key->type != KE_END; key++) {
596 set_bit(EV_KEY, ehotk->inputdev->evbit);
597 set_bit(key->keycode, ehotk->inputdev->keybit);
601 result = input_register_device(ehotk->inputdev);
603 pr_info("Unable to register input device\n");
604 input_free_device(ehotk->inputdev);
608 pr_err("Hotkey device not present, aborting\n");
614 static int notify_brn(void)
616 /* returns the *previous* brightness, or -1 */
617 struct backlight_device *bd = eeepc_backlight_device;
619 int old = bd->props.brightness;
620 bd->props.brightness = read_brightness(bd);
626 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
629 int val = get_acpi(CM_ASL_WLAN);
631 if (val == 1 || val == 0)
639 static void eeepc_rfkill_hotplug(void)
642 struct pci_bus *bus = pci_find_bus(0, 1);
646 pr_warning("Unable to find PCI bus 1?\n");
650 blocked = eeepc_wlan_rfkill_blocked();
652 dev = pci_get_slot(bus, 0);
654 /* Device already present */
658 dev = pci_scan_single_device(bus, 0);
660 pci_bus_assign_resources(bus);
661 if (pci_bus_add_device(dev))
662 pr_err("Unable to hotplug wifi\n");
665 dev = pci_get_slot(bus, 0);
667 pci_remove_bus_device(dev);
672 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
675 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
677 if (event != ACPI_NOTIFY_BUS_CHECK)
680 eeepc_rfkill_hotplug();
683 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
685 static struct key_entry *key;
691 if (event > ACPI_MAX_SYS_NOTIFY)
693 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
695 count = ehotk->event_count[event % 128]++;
696 acpi_bus_generate_proc_event(ehotk->device, event, count);
697 acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
698 dev_name(&ehotk->device->dev), event,
700 if (ehotk->inputdev) {
701 if (brn != -ENODEV) {
702 /* brightness-change events need special
703 * handling for conversion to key events
708 brn += NOTIFY_BRN_MIN;
710 event = NOTIFY_BRN_MIN; /* brightness down */
711 else if (event > brn)
712 event = NOTIFY_BRN_MIN + 2; /* ... up */
714 event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
716 key = eepc_get_entry_by_scancode(event);
720 input_report_key(ehotk->inputdev, key->keycode,
722 input_sync(ehotk->inputdev);
723 input_report_key(ehotk->inputdev, key->keycode,
725 input_sync(ehotk->inputdev);
732 static int eeepc_register_rfkill_notifier(char *node)
734 acpi_status status = AE_OK;
737 status = acpi_get_handle(NULL, node, &handle);
739 if (ACPI_SUCCESS(status)) {
740 status = acpi_install_notify_handler(handle,
744 if (ACPI_FAILURE(status))
745 pr_warning("Failed to register notify on %s\n", node);
752 static void eeepc_unregister_rfkill_notifier(char *node)
754 acpi_status status = AE_OK;
757 status = acpi_get_handle(NULL, node, &handle);
759 if (ACPI_SUCCESS(status)) {
760 status = acpi_remove_notify_handler(handle,
762 eeepc_rfkill_notify);
763 if (ACPI_FAILURE(status))
764 pr_err("Error removing rfkill notify handler %s\n",
769 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
771 kfree(hotplug_slot->info);
775 static int eeepc_setup_pci_hotplug(void)
778 struct pci_bus *bus = pci_find_bus(0, 1);
781 pr_err("Unable to find wifi PCI bus\n");
785 ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
786 if (!ehotk->hotplug_slot)
789 ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
791 if (!ehotk->hotplug_slot->info)
794 ehotk->hotplug_slot->private = ehotk;
795 ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
796 ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
797 eeepc_get_adapter_status(ehotk->hotplug_slot,
798 &ehotk->hotplug_slot->info->adapter_status);
800 ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
802 pr_err("Unable to register hotplug slot - %d\n", ret);
809 kfree(ehotk->hotplug_slot->info);
811 kfree(ehotk->hotplug_slot);
812 ehotk->hotplug_slot = NULL;
817 static int eeepc_hotk_add(struct acpi_device *device)
823 pr_notice(EEEPC_HOTK_NAME "\n");
824 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
827 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
828 ehotk->handle = device->handle;
829 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
830 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
831 device->driver_data = ehotk;
832 ehotk->device = device;
833 result = eeepc_hotk_check();
846 static int eeepc_hotk_remove(struct acpi_device *device, int type)
848 if (!device || !acpi_driver_data(device))
855 static int eeepc_hotk_resume(struct acpi_device *device)
857 if (ehotk->wlan_rfkill) {
860 /* Workaround - it seems that _PTS disables the wireless
861 without notification or changing the value read by WLAN.
862 Normally this is fine because the correct value is restored
863 from the non-volatile storage on resume, but we need to do
864 it ourself if case suspend is aborted, or we lose wireless.
866 wlan = get_acpi(CM_ASL_WLAN);
867 set_acpi(CM_ASL_WLAN, wlan);
869 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
871 eeepc_rfkill_hotplug();
874 if (ehotk->bluetooth_rfkill)
875 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
876 get_acpi(CM_ASL_BLUETOOTH) != 1);
884 static int eeepc_get_fan_pwm(void)
888 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
889 value = value * 255 / 100;
893 static void eeepc_set_fan_pwm(int value)
895 value = SENSORS_LIMIT(value, 0, 255);
896 value = value * 100 / 255;
897 ec_write(EEEPC_EC_SC02, value);
900 static int eeepc_get_fan_rpm(void)
905 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
906 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
907 return (high << 8 | low);
910 static int eeepc_get_fan_ctrl(void)
914 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
915 return ((value & 0x02 ? 1 : 0));
918 static void eeepc_set_fan_ctrl(int manual)
922 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
927 ec_write(EEEPC_EC_SFB3, value);
930 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
934 rv = parse_arg(buf, count, &value);
940 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
942 return sprintf(buf, "%d\n", get());
945 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
946 static ssize_t show_##_name(struct device *dev, \
947 struct device_attribute *attr, \
950 return show_sys_hwmon(_set, buf); \
952 static ssize_t store_##_name(struct device *dev, \
953 struct device_attribute *attr, \
954 const char *buf, size_t count) \
956 return store_sys_hwmon(_get, buf, count); \
958 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
960 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
961 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
962 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
963 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
964 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
967 show_name(struct device *dev, struct device_attribute *attr, char *buf)
969 return sprintf(buf, "eeepc\n");
971 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
973 static struct attribute *hwmon_attributes[] = {
974 &sensor_dev_attr_pwm1.dev_attr.attr,
975 &sensor_dev_attr_fan1_input.dev_attr.attr,
976 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
977 &sensor_dev_attr_name.dev_attr.attr,
981 static struct attribute_group hwmon_attribute_group = {
982 .attrs = hwmon_attributes
988 static void eeepc_backlight_exit(void)
990 if (eeepc_backlight_device)
991 backlight_device_unregister(eeepc_backlight_device);
992 eeepc_backlight_device = NULL;
995 static void eeepc_rfkill_exit(void)
997 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
998 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
999 if (ehotk->wlan_rfkill)
1000 rfkill_unregister(ehotk->wlan_rfkill);
1001 if (ehotk->bluetooth_rfkill)
1002 rfkill_unregister(ehotk->bluetooth_rfkill);
1003 if (ehotk->hotplug_slot)
1004 pci_hp_deregister(ehotk->hotplug_slot);
1007 static void eeepc_input_exit(void)
1009 if (ehotk->inputdev)
1010 input_unregister_device(ehotk->inputdev);
1013 static void eeepc_hwmon_exit(void)
1015 struct device *hwmon;
1017 hwmon = eeepc_hwmon_device;
1020 sysfs_remove_group(&hwmon->kobj,
1021 &hwmon_attribute_group);
1022 hwmon_device_unregister(hwmon);
1023 eeepc_hwmon_device = NULL;
1026 static void __exit eeepc_laptop_exit(void)
1028 eeepc_backlight_exit();
1029 eeepc_rfkill_exit();
1032 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1033 sysfs_remove_group(&platform_device->dev.kobj,
1034 &platform_attribute_group);
1035 platform_device_unregister(platform_device);
1036 platform_driver_unregister(&platform_driver);
1039 static int eeepc_new_rfkill(struct rfkill **rfkill,
1040 const char *name, struct device *dev,
1041 enum rfkill_type type, int cm)
1045 result = get_acpi(cm);
1049 *rfkill = rfkill_alloc(name, dev, type,
1050 &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1055 rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1056 result = rfkill_register(*rfkill);
1058 rfkill_destroy(*rfkill);
1066 static int eeepc_rfkill_init(struct device *dev)
1070 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1071 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1073 result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1075 RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1077 if (result && result != -ENODEV)
1080 result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1081 "eeepc-bluetooth", dev,
1082 RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1084 if (result && result != -ENODEV)
1087 result = eeepc_setup_pci_hotplug();
1089 * If we get -EBUSY then something else is handling the PCI hotplug -
1090 * don't fail in this case
1092 if (result == -EBUSY)
1096 if (result && result != -ENODEV)
1097 eeepc_rfkill_exit();
1101 static int eeepc_backlight_init(struct device *dev)
1103 struct backlight_device *bd;
1105 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1106 NULL, &eeepcbl_ops);
1108 pr_err("Could not register eeepc backlight device\n");
1109 eeepc_backlight_device = NULL;
1112 eeepc_backlight_device = bd;
1113 bd->props.max_brightness = 15;
1114 bd->props.brightness = read_brightness(NULL);
1115 bd->props.power = FB_BLANK_UNBLANK;
1116 backlight_update_status(bd);
1120 static int eeepc_hwmon_init(struct device *dev)
1122 struct device *hwmon;
1125 hwmon = hwmon_device_register(dev);
1126 if (IS_ERR(hwmon)) {
1127 pr_err("Could not register eeepc hwmon device\n");
1128 eeepc_hwmon_device = NULL;
1129 return PTR_ERR(hwmon);
1131 eeepc_hwmon_device = hwmon;
1132 result = sysfs_create_group(&hwmon->kobj,
1133 &hwmon_attribute_group);
1139 static int __init eeepc_laptop_init(void)
1146 result = acpi_bus_register_driver(&eeepc_hotk_driver);
1150 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1154 eeepc_enable_camera();
1156 /* Register platform stuff */
1157 result = platform_driver_register(&platform_driver);
1159 goto fail_platform_driver;
1160 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1161 if (!platform_device) {
1163 goto fail_platform_device1;
1165 result = platform_device_add(platform_device);
1167 goto fail_platform_device2;
1168 result = sysfs_create_group(&platform_device->dev.kobj,
1169 &platform_attribute_group);
1173 dev = &platform_device->dev;
1175 if (!acpi_video_backlight_support()) {
1176 result = eeepc_backlight_init(dev);
1178 goto fail_backlight;
1180 pr_info("Backlight controlled by ACPI video "
1183 result = eeepc_hwmon_init(dev);
1187 result = eeepc_rfkill_init(dev);
1195 eeepc_backlight_exit();
1197 sysfs_remove_group(&platform_device->dev.kobj,
1198 &platform_attribute_group);
1200 platform_device_del(platform_device);
1201 fail_platform_device2:
1202 platform_device_put(platform_device);
1203 fail_platform_device1:
1204 platform_driver_unregister(&platform_driver);
1205 fail_platform_driver:
1210 module_init(eeepc_laptop_init);
1211 module_exit(eeepc_laptop_exit);