6
6
* Copyright (c) 2015-2018 Terry Junge <[email protected] >
7
7
*/
8
8
9
- /*
10
- */
11
-
12
9
#include "hid-ids.h"
13
10
14
11
#include <linux/hid.h>
23
20
24
21
#define PLT_VOL_UP 0x00b1
25
22
#define PLT_VOL_DOWN 0x00b2
23
+ #define PLT_MIC_MUTE 0x00b5
26
24
27
25
#define PLT1_VOL_UP (PLT_HID_1_0_PAGE | PLT_VOL_UP)
28
26
#define PLT1_VOL_DOWN (PLT_HID_1_0_PAGE | PLT_VOL_DOWN)
27
+ #define PLT1_MIC_MUTE (PLT_HID_1_0_PAGE | PLT_MIC_MUTE)
29
28
#define PLT2_VOL_UP (PLT_HID_2_0_PAGE | PLT_VOL_UP)
30
29
#define PLT2_VOL_DOWN (PLT_HID_2_0_PAGE | PLT_VOL_DOWN)
30
+ #define PLT2_MIC_MUTE (PLT_HID_2_0_PAGE | PLT_MIC_MUTE)
31
+ #define HID_TELEPHONY_MUTE (HID_UP_TELEPHONY | 0x2f)
32
+ #define HID_CONSUMER_MUTE (HID_UP_CONSUMER | 0xe2)
31
33
32
34
#define PLT_DA60 0xda60
33
35
#define PLT_BT300_MIN 0x0413
34
36
#define PLT_BT300_MAX 0x0418
35
37
36
-
37
- #define PLT_ALLOW_CONSUMER (field->application == HID_CP_CONSUMERCONTROL && \
38
- (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
39
-
40
- #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
41
- #define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1)
42
-
43
38
#define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
44
- #define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
45
39
46
40
struct plt_drv_data {
47
41
unsigned long device_type ;
48
- unsigned long last_volume_key_ts ;
49
- u32 quirks ;
42
+ unsigned long last_key_ts ;
43
+ unsigned long double_key_to ;
44
+ __u16 last_key ;
50
45
};
51
46
52
47
static int plantronics_input_mapping (struct hid_device * hdev ,
@@ -58,34 +53,43 @@ static int plantronics_input_mapping(struct hid_device *hdev,
58
53
unsigned short mapped_key ;
59
54
struct plt_drv_data * drv_data = hid_get_drvdata (hdev );
60
55
unsigned long plt_type = drv_data -> device_type ;
56
+ int allow_mute = usage -> hid == HID_TELEPHONY_MUTE ;
57
+ int allow_consumer = field -> application == HID_CP_CONSUMERCONTROL &&
58
+ (usage -> hid & HID_USAGE_PAGE ) == HID_UP_CONSUMER &&
59
+ usage -> hid != HID_CONSUMER_MUTE ;
61
60
62
61
/* special case for PTT products */
63
62
if (field -> application == HID_GD_JOYSTICK )
64
63
goto defaulted ;
65
64
66
- /* handle volume up/down mapping */
67
65
/* non-standard types or multi-HID interfaces - plt_type is PID */
68
66
if (!(plt_type & HID_USAGE_PAGE )) {
69
67
switch (plt_type ) {
70
68
case PLT_DA60 :
71
- if (PLT_ALLOW_CONSUMER )
69
+ if (allow_consumer )
72
70
goto defaulted ;
73
- goto ignored ;
71
+ if (usage -> hid == HID_CONSUMER_MUTE ) {
72
+ mapped_key = KEY_MICMUTE ;
73
+ goto mapped ;
74
+ }
75
+ break ;
74
76
default :
75
- if (PLT_ALLOW_CONSUMER )
77
+ if (allow_consumer || allow_mute )
76
78
goto defaulted ;
77
79
}
80
+ goto ignored ;
78
81
}
79
- /* handle standard types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
80
- /* 'basic telephony compliant' - allow default consumer page map */
81
- else if ((plt_type & HID_USAGE ) >= PLT_BASIC_TELEPHONY &&
82
- (plt_type & HID_USAGE ) != PLT_BASIC_EXCEPTION ) {
83
- if (PLT_ALLOW_CONSUMER )
84
- goto defaulted ;
85
- }
86
- /* not 'basic telephony' - apply legacy mapping */
87
- /* only map if the field is in the device's primary vendor page */
88
- else if (!((field -> application ^ plt_type ) & HID_USAGE_PAGE )) {
82
+
83
+ /* handle standard consumer control mapping */
84
+ /* and standard telephony mic mute mapping */
85
+ if (allow_consumer || allow_mute )
86
+ goto defaulted ;
87
+
88
+ /* handle vendor unique types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
89
+ /* if not 'basic telephony compliant' - map vendor unique controls */
90
+ if (!((plt_type & HID_USAGE ) >= PLT_BASIC_TELEPHONY &&
91
+ (plt_type & HID_USAGE ) != PLT_BASIC_EXCEPTION ) &&
92
+ !((field -> application ^ plt_type ) & HID_USAGE_PAGE ))
89
93
switch (usage -> hid ) {
90
94
case PLT1_VOL_UP :
91
95
case PLT2_VOL_UP :
@@ -95,8 +99,11 @@ static int plantronics_input_mapping(struct hid_device *hdev,
95
99
case PLT2_VOL_DOWN :
96
100
mapped_key = KEY_VOLUMEDOWN ;
97
101
goto mapped ;
102
+ case PLT1_MIC_MUTE :
103
+ case PLT2_MIC_MUTE :
104
+ mapped_key = KEY_MICMUTE ;
105
+ goto mapped ;
98
106
}
99
- }
100
107
101
108
/*
102
109
* Future mapping of call control or other usages,
@@ -105,6 +112,8 @@ static int plantronics_input_mapping(struct hid_device *hdev,
105
112
*/
106
113
107
114
ignored :
115
+ hid_dbg (hdev , "usage: %08x (appl: %08x) - ignored\n" ,
116
+ usage -> hid , field -> application );
108
117
return -1 ;
109
118
110
119
defaulted :
@@ -123,38 +132,26 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field,
123
132
struct hid_usage * usage , __s32 value )
124
133
{
125
134
struct plt_drv_data * drv_data = hid_get_drvdata (hdev );
135
+ unsigned long prev_tsto , cur_ts ;
136
+ __u16 prev_key , cur_key ;
126
137
127
- if (drv_data -> quirks & PLT_QUIRK_DOUBLE_VOLUME_KEYS ) {
128
- unsigned long prev_ts , cur_ts ;
138
+ /* Usages are filtered in plantronics_usages. */
129
139
130
- /* Usages are filtered in plantronics_usages. */
140
+ /* HZ too low for ms resolution - double key detection disabled */
141
+ /* or it is a key release - handle key presses only. */
142
+ if (!drv_data -> double_key_to || !value )
143
+ return 0 ;
131
144
132
- if (!value ) /* Handle key presses only. */
133
- return 0 ;
145
+ prev_tsto = drv_data -> last_key_ts + drv_data -> double_key_to ;
146
+ cur_ts = drv_data -> last_key_ts = jiffies ;
147
+ prev_key = drv_data -> last_key ;
148
+ cur_key = drv_data -> last_key = usage -> code ;
134
149
135
- prev_ts = drv_data -> last_volume_key_ts ;
136
- cur_ts = jiffies ;
137
- if (jiffies_to_msecs (cur_ts - prev_ts ) <= PLT_DOUBLE_KEY_TIMEOUT )
138
- return 1 ; /* Ignore the repeated key. */
139
-
140
- drv_data -> last_volume_key_ts = cur_ts ;
150
+ /* If the same key occurs in <= double_key_to -- ignore it */
151
+ if (prev_key == cur_key && time_before_eq (cur_ts , prev_tsto )) {
152
+ hid_dbg (hdev , "double key %d ignored\n" , cur_key );
153
+ return 1 ; /* Ignore the repeated key. */
141
154
}
142
- if (drv_data -> quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS ) {
143
- unsigned long prev_ts , cur_ts ;
144
-
145
- /* Usages are filtered in plantronics_usages. */
146
-
147
- if (!value ) /* Handle key presses only. */
148
- return 0 ;
149
-
150
- prev_ts = drv_data -> last_volume_key_ts ;
151
- cur_ts = jiffies ;
152
- if (jiffies_to_msecs (cur_ts - prev_ts ) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT )
153
- return 1 ; /* Ignore the followed opposite volume key. */
154
-
155
- drv_data -> last_volume_key_ts = cur_ts ;
156
- }
157
-
158
155
return 0 ;
159
156
}
160
157
@@ -196,12 +193,16 @@ static int plantronics_probe(struct hid_device *hdev,
196
193
ret = hid_parse (hdev );
197
194
if (ret ) {
198
195
hid_err (hdev , "parse failed\n" );
199
- goto err ;
196
+ return ret ;
200
197
}
201
198
202
199
drv_data -> device_type = plantronics_device_type (hdev );
203
- drv_data -> quirks = id -> driver_data ;
204
- drv_data -> last_volume_key_ts = jiffies - msecs_to_jiffies (PLT_DOUBLE_KEY_TIMEOUT );
200
+ drv_data -> double_key_to = msecs_to_jiffies (PLT_DOUBLE_KEY_TIMEOUT );
201
+ drv_data -> last_key_ts = jiffies - drv_data -> double_key_to ;
202
+
203
+ /* if HZ does not allow ms resolution - disable double key detection */
204
+ if (drv_data -> double_key_to < PLT_DOUBLE_KEY_TIMEOUT )
205
+ drv_data -> double_key_to = 0 ;
205
206
206
207
hid_set_drvdata (hdev , drv_data );
207
208
@@ -210,29 +211,10 @@ static int plantronics_probe(struct hid_device *hdev,
210
211
if (ret )
211
212
hid_err (hdev , "hw start failed\n" );
212
213
213
- err :
214
214
return ret ;
215
215
}
216
216
217
217
static const struct hid_device_id plantronics_devices [] = {
218
- { HID_USB_DEVICE (USB_VENDOR_ID_PLANTRONICS ,
219
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES ),
220
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
221
- { HID_USB_DEVICE (USB_VENDOR_ID_PLANTRONICS ,
222
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES ),
223
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
224
- { HID_USB_DEVICE (USB_VENDOR_ID_PLANTRONICS ,
225
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES ),
226
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
227
- { HID_USB_DEVICE (USB_VENDOR_ID_PLANTRONICS ,
228
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES ),
229
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
230
- { HID_USB_DEVICE (USB_VENDOR_ID_PLANTRONICS ,
231
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES ),
232
- .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
233
- { HID_USB_DEVICE (USB_VENDOR_ID_PLANTRONICS ,
234
- USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES ),
235
- .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
236
218
{ HID_USB_DEVICE (USB_VENDOR_ID_PLANTRONICS , HID_ANY_ID ) },
237
219
{ }
238
220
};
@@ -241,6 +223,14 @@ MODULE_DEVICE_TABLE(hid, plantronics_devices);
241
223
static const struct hid_usage_id plantronics_usages [] = {
242
224
{ HID_CP_VOLUMEUP , EV_KEY , HID_ANY_ID },
243
225
{ HID_CP_VOLUMEDOWN , EV_KEY , HID_ANY_ID },
226
+ { HID_TELEPHONY_MUTE , EV_KEY , HID_ANY_ID },
227
+ { HID_CONSUMER_MUTE , EV_KEY , HID_ANY_ID },
228
+ { PLT2_VOL_UP , EV_KEY , HID_ANY_ID },
229
+ { PLT2_VOL_DOWN , EV_KEY , HID_ANY_ID },
230
+ { PLT2_MIC_MUTE , EV_KEY , HID_ANY_ID },
231
+ { PLT1_VOL_UP , EV_KEY , HID_ANY_ID },
232
+ { PLT1_VOL_DOWN , EV_KEY , HID_ANY_ID },
233
+ { PLT1_MIC_MUTE , EV_KEY , HID_ANY_ID },
244
234
{ HID_TERMINATOR , HID_TERMINATOR , HID_TERMINATOR }
245
235
};
246
236
0 commit comments