]>
Commit | Line | Data |
---|---|---|
c942fddf | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
14991fc7 AA |
2 | /* |
3 | * toshiba_wmi.c - Toshiba WMI Hotkey Driver | |
4 | * | |
5 | * Copyright (C) 2015 Azael Avalos <coproscefalo@gmail.com> | |
14991fc7 AA |
6 | */ |
7 | ||
8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
9 | ||
10 | #include <linux/kernel.h> | |
11 | #include <linux/module.h> | |
12 | #include <linux/init.h> | |
13 | #include <linux/types.h> | |
14 | #include <linux/acpi.h> | |
15 | #include <linux/input.h> | |
16 | #include <linux/input/sparse-keymap.h> | |
1c80e960 | 17 | #include <linux/dmi.h> |
14991fc7 AA |
18 | |
19 | MODULE_AUTHOR("Azael Avalos"); | |
20 | MODULE_DESCRIPTION("Toshiba WMI Hotkey Driver"); | |
21 | MODULE_LICENSE("GPL"); | |
22 | ||
1c80e960 | 23 | #define WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100" |
14991fc7 | 24 | |
1c80e960 | 25 | MODULE_ALIAS("wmi:"WMI_EVENT_GUID); |
14991fc7 AA |
26 | |
27 | static struct input_dev *toshiba_wmi_input_dev; | |
28 | ||
29 | static const struct key_entry toshiba_wmi_keymap[] __initconst = { | |
30 | /* TODO: Add keymap values once found... */ | |
31 | /*{ KE_KEY, 0x00, { KEY_ } },*/ | |
32 | { KE_END, 0 } | |
33 | }; | |
34 | ||
35 | static void toshiba_wmi_notify(u32 value, void *context) | |
36 | { | |
37 | struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; | |
38 | union acpi_object *obj; | |
39 | acpi_status status; | |
40 | ||
41 | status = wmi_get_event_data(value, &response); | |
42 | if (ACPI_FAILURE(status)) { | |
43 | pr_err("Bad event status 0x%x\n", status); | |
44 | return; | |
45 | } | |
46 | ||
47 | obj = (union acpi_object *)response.pointer; | |
48 | if (!obj) | |
49 | return; | |
50 | ||
51 | /* TODO: Add proper checks once we have data */ | |
52 | pr_debug("Unknown event received, obj type %x\n", obj->type); | |
53 | ||
54 | kfree(response.pointer); | |
55 | } | |
56 | ||
6faadbbb | 57 | static const struct dmi_system_id toshiba_wmi_dmi_table[] __initconst = { |
1c80e960 AA |
58 | { |
59 | .ident = "Toshiba laptop", | |
60 | .matches = { | |
61 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | |
62 | }, | |
63 | }, | |
64 | {} | |
65 | }; | |
66 | ||
14991fc7 AA |
67 | static int __init toshiba_wmi_input_setup(void) |
68 | { | |
69 | acpi_status status; | |
70 | int err; | |
71 | ||
72 | toshiba_wmi_input_dev = input_allocate_device(); | |
73 | if (!toshiba_wmi_input_dev) | |
74 | return -ENOMEM; | |
75 | ||
76 | toshiba_wmi_input_dev->name = "Toshiba WMI hotkeys"; | |
77 | toshiba_wmi_input_dev->phys = "wmi/input0"; | |
78 | toshiba_wmi_input_dev->id.bustype = BUS_HOST; | |
79 | ||
80 | err = sparse_keymap_setup(toshiba_wmi_input_dev, | |
81 | toshiba_wmi_keymap, NULL); | |
82 | if (err) | |
83 | goto err_free_dev; | |
84 | ||
1c80e960 | 85 | status = wmi_install_notify_handler(WMI_EVENT_GUID, |
14991fc7 AA |
86 | toshiba_wmi_notify, NULL); |
87 | if (ACPI_FAILURE(status)) { | |
88 | err = -EIO; | |
c6d973f4 | 89 | goto err_free_dev; |
14991fc7 AA |
90 | } |
91 | ||
92 | err = input_register_device(toshiba_wmi_input_dev); | |
93 | if (err) | |
94 | goto err_remove_notifier; | |
95 | ||
96 | return 0; | |
97 | ||
98 | err_remove_notifier: | |
1c80e960 | 99 | wmi_remove_notify_handler(WMI_EVENT_GUID); |
14991fc7 AA |
100 | err_free_dev: |
101 | input_free_device(toshiba_wmi_input_dev); | |
102 | return err; | |
103 | } | |
104 | ||
105 | static void toshiba_wmi_input_destroy(void) | |
106 | { | |
1c80e960 | 107 | wmi_remove_notify_handler(WMI_EVENT_GUID); |
14991fc7 AA |
108 | input_unregister_device(toshiba_wmi_input_dev); |
109 | } | |
110 | ||
111 | static int __init toshiba_wmi_init(void) | |
112 | { | |
113 | int ret; | |
114 | ||
1c80e960 AA |
115 | if (!wmi_has_guid(WMI_EVENT_GUID) || |
116 | !dmi_check_system(toshiba_wmi_dmi_table)) | |
14991fc7 AA |
117 | return -ENODEV; |
118 | ||
119 | ret = toshiba_wmi_input_setup(); | |
120 | if (ret) { | |
121 | pr_err("Failed to setup input device\n"); | |
122 | return ret; | |
123 | } | |
124 | ||
125 | pr_info("Toshiba WMI Hotkey Driver\n"); | |
126 | ||
127 | return 0; | |
128 | } | |
129 | ||
130 | static void __exit toshiba_wmi_exit(void) | |
131 | { | |
1c80e960 | 132 | if (wmi_has_guid(WMI_EVENT_GUID)) |
14991fc7 AA |
133 | toshiba_wmi_input_destroy(); |
134 | } | |
135 | ||
136 | module_init(toshiba_wmi_init); | |
137 | module_exit(toshiba_wmi_exit); |