static int asus_led_init(struct asus_laptop *asus) { int r = 0; if (asus->is_pega_lucid) return 0; asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); if (!asus->led_workqueue) return -ENOMEM; if (asus->wled_type == TYPE_LED) r = asus_led_register(asus, &asus->wled, "asus::wlan", METHOD_WLAN); if (r) goto error; if (asus->bled_type == TYPE_LED) r = asus_led_register(asus, &asus->bled, "asus::bluetooth", METHOD_BLUETOOTH); if (r) goto error; r = asus_led_register(asus, &asus->mled, "asus::mail", METHOD_MLED); if (r) goto error; r = asus_led_register(asus, &asus->tled, "asus::touchpad", METHOD_TLED); if (r) goto error; r = asus_led_register(asus, &asus->rled, "asus::record", METHOD_RLED); if (r) goto error; r = asus_led_register(asus, &asus->pled, "asus::phone", METHOD_PLED); if (r) goto error; r = asus_led_register(asus, &asus->gled, "asus::gaming", METHOD_GLED); if (r) goto error; if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL) && !acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_GET, NULL)) { struct asus_led *led = &asus->kled; struct led_classdev *cdev = &led->led; led->asus = asus; INIT_WORK(&led->work, asus_kled_cdev_update); cdev->name = "asus::kbd_backlight"; cdev->brightness_set = asus_kled_cdev_set; cdev->brightness_get = asus_kled_cdev_get; cdev->max_brightness = 3; r = led_classdev_register(&asus->platform_device->dev, cdev); } error: if (r) asus_led_exit(asus); return r; }
static int asus_led_init(struct asus_laptop *asus) { int r; /* * The Pegatron Lucid has no physical leds, but all methods are * available in the DSDT... */ if (asus->is_pega_lucid) return 0; /* * Functions that actually update the LED's are called from a * workqueue. By doing this as separate work rather than when the LED * subsystem asks, we avoid messing with the Asus ACPI stuff during a * potentially bad time, such as a timer interrupt. */ asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); if (!asus->led_workqueue) return -ENOMEM; r = asus_led_register(asus, &asus->mled, "asus::mail", METHOD_MLED); if (r) goto error; r = asus_led_register(asus, &asus->tled, "asus::touchpad", METHOD_TLED); if (r) goto error; r = asus_led_register(asus, &asus->rled, "asus::record", METHOD_RLED); if (r) goto error; r = asus_led_register(asus, &asus->pled, "asus::phone", METHOD_PLED); if (r) goto error; r = asus_led_register(asus, &asus->gled, "asus::gaming", METHOD_GLED); if (r) goto error; if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL) && !acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_GET, NULL)) { struct asus_led *led = &asus->kled; struct led_classdev *cdev = &led->led; led->asus = asus; INIT_WORK(&led->work, asus_kled_cdev_update); cdev->name = "asus::kbd_backlight"; cdev->brightness_set = asus_kled_cdev_set; cdev->brightness_get = asus_kled_cdev_get; cdev->max_brightness = 3; r = led_classdev_register(&asus->platform_device->dev, cdev); } error: if (r) asus_led_exit(asus); return r; }
static int asus_acpi_remove(struct acpi_device *device, int type) { struct asus_laptop *asus = acpi_driver_data(device); asus_backlight_exit(asus); asus_rfkill_exit(asus); asus_led_exit(asus); asus_input_exit(asus); asus_platform_exit(asus); kfree(asus->name); kfree(asus); return 0; }
static int __devinit asus_acpi_add(struct acpi_device *device) { struct asus_laptop *asus; int result; pr_notice("Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); asus = kzalloc(sizeof(struct asus_laptop), GFP_KERNEL); if (!asus) return -ENOMEM; asus->handle = device->handle; strcpy(acpi_device_name(device), ASUS_LAPTOP_DEVICE_NAME); strcpy(acpi_device_class(device), ASUS_LAPTOP_CLASS); device->driver_data = asus; asus->device = device; result = asus_acpi_init(asus); if (result) goto fail_platform; /* * Register the platform device first. It is used as a parent for the * sub-devices below. */ result = asus_platform_init(asus); if (result) goto fail_platform; if (!acpi_video_backlight_support()) { result = asus_backlight_init(asus); if (result) goto fail_backlight; } else pr_info("Backlight controlled by ACPI video driver\n"); result = asus_input_init(asus); if (result) goto fail_input; result = asus_led_init(asus); if (result) goto fail_led; result = asus_rfkill_init(asus); if (result) goto fail_rfkill; asus_device_present = true; return 0; fail_rfkill: asus_led_exit(asus); fail_led: asus_input_exit(asus); fail_input: asus_backlight_exit(asus); fail_backlight: asus_platform_exit(asus); fail_platform: kfree(asus->name); kfree(asus); return result; }
static int __devinit asus_acpi_add(struct acpi_device *device) { struct asus_laptop *asus; int result; pr_notice("Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); asus = kzalloc(sizeof(struct asus_laptop), GFP_KERNEL); if (!asus) return -ENOMEM; asus->handle = device->handle; strcpy(acpi_device_name(device), ASUS_LAPTOP_DEVICE_NAME); strcpy(acpi_device_class(device), ASUS_LAPTOP_CLASS); device->driver_data = asus; asus->device = device; asus_dmi_check(); result = asus_acpi_init(asus); if (result) goto fail_platform; asus->is_pega_lucid = asus_check_pega_lucid(asus); result = asus_platform_init(asus); if (result) goto fail_platform; if (!acpi_video_backlight_support()) { result = asus_backlight_init(asus); if (result) goto fail_backlight; } else pr_info("Backlight controlled by ACPI video driver\n"); result = asus_input_init(asus); if (result) goto fail_input; result = asus_led_init(asus); if (result) goto fail_led; result = asus_rfkill_init(asus); if (result && result != -ENODEV) goto fail_rfkill; result = pega_accel_init(asus); if (result && result != -ENODEV) goto fail_pega_accel; result = pega_rfkill_init(asus); if (result && result != -ENODEV) goto fail_pega_rfkill; asus_device_present = true; return 0; fail_pega_rfkill: pega_accel_exit(asus); fail_pega_accel: asus_rfkill_exit(asus); fail_rfkill: asus_led_exit(asus); fail_led: asus_input_exit(asus); fail_input: asus_backlight_exit(asus); fail_backlight: asus_platform_exit(asus); fail_platform: kfree(asus->name); kfree(asus); return result; }