|
|
* | * |
* | * |
* Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor | * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor |
* Copyright (C) 2006 Corentin Chary |
* Copyright (C) 2006-2007 Corentin Chary |
* | * |
* This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by |
|
|
| |
#include <linux/version.h> | #include <linux/version.h> |
| |
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,19) |
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20) |
#warning "This module does not support 2.6.19" |
#warning "This module does not support 2.6.20" |
#endif | #endif |
| |
#include <linux/autoconf.h> | #include <linux/autoconf.h> |
|
|
#include <acpi/acpi_bus.h> | #include <acpi/acpi_bus.h> |
#include <asm/uaccess.h> | #include <asm/uaccess.h> |
| |
#define ASUS_LAPTOP_VERSION "0.41" |
#define ASUS_LAPTOP_VERSION "0.42-cvs" |
| |
#define ASUS_HOTK_NAME "Asus Laptop Support" | #define ASUS_HOTK_NAME "Asus Laptop Support" |
#define ASUS_HOTK_CLASS "hotkey" | #define ASUS_HOTK_CLASS "hotkey" |
|
|
*/ | */ |
static int read_brightness(struct backlight_device *bd); | static int read_brightness(struct backlight_device *bd); |
static int update_bl_status(struct backlight_device *bd); | static int update_bl_status(struct backlight_device *bd); |
static struct backlight_properties asusbl_data = { |
static struct backlight_ops asusbl_ops = { |
.owner = THIS_MODULE, |
|
.get_brightness = read_brightness, | .get_brightness = read_brightness, |
.update_status = update_bl_status, | .update_status = update_bl_status, |
.max_brightness = 15, |
|
}; | }; |
| |
/* These functions actually update the LED's, and are called from a | /* These functions actually update the LED's, and are called from a |
|
|
#define ASUS_LED(object, ledname) \ | #define ASUS_LED(object, ledname) \ |
static void object##_led_set(struct led_classdev *led_cdev, \ | static void object##_led_set(struct led_classdev *led_cdev, \ |
enum led_brightness value); \ | enum led_brightness value); \ |
|
static void object##_led_update(struct work_struct *ignored); \ |
static int object##_led_wk; \ | static int object##_led_wk; \ |
static void object##_led_update(struct work_struct *dummy); \ |
static DECLARE_WORK(object##_led_work, object##_led_update); \ |
static DECLARE_WORK(object##_led_work, object##_led_update); \ |
|
static struct led_classdev object##_led = { \ | static struct led_classdev object##_led = { \ |
.name = "asus:" ledname, \ | .name = "asus:" ledname, \ |
.brightness_set = object##_led_set, \ | .brightness_set = object##_led_set, \ |
|
|
out = !out & 0x1; | out = !out & 0x1; |
break; | break; |
case GLED_ON: | case GLED_ON: |
out += 1; |
out = (out & 0x1) + 1; |
break; | break; |
case GPS_ON: | case GPS_ON: |
handle = (out) ? gps_on_handle : gps_off_handle; | handle = (out) ? gps_on_handle : gps_off_handle; |
|
|
object##_led_wk = value; \ | object##_led_wk = value; \ |
queue_work(led_workqueue, &object##_led_work); \ | queue_work(led_workqueue, &object##_led_work); \ |
} \ | } \ |
static void object##_led_update(struct work_struct *dummy) \ |
static void object##_led_update(struct work_struct *ignored) \ |
{ \ | { \ |
int value = object##_led_wk; \ | int value = object##_led_wk; \ |
write_status(object##_set_handle, value, (mask)); \ | write_status(object##_set_handle, value, (mask)); \ |
|
|
struct backlight_device *bd = asus_backlight_device; | struct backlight_device *bd = asus_backlight_device; |
| |
if (bd) { | if (bd) { |
down(&bd->sem); |
bd->props.power = blank; |
if (likely(bd->props)) { |
backlight_update_status(bd); |
bd->props->power = blank; |
|
if (likely(bd->props->update_status)) |
|
bd->props->update_status(bd); |
|
} |
|
up(&bd->sem); |
|
} | } |
} | } |
| |
|
|
static int update_bl_status(struct backlight_device *bd) | static int update_bl_status(struct backlight_device *bd) |
{ | { |
int rv; | int rv; |
int value = bd->props->brightness; |
int value = bd->props.brightness; |
| |
rv = set_brightness(bd, value); | rv = set_brightness(bd, value); |
if (rv) | if (rv) |
return rv; | return rv; |
| |
value = (bd->props->power == FB_BLANK_UNBLANK) ? 1 : 0; |
value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0; |
return set_lcd_state(value); | return set_lcd_state(value); |
} | } |
| |
|
|
static int asus_hotk_get_info(void) | static int asus_hotk_get_info(void) |
{ | { |
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL }; |
|
union acpi_object *model = NULL; | union acpi_object *model = NULL; |
ulong bsts_result, hwrs_result; | ulong bsts_result, hwrs_result; |
char *string = NULL; | char *string = NULL; |
|
|
* HID), this bit will be moved. A global variable asus_info contains | * HID), this bit will be moved. A global variable asus_info contains |
* the DSDT header. | * the DSDT header. |
*/ | */ |
status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt); |
status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); |
if (ACPI_FAILURE(status)) | if (ACPI_FAILURE(status)) |
printk(ASUS_WARNING "Couldn't get the DSDT table header\n"); | printk(ASUS_WARNING "Couldn't get the DSDT table header\n"); |
else |
|
asus_info = dsdt.pointer; |
|
| |
/* We have to write 0 on init this far for all ASUS models */ | /* We have to write 0 on init this far for all ASUS models */ |
if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { | if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { |
|
|
sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); | sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); |
platform_device_unregister(asuspf_device); | platform_device_unregister(asuspf_device); |
platform_driver_unregister(&asuspf_driver); | platform_driver_unregister(&asuspf_driver); |
|
|
kfree(asus_info); |
|
} | } |
| |
static int asus_backlight_init(struct device *dev) | static int asus_backlight_init(struct device *dev) |
|
|
| |
if (brightness_set_handle && lcd_switch_handle) { | if (brightness_set_handle && lcd_switch_handle) { |
bd = backlight_device_register(ASUS_HOTK_FILE, dev, | bd = backlight_device_register(ASUS_HOTK_FILE, dev, |
NULL, &asusbl_data); |
NULL, &asusbl_ops); |
| |
if (IS_ERR(bd)) { | if (IS_ERR(bd)) { |
printk(ASUS_ERR | printk(ASUS_ERR |
|
|
| |
asus_backlight_device = bd; | asus_backlight_device = bd; |
| |
down(&bd->sem); |
bd->props.max_brightness = 15; |
if (likely(bd->props)) { |
bd->props.brightness = read_brightness(NULL); |
bd->props->brightness = read_brightness(NULL); |
bd->props.power = FB_BLANK_UNBLANK; |
bd->props->power = FB_BLANK_UNBLANK; |
backlight_update_status(bd); |
if (likely(bd->props->update_status)) |
|
bd->props->update_status(bd); |
|
} |
|
up(&bd->sem); |
|
} | } |
return 0; | return 0; |
} | } |