14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 #include <linux/kernel.h>
17 #include <linux/module.h>
19 #include <linux/slab.h>
21 #include <linux/input.h>
24 #define ACPI_TOPSTAR_CLASS "topstar"
30 static const struct key_entry topstar_keymap[] = {
60 static void acpi_topstar_notify(
struct acpi_device *
device,
u32 event)
62 static bool dup_evnt[2];
67 if (event == 0x83 || event == 0x84) {
68 dup = &dup_evnt[
event - 0x83];
76 if (!sparse_keymap_report_event(hkey->
inputdev, event, 1,
true))
77 pr_info(
"unknown event = 0x%02x\n", event);
80 static int acpi_topstar_fncx_switch(
struct acpi_device *device,
bool state)
88 fncx_params[0].
integer.value = state ? 0x86 : 0x87;
91 pr_err(
"Unable to switch FNCX notifications\n");
98 static int acpi_topstar_init_hkey(
struct topstar_hkey *hkey)
100 struct input_dev *
input;
103 input = input_allocate_device();
105 pr_err(
"Unable to allocate input device\n");
109 input->name =
"Topstar Laptop extra buttons";
110 input->phys =
"topstar/input0";
113 error = sparse_keymap_setup(input, topstar_keymap,
NULL);
115 pr_err(
"Unable to setup input device keymap\n");
119 error = input_register_device(input);
121 pr_err(
"Unable to register input device\n");
122 goto err_free_keymap;
129 sparse_keymap_free(input);
131 input_free_device(input);
135 static int acpi_topstar_add(
struct acpi_device *device)
143 strcpy(acpi_device_name(device),
"Topstar TPSACPI");
146 if (acpi_topstar_fncx_switch(device,
true))
149 if (acpi_topstar_init_hkey(tps_hkey))
152 device->driver_data = tps_hkey;
160 static int acpi_topstar_remove(
struct acpi_device *device,
int type)
162 struct topstar_hkey *tps_hkey = acpi_driver_data(device);
164 acpi_topstar_fncx_switch(device,
false);
166 sparse_keymap_free(tps_hkey->
inputdev);
167 input_unregister_device(tps_hkey->
inputdev);
179 static struct acpi_driver acpi_topstar_driver = {
180 .name =
"Topstar laptop ACPI driver",
182 .ids = topstar_device_ids,
184 .add = acpi_topstar_add,
185 .remove = acpi_topstar_remove,
186 .notify = acpi_topstar_notify,