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 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/types.h>
23 #include <linux/platform_device.h>
24 #include <linux/backlight.h>
26 #include <linux/hwmon.h>
27 #include <linux/hwmon-sysfs.h>
28 #include <acpi/acpi_drivers.h>
29 #include <acpi/acpi_bus.h>
30 #include <linux/uaccess.h>
31 #include <linux/input.h>
32 #include <linux/rfkill.h>
33 #include <linux/pci.h>
35 #define EEEPC_LAPTOP_VERSION "0.1"
37 #define EEEPC_HOTK_NAME "Eee PC Hotkey Driver"
38 #define EEEPC_HOTK_FILE "eeepc"
39 #define EEEPC_HOTK_CLASS "hotkey"
40 #define EEEPC_HOTK_DEVICE_NAME "Hotkey"
41 #define EEEPC_HOTK_HID "ASUS010"
43 #define EEEPC_LOG EEEPC_HOTK_FILE ": "
44 #define EEEPC_ERR KERN_ERR EEEPC_LOG
45 #define EEEPC_WARNING KERN_WARNING EEEPC_LOG
46 #define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG
47 #define EEEPC_INFO KERN_INFO EEEPC_LOG
50 * Definitions for Asus EeePC
52 #define NOTIFY_WLAN_ON 0x10
53 #define NOTIFY_BRN_MIN 0x20
54 #define NOTIFY_BRN_MAX 0x2f
57 DISABLE_ASL_WLAN = 0x0001,
58 DISABLE_ASL_BLUETOOTH = 0x0002,
59 DISABLE_ASL_IRDA = 0x0004,
60 DISABLE_ASL_CAMERA = 0x0008,
61 DISABLE_ASL_TV = 0x0010,
62 DISABLE_ASL_GPS = 0x0020,
63 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
64 DISABLE_ASL_MODEM = 0x0080,
65 DISABLE_ASL_CARDREADER = 0x0100,
66 DISABLE_ASL_3G = 0x0200,
67 DISABLE_ASL_WIMAX = 0x0400,
68 DISABLE_ASL_HWCF = 0x0800
85 CM_ASL_CPUTEMPERATURE,
98 CM_ASL_PANELPOWER, /*P901*/
102 static const char *cm_getv[] = {
103 "WLDG", "BTHG", NULL, NULL,
104 "CAMG", NULL, NULL, NULL,
105 NULL, "PBLG", NULL, NULL,
106 "CFVG", NULL, NULL, NULL,
107 "USBG", NULL, NULL, "MODG",
108 "CRDG", "M3GG", "WIMG", "HWCF",
109 "LIDG", "TYPE", "PBPG", "TPDG"
112 static const char *cm_setv[] = {
113 "WLDS", "BTHS", NULL, NULL,
114 "CAMS", NULL, NULL, NULL,
115 "SDSP", "PBLS", "HDPS", NULL,
116 "CFVS", NULL, NULL, NULL,
117 "USBG", NULL, NULL, "MODS",
118 "CRDS", "M3GS", "WIMS", NULL,
119 NULL, NULL, "PBPS", "TPDS"
122 #define EEEPC_EC "\\_SB.PCI0.SBRG.EC0."
124 #define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */
125 #define EEEPC_EC_SC02 0x63
126 #define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */
127 #define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */
128 #define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */
129 #define EEEPC_EC_SFB3 0xD3
132 * This is the main structure, we can use it to store useful information
133 * about the hotk device
136 struct acpi_device *device; /* the device we are in */
137 acpi_handle handle; /* the handle of the hotk device */
138 u32 cm_supported; /* the control methods supported
140 uint init_flag; /* Init flags */
141 u16 event_count[128]; /* count for each event */
142 struct input_dev *inputdev;
144 struct rfkill *eeepc_wlan_rfkill;
145 struct rfkill *eeepc_bluetooth_rfkill;
148 /* The actual device the driver binds to */
149 static struct eeepc_hotk *ehotk;
151 /* Platform device/driver */
152 static struct platform_driver platform_driver = {
154 .name = EEEPC_HOTK_FILE,
155 .owner = THIS_MODULE,
159 static struct platform_device *platform_device;
167 enum { KE_KEY, KE_END };
169 static struct key_entry eeepc_keymap[] = {
170 /* Sleep already handled via generic ACPI code */
171 {KE_KEY, 0x10, KEY_WLAN },
172 {KE_KEY, 0x11, KEY_WLAN },
173 {KE_KEY, 0x12, KEY_PROG1 },
174 {KE_KEY, 0x13, KEY_MUTE },
175 {KE_KEY, 0x14, KEY_VOLUMEDOWN },
176 {KE_KEY, 0x15, KEY_VOLUMEUP },
177 {KE_KEY, 0x1a, KEY_COFFEE },
178 {KE_KEY, 0x1b, KEY_ZOOM },
179 {KE_KEY, 0x1c, KEY_PROG2 },
180 {KE_KEY, 0x1d, KEY_PROG3 },
181 {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
182 {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP },
183 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
184 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
185 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
190 * The hotkey driver declaration
192 static int eeepc_hotk_add(struct acpi_device *device);
193 static int eeepc_hotk_remove(struct acpi_device *device, int type);
194 static int eeepc_hotk_resume(struct acpi_device *device);
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,
207 .add = eeepc_hotk_add,
208 .remove = eeepc_hotk_remove,
209 .resume = eeepc_hotk_resume,
213 /* The backlight device /sys/class/backlight */
214 static struct backlight_device *eeepc_backlight_device;
216 /* The hwmon device */
217 static struct device *eeepc_hwmon_device;
220 * The backlight class declaration
222 static int read_brightness(struct backlight_device *bd);
223 static int update_bl_status(struct backlight_device *bd);
224 static struct backlight_ops eeepcbl_ops = {
225 .get_brightness = read_brightness,
226 .update_status = update_bl_status,
229 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
230 MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
231 MODULE_LICENSE("GPL");
236 static int write_acpi_int(acpi_handle handle, const char *method, int val,
237 struct acpi_buffer *output)
239 struct acpi_object_list params;
240 union acpi_object in_obj;
244 params.pointer = &in_obj;
245 in_obj.type = ACPI_TYPE_INTEGER;
246 in_obj.integer.value = val;
248 status = acpi_evaluate_object(handle, (char *)method, ¶ms, output);
249 return (status == AE_OK ? 0 : -1);
252 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
255 unsigned long long result;
257 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
258 if (ACPI_FAILURE(status)) {
267 static int set_acpi(int cm, int value)
269 if (ehotk->cm_supported & (0x1 << cm)) {
270 const char *method = cm_setv[cm];
273 if (write_acpi_int(ehotk->handle, method, value, NULL))
274 printk(EEEPC_WARNING "Error writing %s\n", method);
279 static int get_acpi(int cm)
282 if ((ehotk->cm_supported & (0x1 << cm))) {
283 const char *method = cm_getv[cm];
286 if (read_acpi_int(ehotk->handle, method, &value))
287 printk(EEEPC_WARNING "Error reading %s\n", method);
295 static int read_brightness(struct backlight_device *bd)
297 return get_acpi(CM_ASL_PANELBRIGHT);
300 static int set_brightness(struct backlight_device *bd, int value)
302 value = max(0, min(15, value));
303 return set_acpi(CM_ASL_PANELBRIGHT, value);
306 static int update_bl_status(struct backlight_device *bd)
308 return set_brightness(bd, bd->props.brightness);
315 static bool eeepc_wlan_rfkill_blocked(void)
317 if (get_acpi(CM_ASL_WLAN) == 1)
322 static int eeepc_rfkill_set(void *data, enum rfkill_state state)
324 unsigned long asl = (unsigned long)data;
326 if (state == RFKILL_STATE_UNBLOCKED)
327 return set_acpi(asl, 1);
328 else if (state == RFKILL_STATE_SOFT_BLOCKED)
329 return set_acpi(asl, 0);
333 static int eeepc_rfkill_state(void *data, enum rfkill_state *state)
335 unsigned long asl = (unsigned long)data;
337 if (get_acpi(asl) == 1)
338 *state = RFKILL_STATE_UNBLOCKED;
340 *state = RFKILL_STATE_SOFT_BLOCKED;
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);
376 static ssize_t show_sys_acpi(int cm, char *buf)
378 return sprintf(buf, "%d\n", get_acpi(cm));
381 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
382 static ssize_t show_##_name(struct device *dev, \
383 struct device_attribute *attr, \
386 return show_sys_acpi(_cm, buf); \
388 static ssize_t store_##_name(struct device *dev, \
389 struct device_attribute *attr, \
390 const char *buf, size_t count) \
392 return store_sys_acpi(_cm, buf, count); \
394 static struct device_attribute dev_attr_##_name = { \
396 .name = __stringify(_name), \
398 .show = show_##_name, \
399 .store = store_##_name, \
402 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
403 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
404 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
405 EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV);
407 static struct attribute *platform_attributes[] = {
408 &dev_attr_camera.attr,
409 &dev_attr_cardr.attr,
411 &dev_attr_cpufv.attr,
415 static struct attribute_group platform_attribute_group = {
416 .attrs = platform_attributes
422 static struct key_entry *eepc_get_entry_by_scancode(int code)
424 struct key_entry *key;
426 for (key = eeepc_keymap; key->type != KE_END; key++)
427 if (code == key->code)
433 static struct key_entry *eepc_get_entry_by_keycode(int code)
435 struct key_entry *key;
437 for (key = eeepc_keymap; key->type != KE_END; key++)
438 if (code == key->keycode && key->type == KE_KEY)
444 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
446 struct key_entry *key = eepc_get_entry_by_scancode(scancode);
448 if (key && key->type == KE_KEY) {
449 *keycode = key->keycode;
456 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
458 struct key_entry *key;
461 if (keycode < 0 || keycode > KEY_MAX)
464 key = eepc_get_entry_by_scancode(scancode);
465 if (key && key->type == KE_KEY) {
466 old_keycode = key->keycode;
467 key->keycode = keycode;
468 set_bit(keycode, dev->keybit);
469 if (!eepc_get_entry_by_keycode(old_keycode))
470 clear_bit(old_keycode, dev->keybit);
477 static int eeepc_hotk_check(void)
479 const struct key_entry *key;
480 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
483 result = acpi_bus_get_status(ehotk->device);
486 if (ehotk->device->status.present) {
487 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
489 printk(EEEPC_ERR "Hotkey initialization failed\n");
492 printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n",
495 /* get control methods supported */
496 if (read_acpi_int(ehotk->handle, "CMSG"
497 , &ehotk->cm_supported)) {
499 "Get control methods supported failed\n");
503 "Get control methods supported: 0x%x\n",
504 ehotk->cm_supported);
506 ehotk->inputdev = input_allocate_device();
507 if (!ehotk->inputdev) {
508 printk(EEEPC_INFO "Unable to allocate input device\n");
511 ehotk->inputdev->name = "Asus EeePC extra buttons";
512 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
513 ehotk->inputdev->id.bustype = BUS_HOST;
514 ehotk->inputdev->getkeycode = eeepc_getkeycode;
515 ehotk->inputdev->setkeycode = eeepc_setkeycode;
517 for (key = eeepc_keymap; key->type != KE_END; key++) {
520 set_bit(EV_KEY, ehotk->inputdev->evbit);
521 set_bit(key->keycode, ehotk->inputdev->keybit);
525 result = input_register_device(ehotk->inputdev);
527 printk(EEEPC_INFO "Unable to register input device\n");
528 input_free_device(ehotk->inputdev);
532 printk(EEEPC_ERR "Hotkey device not present, aborting\n");
538 static int notify_brn(void)
540 /* returns the *previous* brightness, or -1 */
541 struct backlight_device *bd = eeepc_backlight_device;
543 int old = bd->props.brightness;
544 bd->props.brightness = read_brightness(bd);
550 static void eeepc_rfkill_hotplug(void)
553 struct pci_bus *bus = pci_find_bus(0, 1);
557 printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
561 blocked = eeepc_wlan_rfkill_blocked();
563 dev = pci_get_slot(bus, 0);
565 /* Device already present */
569 dev = pci_scan_single_device(bus, 0);
571 pci_bus_assign_resources(bus);
572 if (pci_bus_add_device(dev))
573 printk(EEEPC_ERR "Unable to hotplug wifi\n");
576 dev = pci_get_slot(bus, 0);
578 pci_remove_bus_device(dev);
583 rfkill_force_state(ehotk->eeepc_wlan_rfkill, !blocked);
586 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
588 if (event != ACPI_NOTIFY_BUS_CHECK)
591 eeepc_rfkill_hotplug();
594 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
596 static struct key_entry *key;
602 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
604 count = ehotk->event_count[event % 128]++;
605 acpi_bus_generate_proc_event(ehotk->device, event, count);
606 acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
607 dev_name(&ehotk->device->dev), event,
609 if (ehotk->inputdev) {
610 if (brn != -ENODEV) {
611 /* brightness-change events need special
612 * handling for conversion to key events
617 brn += NOTIFY_BRN_MIN;
619 event = NOTIFY_BRN_MIN; /* brightness down */
620 else if (event > brn)
621 event = NOTIFY_BRN_MIN + 2; /* ... up */
623 event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
625 key = eepc_get_entry_by_scancode(event);
629 input_report_key(ehotk->inputdev, key->keycode,
631 input_sync(ehotk->inputdev);
632 input_report_key(ehotk->inputdev, key->keycode,
634 input_sync(ehotk->inputdev);
641 static int eeepc_register_rfkill_notifier(char *node)
643 acpi_status status = AE_OK;
646 status = acpi_get_handle(NULL, node, &handle);
648 if (ACPI_SUCCESS(status)) {
649 status = acpi_install_notify_handler(handle,
653 if (ACPI_FAILURE(status))
655 "Failed to register notify on %s\n", node);
662 static void eeepc_unregister_rfkill_notifier(char *node)
664 acpi_status status = AE_OK;
667 status = acpi_get_handle(NULL, node, &handle);
669 if (ACPI_SUCCESS(status)) {
670 status = acpi_remove_notify_handler(handle,
672 eeepc_rfkill_notify);
673 if (ACPI_FAILURE(status))
675 "Error removing rfkill notify handler %s\n",
680 static struct rfkill *eeepc_rfkill_alloc(const char *name,
682 enum rfkill_type type, int asl)
684 struct rfkill *rfkill;
686 rfkill = rfkill_allocate(dev, type);
691 rfkill->toggle_radio = eeepc_rfkill_set;
692 rfkill->get_state = eeepc_rfkill_state;
693 if (get_acpi(asl) == 1) {
694 rfkill->state = RFKILL_STATE_UNBLOCKED;
695 rfkill_set_default(type, RFKILL_STATE_UNBLOCKED);
697 rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
698 rfkill_set_default(type, RFKILL_STATE_SOFT_BLOCKED);
703 static int eeepc_hotk_add(struct acpi_device *device)
705 acpi_status status = AE_OK;
710 printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n");
711 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
714 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
715 ehotk->handle = device->handle;
716 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
717 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
718 device->driver_data = ehotk;
719 ehotk->device = device;
720 result = eeepc_hotk_check();
723 status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
724 eeepc_hotk_notify, ehotk);
725 if (ACPI_FAILURE(status))
726 printk(EEEPC_ERR "Error installing notify handler\n");
728 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
729 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
731 if (get_acpi(CM_ASL_WLAN) != -1) {
732 ehotk->eeepc_wlan_rfkill =
733 eeepc_rfkill_alloc("eeepc-wlan",
738 if (!ehotk->eeepc_wlan_rfkill)
741 result = rfkill_register(ehotk->eeepc_wlan_rfkill);
746 if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
747 ehotk->eeepc_wlan_rfkill =
748 eeepc_rfkill_alloc("eeepc-bluetooth",
750 RFKILL_TYPE_BLUETOOTH,
753 if (!ehotk->eeepc_bluetooth_rfkill)
756 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
764 if (ehotk->eeepc_bluetooth_rfkill)
765 rfkill_free(ehotk->eeepc_bluetooth_rfkill);
766 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
767 ehotk->eeepc_wlan_rfkill = NULL;
769 if (ehotk->eeepc_wlan_rfkill)
770 rfkill_free(ehotk->eeepc_wlan_rfkill);
771 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
772 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
780 static int eeepc_hotk_remove(struct acpi_device *device, int type)
782 acpi_status status = 0;
784 if (!device || !acpi_driver_data(device))
786 status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
788 if (ACPI_FAILURE(status))
789 printk(EEEPC_ERR "Error removing notify handler\n");
791 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
792 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
798 static int eeepc_hotk_resume(struct acpi_device *device)
800 if (ehotk->eeepc_wlan_rfkill) {
803 /* Workaround - it seems that _PTS disables the wireless
804 without notification or changing the value read by WLAN.
805 Normally this is fine because the correct value is restored
806 from the non-volatile storage on resume, but we need to do
807 it ourself if case suspend is aborted, or we lose wireless.
809 wlan = get_acpi(CM_ASL_WLAN);
810 set_acpi(CM_ASL_WLAN, wlan);
812 rfkill_force_state(ehotk->eeepc_wlan_rfkill,
815 eeepc_rfkill_hotplug();
818 if (ehotk->eeepc_bluetooth_rfkill)
819 rfkill_force_state(ehotk->eeepc_bluetooth_rfkill,
820 get_acpi(CM_ASL_BLUETOOTH) != 1);
828 static int eeepc_get_fan_pwm(void)
832 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
833 value = value * 255 / 100;
837 static void eeepc_set_fan_pwm(int value)
839 value = SENSORS_LIMIT(value, 0, 255);
840 value = value * 100 / 255;
841 ec_write(EEEPC_EC_SC02, value);
844 static int eeepc_get_fan_rpm(void)
849 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
850 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
851 return (high << 8 | low);
854 static int eeepc_get_fan_ctrl(void)
858 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
859 return ((value & 0x02 ? 1 : 0));
862 static void eeepc_set_fan_ctrl(int manual)
866 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
871 ec_write(EEEPC_EC_SFB3, value);
874 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
878 rv = parse_arg(buf, count, &value);
884 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
886 return sprintf(buf, "%d\n", get());
889 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
890 static ssize_t show_##_name(struct device *dev, \
891 struct device_attribute *attr, \
894 return show_sys_hwmon(_set, buf); \
896 static ssize_t store_##_name(struct device *dev, \
897 struct device_attribute *attr, \
898 const char *buf, size_t count) \
900 return store_sys_hwmon(_get, buf, count); \
902 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
904 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
905 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
906 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
907 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
908 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
911 show_name(struct device *dev, struct device_attribute *attr, char *buf)
913 return sprintf(buf, "eeepc\n");
915 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
917 static struct attribute *hwmon_attributes[] = {
918 &sensor_dev_attr_pwm1.dev_attr.attr,
919 &sensor_dev_attr_fan1_input.dev_attr.attr,
920 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
921 &sensor_dev_attr_name.dev_attr.attr,
925 static struct attribute_group hwmon_attribute_group = {
926 .attrs = hwmon_attributes
932 static void eeepc_backlight_exit(void)
934 if (eeepc_backlight_device)
935 backlight_device_unregister(eeepc_backlight_device);
936 eeepc_backlight_device = NULL;
939 static void eeepc_rfkill_exit(void)
941 if (ehotk->eeepc_wlan_rfkill)
942 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
943 if (ehotk->eeepc_bluetooth_rfkill)
944 rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
947 static void eeepc_input_exit(void)
950 input_unregister_device(ehotk->inputdev);
953 static void eeepc_hwmon_exit(void)
955 struct device *hwmon;
957 hwmon = eeepc_hwmon_device;
960 sysfs_remove_group(&hwmon->kobj,
961 &hwmon_attribute_group);
962 hwmon_device_unregister(hwmon);
963 eeepc_hwmon_device = NULL;
966 static void __exit eeepc_laptop_exit(void)
968 eeepc_backlight_exit();
972 acpi_bus_unregister_driver(&eeepc_hotk_driver);
973 sysfs_remove_group(&platform_device->dev.kobj,
974 &platform_attribute_group);
975 platform_device_unregister(platform_device);
976 platform_driver_unregister(&platform_driver);
979 static int eeepc_backlight_init(struct device *dev)
981 struct backlight_device *bd;
983 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
987 "Could not register eeepc backlight device\n");
988 eeepc_backlight_device = NULL;
991 eeepc_backlight_device = bd;
992 bd->props.max_brightness = 15;
993 bd->props.brightness = read_brightness(NULL);
994 bd->props.power = FB_BLANK_UNBLANK;
995 backlight_update_status(bd);
999 static int eeepc_hwmon_init(struct device *dev)
1001 struct device *hwmon;
1004 hwmon = hwmon_device_register(dev);
1005 if (IS_ERR(hwmon)) {
1007 "Could not register eeepc hwmon device\n");
1008 eeepc_hwmon_device = NULL;
1009 return PTR_ERR(hwmon);
1011 eeepc_hwmon_device = hwmon;
1012 result = sysfs_create_group(&hwmon->kobj,
1013 &hwmon_attribute_group);
1019 static int __init eeepc_laptop_init(void)
1026 result = acpi_bus_register_driver(&eeepc_hotk_driver);
1030 acpi_bus_unregister_driver(&eeepc_hotk_driver);
1033 dev = acpi_get_physical_device(ehotk->device->handle);
1035 if (!acpi_video_backlight_support()) {
1036 result = eeepc_backlight_init(dev);
1038 goto fail_backlight;
1040 printk(EEEPC_INFO "Backlight controlled by ACPI video "
1043 result = eeepc_hwmon_init(dev);
1047 eeepc_enable_camera();
1049 /* Register platform stuff */
1050 result = platform_driver_register(&platform_driver);
1052 goto fail_platform_driver;
1053 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
1054 if (!platform_device) {
1056 goto fail_platform_device1;
1058 result = platform_device_add(platform_device);
1060 goto fail_platform_device2;
1061 result = sysfs_create_group(&platform_device->dev.kobj,
1062 &platform_attribute_group);
1067 platform_device_del(platform_device);
1068 fail_platform_device2:
1069 platform_device_put(platform_device);
1070 fail_platform_device1:
1071 platform_driver_unregister(&platform_driver);
1072 fail_platform_driver:
1075 eeepc_backlight_exit();
1078 eeepc_rfkill_exit();
1082 module_init(eeepc_laptop_init);
1083 module_exit(eeepc_laptop_exit);