asus-laptop: code movement

The asus-laptop driver implements a number of interfaces like the
backlight class driver.  This change makes it easier to examine the
implementation of one interface at at a time, without having to search
through the file to find init() and exit() functions etc.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
This commit is contained in:
Corentin Chary 2009-12-06 16:27:09 +01:00
parent 9129d14d29
commit be4ee82d3e
1 changed files with 223 additions and 217 deletions

View File

@ -58,36 +58,6 @@
#define ASUS_LAPTOP_FILE KBUILD_MODNAME
#define ASUS_LAPTOP_PREFIX "\\_SB.ATKD."
/*
* Some events we use, same for all Asus
*/
#define ATKD_BR_UP 0x10
#define ATKD_BR_DOWN 0x20
#define ATKD_LCD_ON 0x33
#define ATKD_LCD_OFF 0x34
/*
* Known bits returned by \_SB.ATKD.HWRS
*/
#define WL_HWRS 0x80
#define BT_HWRS 0x100
/*
* Flags for hotk status
* WL_ON and BT_ON are also used for wireless_status()
*/
#define WL_ON 0x01 /* internal Wifi */
#define BT_ON 0x02 /* internal Bluetooth */
#define MLED_ON 0x04 /* mail LED */
#define TLED_ON 0x08 /* touchpad LED */
#define RLED_ON 0x10 /* Record LED */
#define PLED_ON 0x20 /* Phone LED */
#define GLED_ON 0x40 /* Gaming LED */
#define LCD_ON 0x80 /* LCD backlight */
#define GPS_ON 0x100 /* GPS */
#define KEY_ON 0x200 /* Keyboard backlight */
MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary");
MODULE_DESCRIPTION(ASUS_LAPTOP_NAME);
MODULE_LICENSE("GPL");
@ -119,6 +89,35 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
"(0 = disabled, 1 = enabled, -1 = don't do anything). "
"default is 1");
/*
* Some events we use, same for all Asus
*/
#define ATKD_BR_UP 0x10
#define ATKD_BR_DOWN 0x20
#define ATKD_LCD_ON 0x33
#define ATKD_LCD_OFF 0x34
/*
* Known bits returned by \_SB.ATKD.HWRS
*/
#define WL_HWRS 0x80
#define BT_HWRS 0x100
/*
* Flags for hotk status
* WL_ON and BT_ON are also used for wireless_status()
*/
#define WL_ON 0x01 /* internal Wifi */
#define BT_ON 0x02 /* internal Bluetooth */
#define MLED_ON 0x04 /* mail LED */
#define TLED_ON 0x08 /* touchpad LED */
#define RLED_ON 0x10 /* Record LED */
#define PLED_ON 0x20 /* Phone LED */
#define GLED_ON 0x40 /* Gaming LED */
#define LCD_ON 0x80 /* LCD backlight */
#define GPS_ON 0x100 /* GPS */
#define KEY_ON 0x200 /* Keyboard backlight */
#define ASUS_HANDLE(object, paths...) \
static acpi_handle object##_handle = NULL; \
static char *object##_paths[] = { paths }
@ -249,36 +248,6 @@ struct asus_laptop {
u16 *keycode_map;
};
/*
* The backlight class declaration
*/
static int read_brightness(struct backlight_device *bd);
static int update_bl_status(struct backlight_device *bd);
static struct backlight_ops asusbl_ops = {
.get_brightness = read_brightness,
.update_status = update_bl_status,
};
#define ASUS_LED(object, ledname, max) \
static void object##_led_set(struct led_classdev *led_cdev, \
enum led_brightness value); \
static enum led_brightness object##_led_get( \
struct led_classdev *led_cdev); \
static void object##_led_update(struct work_struct *ignored); \
static struct led_classdev object##_led = { \
.name = "asus::" ledname, \
.brightness_set = object##_led_set, \
.brightness_get = object##_led_get, \
.max_brightness = max \
}
ASUS_LED(mled, "mail", 1);
ASUS_LED(tled, "touchpad", 1);
ASUS_LED(rled, "record", 1);
ASUS_LED(pled, "phone", 1);
ASUS_LED(gled, "gaming", 1);
ASUS_LED(kled, "kbd_backlight", 3);
struct key_entry {
char type;
u8 code;
@ -427,6 +396,29 @@ static void write_status(struct asus_laptop *asus, acpi_handle handle,
pr_warning(" write failed %x\n", mask);
}
/*
* LEDs
*/
#define ASUS_LED(object, ledname, max) \
static void object##_led_set(struct led_classdev *led_cdev, \
enum led_brightness value); \
static enum led_brightness object##_led_get( \
struct led_classdev *led_cdev); \
static void object##_led_update(struct work_struct *ignored); \
static struct led_classdev object##_led = { \
.name = "asus::" ledname, \
.brightness_set = object##_led_set, \
.brightness_get = object##_led_get, \
.max_brightness = max \
}
ASUS_LED(mled, "mail", 1);
ASUS_LED(tled, "touchpad", 1);
ASUS_LED(rled, "record", 1);
ASUS_LED(pled, "phone", 1);
ASUS_LED(gled, "gaming", 1);
ASUS_LED(kled, "kbd_backlight", 3);
/* /sys/class/led handlers */
#define ASUS_LED_HANDLER(object, mask) \
static void object##_led_set(struct led_classdev *led_cdev, \
@ -459,7 +451,7 @@ ASUS_LED_HANDLER(tled, TLED_ON);
ASUS_LED_HANDLER(gled, GLED_ON);
/*
* Keyboard backlight
* Keyboard backlight (also a LED)
*/
static int get_kled_lvl(void)
{
@ -516,6 +508,70 @@ static enum led_brightness kled_led_get(struct led_classdev *led_cdev)
return get_kled_lvl();
}
#define ASUS_LED_UNREGISTER(object) \
if (object##_led.dev) \
led_classdev_unregister(&object##_led)
static void asus_led_exit(struct asus_laptop *asus)
{
ASUS_LED_UNREGISTER(mled);
ASUS_LED_UNREGISTER(tled);
ASUS_LED_UNREGISTER(pled);
ASUS_LED_UNREGISTER(rled);
ASUS_LED_UNREGISTER(gled);
ASUS_LED_UNREGISTER(kled);
if (asus->leds.workqueue) {
destroy_workqueue(asus->leds.workqueue);
asus->leds.workqueue = NULL;
}
}
/* Ugly macro, need to fix that later */
#define ASUS_LED_REGISTER(asus, object, _name, max) \
do { \
struct led_classdev *ldev = &asus->leds.object; \
if (!object##_set_handle) \
break ; \
\
INIT_WORK(&asus->leds.object##_work, object##_led_update); \
ldev->name = "asus::" _name; \
ldev->brightness_set = object##_led_set; \
ldev->max_brightness = max; \
rv = led_classdev_register(&asus->platform_device->dev, ldev); \
if (rv) \
goto error; \
} while (0)
static int asus_led_init(struct asus_laptop *asus)
{
int rv;
/*
* 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->leds.workqueue = create_singlethread_workqueue("led_workqueue");
if (!asus->leds.workqueue)
return -ENOMEM;
ASUS_LED_REGISTER(asus, mled, "mail", 1);
ASUS_LED_REGISTER(asus, tled, "touchpad", 1);
ASUS_LED_REGISTER(asus, rled, "record", 1);
ASUS_LED_REGISTER(asus, pled, "phone", 1);
ASUS_LED_REGISTER(asus, gled, "gaming", 1);
if (kled_set_handle && kled_get_handle)
ASUS_LED_REGISTER(asus, kled, "kbd_backlight", 3);
error:
if (rv)
asus_led_exit(asus);
return rv;
}
/*
* Backlight device
*/
static int get_lcd_state(struct asus_laptop *asus)
{
return read_status(asus, LCD_ON);
@ -588,6 +644,41 @@ static int update_bl_status(struct backlight_device *bd)
return set_lcd_state(asus, value);
}
static struct backlight_ops asusbl_ops = {
.get_brightness = read_brightness,
.update_status = update_bl_status,
};
static int asus_backlight_init(struct asus_laptop *asus)
{
struct backlight_device *bd;
struct device *dev = &asus->platform_device->dev;
if (brightness_set_handle && lcd_switch_handle) {
bd = backlight_device_register(ASUS_LAPTOP_FILE, dev,
asus, &asusbl_ops);
if (IS_ERR(bd)) {
pr_err("Could not register asus backlight device\n");
asus->backlight_device = NULL;
return PTR_ERR(bd);
}
asus->backlight_device = bd;
bd->props.max_brightness = 15;
bd->props.brightness = read_brightness(NULL);
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
}
return 0;
}
static void asus_backlight_exit(struct asus_laptop *asus)
{
if (asus->backlight_device)
backlight_device_unregister(asus->backlight_device);
}
/*
* Platform device handlers
*/
@ -904,7 +995,7 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr,
}
/*
* Hotkey functions
* Input device (i.e. hotkeys)
*/
static struct key_entry *asus_get_entry_by_scancode(struct asus_laptop *asus,
int code)
@ -965,10 +1056,72 @@ static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
return -EINVAL;
}
static void asus_input_notify(struct asus_laptop *asus, int event)
{
struct key_entry *key;
key = asus_get_entry_by_scancode(asus, event);
if (!key)
return ;
switch (key->type) {
case KE_KEY:
input_report_key(asus->inputdev, key->keycode, 1);
input_sync(asus->inputdev);
input_report_key(asus->inputdev, key->keycode, 0);
input_sync(asus->inputdev);
break;
}
}
static int asus_input_init(struct asus_laptop *asus)
{
const struct key_entry *key;
int result;
asus->inputdev = input_allocate_device();
if (!asus->inputdev) {
pr_info("Unable to allocate input device\n");
return 0;
}
asus->inputdev->name = "Asus Laptop extra buttons";
asus->inputdev->dev.parent = &asus->platform_device->dev;
asus->inputdev->phys = ASUS_LAPTOP_FILE "/input0";
asus->inputdev->id.bustype = BUS_HOST;
asus->inputdev->getkeycode = asus_getkeycode;
asus->inputdev->setkeycode = asus_setkeycode;
input_set_drvdata(asus->inputdev, asus);
asus->keymap = kmemdup(asus_keymap, sizeof(asus_keymap),
GFP_KERNEL);
for (key = asus->keymap; key->type != KE_END; key++) {
switch (key->type) {
case KE_KEY:
set_bit(EV_KEY, asus->inputdev->evbit);
set_bit(key->keycode, asus->inputdev->keybit);
break;
}
}
result = input_register_device(asus->inputdev);
if (result) {
pr_info("Unable to register input device\n");
input_free_device(asus->inputdev);
}
return result;
}
static void asus_input_exit(struct asus_laptop *asus)
{
if (asus->inputdev)
input_unregister_device(asus->inputdev);
}
/*
* ACPI driver
*/
static void asus_acpi_notify(struct acpi_device *device, u32 event)
{
struct asus_laptop *asus = acpi_driver_data(device);
static struct key_entry *key;
u16 count;
/*
@ -990,20 +1143,7 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event)
dev_name(&asus->device->dev), event,
count);
if (asus->inputdev) {
key = asus_get_entry_by_scancode(asus, event);
if (!key)
return ;
switch (key->type) {
case KE_KEY:
input_report_key(asus->inputdev, key->keycode, 1);
input_sync(asus->inputdev);
input_report_key(asus->inputdev, key->keycode, 0);
input_sync(asus->inputdev);
break;
}
}
asus_input_notify(asus, event);
}
#define ASUS_CREATE_DEVICE_ATTR(_name) \
@ -1257,142 +1397,6 @@ static int asus_laptop_get_info(struct asus_laptop *asus)
return AE_OK;
}
static int asus_input_init(struct asus_laptop *asus)
{
const struct key_entry *key;
int result;
asus->inputdev = input_allocate_device();
if (!asus->inputdev) {
pr_info("Unable to allocate input device\n");
return 0;
}
asus->inputdev->name = "Asus Laptop extra buttons";
asus->inputdev->dev.parent = &asus->platform_device->dev;
asus->inputdev->phys = ASUS_LAPTOP_FILE "/input0";
asus->inputdev->id.bustype = BUS_HOST;
asus->inputdev->getkeycode = asus_getkeycode;
asus->inputdev->setkeycode = asus_setkeycode;
input_set_drvdata(asus->inputdev, asus);
asus->keymap = kmemdup(asus_keymap, sizeof(asus_keymap),
GFP_KERNEL);
for (key = asus->keymap; key->type != KE_END; key++) {
switch (key->type) {
case KE_KEY:
set_bit(EV_KEY, asus->inputdev->evbit);
set_bit(key->keycode, asus->inputdev->keybit);
break;
}
}
result = input_register_device(asus->inputdev);
if (result) {
pr_info("Unable to register input device\n");
input_free_device(asus->inputdev);
}
return result;
}
static void asus_backlight_exit(struct asus_laptop *asus)
{
if (asus->backlight_device)
backlight_device_unregister(asus->backlight_device);
}
#define ASUS_LED_UNREGISTER(object) \
if (object##_led.dev) \
led_classdev_unregister(&object##_led)
static void asus_led_exit(struct asus_laptop *asus)
{
ASUS_LED_UNREGISTER(mled);
ASUS_LED_UNREGISTER(tled);
ASUS_LED_UNREGISTER(pled);
ASUS_LED_UNREGISTER(rled);
ASUS_LED_UNREGISTER(gled);
ASUS_LED_UNREGISTER(kled);
if (asus->leds.workqueue) {
destroy_workqueue(asus->leds.workqueue);
asus->leds.workqueue = NULL;
}
}
static void asus_input_exit(struct asus_laptop *asus)
{
if (asus->inputdev)
input_unregister_device(asus->inputdev);
}
static int asus_backlight_init(struct asus_laptop *asus)
{
struct backlight_device *bd;
struct device *dev = &asus->platform_device->dev;
if (brightness_set_handle && lcd_switch_handle) {
bd = backlight_device_register(ASUS_LAPTOP_FILE, dev,
asus, &asusbl_ops);
if (IS_ERR(bd)) {
pr_err("Could not register asus backlight device\n");
asus->backlight_device = NULL;
return PTR_ERR(bd);
}
asus->backlight_device = bd;
bd->props.max_brightness = 15;
bd->props.brightness = read_brightness(NULL);
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
}
return 0;
}
/*
* Ugly macro, need to fix that later
*/
#define ASUS_LED_REGISTER(asus, object, _name, max) \
do { \
struct led_classdev *ldev = &asus->leds.object; \
if (!object##_set_handle) \
break ; \
\
INIT_WORK(&asus->leds.object##_work, object##_led_update); \
ldev->name = "asus::" _name; \
ldev->brightness_set = object##_led_set; \
ldev->max_brightness = max; \
rv = led_classdev_register(&asus->platform_device->dev, ldev); \
if (rv) \
goto error; \
} while (0)
static int asus_led_init(struct asus_laptop *asus)
{
int rv;
/*
* 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->leds.workqueue = create_singlethread_workqueue("led_workqueue");
if (!asus->leds.workqueue)
return -ENOMEM;
ASUS_LED_REGISTER(asus, mled, "mail", 1);
ASUS_LED_REGISTER(asus, tled, "touchpad", 1);
ASUS_LED_REGISTER(asus, rled, "record", 1);
ASUS_LED_REGISTER(asus, pled, "phone", 1);
ASUS_LED_REGISTER(asus, gled, "gaming", 1);
if (kled_set_handle && kled_get_handle)
ASUS_LED_REGISTER(asus, kled, "kbd_backlight", 3);
error:
if (rv)
asus_led_exit(asus);
return rv;
}
static bool asus_device_present;
static int __devinit asus_acpi_init(struct asus_laptop *asus)
@ -1414,8 +1418,10 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
asus_laptop_add_fs(asus);
/* WLED and BLED are on by default */
write_status(asus, bt_switch_handle, 1, BT_ON);
write_status(asus, wl_switch_handle, 1, WL_ON);
if (bluetooth_status >= 0)
write_status(asus, bt_switch_handle, !!bluetooth_status, BT_ON);
if (wireless_status >= 0)
write_status(asus, wl_switch_handle, !!wireless_status, WL_ON);
/* If the h/w switch is off, we need to check the real status */
write_status(asus, NULL, read_status(asus, BT_ON), BT_ON);
@ -1432,8 +1438,8 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
asus->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 */
asus->light_switch = 0; /* Default to light sensor disabled */
asus->light_level = 5; /* level 5 for sensor sensitivity */
if (ls_switch_handle)
set_light_sens_switch(asus, asus->light_switch);