29
29
#define MS_NOGET BIT(4)
30
30
#define MS_DUPLICATE_USAGES BIT(5)
31
31
#define MS_SURFACE_DIAL BIT(6)
32
+ #define MS_QUIRK_FF BIT(7)
33
+
34
+ struct ms_data {
35
+ unsigned long quirks ;
36
+ struct hid_device * hdev ;
37
+ struct work_struct ff_worker ;
38
+ __u8 strong ;
39
+ __u8 weak ;
40
+ void * output_report_dmabuf ;
41
+ };
42
+
43
+ #define XB1S_FF_REPORT 3
44
+ #define ENABLE_WEAK BIT(0)
45
+ #define ENABLE_STRONG BIT(1)
46
+
47
+ enum {
48
+ MAGNITUDE_STRONG = 2 ,
49
+ MAGNITUDE_WEAK ,
50
+ MAGNITUDE_NUM
51
+ };
52
+
53
+ struct xb1s_ff_report {
54
+ __u8 report_id ;
55
+ __u8 enable ;
56
+ __u8 magnitude [MAGNITUDE_NUM ];
57
+ __u8 duration_10ms ;
58
+ __u8 start_delay_10ms ;
59
+ __u8 loop_count ;
60
+ } __packed ;
32
61
33
62
static __u8 * ms_report_fixup (struct hid_device * hdev , __u8 * rdesc ,
34
63
unsigned int * rsize )
35
64
{
36
- unsigned long quirks = (unsigned long )hid_get_drvdata (hdev );
65
+ struct ms_data * ms = hid_get_drvdata (hdev );
66
+ unsigned long quirks = ms -> quirks ;
37
67
38
68
/*
39
69
* Microsoft Wireless Desktop Receiver (Model 1028) has
@@ -159,7 +189,8 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
159
189
struct hid_field * field , struct hid_usage * usage ,
160
190
unsigned long * * bit , int * max )
161
191
{
162
- unsigned long quirks = (unsigned long )hid_get_drvdata (hdev );
192
+ struct ms_data * ms = hid_get_drvdata (hdev );
193
+ unsigned long quirks = ms -> quirks ;
163
194
164
195
if (quirks & MS_ERGONOMY ) {
165
196
int ret = ms_ergonomy_kb_quirk (hi , usage , bit , max );
@@ -185,7 +216,8 @@ static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
185
216
struct hid_field * field , struct hid_usage * usage ,
186
217
unsigned long * * bit , int * max )
187
218
{
188
- unsigned long quirks = (unsigned long )hid_get_drvdata (hdev );
219
+ struct ms_data * ms = hid_get_drvdata (hdev );
220
+ unsigned long quirks = ms -> quirks ;
189
221
190
222
if (quirks & MS_DUPLICATE_USAGES )
191
223
clear_bit (usage -> code , * bit );
@@ -196,7 +228,8 @@ static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
196
228
static int ms_event (struct hid_device * hdev , struct hid_field * field ,
197
229
struct hid_usage * usage , __s32 value )
198
230
{
199
- unsigned long quirks = (unsigned long )hid_get_drvdata (hdev );
231
+ struct ms_data * ms = hid_get_drvdata (hdev );
232
+ unsigned long quirks = ms -> quirks ;
200
233
struct input_dev * input ;
201
234
202
235
if (!(hdev -> claimed & HID_CLAIMED_INPUT ) || !field -> hidinput ||
@@ -251,12 +284,97 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
251
284
return 0 ;
252
285
}
253
286
287
+ static void ms_ff_worker (struct work_struct * work )
288
+ {
289
+ struct ms_data * ms = container_of (work , struct ms_data , ff_worker );
290
+ struct hid_device * hdev = ms -> hdev ;
291
+ struct xb1s_ff_report * r = ms -> output_report_dmabuf ;
292
+ int ret ;
293
+
294
+ memset (r , 0 , sizeof (* r ));
295
+
296
+ r -> report_id = XB1S_FF_REPORT ;
297
+ r -> enable = ENABLE_WEAK | ENABLE_STRONG ;
298
+ /*
299
+ * Specifying maximum duration and maximum loop count should
300
+ * cover maximum duration of a single effect, which is 65536
301
+ * ms
302
+ */
303
+ r -> duration_10ms = U8_MAX ;
304
+ r -> loop_count = U8_MAX ;
305
+ r -> magnitude [MAGNITUDE_STRONG ] = ms -> strong ; /* left actuator */
306
+ r -> magnitude [MAGNITUDE_WEAK ] = ms -> weak ; /* right actuator */
307
+
308
+ ret = hid_hw_output_report (hdev , (__u8 * )r , sizeof (* r ));
309
+ if (ret )
310
+ hid_warn (hdev , "failed to send FF report\n" );
311
+ }
312
+
313
+ static int ms_play_effect (struct input_dev * dev , void * data ,
314
+ struct ff_effect * effect )
315
+ {
316
+ struct hid_device * hid = input_get_drvdata (dev );
317
+ struct ms_data * ms = hid_get_drvdata (hid );
318
+
319
+ if (effect -> type != FF_RUMBLE )
320
+ return 0 ;
321
+
322
+ /*
323
+ * Magnitude is 0..100 so scale the 16-bit input here
324
+ */
325
+ ms -> strong = ((u32 ) effect -> u .rumble .strong_magnitude * 100 ) / U16_MAX ;
326
+ ms -> weak = ((u32 ) effect -> u .rumble .weak_magnitude * 100 ) / U16_MAX ;
327
+
328
+ schedule_work (& ms -> ff_worker );
329
+ return 0 ;
330
+ }
331
+
332
+ static int ms_init_ff (struct hid_device * hdev )
333
+ {
334
+ struct hid_input * hidinput = list_entry (hdev -> inputs .next ,
335
+ struct hid_input , list );
336
+ struct input_dev * input_dev = hidinput -> input ;
337
+ struct ms_data * ms = hid_get_drvdata (hdev );
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
+
254
365
static int ms_probe (struct hid_device * hdev , const struct hid_device_id * id )
255
366
{
256
367
unsigned long quirks = id -> driver_data ;
368
+ struct ms_data * ms ;
257
369
int ret ;
258
370
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 );
260
378
261
379
if (quirks & MS_NOGET )
262
380
hdev -> quirks |= HID_QUIRK_NOGET ;
@@ -277,11 +395,21 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
277
395
goto err_free ;
278
396
}
279
397
398
+ ret = ms_init_ff (hdev );
399
+ if (ret )
400
+ hid_err (hdev , "could not initialize ff, continuing anyway" );
401
+
280
402
return 0 ;
281
403
err_free :
282
404
return ret ;
283
405
}
284
406
407
+ static void ms_remove (struct hid_device * hdev )
408
+ {
409
+ hid_hw_stop (hdev );
410
+ ms_remove_ff (hdev );
411
+ }
412
+
285
413
static const struct hid_device_id ms_devices [] = {
286
414
{ HID_USB_DEVICE (USB_VENDOR_ID_MICROSOFT , USB_DEVICE_ID_SIDEWINDER_GV ),
287
415
.driver_data = MS_HIDINPUT },
@@ -318,6 +446,8 @@ static const struct hid_device_id ms_devices[] = {
318
446
.driver_data = MS_PRESENTER },
319
447
{ HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_MICROSOFT , 0x091B ),
320
448
.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 },
321
451
{ }
322
452
};
323
453
MODULE_DEVICE_TABLE (hid , ms_devices );
@@ -330,6 +460,7 @@ static struct hid_driver ms_driver = {
330
460
.input_mapped = ms_input_mapped ,
331
461
.event = ms_event ,
332
462
.probe = ms_probe ,
463
+ .remove = ms_remove ,
333
464
};
334
465
module_hid_driver (ms_driver );
335
466
0 commit comments