aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-01-29 11:57:43 -0500
committerJiri Kosina <jkosina@suse.cz>2014-02-03 05:11:53 -0500
commit3faed1aff786a007b3ea0549ac469e09f48c98f9 (patch)
treeebeb9fddb3a4bd2a2544a8ad5c9a03b3891abdcb /drivers/hid
parentaac59f6a96044f423408ee17f4e8e11d904c2b80 (diff)
HID: hid-microsoft: Add support for scrollwheel and special keypad keys
The Microsoft Office keyboard has a scrollwheel as well as some special keys above the keypad which are handled through the custom MS usage page, this commit adds support for these. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-microsoft.c49
3 files changed, 50 insertions, 1 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 026ab0fc06f7..cd33ec66133e 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1779,6 +1779,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1779 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, 1779 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
1780 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, 1780 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
1781 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, 1781 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
1782 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
1782 { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, 1783 { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
1783 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, 1784 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
1784 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, 1785 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 92b40c09d917..6f1c97bfbd26 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -609,6 +609,7 @@
609 609
610#define USB_VENDOR_ID_MICROSOFT 0x045e 610#define USB_VENDOR_ID_MICROSOFT 0x045e
611#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b 611#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
612#define USB_DEVICE_ID_MS_OFFICE_KB 0x0048
612#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d 613#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
613#define USB_DEVICE_ID_MS_NE4K 0x00db 614#define USB_DEVICE_ID_MS_NE4K 0x00db
614#define USB_DEVICE_ID_MS_NE4K_JP 0x00dc 615#define USB_DEVICE_ID_MS_NE4K_JP 0x00dc
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 5268dec5d81a..fe415e8ed7c4 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -68,6 +68,26 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
68 switch (usage->hid & HID_USAGE) { 68 switch (usage->hid & HID_USAGE) {
69 case 0xfd06: ms_map_key_clear(KEY_CHAT); break; 69 case 0xfd06: ms_map_key_clear(KEY_CHAT); break;
70 case 0xfd07: ms_map_key_clear(KEY_PHONE); break; 70 case 0xfd07: ms_map_key_clear(KEY_PHONE); break;
71 case 0xff00:
72 /* Special keypad keys */
73 ms_map_key_clear(KEY_KPEQUAL);
74 set_bit(KEY_KPLEFTPAREN, input->keybit);
75 set_bit(KEY_KPRIGHTPAREN, input->keybit);
76 break;
77 case 0xff01:
78 /* Scroll wheel */
79 hid_map_usage_clear(hi, usage, bit, max, EV_REL, REL_WHEEL);
80 break;
81 case 0xff02:
82 /*
83 * This byte contains a copy of the modifier keys byte of a
84 * standard hid keyboard report, as send by interface 0
85 * (this usage is found on interface 1).
86 *
87 * This byte only gets send when another key in the same report
88 * changes state, and as such is useless, ignore it.
89 */
90 return -1;
71 case 0xff05: 91 case 0xff05:
72 set_bit(EV_REP, input->evbit); 92 set_bit(EV_REP, input->evbit);
73 ms_map_key_clear(KEY_F13); 93 ms_map_key_clear(KEY_F13);
@@ -137,14 +157,39 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
137 struct hid_usage *usage, __s32 value) 157 struct hid_usage *usage, __s32 value)
138{ 158{
139 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 159 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
160 struct input_dev *input;
140 161
141 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || 162 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
142 !usage->type) 163 !usage->type)
143 return 0; 164 return 0;
144 165
166 input = field->hidinput->input;
167
145 /* Handling MS keyboards special buttons */ 168 /* Handling MS keyboards special buttons */
169 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) {
170 /* Special keypad keys */
171 input_report_key(input, KEY_KPEQUAL, value & 0x01);
172 input_report_key(input, KEY_KPLEFTPAREN, value & 0x02);
173 input_report_key(input, KEY_KPRIGHTPAREN, value & 0x04);
174 return 1;
175 }
176
177 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff01)) {
178 /* Scroll wheel */
179 int step = ((value & 0x60) >> 5) + 1;
180
181 switch (value & 0x1f) {
182 case 0x01:
183 input_report_rel(input, REL_WHEEL, step);
184 break;
185 case 0x1f:
186 input_report_rel(input, REL_WHEEL, -step);
187 break;
188 }
189 return 1;
190 }
191
146 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { 192 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
147 struct input_dev *input = field->hidinput->input;
148 static unsigned int last_key = 0; 193 static unsigned int last_key = 0;
149 unsigned int key = 0; 194 unsigned int key = 0;
150 switch (value) { 195 switch (value) {
@@ -197,6 +242,8 @@ err_free:
197static const struct hid_device_id ms_devices[] = { 242static const struct hid_device_id ms_devices[] = {
198 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV), 243 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
199 .driver_data = MS_HIDINPUT }, 244 .driver_data = MS_HIDINPUT },
245 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB),
246 .driver_data = MS_ERGONOMY },
200 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K), 247 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
201 .driver_data = MS_ERGONOMY }, 248 .driver_data = MS_ERGONOMY },
202 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP), 249 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP),