66 * Copyright (c) 2015-2018 Terry Junge <terry.junge@plantronics.com>
77 */
88
9- /*
10- */
11-
129#include "hid-ids.h"
1310
1411#include <linux/hid.h>
2320
2421#define PLT_VOL_UP 0x00b1
2522#define PLT_VOL_DOWN 0x00b2
23+ #define PLT_MIC_MUTE 0x00b5
2624
2725#define PLT1_VOL_UP (PLT_HID_1_0_PAGE | PLT_VOL_UP)
2826#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)
2928#define PLT2_VOL_UP (PLT_HID_2_0_PAGE | PLT_VOL_UP)
3029#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)
3133
3234#define PLT_DA60 0xda60
3335#define PLT_BT300_MIN 0x0413
3436#define PLT_BT300_MAX 0x0418
3537
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-
4338#define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
44- #define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
4539
4640struct plt_drv_data {
4741 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 ;
5045};
5146
5247static int plantronics_input_mapping (struct hid_device * hdev ,
@@ -58,34 +53,43 @@ static int plantronics_input_mapping(struct hid_device *hdev,
5853 unsigned short mapped_key ;
5954 struct plt_drv_data * drv_data = hid_get_drvdata (hdev );
6055 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 ;
6160
6261 /* special case for PTT products */
6362 if (field -> application == HID_GD_JOYSTICK )
6463 goto defaulted ;
6564
66- /* handle volume up/down mapping */
6765 /* non-standard types or multi-HID interfaces - plt_type is PID */
6866 if (!(plt_type & HID_USAGE_PAGE )) {
6967 switch (plt_type ) {
7068 case PLT_DA60 :
71- if (PLT_ALLOW_CONSUMER )
69+ if (allow_consumer )
7270 goto defaulted ;
73- goto ignored ;
71+ if (usage -> hid == HID_CONSUMER_MUTE ) {
72+ mapped_key = KEY_MICMUTE ;
73+ goto mapped ;
74+ }
75+ break ;
7476 default :
75- if (PLT_ALLOW_CONSUMER )
77+ if (allow_consumer || allow_mute )
7678 goto defaulted ;
7779 }
80+ goto ignored ;
7881 }
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 ))
8993 switch (usage -> hid ) {
9094 case PLT1_VOL_UP :
9195 case PLT2_VOL_UP :
@@ -95,8 +99,11 @@ static int plantronics_input_mapping(struct hid_device *hdev,
9599 case PLT2_VOL_DOWN :
96100 mapped_key = KEY_VOLUMEDOWN ;
97101 goto mapped ;
102+ case PLT1_MIC_MUTE :
103+ case PLT2_MIC_MUTE :
104+ mapped_key = KEY_MICMUTE ;
105+ goto mapped ;
98106 }
99- }
100107
101108/*
102109 * Future mapping of call control or other usages,
@@ -105,6 +112,8 @@ static int plantronics_input_mapping(struct hid_device *hdev,
105112 */
106113
107114ignored :
115+ hid_dbg (hdev , "usage: %08x (appl: %08x) - ignored\n" ,
116+ usage -> hid , field -> application );
108117 return -1 ;
109118
110119defaulted :
@@ -123,38 +132,26 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field,
123132 struct hid_usage * usage , __s32 value )
124133{
125134 struct plt_drv_data * drv_data = hid_get_drvdata (hdev );
135+ unsigned long prev_tsto , cur_ts ;
136+ __u16 prev_key , cur_key ;
126137
127- if (drv_data -> quirks & PLT_QUIRK_DOUBLE_VOLUME_KEYS ) {
128- unsigned long prev_ts , cur_ts ;
138+ /* Usages are filtered in plantronics_usages. */
129139
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 ;
131144
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 ;
134149
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. */
141154 }
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-
158155 return 0 ;
159156}
160157
@@ -196,12 +193,16 @@ static int plantronics_probe(struct hid_device *hdev,
196193 ret = hid_parse (hdev );
197194 if (ret ) {
198195 hid_err (hdev , "parse failed\n" );
199- goto err ;
196+ return ret ;
200197 }
201198
202199 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 ;
205206
206207 hid_set_drvdata (hdev , drv_data );
207208
@@ -210,29 +211,10 @@ static int plantronics_probe(struct hid_device *hdev,
210211 if (ret )
211212 hid_err (hdev , "hw start failed\n" );
212213
213- err :
214214 return ret ;
215215}
216216
217217static 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 },
236218 { HID_USB_DEVICE (USB_VENDOR_ID_PLANTRONICS , HID_ANY_ID ) },
237219 { }
238220};
@@ -241,6 +223,14 @@ MODULE_DEVICE_TABLE(hid, plantronics_devices);
241223static const struct hid_usage_id plantronics_usages [] = {
242224 { HID_CP_VOLUMEUP , EV_KEY , HID_ANY_ID },
243225 { 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 },
244234 { HID_TERMINATOR , HID_TERMINATOR , HID_TERMINATOR }
245235};
246236
0 commit comments