diff options
Diffstat (limited to 'drivers/input/tablet')
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 12 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 163 |
2 files changed, 111 insertions, 64 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 8b5d2873f0c..f46502589e4 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf) | |||
673 | int rv; | 673 | int rv; |
674 | 674 | ||
675 | mutex_lock(&wacom->lock); | 675 | mutex_lock(&wacom->lock); |
676 | if (wacom->open) { | 676 | |
677 | /* switch to wacom mode first */ | ||
678 | wacom_query_tablet_data(intf, features); | ||
679 | |||
680 | if (wacom->open) | ||
677 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); | 681 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); |
678 | /* switch to wacom mode if needed */ | 682 | else |
679 | if (!wacom_retrieve_hid_descriptor(intf, features)) | ||
680 | wacom_query_tablet_data(intf, features); | ||
681 | } else | ||
682 | rv = 0; | 683 | rv = 0; |
684 | |||
683 | mutex_unlock(&wacom->lock); | 685 | mutex_unlock(&wacom->lock); |
684 | 686 | ||
685 | return rv; | 687 | return rv; |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index b3ba3437a2e..4a852d815c6 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
155 | { | 155 | { |
156 | struct wacom_features *features = &wacom->features; | 156 | struct wacom_features *features = &wacom->features; |
157 | unsigned char *data = wacom->data; | 157 | unsigned char *data = wacom->data; |
158 | int x, y, prox; | 158 | int x, y, rw; |
159 | int rw = 0; | 159 | static int penData = 0; |
160 | int retval = 0; | ||
161 | 160 | ||
162 | if (data[0] != WACOM_REPORT_PENABLED) { | 161 | if (data[0] != WACOM_REPORT_PENABLED) { |
163 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); | 162 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); |
164 | goto exit; | 163 | return 0; |
165 | } | 164 | } |
166 | 165 | ||
167 | prox = data[1] & 0x80; | 166 | if (data[1] & 0x80) { |
168 | if (prox || wacom->id[0]) { | 167 | /* in prox and not a pad data */ |
169 | if (prox) { | 168 | penData = 1; |
170 | switch ((data[1] >> 5) & 3) { | 169 | |
170 | switch ((data[1] >> 5) & 3) { | ||
171 | 171 | ||
172 | case 0: /* Pen */ | 172 | case 0: /* Pen */ |
173 | wacom->tool[0] = BTN_TOOL_PEN; | 173 | wacom->tool[0] = BTN_TOOL_PEN; |
@@ -181,13 +181,23 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
181 | 181 | ||
182 | case 2: /* Mouse with wheel */ | 182 | case 2: /* Mouse with wheel */ |
183 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); | 183 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); |
184 | if (features->type == WACOM_G4 || features->type == WACOM_MO) { | ||
185 | rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); | ||
186 | wacom_report_rel(wcombo, REL_WHEEL, -rw); | ||
187 | } else | ||
188 | wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); | ||
184 | /* fall through */ | 189 | /* fall through */ |
185 | 190 | ||
186 | case 3: /* Mouse without wheel */ | 191 | case 3: /* Mouse without wheel */ |
187 | wacom->tool[0] = BTN_TOOL_MOUSE; | 192 | wacom->tool[0] = BTN_TOOL_MOUSE; |
188 | wacom->id[0] = CURSOR_DEVICE_ID; | 193 | wacom->id[0] = CURSOR_DEVICE_ID; |
194 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | ||
195 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | ||
196 | if (features->type == WACOM_G4 || features->type == WACOM_MO) | ||
197 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); | ||
198 | else | ||
199 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); | ||
189 | break; | 200 | break; |
190 | } | ||
191 | } | 201 | } |
192 | x = wacom_le16_to_cpu(&data[2]); | 202 | x = wacom_le16_to_cpu(&data[2]); |
193 | y = wacom_le16_to_cpu(&data[4]); | 203 | y = wacom_le16_to_cpu(&data[4]); |
@@ -198,32 +208,36 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
198 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); | 208 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); |
199 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 209 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
200 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); | 210 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); |
201 | } else { | ||
202 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | ||
203 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | ||
204 | if (features->type == WACOM_G4 || | ||
205 | features->type == WACOM_MO) { | ||
206 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); | ||
207 | rw = (signed)(data[7] & 0x04) - (data[7] & 0x03); | ||
208 | } else { | ||
209 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); | ||
210 | rw = -(signed)data[6]; | ||
211 | } | ||
212 | wacom_report_rel(wcombo, REL_WHEEL, rw); | ||
213 | } | 211 | } |
214 | |||
215 | if (!prox) | ||
216 | wacom->id[0] = 0; | ||
217 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ | 212 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ |
218 | wacom_report_key(wcombo, wacom->tool[0], prox); | 213 | wacom_report_key(wcombo, wacom->tool[0], 1); |
219 | wacom_input_sync(wcombo); /* sync last event */ | 214 | } else if (wacom->id[0]) { |
215 | wacom_report_abs(wcombo, ABS_X, 0); | ||
216 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
217 | if (wacom->tool[0] == BTN_TOOL_MOUSE) { | ||
218 | wacom_report_key(wcombo, BTN_LEFT, 0); | ||
219 | wacom_report_key(wcombo, BTN_RIGHT, 0); | ||
220 | wacom_report_abs(wcombo, ABS_DISTANCE, 0); | ||
221 | } else { | ||
222 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | ||
223 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
224 | wacom_report_key(wcombo, BTN_STYLUS, 0); | ||
225 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | ||
226 | } | ||
227 | wacom->id[0] = 0; | ||
228 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | ||
229 | wacom_report_key(wcombo, wacom->tool[0], 0); | ||
220 | } | 230 | } |
221 | 231 | ||
222 | /* send pad data */ | 232 | /* send pad data */ |
223 | switch (features->type) { | 233 | switch (features->type) { |
224 | case WACOM_G4: | 234 | case WACOM_G4: |
225 | prox = data[7] & 0xf8; | 235 | if (data[7] & 0xf8) { |
226 | if (prox || wacom->id[1]) { | 236 | if (penData) { |
237 | wacom_input_sync(wcombo); /* sync last event */ | ||
238 | if (!wacom->id[0]) | ||
239 | penData = 0; | ||
240 | } | ||
227 | wacom->id[1] = PAD_DEVICE_ID; | 241 | wacom->id[1] = PAD_DEVICE_ID; |
228 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 242 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
229 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 243 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
@@ -231,16 +245,29 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
231 | wacom_report_rel(wcombo, REL_WHEEL, rw); | 245 | wacom_report_rel(wcombo, REL_WHEEL, rw); |
232 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 246 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); |
233 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 247 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
234 | if (!prox) | 248 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
235 | wacom->id[1] = 0; | 249 | } else if (wacom->id[1]) { |
236 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 250 | if (penData) { |
251 | wacom_input_sync(wcombo); /* sync last event */ | ||
252 | if (!wacom->id[0]) | ||
253 | penData = 0; | ||
254 | } | ||
255 | wacom->id[1] = 0; | ||
256 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | ||
257 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | ||
258 | wacom_report_rel(wcombo, REL_WHEEL, 0); | ||
259 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | ||
260 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
237 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 261 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
238 | } | 262 | } |
239 | retval = 1; | ||
240 | break; | 263 | break; |
241 | case WACOM_MO: | 264 | case WACOM_MO: |
242 | prox = (data[7] & 0xf8) || data[8]; | 265 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { |
243 | if (prox || wacom->id[1]) { | 266 | if (penData) { |
267 | wacom_input_sync(wcombo); /* sync last event */ | ||
268 | if (!wacom->id[0]) | ||
269 | penData = 0; | ||
270 | } | ||
244 | wacom->id[1] = PAD_DEVICE_ID; | 271 | wacom->id[1] = PAD_DEVICE_ID; |
245 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 272 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
246 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 273 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
@@ -248,16 +275,27 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
248 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | 275 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); |
249 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | 276 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); |
250 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 277 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); |
251 | if (!prox) | ||
252 | wacom->id[1] = 0; | ||
253 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 278 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
254 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 279 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
280 | } else if (wacom->id[1]) { | ||
281 | if (penData) { | ||
282 | wacom_input_sync(wcombo); /* sync last event */ | ||
283 | if (!wacom->id[0]) | ||
284 | penData = 0; | ||
285 | } | ||
286 | wacom->id[1] = 0; | ||
287 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | ||
288 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | ||
289 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); | ||
290 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | ||
291 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | ||
292 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | ||
293 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
294 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
255 | } | 295 | } |
256 | retval = 1; | ||
257 | break; | 296 | break; |
258 | } | 297 | } |
259 | exit: | 298 | return 1; |
260 | return retval; | ||
261 | } | 299 | } |
262 | 300 | ||
263 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | 301 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) |
@@ -598,9 +636,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
598 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) | 636 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) |
599 | { | 637 | { |
600 | wacom_report_abs(wcombo, ABS_X, | 638 | wacom_report_abs(wcombo, ABS_X, |
601 | data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8)); | 639 | (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); |
602 | wacom_report_abs(wcombo, ABS_Y, | 640 | wacom_report_abs(wcombo, ABS_Y, |
603 | data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8)); | 641 | (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); |
604 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 642 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); |
605 | wacom_report_key(wcombo, wacom->tool[idx], 1); | 643 | wacom_report_key(wcombo, wacom->tool[idx], 1); |
606 | if (idx) | 644 | if (idx) |
@@ -744,24 +782,31 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
744 | 782 | ||
745 | touchInProx = 0; | 783 | touchInProx = 0; |
746 | 784 | ||
747 | if (!wacom->id[0]) { /* first in prox */ | 785 | if (prox) { /* in prox */ |
748 | /* Going into proximity select tool */ | 786 | if (!wacom->id[0]) { |
749 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 787 | /* Going into proximity select tool */ |
750 | if (wacom->tool[0] == BTN_TOOL_PEN) | 788 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
751 | wacom->id[0] = STYLUS_DEVICE_ID; | 789 | if (wacom->tool[0] == BTN_TOOL_PEN) |
752 | else | 790 | wacom->id[0] = STYLUS_DEVICE_ID; |
753 | wacom->id[0] = ERASER_DEVICE_ID; | 791 | else |
754 | } | 792 | wacom->id[0] = ERASER_DEVICE_ID; |
755 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 793 | } |
756 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | 794 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
757 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | 795 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); |
758 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | 796 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); |
759 | pressure = ((data[7] & 0x01) << 8) | data[6]; | 797 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); |
760 | if (pressure < 0) | 798 | pressure = ((data[7] & 0x01) << 8) | data[6]; |
761 | pressure = features->pressure_max + pressure + 1; | 799 | if (pressure < 0) |
762 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | 800 | pressure = features->pressure_max + pressure + 1; |
763 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); | 801 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); |
764 | if (!prox) { /* out-prox */ | 802 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); |
803 | } else { | ||
804 | wacom_report_abs(wcombo, ABS_X, 0); | ||
805 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
806 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | ||
807 | wacom_report_key(wcombo, BTN_STYLUS, 0); | ||
808 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | ||
809 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
765 | wacom->id[0] = 0; | 810 | wacom->id[0] = 0; |
766 | /* pen is out so touch can be enabled now */ | 811 | /* pen is out so touch can be enabled now */ |
767 | touchInProx = 1; | 812 | touchInProx = 1; |