26 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28 #include <linux/kernel.h>
29 #include <linux/module.h>
31 #include <linux/slab.h>
32 #include <linux/types.h>
33 #include <linux/input.h>
37 #include <linux/string.h>
44 #define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
46 static int acpi_video;
56 static const struct key_entry dell_wmi_legacy_keymap[]
__initconst = {
108 static bool dell_new_hk_type;
133 KEY_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
140 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
146 static struct input_dev *dell_wmi_input_dev;
155 if (status !=
AE_OK) {
156 pr_info(
"bad event status 0x%x\n", status);
163 const struct key_entry *
key;
167 if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
168 pr_info(
"Received unknown WMI event (0x%x)\n",
174 if (dell_new_hk_type || buffer_entry[1] == 0x0)
175 reported_key = (
int)buffer_entry[2];
177 reported_key = (
int)buffer_entry[1] & 0xffff;
179 key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev,
182 pr_info(
"Unknown key %x pressed\n", reported_key);
189 sparse_keymap_report_entry(dell_wmi_input_dev, key,
196 static const struct key_entry *
__init dell_wmi_prepare_new_keymap(
void)
198 int hotkey_num = (dell_bios_hotkey_table->
header.length - 4) /
200 struct key_entry *keymap;
203 keymap = kcalloc(hotkey_num + 1,
sizeof(
struct key_entry),
GFP_KERNEL);
207 for (i = 0; i < hotkey_num; i++) {
209 &dell_bios_hotkey_table->
keymap[
i];
212 keymap[
i].keycode = bios_entry->
keycode < 256 ?
213 bios_to_linux_keycode[bios_entry->
keycode] :
217 keymap[hotkey_num].type =
KE_END;
222 static int __init dell_wmi_input_setup(
void)
226 dell_wmi_input_dev = input_allocate_device();
227 if (!dell_wmi_input_dev)
230 dell_wmi_input_dev->name =
"Dell WMI hotkeys";
231 dell_wmi_input_dev->phys =
"wmi/input0";
232 dell_wmi_input_dev->id.bustype =
BUS_HOST;
234 if (dell_new_hk_type) {
235 const struct key_entry *keymap = dell_wmi_prepare_new_keymap();
241 err = sparse_keymap_setup(dell_wmi_input_dev, keymap,
NULL);
249 err = sparse_keymap_setup(dell_wmi_input_dev,
250 dell_wmi_legacy_keymap,
NULL);
255 err = input_register_device(dell_wmi_input_dev);
257 goto err_free_keymap;
262 sparse_keymap_free(dell_wmi_input_dev);
264 input_free_device(dell_wmi_input_dev);
268 static void dell_wmi_input_destroy(
void)
270 sparse_keymap_free(dell_wmi_input_dev);
271 input_unregister_device(dell_wmi_input_dev);
277 dell_new_hk_type =
true;
278 dell_bios_hotkey_table =
283 static int __init dell_wmi_init(
void)
289 pr_warn(
"No known WMI GUID found\n");
296 err = dell_wmi_input_setup();
301 dell_wmi_notify,
NULL);
303 dell_wmi_input_destroy();
304 pr_err(
"Unable to register notify handler - %d\n", status);
312 static void __exit dell_wmi_exit(
void)
315 dell_wmi_input_destroy();