1
1
/*
2
- * HID driver for ELECOM devices.
2
+ * HID driver for ELECOM devices:
3
+ * - BM084 Bluetooth Mouse
4
+ * - EX-G Trackball (Wired and wireless)
5
+ * - DEFT Trackball (Wired and wireless)
6
+ * - HUGE Trackball (Wired and wireless)
7
+ *
3
8
* Copyright (c) 2010 Richard Nauber <[email protected] >
4
9
* Copyright (c) 2016 Yuxuan Shui <[email protected] >
5
10
* Copyright (c) 2017 Diego Elio Pettenò <[email protected] >
6
11
* Copyright (c) 2017 Alex Manoussakis <[email protected] >
12
+ * Copyright (c) 2017 Tomasz Kramkowski <[email protected] >
7
13
*/
8
14
9
15
/*
19
25
20
26
#include "hid-ids.h"
21
27
28
+ /*
29
+ * Certain ELECOM mice misreport their button count meaning that they only work
30
+ * correctly with the ELECOM mouse assistant software which is unavailable for
31
+ * Linux. A four extra INPUT reports and a FEATURE report are described by the
32
+ * report descriptor but it does not appear that these enable software to
33
+ * control what the extra buttons map to. The only simple and straightforward
34
+ * solution seems to involve fixing up the report descriptor.
35
+ *
36
+ * Report descriptor format:
37
+ * Positions 13, 15, 21 and 31 store the button bit count, button usage minimum,
38
+ * button usage maximum and padding bit count respectively.
39
+ */
40
+ #define MOUSE_BUTTONS_MAX 8
41
+ static void mouse_button_fixup (struct hid_device * hdev ,
42
+ __u8 * rdesc , unsigned int rsize ,
43
+ int nbuttons )
44
+ {
45
+ if (rsize < 32 || rdesc [12 ] != 0x95 ||
46
+ rdesc [14 ] != 0x75 || rdesc [15 ] != 0x01 ||
47
+ rdesc [20 ] != 0x29 || rdesc [30 ] != 0x75 )
48
+ return ;
49
+ hid_info (hdev , "Fixing up Elecom mouse button count\n" );
50
+ nbuttons = clamp (nbuttons , 0 , MOUSE_BUTTONS_MAX );
51
+ rdesc [13 ] = nbuttons ;
52
+ rdesc [21 ] = nbuttons ;
53
+ rdesc [31 ] = MOUSE_BUTTONS_MAX - nbuttons ;
54
+ }
55
+
22
56
static __u8 * elecom_report_fixup (struct hid_device * hdev , __u8 * rdesc ,
23
57
unsigned int * rsize )
24
58
{
@@ -31,52 +65,24 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
31
65
rdesc [47 ] = 0x00 ;
32
66
}
33
67
break ;
68
+ case USB_DEVICE_ID_ELECOM_EX_G_WIRED :
69
+ case USB_DEVICE_ID_ELECOM_EX_G_WIRELESS :
70
+ mouse_button_fixup (hdev , rdesc , * rsize , 6 );
71
+ break ;
34
72
case USB_DEVICE_ID_ELECOM_DEFT_WIRED :
35
73
case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS :
36
74
case USB_DEVICE_ID_ELECOM_HUGE_WIRED :
37
75
case USB_DEVICE_ID_ELECOM_HUGE_WIRELESS :
38
- /* The DEFT/HUGE trackball has eight buttons, but its descriptor
39
- * only reports five, disabling the three Fn buttons on the top
40
- * of the mouse.
41
- *
42
- * Apply the following diff to the descriptor:
43
- *
44
- * Collection (Physical), Collection (Physical),
45
- * Report ID (1), Report ID (1),
46
- * Report Count (5), -> Report Count (8),
47
- * Report Size (1), Report Size (1),
48
- * Usage Page (Button), Usage Page (Button),
49
- * Usage Minimum (01h), Usage Minimum (01h),
50
- * Usage Maximum (05h), -> Usage Maximum (08h),
51
- * Logical Minimum (0), Logical Minimum (0),
52
- * Logical Maximum (1), Logical Maximum (1),
53
- * Input (Variable), Input (Variable),
54
- * Report Count (1), -> Report Count (0),
55
- * Report Size (3), Report Size (3),
56
- * Input (Constant), Input (Constant),
57
- * Report Size (16), Report Size (16),
58
- * Report Count (2), Report Count (2),
59
- * Usage Page (Desktop), Usage Page (Desktop),
60
- * Usage (X), Usage (X),
61
- * Usage (Y), Usage (Y),
62
- * Logical Minimum (-32768), Logical Minimum (-32768),
63
- * Logical Maximum (32767), Logical Maximum (32767),
64
- * Input (Variable, Relative), Input (Variable, Relative),
65
- * End Collection, End Collection,
66
- */
67
- if (* rsize == 213 && rdesc [13 ] == 5 && rdesc [21 ] == 5 ) {
68
- hid_info (hdev , "Fixing up Elecom DEFT/HUGE Fn buttons\n" );
69
- rdesc [13 ] = 8 ; /* Button/Variable Report Count */
70
- rdesc [21 ] = 8 ; /* Button/Variable Usage Maximum */
71
- rdesc [29 ] = 0 ; /* Button/Constant Report Count */
72
- }
76
+ mouse_button_fixup (hdev , rdesc , * rsize , 8 );
73
77
break ;
74
78
}
75
79
return rdesc ;
76
80
}
77
81
78
82
static const struct hid_device_id elecom_devices [] = {
79
83
{ HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_ELECOM , USB_DEVICE_ID_ELECOM_BM084 ) },
84
+ { HID_USB_DEVICE (USB_VENDOR_ID_ELECOM , USB_DEVICE_ID_ELECOM_EX_G_WIRED ) },
85
+ { HID_USB_DEVICE (USB_VENDOR_ID_ELECOM , USB_DEVICE_ID_ELECOM_EX_G_WIRELESS ) },
80
86
{ HID_USB_DEVICE (USB_VENDOR_ID_ELECOM , USB_DEVICE_ID_ELECOM_DEFT_WIRED ) },
81
87
{ HID_USB_DEVICE (USB_VENDOR_ID_ELECOM , USB_DEVICE_ID_ELECOM_DEFT_WIRELESS ) },
82
88
{ HID_USB_DEVICE (USB_VENDOR_ID_ELECOM , USB_DEVICE_ID_ELECOM_HUGE_WIRED ) },
0 commit comments