diff options
Diffstat (limited to 'drivers/hid/hid-microsoft.c')
-rw-r--r-- | drivers/hid/hid-microsoft.c | 74 |
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, | |||
83 | static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage, | 122 | static 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: | |||
194 | static const struct hid_device_id ms_devices[] = { | 258 | static 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), |