Commit 3093ced2 authored by Guillaume Douézan-Grard's avatar Guillaume Douézan-Grard Committed by Andy Shevchenko

platform/x86: topstar-laptop: split ACPI events and input handling

* get the `acpi_device` from the `topstar_laptop` struct,

* split input registering and `sparse_keymap` events from ACPI events
handling,

* use notify, init and exit functions for ACPI and input handling
Signed-off-by: default avatarGuillaume Douézan-Grard <gdouezangrard@gmail.com>
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
parent 66aa0d60
...@@ -24,9 +24,14 @@ ...@@ -24,9 +24,14 @@
#define TOPSTAR_LAPTOP_CLASS "topstar" #define TOPSTAR_LAPTOP_CLASS "topstar"
struct topstar_laptop { struct topstar_laptop {
struct acpi_device *device;
struct input_dev *input; struct input_dev *input;
}; };
/*
* Input
*/
static const struct key_entry topstar_keymap[] = { static const struct key_entry topstar_keymap[] = {
{ KE_KEY, 0x80, { KEY_BRIGHTNESSUP } }, { KE_KEY, 0x80, { KEY_BRIGHTNESSUP } },
{ KE_KEY, 0x81, { KEY_BRIGHTNESSDOWN } }, { KE_KEY, 0x81, { KEY_BRIGHTNESSDOWN } },
...@@ -57,40 +62,12 @@ static const struct key_entry topstar_keymap[] = { ...@@ -57,40 +62,12 @@ static const struct key_entry topstar_keymap[] = {
{ KE_END, 0 } { KE_END, 0 }
}; };
static void topstar_acpi_notify(struct acpi_device *device, u32 event) static void topstar_input_notify(struct topstar_laptop *topstar, int event)
{ {
static bool dup_evnt[2];
bool *dup;
struct topstar_laptop *topstar = acpi_driver_data(device);
/* 0x83 and 0x84 key events comes duplicated... */
if (event == 0x83 || event == 0x84) {
dup = &dup_evnt[event - 0x83];
if (*dup) {
*dup = false;
return;
}
*dup = true;
}
if (!sparse_keymap_report_event(topstar->input, event, 1, true)) if (!sparse_keymap_report_event(topstar->input, event, 1, true))
pr_info("unknown event = 0x%02x\n", event); pr_info("unknown event = 0x%02x\n", event);
} }
static int topstar_acpi_fncx_switch(struct acpi_device *device, bool state)
{
acpi_status status;
status = acpi_execute_simple_method(device->handle, "FNCX",
state ? 0x86 : 0x87);
if (ACPI_FAILURE(status)) {
pr_err("Unable to switch FNCX notifications\n");
return -ENODEV;
}
return 0;
}
static int topstar_input_init(struct topstar_laptop *topstar) static int topstar_input_init(struct topstar_laptop *topstar)
{ {
struct input_dev *input; struct input_dev *input;
...@@ -124,9 +101,62 @@ static int topstar_input_init(struct topstar_laptop *topstar) ...@@ -124,9 +101,62 @@ static int topstar_input_init(struct topstar_laptop *topstar)
return err; return err;
} }
static void topstar_input_exit(struct topstar_laptop *topstar)
{
input_unregister_device(topstar->input);
}
/*
* ACPI
*/
static int topstar_acpi_fncx_switch(struct acpi_device *device, bool state)
{
acpi_status status;
u64 arg = state ? 0x86 : 0x87;
status = acpi_execute_simple_method(device->handle, "FNCX", arg);
if (ACPI_FAILURE(status)) {
pr_err("Unable to switch FNCX notifications\n");
return -ENODEV;
}
return 0;
}
static void topstar_acpi_notify(struct acpi_device *device, u32 event)
{
struct topstar_laptop *topstar = acpi_driver_data(device);
static bool dup_evnt[2];
bool *dup;
/* 0x83 and 0x84 key events comes duplicated... */
if (event == 0x83 || event == 0x84) {
dup = &dup_evnt[event - 0x83];
if (*dup) {
*dup = false;
return;
}
*dup = true;
}
topstar_input_notify(topstar, event);
}
static int topstar_acpi_init(struct topstar_laptop *topstar)
{
return topstar_acpi_fncx_switch(topstar->device, true);
}
static void topstar_acpi_exit(struct topstar_laptop *topstar)
{
topstar_acpi_fncx_switch(topstar->device, false);
}
static int topstar_acpi_add(struct acpi_device *device) static int topstar_acpi_add(struct acpi_device *device)
{ {
struct topstar_laptop *topstar; struct topstar_laptop *topstar;
int err;
topstar = kzalloc(sizeof(struct topstar_laptop), GFP_KERNEL); topstar = kzalloc(sizeof(struct topstar_laptop), GFP_KERNEL);
if (!topstar) if (!topstar)
...@@ -134,30 +164,34 @@ static int topstar_acpi_add(struct acpi_device *device) ...@@ -134,30 +164,34 @@ static int topstar_acpi_add(struct acpi_device *device)
strcpy(acpi_device_name(device), "Topstar TPSACPI"); strcpy(acpi_device_name(device), "Topstar TPSACPI");
strcpy(acpi_device_class(device), TOPSTAR_LAPTOP_CLASS); strcpy(acpi_device_class(device), TOPSTAR_LAPTOP_CLASS);
device->driver_data = topstar;
topstar->device = device;
if (topstar_acpi_fncx_switch(device, true)) err = topstar_acpi_init(topstar);
if (err)
goto err_free; goto err_free;
if (topstar_input_init(topstar)) err = topstar_input_init(topstar);
goto err_free; if (err)
goto err_acpi_exit;
device->driver_data = topstar;
return 0; return 0;
err_acpi_exit:
topstar_acpi_exit(topstar);
err_free: err_free:
kfree(topstar); kfree(topstar);
return -ENODEV; return err;
} }
static int topstar_acpi_remove(struct acpi_device *device) static int topstar_acpi_remove(struct acpi_device *device)
{ {
struct topstar_laptop *topstar = acpi_driver_data(device); struct topstar_laptop *topstar = acpi_driver_data(device);
topstar_acpi_fncx_switch(device, false); topstar_input_exit(topstar);
topstar_acpi_exit(topstar);
input_unregister_device(topstar->input);
kfree(topstar); kfree(topstar);
return 0; return 0;
} }
...@@ -188,7 +222,6 @@ static int __init topstar_laptop_init(void) ...@@ -188,7 +222,6 @@ static int __init topstar_laptop_init(void)
return ret; return ret;
pr_info("ACPI extras driver loaded\n"); pr_info("ACPI extras driver loaded\n");
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment