aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/tablet')
-rw-r--r--drivers/input/tablet/wacom_sys.c12
-rw-r--r--drivers/input/tablet/wacom_wac.c163
2 files changed, 111 insertions, 64 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 8b5d2873f0c4..f46502589e4e 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 b3ba3437a2eb..4a852d815c68 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 }
259exit: 298 return 1;
260 return retval;
261} 299}
262 300
263static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) 301static 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)
598static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) 636static 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;