1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Force feedback support for EMS Trio Linker Plus II
5 * Copyright (c) 2010 Ignaz Forster <ignaz.forster@gmx.de>
12 #include <linux/hid.h>
13 #include <linux/input.h>
14 #include <linux/module.h>
19 struct hid_report
*report
;
22 static int emsff_play(struct input_dev
*dev
, void *data
,
23 struct ff_effect
*effect
)
25 struct hid_device
*hid
= input_get_drvdata(dev
);
26 struct emsff_device
*emsff
= data
;
29 weak
= effect
->u
.rumble
.weak_magnitude
;
30 strong
= effect
->u
.rumble
.strong_magnitude
;
32 dbg_hid("called with 0x%04x 0x%04x\n", strong
, weak
);
34 weak
= weak
* 0xff / 0xffff;
35 strong
= strong
* 0xff / 0xffff;
37 emsff
->report
->field
[0]->value
[1] = weak
;
38 emsff
->report
->field
[0]->value
[2] = strong
;
40 dbg_hid("running with 0x%02x 0x%02x\n", strong
, weak
);
41 hid_hw_request(hid
, emsff
->report
, HID_REQ_SET_REPORT
);
46 static int emsff_init(struct hid_device
*hid
)
48 struct emsff_device
*emsff
;
49 struct hid_report
*report
;
50 struct hid_input
*hidinput
;
51 struct list_head
*report_list
=
52 &hid
->report_enum
[HID_OUTPUT_REPORT
].report_list
;
53 struct input_dev
*dev
;
56 if (list_empty(&hid
->inputs
)) {
57 hid_err(hid
, "no inputs found\n");
60 hidinput
= list_first_entry(&hid
->inputs
, struct hid_input
, list
);
61 dev
= hidinput
->input
;
63 if (list_empty(report_list
)) {
64 hid_err(hid
, "no output reports found\n");
68 report
= list_first_entry(report_list
, struct hid_report
, list
);
69 if (report
->maxfield
< 1) {
70 hid_err(hid
, "no fields in the report\n");
74 if (report
->field
[0]->report_count
< 7) {
75 hid_err(hid
, "not enough values in the field\n");
79 emsff
= kzalloc(sizeof(struct emsff_device
), GFP_KERNEL
);
83 set_bit(FF_RUMBLE
, dev
->ffbit
);
85 error
= input_ff_create_memless(dev
, emsff
, emsff_play
);
91 emsff
->report
= report
;
92 emsff
->report
->field
[0]->value
[0] = 0x01;
93 emsff
->report
->field
[0]->value
[1] = 0x00;
94 emsff
->report
->field
[0]->value
[2] = 0x00;
95 emsff
->report
->field
[0]->value
[3] = 0x00;
96 emsff
->report
->field
[0]->value
[4] = 0x00;
97 emsff
->report
->field
[0]->value
[5] = 0x00;
98 emsff
->report
->field
[0]->value
[6] = 0x00;
99 hid_hw_request(hid
, emsff
->report
, HID_REQ_SET_REPORT
);
101 hid_info(hid
, "force feedback for EMS based devices by Ignaz Forster <ignaz.forster@gmx.de>\n");
106 static int ems_probe(struct hid_device
*hdev
, const struct hid_device_id
*id
)
110 ret
= hid_parse(hdev
);
112 hid_err(hdev
, "parse failed\n");
116 ret
= hid_hw_start(hdev
, HID_CONNECT_DEFAULT
& ~HID_CONNECT_FF
);
118 hid_err(hdev
, "hw start failed\n");
122 ret
= emsff_init(hdev
);
124 dev_err(&hdev
->dev
, "force feedback init failed\n");
134 static const struct hid_device_id ems_devices
[] = {
135 { HID_USB_DEVICE(USB_VENDOR_ID_EMS
, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II
) },
138 MODULE_DEVICE_TABLE(hid
, ems_devices
);
140 static struct hid_driver ems_driver
= {
142 .id_table
= ems_devices
,
145 module_hid_driver(ems_driver
);
147 MODULE_LICENSE("GPL");