aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPing Cheng <pinglinux@gmail.com>2011-01-11 04:06:58 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-01-11 04:07:44 -0500
commit5fca6cac9feed75efc0b2c454305a5f538d887f5 (patch)
treeab3ff09e1c60cb7e53b82abfa01c8bd73426ddd7
parent9d084a3d5dffd076a9a006164ea0dbd9c495f2b0 (diff)
Input: wacom_w8001 - add single-touch support
Emulate single-touch compatible events for the 2-finger panels so that they can be used with single-touch legacy clients. Assign device ids as Wacom USB vendor ID and product ID. Name the device to reflect its specific features. Scale touch coordinates to pen maximum if pen supported. Signed-off-by: Ping Cheng <pingc@wacom.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c182
1 files changed, 149 insertions, 33 deletions
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 8ed53aded2d3..5cb8449c909d 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (c) 2008 Jaya Kumar 4 * Copyright (c) 2008 Jaya Kumar
5 * Copyright (c) 2010 Red Hat, Inc. 5 * Copyright (c) 2010 Red Hat, Inc.
6 * Copyright (c) 2010 - 2011 Ping Cheng, Wacom. <pingc@wacom.com>
6 * 7 *
7 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for 9 * License. See the file COPYING in the main directory of this archive for
@@ -64,11 +65,11 @@ struct w8001_coord {
64 65
65/* touch query reply packet */ 66/* touch query reply packet */
66struct w8001_touch_query { 67struct w8001_touch_query {
68 u16 x;
69 u16 y;
67 u8 panel_res; 70 u8 panel_res;
68 u8 capacity_res; 71 u8 capacity_res;
69 u8 sensor_id; 72 u8 sensor_id;
70 u16 x;
71 u16 y;
72}; 73};
73 74
74/* 75/*
@@ -87,9 +88,14 @@ struct w8001 {
87 char phys[32]; 88 char phys[32];
88 int type; 89 int type;
89 unsigned int pktlen; 90 unsigned int pktlen;
91 u16 max_touch_x;
92 u16 max_touch_y;
93 u16 max_pen_x;
94 u16 max_pen_y;
95 char name[64];
90}; 96};
91 97
92static void parse_data(u8 *data, struct w8001_coord *coord) 98static void parse_pen_data(u8 *data, struct w8001_coord *coord)
93{ 99{
94 memset(coord, 0, sizeof(*coord)); 100 memset(coord, 0, sizeof(*coord));
95 101
@@ -113,11 +119,30 @@ static void parse_data(u8 *data, struct w8001_coord *coord)
113 coord->tilt_y = data[8] & 0x7F; 119 coord->tilt_y = data[8] & 0x7F;
114} 120}
115 121
116static void parse_touch(struct w8001 *w8001) 122static void parse_single_touch(u8 *data, struct w8001_coord *coord)
123{
124 coord->x = (data[1] << 7) | data[2];
125 coord->y = (data[3] << 7) | data[4];
126 coord->tsw = data[0] & 0x01;
127}
128
129static void scale_touch_coordinates(struct w8001 *w8001,
130 unsigned int *x, unsigned int *y)
131{
132 if (w8001->max_pen_x && w8001->max_touch_x)
133 *x = *x * w8001->max_pen_x / w8001->max_touch_x;
134
135 if (w8001->max_pen_y && w8001->max_touch_y)
136 *y = *y * w8001->max_pen_y / w8001->max_touch_y;
137}
138
139static void parse_multi_touch(struct w8001 *w8001)
117{ 140{
118 struct input_dev *dev = w8001->dev; 141 struct input_dev *dev = w8001->dev;
119 unsigned char *data = w8001->data; 142 unsigned char *data = w8001->data;
143 unsigned int x, y;
120 int i; 144 int i;
145 int count = 0;
121 146
122 for (i = 0; i < 2; i++) { 147 for (i = 0; i < 2; i++) {
123 bool touch = data[0] & (1 << i); 148 bool touch = data[0] & (1 << i);
@@ -125,15 +150,29 @@ static void parse_touch(struct w8001 *w8001)
125 input_mt_slot(dev, i); 150 input_mt_slot(dev, i);
126 input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); 151 input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch);
127 if (touch) { 152 if (touch) {
128 int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]); 153 x = (data[6 * i + 1] << 7) | data[6 * i + 2];
129 int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]); 154 y = (data[6 * i + 3] << 7) | data[6 * i + 4];
130 /* data[5,6] and [11,12] is finger capacity */ 155 /* data[5,6] and [11,12] is finger capacity */
131 156
157 /* scale to pen maximum */
158 scale_touch_coordinates(w8001, &x, &y);
159
132 input_report_abs(dev, ABS_MT_POSITION_X, x); 160 input_report_abs(dev, ABS_MT_POSITION_X, x);
133 input_report_abs(dev, ABS_MT_POSITION_Y, y); 161 input_report_abs(dev, ABS_MT_POSITION_Y, y);
162 count++;
134 } 163 }
135 } 164 }
136 165
166 /* emulate single touch events when stylus is out of proximity.
167 * This is to make single touch backward support consistent
168 * across all Wacom single touch devices.
169 */
170 if (w8001->type != BTN_TOOL_PEN &&
171 w8001->type != BTN_TOOL_RUBBER) {
172 w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED;
173 input_mt_report_pointer_emulation(dev, true);
174 }
175
137 input_sync(dev); 176 input_sync(dev);
138} 177}
139 178
@@ -152,6 +191,15 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
152 query->y = data[5] << 9; 191 query->y = data[5] << 9;
153 query->y |= data[6] << 2; 192 query->y |= data[6] << 2;
154 query->y |= (data[2] >> 3) & 0x3; 193 query->y |= (data[2] >> 3) & 0x3;
194
195 /* Early days' single-finger touch models need the following defaults */
196 if (!query->x && !query->y) {
197 query->x = 1024;
198 query->y = 1024;
199 if (query->panel_res)
200 query->x = query->y = (1 << query->panel_res);
201 query->panel_res = 10;
202 }
155} 203}
156 204
157static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) 205static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
@@ -161,16 +209,15 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
161 /* 209 /*
162 * We have 1 bit for proximity (rdy) and 3 bits for tip, side, 210 * We have 1 bit for proximity (rdy) and 3 bits for tip, side,
163 * side2/eraser. If rdy && f2 are set, this can be either pen + side2, 211 * side2/eraser. If rdy && f2 are set, this can be either pen + side2,
164 * or eraser. assume 212 * or eraser. Assume:
165 * - if dev is already in proximity and f2 is toggled → pen + side2 213 * - if dev is already in proximity and f2 is toggled → pen + side2
166 * - if dev comes into proximity with f2 set → eraser 214 * - if dev comes into proximity with f2 set → eraser
167 * If f2 disappears after assuming eraser, fake proximity out for 215 * If f2 disappears after assuming eraser, fake proximity out for
168 * eraser and in for pen. 216 * eraser and in for pen.
169 */ 217 */
170 218
171 if (!w8001->type) { 219 switch (w8001->type) {
172 w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; 220 case BTN_TOOL_RUBBER:
173 } else if (w8001->type == BTN_TOOL_RUBBER) {
174 if (!coord->f2) { 221 if (!coord->f2) {
175 input_report_abs(dev, ABS_PRESSURE, 0); 222 input_report_abs(dev, ABS_PRESSURE, 0);
176 input_report_key(dev, BTN_TOUCH, 0); 223 input_report_key(dev, BTN_TOUCH, 0);
@@ -180,8 +227,21 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
180 input_sync(dev); 227 input_sync(dev);
181 w8001->type = BTN_TOOL_PEN; 228 w8001->type = BTN_TOOL_PEN;
182 } 229 }
183 } else { 230 break;
231
232 case BTN_TOOL_FINGER:
233 input_report_key(dev, BTN_TOUCH, 0);
234 input_report_key(dev, BTN_TOOL_FINGER, 0);
235 input_sync(dev);
236 /* fall through */
237
238 case KEY_RESERVED:
239 w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
240 break;
241
242 default:
184 input_report_key(dev, BTN_STYLUS2, coord->f2); 243 input_report_key(dev, BTN_STYLUS2, coord->f2);
244 break;
185 } 245 }
186 246
187 input_report_abs(dev, ABS_X, coord->x); 247 input_report_abs(dev, ABS_X, coord->x);
@@ -193,7 +253,26 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
193 input_sync(dev); 253 input_sync(dev);
194 254
195 if (!coord->rdy) 255 if (!coord->rdy)
196 w8001->type = 0; 256 w8001->type = KEY_RESERVED;
257}
258
259static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord)
260{
261 struct input_dev *dev = w8001->dev;
262 unsigned int x = coord->x;
263 unsigned int y = coord->y;
264
265 /* scale to pen maximum */
266 scale_touch_coordinates(w8001, &x, &y);
267
268 input_report_abs(dev, ABS_X, x);
269 input_report_abs(dev, ABS_Y, y);
270 input_report_key(dev, BTN_TOUCH, coord->tsw);
271 input_report_key(dev, BTN_TOOL_FINGER, coord->tsw);
272
273 input_sync(dev);
274
275 w8001->type = coord->tsw ? BTN_TOOL_FINGER : KEY_RESERVED;
197} 276}
198 277
199static irqreturn_t w8001_interrupt(struct serio *serio, 278static irqreturn_t w8001_interrupt(struct serio *serio,
@@ -214,9 +293,18 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
214 293
215 case W8001_PKTLEN_TOUCH93 - 1: 294 case W8001_PKTLEN_TOUCH93 - 1:
216 case W8001_PKTLEN_TOUCH9A - 1: 295 case W8001_PKTLEN_TOUCH9A - 1:
217 /* ignore one-finger touch packet. */ 296 tmp = w8001->data[0] & W8001_TOUCH_BYTE;
218 if (w8001->pktlen == w8001->idx) 297 if (tmp != W8001_TOUCH_BYTE)
298 break;
299
300 if (w8001->pktlen == w8001->idx) {
219 w8001->idx = 0; 301 w8001->idx = 0;
302 if (w8001->type != BTN_TOOL_PEN &&
303 w8001->type != BTN_TOOL_RUBBER) {
304 parse_single_touch(w8001->data, &coord);
305 report_single_touch(w8001, &coord);
306 }
307 }
220 break; 308 break;
221 309
222 /* Pen coordinates packet */ 310 /* Pen coordinates packet */
@@ -225,18 +313,18 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
225 if (unlikely(tmp == W8001_TAB_BYTE)) 313 if (unlikely(tmp == W8001_TAB_BYTE))
226 break; 314 break;
227 315
228 tmp = (w8001->data[0] & W8001_TOUCH_BYTE); 316 tmp = w8001->data[0] & W8001_TOUCH_BYTE;
229 if (tmp == W8001_TOUCH_BYTE) 317 if (tmp == W8001_TOUCH_BYTE)
230 break; 318 break;
231 319
232 w8001->idx = 0; 320 w8001->idx = 0;
233 parse_data(w8001->data, &coord); 321 parse_pen_data(w8001->data, &coord);
234 report_pen_events(w8001, &coord); 322 report_pen_events(w8001, &coord);
235 break; 323 break;
236 324
237 /* control packet */ 325 /* control packet */
238 case W8001_PKTLEN_TPCCTL - 1: 326 case W8001_PKTLEN_TPCCTL - 1:
239 tmp = (w8001->data[0] & W8001_TOUCH_MASK); 327 tmp = w8001->data[0] & W8001_TOUCH_MASK;
240 if (tmp == W8001_TOUCH_BYTE) 328 if (tmp == W8001_TOUCH_BYTE)
241 break; 329 break;
242 330
@@ -249,7 +337,7 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
249 /* 2 finger touch packet */ 337 /* 2 finger touch packet */
250 case W8001_PKTLEN_TOUCH2FG - 1: 338 case W8001_PKTLEN_TOUCH2FG - 1:
251 w8001->idx = 0; 339 w8001->idx = 0;
252 parse_touch(w8001); 340 parse_multi_touch(w8001);
253 break; 341 break;
254 } 342 }
255 343
@@ -279,6 +367,7 @@ static int w8001_setup(struct w8001 *w8001)
279{ 367{
280 struct input_dev *dev = w8001->dev; 368 struct input_dev *dev = w8001->dev;
281 struct w8001_coord coord; 369 struct w8001_coord coord;
370 struct w8001_touch_query touch;
282 int error; 371 int error;
283 372
284 error = w8001_command(w8001, W8001_CMD_STOP, false); 373 error = w8001_command(w8001, W8001_CMD_STOP, false);
@@ -287,14 +376,21 @@ static int w8001_setup(struct w8001 *w8001)
287 376
288 msleep(250); /* wait 250ms before querying the device */ 377 msleep(250); /* wait 250ms before querying the device */
289 378
379 dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
380 strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name));
381
290 /* penabled? */ 382 /* penabled? */
291 error = w8001_command(w8001, W8001_CMD_QUERY, true); 383 error = w8001_command(w8001, W8001_CMD_QUERY, true);
292 if (!error) { 384 if (!error) {
385 __set_bit(BTN_TOUCH, dev->keybit);
293 __set_bit(BTN_TOOL_PEN, dev->keybit); 386 __set_bit(BTN_TOOL_PEN, dev->keybit);
294 __set_bit(BTN_TOOL_RUBBER, dev->keybit); 387 __set_bit(BTN_TOOL_RUBBER, dev->keybit);
295 __set_bit(BTN_STYLUS, dev->keybit); 388 __set_bit(BTN_STYLUS, dev->keybit);
296 __set_bit(BTN_STYLUS2, dev->keybit); 389 __set_bit(BTN_STYLUS2, dev->keybit);
297 parse_data(w8001->response, &coord); 390
391 parse_pen_data(w8001->response, &coord);
392 w8001->max_pen_x = coord.x;
393 w8001->max_pen_y = coord.y;
298 394
299 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); 395 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
300 input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); 396 input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
@@ -303,6 +399,8 @@ static int w8001_setup(struct w8001 *w8001)
303 input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); 399 input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
304 input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); 400 input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
305 } 401 }
402 w8001->id = 0x90;
403 strlcat(w8001->name, " Penabled", sizeof(w8001->name));
306 } 404 }
307 405
308 /* Touch enabled? */ 406 /* Touch enabled? */
@@ -313,24 +411,38 @@ static int w8001_setup(struct w8001 *w8001)
313 * second byte is empty, which indicates touch is not supported. 411 * second byte is empty, which indicates touch is not supported.
314 */ 412 */
315 if (!error && w8001->response[1]) { 413 if (!error && w8001->response[1]) {
316 struct w8001_touch_query touch; 414 __set_bit(BTN_TOUCH, dev->keybit);
415 __set_bit(BTN_TOOL_FINGER, dev->keybit);
317 416
318 parse_touchquery(w8001->response, &touch); 417 parse_touchquery(w8001->response, &touch);
418 w8001->max_touch_x = touch.x;
419 w8001->max_touch_y = touch.y;
420
421 /* scale to pen maximum */
422 if (w8001->max_pen_x && w8001->max_pen_y) {
423 touch.x = w8001->max_pen_x;
424 touch.y = w8001->max_pen_y;
425 }
319 426
320 input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); 427 input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
321 input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); 428 input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0);
322 __set_bit(BTN_TOOL_FINGER, dev->keybit);
323 429
324 switch (touch.sensor_id) { 430 switch (touch.sensor_id) {
325 case 0: 431 case 0:
326 case 2: 432 case 2:
327 w8001->pktlen = W8001_PKTLEN_TOUCH93; 433 w8001->pktlen = W8001_PKTLEN_TOUCH93;
434 w8001->id = 0x93;
435 strlcat(w8001->name, " 1FG", sizeof(w8001->name));
328 break; 436 break;
437
329 case 1: 438 case 1:
330 case 3: 439 case 3:
331 case 4: 440 case 4:
332 w8001->pktlen = W8001_PKTLEN_TOUCH9A; 441 w8001->pktlen = W8001_PKTLEN_TOUCH9A;
442 strlcat(w8001->name, " 1FG", sizeof(w8001->name));
443 w8001->id = 0x9a;
333 break; 444 break;
445
334 case 5: 446 case 5:
335 w8001->pktlen = W8001_PKTLEN_TOUCH2FG; 447 w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
336 448
@@ -341,10 +453,18 @@ static int w8001_setup(struct w8001 *w8001)
341 0, touch.y, 0, 0); 453 0, touch.y, 0, 0);
342 input_set_abs_params(dev, ABS_MT_TOOL_TYPE, 454 input_set_abs_params(dev, ABS_MT_TOOL_TYPE,
343 0, MT_TOOL_MAX, 0, 0); 455 0, MT_TOOL_MAX, 0, 0);
456
457 strlcat(w8001->name, " 2FG", sizeof(w8001->name));
458 if (w8001->max_pen_x && w8001->max_pen_y)
459 w8001->id = 0xE3;
460 else
461 w8001->id = 0xE2;
344 break; 462 break;
345 } 463 }
346 } 464 }
347 465
466 strlcat(w8001->name, " Touchscreen", sizeof(w8001->name));
467
348 return w8001_command(w8001, W8001_CMD_START, false); 468 return w8001_command(w8001, W8001_CMD_START, false);
349} 469}
350 470
@@ -384,22 +504,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
384 } 504 }
385 505
386 w8001->serio = serio; 506 w8001->serio = serio;
387 w8001->id = serio->id.id;
388 w8001->dev = input_dev; 507 w8001->dev = input_dev;
389 init_completion(&w8001->cmd_done); 508 init_completion(&w8001->cmd_done);
390 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); 509 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
391 510
392 input_dev->name = "Wacom W8001 Penabled Serial TouchScreen";
393 input_dev->phys = w8001->phys;
394 input_dev->id.bustype = BUS_RS232;
395 input_dev->id.vendor = SERIO_W8001;
396 input_dev->id.product = w8001->id;
397 input_dev->id.version = 0x0100;
398 input_dev->dev.parent = &serio->dev;
399
400 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
401 __set_bit(BTN_TOUCH, input_dev->keybit);
402
403 serio_set_drvdata(serio, w8001); 511 serio_set_drvdata(serio, w8001);
404 err = serio_open(serio, drv); 512 err = serio_open(serio, drv);
405 if (err) 513 if (err)
@@ -409,6 +517,14 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
409 if (err) 517 if (err)
410 goto fail3; 518 goto fail3;
411 519
520 input_dev->name = w8001->name;
521 input_dev->phys = w8001->phys;
522 input_dev->id.product = w8001->id;
523 input_dev->id.bustype = BUS_RS232;
524 input_dev->id.vendor = 0x056a;
525 input_dev->id.version = 0x0100;
526 input_dev->dev.parent = &serio->dev;
527
412 err = input_register_device(w8001->dev); 528 err = input_register_device(w8001->dev);
413 if (err) 529 if (err)
414 goto fail3; 530 goto fail3;