aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-microsoft.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-microsoft.c')
-rw-r--r--drivers/hid/hid-microsoft.c74
1 files changed, 70 insertions, 4 deletions
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 404a3a8a82f1..6fd58175a291 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -62,9 +62,48 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
62{ 62{
63 struct input_dev *input = hi->input; 63 struct input_dev *input = hi->input;
64 64
65 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
66 switch (usage->hid & HID_USAGE) {
67 /*
68 * Microsoft uses these 2 reserved usage ids for 2 keys on
69 * the MS office kb labelled "Office Home" and "Task Pane".
70 */
71 case 0x29d:
72 ms_map_key_clear(KEY_PROG1);
73 return 1;
74 case 0x29e:
75 ms_map_key_clear(KEY_PROG2);
76 return 1;
77 }
78 return 0;
79 }
80
81 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
82 return 0;
83
65 switch (usage->hid & HID_USAGE) { 84 switch (usage->hid & HID_USAGE) {
66 case 0xfd06: ms_map_key_clear(KEY_CHAT); break; 85 case 0xfd06: ms_map_key_clear(KEY_CHAT); break;
67 case 0xfd07: ms_map_key_clear(KEY_PHONE); break; 86 case 0xfd07: ms_map_key_clear(KEY_PHONE); break;
87 case 0xff00:
88 /* Special keypad keys */
89 ms_map_key_clear(KEY_KPEQUAL);
90 set_bit(KEY_KPLEFTPAREN, input->keybit);
91 set_bit(KEY_KPRIGHTPAREN, input->keybit);
92 break;
93 case 0xff01:
94 /* Scroll wheel */
95 hid_map_usage_clear(hi, usage, bit, max, EV_REL, REL_WHEEL);
96 break;
97 case 0xff02:
98 /*
99 * This byte contains a copy of the modifier keys byte of a
100 * standard hid keyboard report, as send by interface 0
101 * (this usage is found on interface 1).
102 *
103 * This byte only gets send when another key in the same report
104 * changes state, and as such is useless, ignore it.
105 */
106 return -1;
68 case 0xff05: 107 case 0xff05:
69 set_bit(EV_REP, input->evbit); 108 set_bit(EV_REP, input->evbit);
70 ms_map_key_clear(KEY_F13); 109 ms_map_key_clear(KEY_F13);
@@ -83,6 +122,9 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
83static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage, 122static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
84 unsigned long **bit, int *max) 123 unsigned long **bit, int *max)
85{ 124{
125 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
126 return 0;
127
86 set_bit(EV_REP, hi->input->evbit); 128 set_bit(EV_REP, hi->input->evbit);
87 switch (usage->hid & HID_USAGE) { 129 switch (usage->hid & HID_USAGE) {
88 case 0xfd08: ms_map_key_clear(KEY_FORWARD); break; 130 case 0xfd08: ms_map_key_clear(KEY_FORWARD); break;
@@ -102,9 +144,6 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
102{ 144{
103 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 145 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
104 146
105 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
106 return 0;
107
108 if (quirks & MS_ERGONOMY) { 147 if (quirks & MS_ERGONOMY) {
109 int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max); 148 int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
110 if (ret) 149 if (ret)
@@ -134,14 +173,39 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
134 struct hid_usage *usage, __s32 value) 173 struct hid_usage *usage, __s32 value)
135{ 174{
136 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 175 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
176 struct input_dev *input;
137 177
138 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || 178 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
139 !usage->type) 179 !usage->type)
140 return 0; 180 return 0;
141 181
182 input = field->hidinput->input;
183
142 /* Handling MS keyboards special buttons */ 184 /* Handling MS keyboards special buttons */
185 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) {
186 /* Special keypad keys */
187 input_report_key(input, KEY_KPEQUAL, value & 0x01);
188 input_report_key(input, KEY_KPLEFTPAREN, value & 0x02);
189 input_report_key(input, KEY_KPRIGHTPAREN, value & 0x04);
190 return 1;
191 }
192
193 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff01)) {
194 /* Scroll wheel */
195 int step = ((value & 0x60) >> 5) + 1;
196
197 switch (value & 0x1f) {
198 case 0x01:
199 input_report_rel(input, REL_WHEEL, step);
200 break;
201 case 0x1f:
202 input_report_rel(input, REL_WHEEL, -step);
203 break;
204 }
205 return 1;
206 }
207
143 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { 208 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
144 struct input_dev *input = field->hidinput->input;
145 static unsigned int last_key = 0; 209 static unsigned int last_key = 0;
146 unsigned int key = 0; 210 unsigned int key = 0;
147 switch (value) { 211 switch (value) {
@@ -194,6 +258,8 @@ err_free:
194static const struct hid_device_id ms_devices[] = { 258static const struct hid_device_id ms_devices[] = {
195 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV), 259 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
196 .driver_data = MS_HIDINPUT }, 260 .driver_data = MS_HIDINPUT },
261 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB),
262 .driver_data = MS_ERGONOMY },
197 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K), 263 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
198 .driver_data = MS_ERGONOMY }, 264 .driver_data = MS_ERGONOMY },
199 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP), 265 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP),