hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/hid/hid-microsoft.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * HID driver for some microsoft "special" devices
34 *
....@@ -9,10 +10,6 @@
910 */
1011
1112 /*
12
- * This program is free software; you can redistribute it and/or modify it
13
- * under the terms of the GNU General Public License as published by the Free
14
- * Software Foundation; either version 2 of the License, or (at your option)
15
- * any later version.
1613 */
1714
1815 #include <linux/device.h>
....@@ -29,11 +26,41 @@
2926 #define MS_NOGET BIT(4)
3027 #define MS_DUPLICATE_USAGES BIT(5)
3128 #define MS_SURFACE_DIAL BIT(6)
29
+#define MS_QUIRK_FF BIT(7)
30
+
31
+struct ms_data {
32
+ unsigned long quirks;
33
+ struct hid_device *hdev;
34
+ struct work_struct ff_worker;
35
+ __u8 strong;
36
+ __u8 weak;
37
+ void *output_report_dmabuf;
38
+};
39
+
40
+#define XB1S_FF_REPORT 3
41
+#define ENABLE_WEAK BIT(0)
42
+#define ENABLE_STRONG BIT(1)
43
+
44
+enum {
45
+ MAGNITUDE_STRONG = 2,
46
+ MAGNITUDE_WEAK,
47
+ MAGNITUDE_NUM
48
+};
49
+
50
+struct xb1s_ff_report {
51
+ __u8 report_id;
52
+ __u8 enable;
53
+ __u8 magnitude[MAGNITUDE_NUM];
54
+ __u8 duration_10ms;
55
+ __u8 start_delay_10ms;
56
+ __u8 loop_count;
57
+} __packed;
3258
3359 static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
3460 unsigned int *rsize)
3561 {
36
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
62
+ struct ms_data *ms = hid_get_drvdata(hdev);
63
+ unsigned long quirks = ms->quirks;
3764
3865 /*
3966 * Microsoft Wireless Desktop Receiver (Model 1028) has
....@@ -136,16 +163,13 @@
136163 {
137164 switch (usage->hid & HID_USAGE_PAGE) {
138165 case 0xff070000:
139
- /* fall-through */
140166 case HID_UP_DIGITIZER:
141167 /* ignore those axis */
142168 return -1;
143169 case HID_UP_GENDESK:
144170 switch (usage->hid) {
145171 case HID_GD_X:
146
- /* fall-through */
147172 case HID_GD_Y:
148
- /* fall-through */
149173 case HID_GD_RFKILL_BTN:
150174 /* ignore those axis */
151175 return -1;
....@@ -159,7 +183,8 @@
159183 struct hid_field *field, struct hid_usage *usage,
160184 unsigned long **bit, int *max)
161185 {
162
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
186
+ struct ms_data *ms = hid_get_drvdata(hdev);
187
+ unsigned long quirks = ms->quirks;
163188
164189 if (quirks & MS_ERGONOMY) {
165190 int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
....@@ -185,7 +210,8 @@
185210 struct hid_field *field, struct hid_usage *usage,
186211 unsigned long **bit, int *max)
187212 {
188
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
213
+ struct ms_data *ms = hid_get_drvdata(hdev);
214
+ unsigned long quirks = ms->quirks;
189215
190216 if (quirks & MS_DUPLICATE_USAGES)
191217 clear_bit(usage->code, *bit);
....@@ -196,7 +222,8 @@
196222 static int ms_event(struct hid_device *hdev, struct hid_field *field,
197223 struct hid_usage *usage, __s32 value)
198224 {
199
- unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
225
+ struct ms_data *ms = hid_get_drvdata(hdev);
226
+ unsigned long quirks = ms->quirks;
200227 struct input_dev *input;
201228
202229 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
....@@ -251,12 +278,103 @@
251278 return 0;
252279 }
253280
281
+static void ms_ff_worker(struct work_struct *work)
282
+{
283
+ struct ms_data *ms = container_of(work, struct ms_data, ff_worker);
284
+ struct hid_device *hdev = ms->hdev;
285
+ struct xb1s_ff_report *r = ms->output_report_dmabuf;
286
+ int ret;
287
+
288
+ memset(r, 0, sizeof(*r));
289
+
290
+ r->report_id = XB1S_FF_REPORT;
291
+ r->enable = ENABLE_WEAK | ENABLE_STRONG;
292
+ /*
293
+ * Specifying maximum duration and maximum loop count should
294
+ * cover maximum duration of a single effect, which is 65536
295
+ * ms
296
+ */
297
+ r->duration_10ms = U8_MAX;
298
+ r->loop_count = U8_MAX;
299
+ r->magnitude[MAGNITUDE_STRONG] = ms->strong; /* left actuator */
300
+ r->magnitude[MAGNITUDE_WEAK] = ms->weak; /* right actuator */
301
+
302
+ ret = hid_hw_output_report(hdev, (__u8 *)r, sizeof(*r));
303
+ if (ret < 0)
304
+ hid_warn(hdev, "failed to send FF report\n");
305
+}
306
+
307
+static int ms_play_effect(struct input_dev *dev, void *data,
308
+ struct ff_effect *effect)
309
+{
310
+ struct hid_device *hid = input_get_drvdata(dev);
311
+ struct ms_data *ms = hid_get_drvdata(hid);
312
+
313
+ if (effect->type != FF_RUMBLE)
314
+ return 0;
315
+
316
+ /*
317
+ * Magnitude is 0..100 so scale the 16-bit input here
318
+ */
319
+ ms->strong = ((u32) effect->u.rumble.strong_magnitude * 100) / U16_MAX;
320
+ ms->weak = ((u32) effect->u.rumble.weak_magnitude * 100) / U16_MAX;
321
+
322
+ schedule_work(&ms->ff_worker);
323
+ return 0;
324
+}
325
+
326
+static int ms_init_ff(struct hid_device *hdev)
327
+{
328
+ struct hid_input *hidinput;
329
+ struct input_dev *input_dev;
330
+ struct ms_data *ms = hid_get_drvdata(hdev);
331
+
332
+ if (list_empty(&hdev->inputs)) {
333
+ hid_err(hdev, "no inputs found\n");
334
+ return -ENODEV;
335
+ }
336
+ hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
337
+ input_dev = hidinput->input;
338
+
339
+ if (!(ms->quirks & MS_QUIRK_FF))
340
+ return 0;
341
+
342
+ ms->hdev = hdev;
343
+ INIT_WORK(&ms->ff_worker, ms_ff_worker);
344
+
345
+ ms->output_report_dmabuf = devm_kzalloc(&hdev->dev,
346
+ sizeof(struct xb1s_ff_report),
347
+ GFP_KERNEL);
348
+ if (ms->output_report_dmabuf == NULL)
349
+ return -ENOMEM;
350
+
351
+ input_set_capability(input_dev, EV_FF, FF_RUMBLE);
352
+ return input_ff_create_memless(input_dev, NULL, ms_play_effect);
353
+}
354
+
355
+static void ms_remove_ff(struct hid_device *hdev)
356
+{
357
+ struct ms_data *ms = hid_get_drvdata(hdev);
358
+
359
+ if (!(ms->quirks & MS_QUIRK_FF))
360
+ return;
361
+
362
+ cancel_work_sync(&ms->ff_worker);
363
+}
364
+
254365 static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
255366 {
256367 unsigned long quirks = id->driver_data;
368
+ struct ms_data *ms;
257369 int ret;
258370
259
- hid_set_drvdata(hdev, (void *)quirks);
371
+ ms = devm_kzalloc(&hdev->dev, sizeof(*ms), GFP_KERNEL);
372
+ if (ms == NULL)
373
+ return -ENOMEM;
374
+
375
+ ms->quirks = quirks;
376
+
377
+ hid_set_drvdata(hdev, ms);
260378
261379 if (quirks & MS_NOGET)
262380 hdev->quirks |= HID_QUIRK_NOGET;
....@@ -277,9 +395,19 @@
277395 goto err_free;
278396 }
279397
398
+ ret = ms_init_ff(hdev);
399
+ if (ret)
400
+ hid_err(hdev, "could not initialize ff, continuing anyway");
401
+
280402 return 0;
281403 err_free:
282404 return ret;
405
+}
406
+
407
+static void ms_remove(struct hid_device *hdev)
408
+{
409
+ hid_hw_stop(hdev);
410
+ ms_remove_ff(hdev);
283411 }
284412
285413 static const struct hid_device_id ms_devices[] = {
....@@ -318,6 +446,10 @@
318446 .driver_data = MS_PRESENTER },
319447 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, 0x091B),
320448 .driver_data = MS_SURFACE_DIAL },
449
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER),
450
+ .driver_data = MS_QUIRK_FF },
451
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS),
452
+ .driver_data = MS_QUIRK_FF },
321453 { }
322454 };
323455 MODULE_DEVICE_TABLE(hid, ms_devices);
....@@ -330,6 +462,7 @@
330462 .input_mapped = ms_input_mapped,
331463 .event = ms_event,
332464 .probe = ms_probe,
465
+ .remove = ms_remove,
333466 };
334467 module_hid_driver(ms_driver);
335468