Loading drivers/platform/x86/asus-laptop.c +180 −189 Original line number Diff line number Diff line Loading @@ -201,6 +201,8 @@ ASUS_HANDLE(kled_get, ASUS_HOTK_PREFIX "GLKB"); */ struct asus_hotk { char *name; /* laptop name */ struct platform_device *platform_device; struct acpi_device *device; /* the device we are in */ acpi_handle handle; /* the handle of the hotk device */ char status; /* status of the hotk, for LEDs, ... */ Loading @@ -222,33 +224,6 @@ static struct acpi_table_header *asus_info; /* The actual device the driver binds to */ static struct asus_hotk *hotk; /* * The hotkey driver declaration */ static const struct acpi_device_id asus_device_ids[] = { {"ATK0100", 0}, {"ATK0101", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, asus_device_ids); static int asus_hotk_add(struct acpi_device *device); static int asus_hotk_remove(struct acpi_device *device, int type); static void asus_hotk_notify(struct acpi_device *device, u32 event); static struct acpi_driver asus_hotk_driver = { .name = ASUS_HOTK_NAME, .class = ASUS_HOTK_CLASS, .owner = THIS_MODULE, .ids = asus_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = asus_hotk_add, .remove = asus_hotk_remove, .notify = asus_hotk_notify, }, }; /* The backlight device /sys/class/backlight */ static struct backlight_device *asus_backlight_device; Loading Loading @@ -936,7 +911,7 @@ static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) return -EINVAL; } static void asus_hotk_notify(struct acpi_device *device, u32 event) static void asus_acpi_notify(struct acpi_device *device, u32 event) { static struct key_entry *key; u16 count; Loading Loading @@ -1013,19 +988,49 @@ static struct attribute *asuspf_attributes[] = { NULL }; static struct attribute_group asuspf_attribute_group = { static struct attribute_group platform_attribute_group = { .attrs = asuspf_attributes }; static struct platform_driver asuspf_driver = { static int asus_platform_init(void) { int result; hotk->platform_device = platform_device_alloc(ASUS_HOTK_FILE, -1); if (!hotk->platform_device) return -ENOMEM; result = platform_device_add(hotk->platform_device); if (result) goto fail_platform_device; result = sysfs_create_group(&hotk->platform_device->dev.kobj, &platform_attribute_group); if (result) goto fail_sysfs; return 0; fail_sysfs: platform_device_del(hotk->platform_device); fail_platform_device: platform_device_put(hotk->platform_device); return result; } static void asus_platform_exit(void) { sysfs_remove_group(&hotk->platform_device->dev.kobj, &platform_attribute_group); platform_device_unregister(hotk->platform_device); } static struct platform_driver platform_driver = { .driver = { .name = ASUS_HOTK_FILE, .owner = THIS_MODULE, } }; static struct platform_device *asuspf_device; static void asus_hotk_add_fs(void) { ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL); Loading Loading @@ -1196,7 +1201,7 @@ static int asus_hotk_get_info(void) return AE_OK; } static int asus_input_init(void) static int asus_input_init(struct device *dev) { const struct key_entry *key; int result; Loading @@ -1207,6 +1212,7 @@ static int asus_input_init(void) return 0; } hotk->inputdev->name = "Asus Laptop extra buttons"; hotk->inputdev->dev.parent = dev; hotk->inputdev->phys = ASUS_HOTK_FILE "/input0"; hotk->inputdev->id.bustype = BUS_HOST; hotk->inputdev->getkeycode = asus_getkeycode; Loading @@ -1228,101 +1234,6 @@ static int asus_input_init(void) return result; } static int asus_hotk_check(void) { int result = 0; result = acpi_bus_get_status(hotk->device); if (result) return result; if (hotk->device->status.present) { result = asus_hotk_get_info(); } else { pr_err("Hotkey device not present, aborting\n"); return -EINVAL; } return result; } static int asus_hotk_found; static int asus_hotk_add(struct acpi_device *device) { int result; pr_notice("Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); if (!hotk) return -ENOMEM; hotk->handle = device->handle; strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); device->driver_data = hotk; hotk->device = device; result = asus_hotk_check(); if (result) goto end; asus_hotk_add_fs(); asus_hotk_found = 1; /* WLED and BLED are on by default */ if (bluetooth_status != -1) write_status(bt_switch_handle, !!bluetooth_status, BT_ON); if (wireless_status != -1) write_status(wl_switch_handle, !!wireless_status, WL_ON); /* If the h/w switch is off, we need to check the real status */ write_status(NULL, read_status(BT_ON), BT_ON); write_status(NULL, read_status(WL_ON), WL_ON); /* LCD Backlight is on by default */ write_status(NULL, 1, LCD_ON); /* Keyboard Backlight is on by default */ if (kled_set_handle) set_kled_lvl(1); /* LED display is off by default */ hotk->ledd_status = 0xFFF; /* Set initial values of light sensor and level */ hotk->light_switch = 0; /* Default to light sensor disabled */ hotk->light_level = 5; /* level 5 for sensor sensitivity */ if (ls_switch_handle) set_light_sens_switch(hotk->light_switch); if (ls_level_handle) set_light_sens_level(hotk->light_level); /* GPS is on by default */ write_status(NULL, 1, GPS_ON); end: if (result) { kfree(hotk->name); kfree(hotk); } return result; } static int asus_hotk_remove(struct acpi_device *device, int type) { kfree(hotk->name); kfree(hotk); return 0; } static void asus_backlight_exit(void) { if (asus_backlight_device) Loading Loading @@ -1350,18 +1261,6 @@ static void asus_input_exit(void) input_unregister_device(hotk->inputdev); } static void __exit asus_laptop_exit(void) { asus_backlight_exit(); asus_led_exit(); asus_input_exit(); acpi_bus_unregister_driver(&asus_hotk_driver); sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); platform_device_unregister(asuspf_device); platform_driver_unregister(&asuspf_driver); } static int asus_backlight_init(struct device *dev) { struct backlight_device *bd; Loading Loading @@ -1448,87 +1347,179 @@ static int asus_led_init(struct device *dev) return rv; } static int __init asus_laptop_init(void) static bool asus_device_present; static int __devinit asus_acpi_init(struct acpi_device *device) { int result; int result = 0; result = acpi_bus_register_driver(&asus_hotk_driver); if (result < 0) result = acpi_bus_get_status(hotk->device); if (result) return result; /* * This is a bit of a kludge. We only want this module loaded * for ASUS systems, but there's currently no way to probe the * ACPI namespace for ASUS HIDs. So we just return failure if * we didn't find one, which will cause the module to be * unloaded. */ if (!asus_hotk_found) { acpi_bus_unregister_driver(&asus_hotk_driver); if (!hotk->device->status.present) { pr_err("Hotkey device not present, aborting\n"); return -ENODEV; } result = asus_input_init(); result = asus_hotk_get_info(); if (result) goto fail_input; return result; /* Register platform stuff */ result = platform_driver_register(&asuspf_driver); if (result) goto fail_platform_driver; asus_hotk_add_fs(); /* WLED and BLED are on by default */ write_status(bt_switch_handle, 1, BT_ON); write_status(wl_switch_handle, 1, WL_ON); /* If the h/w switch is off, we need to check the real status */ write_status(NULL, read_status(BT_ON), BT_ON); write_status(NULL, read_status(WL_ON), WL_ON); /* LCD Backlight is on by default */ write_status(NULL, 1, LCD_ON); asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1); if (!asuspf_device) { result = -ENOMEM; goto fail_platform_device1; /* Keyboard Backlight is on by default */ if (kled_set_handle) set_kled_lvl(1); /* LED display is off by default */ hotk->ledd_status = 0xFFF; /* Set initial values of light sensor and level */ hotk->light_switch = 0; /* Default to light sensor disabled */ hotk->light_level = 5; /* level 5 for sensor sensitivity */ if (ls_switch_handle) set_light_sens_switch(hotk->light_switch); if (ls_level_handle) set_light_sens_level(hotk->light_level); /* GPS is on by default */ write_status(NULL, 1, GPS_ON); return result; } result = platform_device_add(asuspf_device); if (result) goto fail_platform_device2; static int __devinit asus_acpi_add(struct acpi_device *device) { int result; pr_notice("Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); if (!hotk) return -ENOMEM; hotk->handle = device->handle; strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); device->driver_data = hotk; hotk->device = device; result = sysfs_create_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); result = asus_acpi_init(device); if (result) goto fail_sysfs; goto fail_platform; result = asus_led_init(&asuspf_device->dev); /* * Register the platform device first. It is used as a parent for the * sub-devices below. */ result = asus_platform_init(); if (result) goto fail_led; goto fail_platform; if (!acpi_video_backlight_support()) { result = asus_backlight_init(&asuspf_device->dev); result = asus_backlight_init(&hotk->platform_device->dev); if (result) goto fail_backlight; } else pr_info("Brightness ignored, must be controlled by " "ACPI video driver\n"); pr_info("Backlight controlled by ACPI video driver\n"); result = asus_input_init(&hotk->platform_device->dev); if (result) goto fail_input; result = asus_led_init(&hotk->platform_device->dev); if (result) goto fail_led; asus_device_present = true; return 0; fail_led: asus_input_exit(); fail_input: asus_backlight_exit(); fail_backlight: asus_platform_exit(); fail_platform: kfree(hotk->name); kfree(hotk); return result; } static int asus_acpi_remove(struct acpi_device *device, int type) { asus_backlight_exit(); asus_led_exit(); asus_input_exit(); asus_platform_exit(); fail_led: sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); kfree(hotk->name); kfree(hotk); return 0; } fail_sysfs: platform_device_del(asuspf_device); static const struct acpi_device_id asus_device_ids[] = { {"ATK0100", 0}, {"ATK0101", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, asus_device_ids); fail_platform_device2: platform_device_put(asuspf_device); static struct acpi_driver asus_acpi_driver = { .name = ASUS_HOTK_NAME, .class = ASUS_HOTK_CLASS, .owner = THIS_MODULE, .ids = asus_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = asus_acpi_add, .remove = asus_acpi_remove, .notify = asus_acpi_notify, }, }; fail_platform_device1: platform_driver_unregister(&asuspf_driver); static int __init asus_laptop_init(void) { int result; fail_platform_driver: asus_input_exit(); result = platform_driver_register(&platform_driver); if (result < 0) return result; fail_input: result = acpi_bus_register_driver(&asus_acpi_driver); if (result < 0) goto fail_acpi_driver; if (!asus_device_present) { result = -ENODEV; goto fail_no_device; } return 0; fail_no_device: acpi_bus_unregister_driver(&asus_acpi_driver); fail_acpi_driver: platform_driver_unregister(&platform_driver); return result; } static void __exit asus_laptop_exit(void) { acpi_bus_unregister_driver(&asus_acpi_driver); platform_driver_unregister(&platform_driver); } module_init(asus_laptop_init); module_exit(asus_laptop_exit); Loading
drivers/platform/x86/asus-laptop.c +180 −189 Original line number Diff line number Diff line Loading @@ -201,6 +201,8 @@ ASUS_HANDLE(kled_get, ASUS_HOTK_PREFIX "GLKB"); */ struct asus_hotk { char *name; /* laptop name */ struct platform_device *platform_device; struct acpi_device *device; /* the device we are in */ acpi_handle handle; /* the handle of the hotk device */ char status; /* status of the hotk, for LEDs, ... */ Loading @@ -222,33 +224,6 @@ static struct acpi_table_header *asus_info; /* The actual device the driver binds to */ static struct asus_hotk *hotk; /* * The hotkey driver declaration */ static const struct acpi_device_id asus_device_ids[] = { {"ATK0100", 0}, {"ATK0101", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, asus_device_ids); static int asus_hotk_add(struct acpi_device *device); static int asus_hotk_remove(struct acpi_device *device, int type); static void asus_hotk_notify(struct acpi_device *device, u32 event); static struct acpi_driver asus_hotk_driver = { .name = ASUS_HOTK_NAME, .class = ASUS_HOTK_CLASS, .owner = THIS_MODULE, .ids = asus_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = asus_hotk_add, .remove = asus_hotk_remove, .notify = asus_hotk_notify, }, }; /* The backlight device /sys/class/backlight */ static struct backlight_device *asus_backlight_device; Loading Loading @@ -936,7 +911,7 @@ static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) return -EINVAL; } static void asus_hotk_notify(struct acpi_device *device, u32 event) static void asus_acpi_notify(struct acpi_device *device, u32 event) { static struct key_entry *key; u16 count; Loading Loading @@ -1013,19 +988,49 @@ static struct attribute *asuspf_attributes[] = { NULL }; static struct attribute_group asuspf_attribute_group = { static struct attribute_group platform_attribute_group = { .attrs = asuspf_attributes }; static struct platform_driver asuspf_driver = { static int asus_platform_init(void) { int result; hotk->platform_device = platform_device_alloc(ASUS_HOTK_FILE, -1); if (!hotk->platform_device) return -ENOMEM; result = platform_device_add(hotk->platform_device); if (result) goto fail_platform_device; result = sysfs_create_group(&hotk->platform_device->dev.kobj, &platform_attribute_group); if (result) goto fail_sysfs; return 0; fail_sysfs: platform_device_del(hotk->platform_device); fail_platform_device: platform_device_put(hotk->platform_device); return result; } static void asus_platform_exit(void) { sysfs_remove_group(&hotk->platform_device->dev.kobj, &platform_attribute_group); platform_device_unregister(hotk->platform_device); } static struct platform_driver platform_driver = { .driver = { .name = ASUS_HOTK_FILE, .owner = THIS_MODULE, } }; static struct platform_device *asuspf_device; static void asus_hotk_add_fs(void) { ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL); Loading Loading @@ -1196,7 +1201,7 @@ static int asus_hotk_get_info(void) return AE_OK; } static int asus_input_init(void) static int asus_input_init(struct device *dev) { const struct key_entry *key; int result; Loading @@ -1207,6 +1212,7 @@ static int asus_input_init(void) return 0; } hotk->inputdev->name = "Asus Laptop extra buttons"; hotk->inputdev->dev.parent = dev; hotk->inputdev->phys = ASUS_HOTK_FILE "/input0"; hotk->inputdev->id.bustype = BUS_HOST; hotk->inputdev->getkeycode = asus_getkeycode; Loading @@ -1228,101 +1234,6 @@ static int asus_input_init(void) return result; } static int asus_hotk_check(void) { int result = 0; result = acpi_bus_get_status(hotk->device); if (result) return result; if (hotk->device->status.present) { result = asus_hotk_get_info(); } else { pr_err("Hotkey device not present, aborting\n"); return -EINVAL; } return result; } static int asus_hotk_found; static int asus_hotk_add(struct acpi_device *device) { int result; pr_notice("Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); if (!hotk) return -ENOMEM; hotk->handle = device->handle; strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); device->driver_data = hotk; hotk->device = device; result = asus_hotk_check(); if (result) goto end; asus_hotk_add_fs(); asus_hotk_found = 1; /* WLED and BLED are on by default */ if (bluetooth_status != -1) write_status(bt_switch_handle, !!bluetooth_status, BT_ON); if (wireless_status != -1) write_status(wl_switch_handle, !!wireless_status, WL_ON); /* If the h/w switch is off, we need to check the real status */ write_status(NULL, read_status(BT_ON), BT_ON); write_status(NULL, read_status(WL_ON), WL_ON); /* LCD Backlight is on by default */ write_status(NULL, 1, LCD_ON); /* Keyboard Backlight is on by default */ if (kled_set_handle) set_kled_lvl(1); /* LED display is off by default */ hotk->ledd_status = 0xFFF; /* Set initial values of light sensor and level */ hotk->light_switch = 0; /* Default to light sensor disabled */ hotk->light_level = 5; /* level 5 for sensor sensitivity */ if (ls_switch_handle) set_light_sens_switch(hotk->light_switch); if (ls_level_handle) set_light_sens_level(hotk->light_level); /* GPS is on by default */ write_status(NULL, 1, GPS_ON); end: if (result) { kfree(hotk->name); kfree(hotk); } return result; } static int asus_hotk_remove(struct acpi_device *device, int type) { kfree(hotk->name); kfree(hotk); return 0; } static void asus_backlight_exit(void) { if (asus_backlight_device) Loading Loading @@ -1350,18 +1261,6 @@ static void asus_input_exit(void) input_unregister_device(hotk->inputdev); } static void __exit asus_laptop_exit(void) { asus_backlight_exit(); asus_led_exit(); asus_input_exit(); acpi_bus_unregister_driver(&asus_hotk_driver); sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); platform_device_unregister(asuspf_device); platform_driver_unregister(&asuspf_driver); } static int asus_backlight_init(struct device *dev) { struct backlight_device *bd; Loading Loading @@ -1448,87 +1347,179 @@ static int asus_led_init(struct device *dev) return rv; } static int __init asus_laptop_init(void) static bool asus_device_present; static int __devinit asus_acpi_init(struct acpi_device *device) { int result; int result = 0; result = acpi_bus_register_driver(&asus_hotk_driver); if (result < 0) result = acpi_bus_get_status(hotk->device); if (result) return result; /* * This is a bit of a kludge. We only want this module loaded * for ASUS systems, but there's currently no way to probe the * ACPI namespace for ASUS HIDs. So we just return failure if * we didn't find one, which will cause the module to be * unloaded. */ if (!asus_hotk_found) { acpi_bus_unregister_driver(&asus_hotk_driver); if (!hotk->device->status.present) { pr_err("Hotkey device not present, aborting\n"); return -ENODEV; } result = asus_input_init(); result = asus_hotk_get_info(); if (result) goto fail_input; return result; /* Register platform stuff */ result = platform_driver_register(&asuspf_driver); if (result) goto fail_platform_driver; asus_hotk_add_fs(); /* WLED and BLED are on by default */ write_status(bt_switch_handle, 1, BT_ON); write_status(wl_switch_handle, 1, WL_ON); /* If the h/w switch is off, we need to check the real status */ write_status(NULL, read_status(BT_ON), BT_ON); write_status(NULL, read_status(WL_ON), WL_ON); /* LCD Backlight is on by default */ write_status(NULL, 1, LCD_ON); asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1); if (!asuspf_device) { result = -ENOMEM; goto fail_platform_device1; /* Keyboard Backlight is on by default */ if (kled_set_handle) set_kled_lvl(1); /* LED display is off by default */ hotk->ledd_status = 0xFFF; /* Set initial values of light sensor and level */ hotk->light_switch = 0; /* Default to light sensor disabled */ hotk->light_level = 5; /* level 5 for sensor sensitivity */ if (ls_switch_handle) set_light_sens_switch(hotk->light_switch); if (ls_level_handle) set_light_sens_level(hotk->light_level); /* GPS is on by default */ write_status(NULL, 1, GPS_ON); return result; } result = platform_device_add(asuspf_device); if (result) goto fail_platform_device2; static int __devinit asus_acpi_add(struct acpi_device *device) { int result; pr_notice("Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); if (!hotk) return -ENOMEM; hotk->handle = device->handle; strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); device->driver_data = hotk; hotk->device = device; result = sysfs_create_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); result = asus_acpi_init(device); if (result) goto fail_sysfs; goto fail_platform; result = asus_led_init(&asuspf_device->dev); /* * Register the platform device first. It is used as a parent for the * sub-devices below. */ result = asus_platform_init(); if (result) goto fail_led; goto fail_platform; if (!acpi_video_backlight_support()) { result = asus_backlight_init(&asuspf_device->dev); result = asus_backlight_init(&hotk->platform_device->dev); if (result) goto fail_backlight; } else pr_info("Brightness ignored, must be controlled by " "ACPI video driver\n"); pr_info("Backlight controlled by ACPI video driver\n"); result = asus_input_init(&hotk->platform_device->dev); if (result) goto fail_input; result = asus_led_init(&hotk->platform_device->dev); if (result) goto fail_led; asus_device_present = true; return 0; fail_led: asus_input_exit(); fail_input: asus_backlight_exit(); fail_backlight: asus_platform_exit(); fail_platform: kfree(hotk->name); kfree(hotk); return result; } static int asus_acpi_remove(struct acpi_device *device, int type) { asus_backlight_exit(); asus_led_exit(); asus_input_exit(); asus_platform_exit(); fail_led: sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); kfree(hotk->name); kfree(hotk); return 0; } fail_sysfs: platform_device_del(asuspf_device); static const struct acpi_device_id asus_device_ids[] = { {"ATK0100", 0}, {"ATK0101", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, asus_device_ids); fail_platform_device2: platform_device_put(asuspf_device); static struct acpi_driver asus_acpi_driver = { .name = ASUS_HOTK_NAME, .class = ASUS_HOTK_CLASS, .owner = THIS_MODULE, .ids = asus_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = asus_acpi_add, .remove = asus_acpi_remove, .notify = asus_acpi_notify, }, }; fail_platform_device1: platform_driver_unregister(&asuspf_driver); static int __init asus_laptop_init(void) { int result; fail_platform_driver: asus_input_exit(); result = platform_driver_register(&platform_driver); if (result < 0) return result; fail_input: result = acpi_bus_register_driver(&asus_acpi_driver); if (result < 0) goto fail_acpi_driver; if (!asus_device_present) { result = -ENODEV; goto fail_no_device; } return 0; fail_no_device: acpi_bus_unregister_driver(&asus_acpi_driver); fail_acpi_driver: platform_driver_unregister(&platform_driver); return result; } static void __exit asus_laptop_exit(void) { acpi_bus_unregister_driver(&asus_acpi_driver); platform_driver_unregister(&platform_driver); } module_init(asus_laptop_init); module_exit(asus_laptop_exit);