hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/hid/hid-cougar.c
....@@ -7,6 +7,7 @@
77
88 #include <linux/hid.h>
99 #include <linux/module.h>
10
+#include <linux/printk.h>
1011
1112 #include "hid-ids.h"
1213
....@@ -15,11 +16,9 @@
1516 MODULE_LICENSE("GPL");
1617 MODULE_INFO(key_mappings, "G1-G6 are mapped to F13-F18");
1718
18
-static int cougar_g6_is_space = 1;
19
-module_param_named(g6_is_space, cougar_g6_is_space, int, 0600);
19
+static bool g6_is_space = true;
2020 MODULE_PARM_DESC(g6_is_space,
21
- "If set, G6 programmable key sends SPACE instead of F18 (0=off, 1=on) (default=1)");
22
-
21
+ "If true, G6 programmable key sends SPACE instead of F18 (default=true)");
2322
2423 #define COUGAR_VENDOR_USAGE 0xff00ff00
2524
....@@ -82,20 +81,23 @@
8281 static LIST_HEAD(cougar_udev_list);
8382 static DEFINE_MUTEX(cougar_udev_list_lock);
8483
85
-static void cougar_fix_g6_mapping(struct hid_device *hdev)
84
+/**
85
+ * cougar_fix_g6_mapping - configure the mapping for key G6/Spacebar
86
+ */
87
+static void cougar_fix_g6_mapping(void)
8688 {
8789 int i;
8890
8991 for (i = 0; cougar_mapping[i][0]; i++) {
9092 if (cougar_mapping[i][0] == COUGAR_KEY_G6) {
9193 cougar_mapping[i][1] =
92
- cougar_g6_is_space ? KEY_SPACE : KEY_F18;
93
- hid_info(hdev, "G6 mapped to %s\n",
94
- cougar_g6_is_space ? "space" : "F18");
94
+ g6_is_space ? KEY_SPACE : KEY_F18;
95
+ pr_info("cougar: G6 mapped to %s\n",
96
+ g6_is_space ? "space" : "F18");
9597 return;
9698 }
9799 }
98
- hid_warn(hdev, "no mapping defined for G6/spacebar");
100
+ pr_warn("cougar: no mappings defined for G6/spacebar");
99101 }
100102
101103 /*
....@@ -154,7 +156,8 @@
154156 * Bind the device group's shared data to this cougar struct.
155157 * If no shared data exists for this group, create and initialize it.
156158 */
157
-static int cougar_bind_shared_data(struct hid_device *hdev, struct cougar *cougar)
159
+static int cougar_bind_shared_data(struct hid_device *hdev,
160
+ struct cougar *cougar)
158161 {
159162 struct cougar_shared *shared;
160163 int error = 0;
....@@ -204,7 +207,7 @@
204207 error = hid_parse(hdev);
205208 if (error) {
206209 hid_err(hdev, "parse failed\n");
207
- goto fail;
210
+ return error;
208211 }
209212
210213 if (hdev->collection->usage == COUGAR_VENDOR_USAGE) {
....@@ -216,7 +219,7 @@
216219 error = hid_hw_start(hdev, connect_mask);
217220 if (error) {
218221 hid_err(hdev, "hw start failed\n");
219
- goto fail;
222
+ return error;
220223 }
221224
222225 error = cougar_bind_shared_data(hdev, cougar);
....@@ -228,7 +231,6 @@
228231 * to it.
229232 */
230233 if (hdev->collection->usage == HID_GD_KEYBOARD) {
231
- cougar_fix_g6_mapping(hdev);
232234 list_for_each_entry_safe(hidinput, next, &hdev->inputs, list) {
233235 if (hidinput->registered && hidinput->input != NULL) {
234236 cougar->shared->input = hidinput->input;
....@@ -237,6 +239,8 @@
237239 }
238240 }
239241 } else if (hdev->collection->usage == COUGAR_VENDOR_USAGE) {
242
+ /* Preinit the mapping table */
243
+ cougar_fix_g6_mapping();
240244 error = hid_hw_open(hdev);
241245 if (error)
242246 goto fail_stop_and_cleanup;
....@@ -245,8 +249,6 @@
245249
246250 fail_stop_and_cleanup:
247251 hid_hw_stop(hdev);
248
-fail:
249
- hid_set_drvdata(hdev, NULL);
250252 return error;
251253 }
252254
....@@ -257,26 +259,32 @@
257259 u8 *data, int size)
258260 {
259261 struct cougar *cougar;
262
+ struct cougar_shared *shared;
260263 unsigned char code, action;
261264 int i;
262265
263266 cougar = hid_get_drvdata(hdev);
264
- if (!cougar->special_intf || !cougar->shared ||
265
- !cougar->shared->input || !cougar->shared->enabled)
267
+ shared = cougar->shared;
268
+ if (!cougar->special_intf || !shared)
266269 return 0;
270
+
271
+ if (!shared->enabled || !shared->input)
272
+ return -EPERM;
267273
268274 code = data[COUGAR_FIELD_CODE];
269275 action = data[COUGAR_FIELD_ACTION];
270276 for (i = 0; cougar_mapping[i][0]; i++) {
271277 if (code == cougar_mapping[i][0]) {
272
- input_event(cougar->shared->input, EV_KEY,
278
+ input_event(shared->input, EV_KEY,
273279 cougar_mapping[i][1], action);
274
- input_sync(cougar->shared->input);
275
- return 0;
280
+ input_sync(shared->input);
281
+ return -EPERM;
276282 }
277283 }
278
- hid_warn(hdev, "unmapped special key code %x: ignoring\n", code);
279
- return 0;
284
+ /* Avoid warnings on the same unmapped key twice */
285
+ if (action != 0)
286
+ hid_warn(hdev, "unmapped special key code %0x: ignoring\n", code);
287
+ return -EPERM;
280288 }
281289
282290 static void cougar_remove(struct hid_device *hdev)
....@@ -293,9 +301,31 @@
293301 hid_hw_stop(hdev);
294302 }
295303
296
-static struct hid_device_id cougar_id_table[] = {
304
+static int cougar_param_set_g6_is_space(const char *val,
305
+ const struct kernel_param *kp)
306
+{
307
+ int ret;
308
+
309
+ ret = param_set_bool(val, kp);
310
+ if (ret)
311
+ return ret;
312
+
313
+ cougar_fix_g6_mapping();
314
+
315
+ return 0;
316
+}
317
+
318
+static const struct kernel_param_ops cougar_g6_is_space_ops = {
319
+ .set = cougar_param_set_g6_is_space,
320
+ .get = param_get_bool,
321
+};
322
+module_param_cb(g6_is_space, &cougar_g6_is_space_ops, &g6_is_space, 0644);
323
+
324
+static const struct hid_device_id cougar_id_table[] = {
297325 { HID_USB_DEVICE(USB_VENDOR_ID_SOLID_YEAR,
298326 USB_DEVICE_ID_COUGAR_500K_GAMING_KEYBOARD) },
327
+ { HID_USB_DEVICE(USB_VENDOR_ID_SOLID_YEAR,
328
+ USB_DEVICE_ID_COUGAR_700K_GAMING_KEYBOARD) },
299329 {}
300330 };
301331 MODULE_DEVICE_TABLE(hid, cougar_id_table);