diff options
author | Hans de Goede <hdegoede@redhat.com> | 2014-01-29 11:57:43 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-02-03 05:11:53 -0500 |
commit | 3faed1aff786a007b3ea0549ac469e09f48c98f9 (patch) | |
tree | ebeb9fddb3a4bd2a2544a8ad5c9a03b3891abdcb /drivers/hid | |
parent | aac59f6a96044f423408ee17f4e8e11d904c2b80 (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.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 1 | ||||
-rw-r--r-- | drivers/hid/hid-microsoft.c | 49 |
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: | |||
197 | static const struct hid_device_id ms_devices[] = { | 242 | static 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), |