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);
374 static ssize_t show_sys_acpi(int cm, char *buf)
376 return sprintf(buf, "%d\n", get_acpi(cm));
379 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
380 static ssize_t show_##_name(struct device *dev, \
381 struct device_attribute *attr, \
384 return show_sys_acpi(_cm, buf); \
386 static ssize_t store_##_name(struct device *dev, \
387 struct device_attribute *attr, \
388 const char *buf, size_t count) \
390 return store_sys_acpi(_cm, buf, count); \
392 static struct device_attribute dev_attr_##_name = { \
394 .name = __stringify(_name), \
396 .show = show_##_name, \
397 .store = store_##_name, \
400 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
401 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
402 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
409 static int get_cpufv(struct eeepc_cpufv *c)
411 c->cur = get_acpi(CM_ASL_CPUFV);
412 c->num = (c->cur >> 8) & 0xff;
414 if (c->cur < 0 || c->num <= 0 || c->num > 12)
419 static ssize_t show_available_cpufv(struct device *dev,
420 struct device_attribute *attr,
423 struct eeepc_cpufv c;
429 for (i = 0; i < c.num; i++)
430 len += sprintf(buf + len, "%d ", i);
431 len += sprintf(buf + len, "\n");
435 static ssize_t show_cpufv(struct device *dev,
436 struct device_attribute *attr,
439 struct eeepc_cpufv c;
443 return sprintf(buf, "%#x\n", (c.num << 8) | c.cur);
446 static ssize_t store_cpufv(struct device *dev,
447 struct device_attribute *attr,
448 const char *buf, size_t count)
450 struct eeepc_cpufv c;
455 rv = parse_arg(buf, count, &value);
458 if (!rv || value < 0 || value >= c.num)
460 set_acpi(CM_ASL_CPUFV, value);
464 static struct device_attribute dev_attr_cpufv = {
472 static struct device_attribute dev_attr_available_cpufv = {
474 .name = "available_cpufv",
476 .show = show_available_cpufv
479 static struct attribute *platform_attributes[] = {
480 &dev_attr_camera.attr,
481 &dev_attr_cardr.attr,
483 &dev_attr_cpufv.attr,
484 &dev_attr_available_cpufv.attr,
488 static struct attribute_group platform_attribute_group = {
489 .attrs = platform_attributes
495 static struct key_entry *eepc_get_entry_by_scancode(int code)
497 struct key_entry *key;
499 for (key = eeepc_keymap; key->type != KE_END; key++)
500 if (code == key->code)
506 static struct key_entry *eepc_get_entry_by_keycode(int code)
508 struct key_entry *key;
510 for (key = eeepc_keymap; key->type != KE_END; key++)
511 if (code == key->keycode && key->type == KE_KEY)
517 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
519 struct key_entry *key = eepc_get_entry_by_scancode(scancode);
521 if (key && key->type == KE_KEY) {
522 *keycode = key->keycode;
529 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
531 struct key_entry *key;
534 if (keycode < 0 || keycode > KEY_MAX)
537 key = eepc_get_entry_by_scancode(scancode);
538 if (key && key->type == KE_KEY) {
539 old_keycode = key->keycode;
540 key->keycode = keycode;
541 set_bit(keycode, dev->keybit);
542 if (!eepc_get_entry_by_keycode(old_keycode))
543 clear_bit(old_keycode, dev->keybit);
550 static int eeepc_hotk_check(void)
552 const struct key_entry *key;
553 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
556 result = acpi_bus_get_status(ehotk->device);
559 if (ehotk->device->status.present) {
560 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
562 pr_err("Hotkey initialization failed\n");
565 pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag);
567 /* get control methods supported */
568 if (read_acpi_int(ehotk->handle, "CMSG"
569 , &ehotk->cm_supported)) {
570 pr_err("Get control methods supported failed\n");
573 pr_info("Get control methods supported: 0x%x\n",
574 ehotk->cm_supported);
576 ehotk->inputdev = input_allocate_device();
577 if (!ehotk->inputdev) {
578 pr_info("Unable to allocate input device\n");
581 ehotk->inputdev->name = "Asus EeePC extra buttons";
582 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
583 ehotk->inputdev->id.bustype = BUS_HOST;
584 ehotk->inputdev->getkeycode = eeepc_getkeycode;
585 ehotk->inputdev->setkeycode = eeepc_setkeycode;
587 for (key = eeepc_keymap; key->type != KE_END; key++) {
590 set_bit(EV_KEY, ehotk->inputdev->evbit);
591 set_bit(key->keycode, ehotk->inputdev->keybit);
595 result = input_register_device(ehotk->inputdev);
597 pr_info("Unable to register input device\n");
598 input_free_device(ehotk->inputdev);
602 pr_err("Hotkey device not present, aborting\n");
608 static int notify_brn(void)
610 /* returns the *previous* brightness, or -1 */
611 struct backlight_device *bd = eeepc_backlight_device;
613 int old = bd->props.brightness;
614 bd->props.brightness = read_brightness(bd);
620 static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
623 int val = get_acpi(CM_ASL_WLAN);
625 if (val == 1 || val == 0)
633 static void eeepc_rfkill_hotplug(void)
636 struct pci_bus *bus = pci_find_bus(0, 1);
640 pr_warning("Unable to find PCI bus 1?\n");
644 blocked = eeepc_wlan_rfkill_blocked();
646 dev = pci_get_slot(bus, 0);
648 /* Device already present */
652 dev = pci_scan_single_device(bus, 0);
654 pci_bus_assign_resources(bus);
655 if (pci_bus_add_device(dev))
656 pr_err("Unable to hotplug wifi\n");
659 dev = pci_get_slot(bus, 0);
661 pci_remove_bus_device(dev);
666 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
669 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
671 if (event != ACPI_NOTIFY_BUS_CHECK)
674 eeepc_rfkill_hotplug();
677 static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
679 static struct key_entry *key;
685 if (event > ACPI_MAX_SYS_NOTIFY)
687 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
689 count = ehotk->event_count[event % 128]++;
690 acpi_bus_generate_proc_event(ehotk->device, event, count);
691 acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
692 dev_name(&ehotk->device->dev), event,
694 if (ehotk->inputdev) {
695 if (brn != -ENODEV) {
696 /* brightness-change events need special
697 * handling for conversion to key events
702 brn += NOTIFY_BRN_MIN;
704 event = NOTIFY_BRN_MIN; /* brightness down */
705 else if (event > brn)
706 event = NOTIFY_BRN_MIN + 2; /* ... up */
708 event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
710 key = eepc_get_entry_by_scancode(event);
714 input_report_key(ehotk->inputdev, key->keycode,
716 input_sync(ehotk->inputdev);
717 input_report_key(ehotk->inputdev, key->keycode,
719 input_sync(ehotk->inputdev);
726 static int eeepc_register_rfkill_notifier(char *node)
728 acpi_status status = AE_OK;
731 status = acpi_get_handle(NULL, node, &handle);
733 if (ACPI_SUCCESS(status)) {
734 status = acpi_install_notify_handler(handle,
738 if (ACPI_FAILURE(status))
739 pr_warning("Failed to register notify on %s\n", node);
746 static void eeepc_unregister_rfkill_notifier(char *node)
748 acpi_status status = AE_OK;
751 status = acpi_get_handle(NULL, node, &handle);
753 if (ACPI_SUCCESS(status)) {
754 status = acpi_remove_notify_handler(handle,
756 eeepc_rfkill_notify);
757 if (ACPI_FAILURE(status))
758 pr_err("Error removing rfkill notify handler %s\n",
763 static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
765 kfree(hotplug_slot->info);
769 static int eeepc_setup_pci_hotplug(void)
772 struct pci_bus *bus = pci_find_bus(0, 1);
775 pr_err("Unable to find wifi PCI bus\n");
779 ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
780 if (!ehotk->hotplug_slot)
783 ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
785 if (!ehotk->hotplug_slot->info)
788 ehotk->hotplug_slot->private = ehotk;
789 ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug;
790 ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops;
791 eeepc_get_adapter_status(ehotk->hotplug_slot,
792 &ehotk->hotplug_slot->info->adapter_status);
794 ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi");
796 pr_err("Unable to register hotplug slot - %d\n", ret);
803 kfree(ehotk->hotplug_slot->info);
805 kfree(ehotk->hotplug_slot);
806 ehotk->hotplug_slot = NULL;
811 static int eeepc_hotk_add(struct acpi_device *device)
817 pr_notice(EEEPC_HOTK_NAME "\n");
818 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
821 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
822 ehotk->handle = device->handle;
823 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
824 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
825 device->driver_data = ehotk;
826 ehotk->device = device;
827 result = eeepc_hotk_check();
840 static int eeepc_hotk_remove(struct acpi_device *device, int type)
842 if (!device || !acpi_driver_data(device))
849 static int eeepc_hotk_resume(struct acpi_device *device)
851 if (ehotk->wlan_rfkill) {
854 /* Workaround - it seems that _PTS disables the wireless
855 without notification or changing the value read by WLAN.
856 Normally this is fine because the correct value is restored
857 from the non-volatile storage on resume, but we need to do
858 it ourself if case suspend is aborted, or we lose wireless.
860 wlan = get_acpi(CM_ASL_WLAN);
861 set_acpi(CM_ASL_WLAN, wlan);
863 rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1);
865 eeepc_rfkill_hotplug();
868 if (ehotk->bluetooth_rfkill)
869 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
870 get_acpi(CM_ASL_BLUETOOTH) != 1);
878 static int eeepc_get_fan_pwm(void)
882 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
883 value = value * 255 / 100;
887 static void eeepc_set_fan_pwm(int value)
889 value = SENSORS_LIMIT(value, 0, 255);
890 value = value * 100 / 255;
891 ec_write(EEEPC_EC_SC02, value);
894 static int eeepc_get_fan_rpm(void)
899 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
900 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
901 return (high << 8 | low);
904 static int eeepc_get_fan_ctrl(void)
908 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
909 return ((value & 0x02 ? 1 : 0));
912 static void eeepc_set_fan_ctrl(int manual)
916 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
921 ec_write(EEEPC_EC_SFB3, value);
924 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
928 rv = parse_arg(buf, count, &value);
934 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
936 return sprintf(buf, "%d\n", get());
939 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
940 static ssize_t show_##_name(struct device *dev, \
941 struct device_attribute *attr, \
944 return show_sys_hwmon(_set, buf); \
946 static ssize_t store_##_name(struct device *dev, \
947 struct device_attribute *attr, \
948 const char *buf, size_t count) \
950 return store_sys_hwmon(_get, buf, count); \
952 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
954 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
955 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
956 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
957 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
958 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
961 show_name(struct device *dev, struct device_attribute *attr, char *buf)
963 return sprintf(buf, "eeepc\n");
965 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
967 static struct attribute *hwmon_attributes[] = {
968 &sensor_dev_attr_pwm1.dev_attr.attr,
969 &sensor_dev_attr_fan1_input.dev_attr.attr,
970 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
971 &sensor_dev_attr_name.dev_attr.attr,
975 static struct attribute_group hwmon_attribute_group = {
976 .attrs = hwmon_attributes
982 static void eeepc_backlight_exit(void)
984 if (eeepc_backlight_device)
985 backlight_device_unregister(eeepc_backlight_device);
986 eeepc_backlight_device = NULL;
989 static void eeepc_rfkill_exit(void)
991 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
992 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
993 if (ehotk->wlan_rfkill)
994 rfkill_unregister(ehotk->wlan_rfkill);
995 if (ehotk->bluetooth_rfkill)
996 rfkill_unregister(ehotk->bluetooth_rfkill);
997 if (ehotk->hotplug_slot)
998 pci_hp_deregister(ehotk->hotplug_slot);
1001 static void eeepc_input_exit(void)
1003 if (ehotk->inputdev)
1004 input_unregister_device(ehotk->inputdev);
1007 static void eeepc_hwmon_exit(void)
1009 struct device *hwmon;
1011 hwmon = eeepc_hwmon_device;
1014 sysfs_remove_group(&hwmon->kobj,
1015 &hwmon_attribute_group);
1016 hwmon_device_unregister(hwmon);
1017 eeepc_hwmon_device = NULL;
1020 static void __exit eeepc_laptop_exit(void)
1022 eeepc_backlight_exit();
1023 eeepc_rfkill_exit();
1026 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1027 sysfs_remove_group(&platform_device->dev.kobj,
1028 &platform_attribute_group);
1029 platform_device_unregister(platform_device);
1030 platform_driver_unregister(&platform_driver);
1033 static int eeepc_new_rfkill(struct rfkill **rfkill,
1034 const char *name, struct device *dev,
1035 enum rfkill_type type, int cm)
1039 if (get_acpi(cm) == -1)
1042 *rfkill = rfkill_alloc(name, dev, type,
1043 &eeepc_rfkill_ops, (void *)(unsigned long)cm);
1048 rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1);
1049 result = rfkill_register(*rfkill);
1051 rfkill_destroy(*rfkill);
1059 static int eeepc_rfkill_init(struct device *dev)
1063 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
1064 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
1066 result = eeepc_new_rfkill(&ehotk->wlan_rfkill,
1068 RFKILL_TYPE_WLAN, CM_ASL_WLAN);
1070 if (result && result != -ENODEV)
1073 result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill,
1074 "eeepc-bluetooth", dev,
1075 RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH);
1077 if (result && result != -ENODEV)
1080 result = eeepc_setup_pci_hotplug();
1082 * If we get -EBUSY then something else is handling the PCI hotplug -
1083 * don't fail in this case
1085 if (result == -EBUSY)
1089 if (result && result != -ENODEV)
1090 eeepc_rfkill_exit();
1094 static int eeepc_backlight_init(struct device *dev)
1096 struct backlight_device *bd;
1098 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
1099 NULL, &eeepcbl_ops);
1101 pr_err("Could not register eeepc backlight device\n");
1102 eeepc_backlight_device = NULL;
1105 eeepc_backlight_device = bd;
1106 bd->props.max_brightness = 15;
1107 bd->props.brightness = read_brightness(NULL);
1108 bd->props.power = FB_BLANK_UNBLANK;
1109 backlight_update_status(bd);
1113 static int eeepc_hwmon_init(struct device *dev)
1115 struct device *hwmon;
1118 hwmon = hwmon_device_register(dev);
1119 if (IS_ERR(hwmon)) {
1120 pr_err("Could not register eeepc hwmon device\n");
1121 eeepc_hwmon_device = NULL;
1122 return PTR_ERR(hwmon);
1124 eeepc_hwmon_device = hwmon;
1125 result = sysfs_create_group(&hwmon->kobj,
1126 &hwmon_attribute_group);
1132 static int __init eeepc_laptop_init(void)
1139 result = acpi_bus_register_driver(&eeepc_hotk_driver);
1143 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1147 eeepc_enable_camera();
1149 /* Register platform stuff */
1150 result = platform_driver_register(&platform_driver);
1152 goto fail_platform_driver;
1153 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1154 if (!platform_device) {
1156 goto fail_platform_device1;
1158 result = platform_device_add(platform_device);
1160 goto fail_platform_device2;
1161 result = sysfs_create_group(&platform_device->dev.kobj,
1162 &platform_attribute_group);
1166 dev = &platform_device->dev;
1168 if (!acpi_video_backlight_support()) {
1169 result = eeepc_backlight_init(dev);
1171 goto fail_backlight;
1173 pr_info("Backlight controlled by ACPI video "
1176 result = eeepc_hwmon_init(dev);
1180 result = eeepc_rfkill_init(dev);
1188 eeepc_backlight_exit();
1190 sysfs_remove_group(&platform_device->dev.kobj,
1191 &platform_attribute_group);
1193 platform_device_del(platform_device);
1194 fail_platform_device2:
1195 platform_device_put(platform_device);
1196 fail_platform_device1:
1197 platform_driver_unregister(&platform_driver);
1198 fail_platform_driver:
1203 module_init(eeepc_laptop_init);
1204 module_exit(eeepc_laptop_exit);