2
2
* Plantronics USB HID Driver
3
3
*
4
4
* Copyright (c) 2014 JD Cole <[email protected] >
5
- * Copyright (c) 2014 Terry Junge <[email protected] >
5
+ * Copyright (c) 2015 Terry Junge <[email protected] >
6
6
*/
7
7
8
8
/*
17
17
#include <linux/hid.h>
18
18
#include <linux/module.h>
19
19
20
+ #define PLT_HID_1_0_PAGE 0xffa00000
21
+ #define PLT_HID_2_0_PAGE 0xffa20000
22
+
23
+ #define PLT_BASIC_TELEPHONY 0x0003
24
+ #define PLT_BASIC_EXCEPTION 0x0005
25
+
26
+ #define PLT_VOL_UP 0x00b1
27
+ #define PLT_VOL_DOWN 0x00b2
28
+
29
+ #define PLT1_VOL_UP (PLT_HID_1_0_PAGE | PLT_VOL_UP)
30
+ #define PLT1_VOL_DOWN (PLT_HID_1_0_PAGE | PLT_VOL_DOWN)
31
+ #define PLT2_VOL_UP (PLT_HID_2_0_PAGE | PLT_VOL_UP)
32
+ #define PLT2_VOL_DOWN (PLT_HID_2_0_PAGE | PLT_VOL_DOWN)
33
+
34
+ #define PLT_DA60 0xda60
35
+ #define PLT_BT300_MIN 0x0413
36
+ #define PLT_BT300_MAX 0x0418
37
+
38
+
39
+ #define PLT_ALLOW_CONSUMER (field->application == HID_CP_CONSUMERCONTROL && \
40
+ (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
41
+
20
42
static int plantronics_input_mapping (struct hid_device * hdev ,
21
43
struct hid_input * hi ,
22
44
struct hid_field * field ,
23
45
struct hid_usage * usage ,
24
46
unsigned long * * bit , int * max )
25
47
{
26
- if (field -> application == HID_CP_CONSUMERCONTROL
27
- && (usage -> hid & HID_USAGE_PAGE ) == HID_UP_CONSUMER ) {
28
- hid_dbg (hdev , "usage: %08x (appl: %08x) - defaulted\n" ,
29
- usage -> hid , field -> application );
30
- return 0 ;
48
+ unsigned short mapped_key ;
49
+ unsigned long plt_type = (unsigned long )hid_get_drvdata (hdev );
50
+
51
+ /* handle volume up/down mapping */
52
+ /* non-standard types or multi-HID interfaces - plt_type is PID */
53
+ if (!(plt_type & HID_USAGE_PAGE )) {
54
+ switch (plt_type ) {
55
+ case PLT_DA60 :
56
+ if (PLT_ALLOW_CONSUMER )
57
+ goto defaulted ;
58
+ goto ignored ;
59
+ default :
60
+ if (PLT_ALLOW_CONSUMER )
61
+ goto defaulted ;
62
+ }
63
+ }
64
+ /* handle standard types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
65
+ /* 'basic telephony compliant' - allow default consumer page map */
66
+ else if ((plt_type & HID_USAGE ) >= PLT_BASIC_TELEPHONY &&
67
+ (plt_type & HID_USAGE ) != PLT_BASIC_EXCEPTION ) {
68
+ if (PLT_ALLOW_CONSUMER )
69
+ goto defaulted ;
70
+ }
71
+ /* not 'basic telephony' - apply legacy mapping */
72
+ /* only map if the field is in the device's primary vendor page */
73
+ else if (!((field -> application ^ plt_type ) & HID_USAGE_PAGE )) {
74
+ switch (usage -> hid ) {
75
+ case PLT1_VOL_UP :
76
+ case PLT2_VOL_UP :
77
+ mapped_key = KEY_VOLUMEUP ;
78
+ goto mapped ;
79
+ case PLT1_VOL_DOWN :
80
+ case PLT2_VOL_DOWN :
81
+ mapped_key = KEY_VOLUMEDOWN ;
82
+ goto mapped ;
83
+ }
31
84
}
32
85
33
- hid_dbg (hdev , "usage: %08x (appl: %08x) - ignored\n" ,
34
- usage -> hid , field -> application );
86
+ /*
87
+ * Future mapping of call control or other usages,
88
+ * if and when keys are defined would go here
89
+ * otherwise, ignore everything else that was not mapped
90
+ */
35
91
92
+ ignored :
36
93
return -1 ;
94
+
95
+ defaulted :
96
+ hid_dbg (hdev , "usage: %08x (appl: %08x) - defaulted\n" ,
97
+ usage -> hid , field -> application );
98
+ return 0 ;
99
+
100
+ mapped :
101
+ hid_map_usage_clear (hi , usage , bit , max , EV_KEY , mapped_key );
102
+ hid_dbg (hdev , "usage: %08x (appl: %08x) - mapped to key %d\n" ,
103
+ usage -> hid , field -> application , mapped_key );
104
+ return 1 ;
105
+ }
106
+
107
+ static unsigned long plantronics_device_type (struct hid_device * hdev )
108
+ {
109
+ unsigned i , col_page ;
110
+ unsigned long plt_type = hdev -> product ;
111
+
112
+ /* multi-HID interfaces? - plt_type is PID */
113
+ if (plt_type >= PLT_BT300_MIN && plt_type <= PLT_BT300_MAX )
114
+ goto exit ;
115
+
116
+ /* determine primary vendor page */
117
+ for (i = 0 ; i < hdev -> maxcollection ; i ++ ) {
118
+ col_page = hdev -> collection [i ].usage & HID_USAGE_PAGE ;
119
+ if (col_page == PLT_HID_2_0_PAGE ) {
120
+ plt_type = hdev -> collection [i ].usage ;
121
+ break ;
122
+ }
123
+ if (col_page == PLT_HID_1_0_PAGE )
124
+ plt_type = hdev -> collection [i ].usage ;
125
+ }
126
+
127
+ exit :
128
+ hid_dbg (hdev , "plt_type decoded as: %08lx\n" , plt_type );
129
+ return plt_type ;
130
+ }
131
+
132
+ static int plantronics_probe (struct hid_device * hdev ,
133
+ const struct hid_device_id * id )
134
+ {
135
+ int ret ;
136
+
137
+ ret = hid_parse (hdev );
138
+ if (ret ) {
139
+ hid_err (hdev , "parse failed\n" );
140
+ goto err ;
141
+ }
142
+
143
+ hid_set_drvdata (hdev , (void * )plantronics_device_type (hdev ));
144
+
145
+ ret = hid_hw_start (hdev , HID_CONNECT_DEFAULT |
146
+ HID_CONNECT_HIDINPUT_FORCE | HID_CONNECT_HIDDEV_FORCE );
147
+ if (ret )
148
+ hid_err (hdev , "hw start failed\n" );
149
+
150
+ err :
151
+ return ret ;
37
152
}
38
153
39
154
static const struct hid_device_id plantronics_devices [] = {
@@ -46,6 +161,7 @@ static struct hid_driver plantronics_driver = {
46
161
.name = "plantronics" ,
47
162
.id_table = plantronics_devices ,
48
163
.input_mapping = plantronics_input_mapping ,
164
+ .probe = plantronics_probe ,
49
165
};
50
166
module_hid_driver (plantronics_driver );
51
167
0 commit comments