Lines Matching +full:touchscreen +full:- +full:x +full:- +full:mm
2 * Wacom W8001 penabled serial touchscreen driver
6 * Copyright (c) 2010 - 2011 Ping Cheng, Wacom. <pingc@wacom.com>
12 * Layout based on Elo serial touchscreen driver by Vojtech Pavlik
24 #define DRIVER_DESC "Wacom W8001 serial touchscreen driver"
55 /* resolution in points/mm */
64 u16 x; member
73 u16 x; member
81 * Per-touchscreen data.
111 coord->rdy = data[0] & 0x20; in parse_pen_data()
112 coord->tsw = data[0] & 0x01; in parse_pen_data()
113 coord->f1 = data[0] & 0x02; in parse_pen_data()
114 coord->f2 = data[0] & 0x04; in parse_pen_data()
116 coord->x = (data[1] & 0x7F) << 9; in parse_pen_data()
117 coord->x |= (data[2] & 0x7F) << 2; in parse_pen_data()
118 coord->x |= (data[6] & 0x60) >> 5; in parse_pen_data()
120 coord->y = (data[3] & 0x7F) << 9; in parse_pen_data()
121 coord->y |= (data[4] & 0x7F) << 2; in parse_pen_data()
122 coord->y |= (data[6] & 0x18) >> 3; in parse_pen_data()
124 coord->pen_pressure = data[5] & 0x7F; in parse_pen_data()
125 coord->pen_pressure |= (data[6] & 0x07) << 7 ; in parse_pen_data()
127 coord->tilt_x = data[7] & 0x7F; in parse_pen_data()
128 coord->tilt_y = data[8] & 0x7F; in parse_pen_data()
133 coord->x = (data[1] << 7) | data[2]; in parse_single_touch()
134 coord->y = (data[3] << 7) | data[4]; in parse_single_touch()
135 coord->tsw = data[0] & 0x01; in parse_single_touch()
139 unsigned int *x, unsigned int *y) in scale_touch_coordinates() argument
141 if (w8001->max_pen_x && w8001->max_touch_x) in scale_touch_coordinates()
142 *x = *x * w8001->max_pen_x / w8001->max_touch_x; in scale_touch_coordinates()
144 if (w8001->max_pen_y && w8001->max_touch_y) in scale_touch_coordinates()
145 *y = *y * w8001->max_pen_y / w8001->max_touch_y; in scale_touch_coordinates()
150 struct input_dev *dev = w8001->touch_dev; in parse_multi_touch()
151 unsigned char *data = w8001->data; in parse_multi_touch()
152 unsigned int x, y; in parse_multi_touch() local
162 x = (data[6 * i + 1] << 7) | data[6 * i + 2]; in parse_multi_touch()
167 scale_touch_coordinates(w8001, &x, &y); in parse_multi_touch()
169 input_report_abs(dev, ABS_MT_POSITION_X, x); in parse_multi_touch()
179 if (w8001->type != BTN_TOOL_PEN && in parse_multi_touch()
180 w8001->type != BTN_TOOL_RUBBER) { in parse_multi_touch()
181 w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED; in parse_multi_touch()
192 query->panel_res = data[1]; in parse_touchquery()
193 query->sensor_id = data[2] & 0x7; in parse_touchquery()
194 query->capacity_res = data[7]; in parse_touchquery()
196 query->x = data[3] << 9; in parse_touchquery()
197 query->x |= data[4] << 2; in parse_touchquery()
198 query->x |= (data[2] >> 5) & 0x3; in parse_touchquery()
200 query->y = data[5] << 9; in parse_touchquery()
201 query->y |= data[6] << 2; in parse_touchquery()
202 query->y |= (data[2] >> 3) & 0x3; in parse_touchquery()
204 /* Early days' single-finger touch models need the following defaults */ in parse_touchquery()
205 if (!query->x && !query->y) { in parse_touchquery()
206 query->x = 1024; in parse_touchquery()
207 query->y = 1024; in parse_touchquery()
208 if (query->panel_res) in parse_touchquery()
209 query->x = query->y = (1 << query->panel_res); in parse_touchquery()
210 query->panel_res = W8001_TOUCH_RESOLUTION; in parse_touchquery()
216 struct input_dev *dev = w8001->pen_dev; in report_pen_events()
222 * - if dev is already in proximity and f2 is toggled → pen + side2 in report_pen_events()
223 * - if dev comes into proximity with f2 set → eraser in report_pen_events()
228 switch (w8001->type) { in report_pen_events()
230 if (!coord->f2) { in report_pen_events()
237 w8001->type = BTN_TOOL_PEN; in report_pen_events()
243 w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; in report_pen_events()
247 input_report_key(dev, BTN_STYLUS2, coord->f2); in report_pen_events()
251 input_report_abs(dev, ABS_X, coord->x); in report_pen_events()
252 input_report_abs(dev, ABS_Y, coord->y); in report_pen_events()
253 input_report_abs(dev, ABS_PRESSURE, coord->pen_pressure); in report_pen_events()
254 input_report_key(dev, BTN_TOUCH, coord->tsw); in report_pen_events()
255 input_report_key(dev, BTN_STYLUS, coord->f1); in report_pen_events()
256 input_report_key(dev, w8001->type, coord->rdy); in report_pen_events()
259 if (!coord->rdy) in report_pen_events()
260 w8001->type = KEY_RESERVED; in report_pen_events()
265 struct input_dev *dev = w8001->touch_dev; in report_single_touch()
266 unsigned int x = coord->x; in report_single_touch() local
267 unsigned int y = coord->y; in report_single_touch()
270 scale_touch_coordinates(w8001, &x, &y); in report_single_touch()
272 input_report_abs(dev, ABS_X, x); in report_single_touch()
274 input_report_key(dev, BTN_TOUCH, coord->tsw); in report_single_touch()
278 w8001->type = coord->tsw ? BTN_TOOL_FINGER : KEY_RESERVED; in report_single_touch()
288 w8001->data[w8001->idx] = data; in w8001_interrupt()
289 switch (w8001->idx++) { in w8001_interrupt()
292 pr_debug("w8001: unsynchronized data: 0x%02x\n", data); in w8001_interrupt()
293 w8001->idx = 0; in w8001_interrupt()
297 case W8001_PKTLEN_TOUCH93 - 1: in w8001_interrupt()
298 case W8001_PKTLEN_TOUCH9A - 1: in w8001_interrupt()
299 tmp = w8001->data[0] & W8001_TOUCH_BYTE; in w8001_interrupt()
303 if (w8001->pktlen == w8001->idx) { in w8001_interrupt()
304 w8001->idx = 0; in w8001_interrupt()
305 if (w8001->type != BTN_TOOL_PEN && in w8001_interrupt()
306 w8001->type != BTN_TOOL_RUBBER) { in w8001_interrupt()
307 parse_single_touch(w8001->data, &coord); in w8001_interrupt()
314 case W8001_PKTLEN_TPCPEN - 1: in w8001_interrupt()
315 tmp = w8001->data[0] & W8001_TAB_MASK; in w8001_interrupt()
319 tmp = w8001->data[0] & W8001_TOUCH_BYTE; in w8001_interrupt()
323 w8001->idx = 0; in w8001_interrupt()
324 parse_pen_data(w8001->data, &coord); in w8001_interrupt()
329 case W8001_PKTLEN_TPCCTL - 1: in w8001_interrupt()
330 tmp = w8001->data[0] & W8001_TOUCH_MASK; in w8001_interrupt()
334 w8001->idx = 0; in w8001_interrupt()
335 memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); in w8001_interrupt()
336 w8001->response_type = W8001_QUERY_PACKET; in w8001_interrupt()
337 complete(&w8001->cmd_done); in w8001_interrupt()
341 case W8001_PKTLEN_TOUCH2FG - 1: in w8001_interrupt()
342 w8001->idx = 0; in w8001_interrupt()
352 if (!w8001->touch_dev && w8001->idx > W8001_PKTLEN_TPCPEN - 1) in w8001_interrupt()
353 w8001->idx = 0; in w8001_interrupt()
364 w8001->response_type = 0; in w8001_command()
365 init_completion(&w8001->cmd_done); in w8001_command()
367 rc = serio_write(w8001->serio, command); in w8001_command()
370 wait_for_completion_timeout(&w8001->cmd_done, HZ); in w8001_command()
371 if (w8001->response_type != W8001_QUERY_PACKET) in w8001_command()
372 rc = -EIO; in w8001_command()
383 err = mutex_lock_interruptible(&w8001->mutex); in w8001_open()
387 if (w8001->open_count++ == 0) { in w8001_open()
390 w8001->open_count--; in w8001_open()
393 mutex_unlock(&w8001->mutex); in w8001_open()
401 mutex_lock(&w8001->mutex); in w8001_close()
403 if (--w8001->open_count == 0) in w8001_close()
406 mutex_unlock(&w8001->mutex); in w8001_close()
425 struct input_dev *dev = w8001->pen_dev; in w8001_setup_pen()
434 __set_bit(EV_KEY, dev->evbit); in w8001_setup_pen()
435 __set_bit(EV_ABS, dev->evbit); in w8001_setup_pen()
436 __set_bit(BTN_TOUCH, dev->keybit); in w8001_setup_pen()
437 __set_bit(BTN_TOOL_PEN, dev->keybit); in w8001_setup_pen()
438 __set_bit(BTN_TOOL_RUBBER, dev->keybit); in w8001_setup_pen()
439 __set_bit(BTN_STYLUS, dev->keybit); in w8001_setup_pen()
440 __set_bit(BTN_STYLUS2, dev->keybit); in w8001_setup_pen()
441 __set_bit(INPUT_PROP_DIRECT, dev->propbit); in w8001_setup_pen()
443 parse_pen_data(w8001->response, &coord); in w8001_setup_pen()
444 w8001->max_pen_x = coord.x; in w8001_setup_pen()
445 w8001->max_pen_y = coord.y; in w8001_setup_pen()
447 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); in w8001_setup_pen()
457 w8001->id = 0x90; in w8001_setup_pen()
466 struct input_dev *dev = w8001->touch_dev; in w8001_setup_touch()
476 * Some non-touch devices may reply to the touch query. But their in w8001_setup_touch()
479 if (!w8001->response[1]) in w8001_setup_touch()
480 return -ENXIO; in w8001_setup_touch()
482 __set_bit(EV_KEY, dev->evbit); in w8001_setup_touch()
483 __set_bit(EV_ABS, dev->evbit); in w8001_setup_touch()
484 __set_bit(BTN_TOUCH, dev->keybit); in w8001_setup_touch()
485 __set_bit(INPUT_PROP_DIRECT, dev->propbit); in w8001_setup_touch()
487 parse_touchquery(w8001->response, &touch); in w8001_setup_touch()
488 w8001->max_touch_x = touch.x; in w8001_setup_touch()
489 w8001->max_touch_y = touch.y; in w8001_setup_touch()
491 if (w8001->max_pen_x && w8001->max_pen_y) { in w8001_setup_touch()
493 touch.x = w8001->max_pen_x; in w8001_setup_touch()
494 touch.y = w8001->max_pen_y; in w8001_setup_touch()
498 input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); in w8001_setup_touch()
506 w8001->pktlen = W8001_PKTLEN_TOUCH93; in w8001_setup_touch()
507 w8001->id = 0x93; in w8001_setup_touch()
514 w8001->pktlen = W8001_PKTLEN_TOUCH9A; in w8001_setup_touch()
516 w8001->id = 0x9a; in w8001_setup_touch()
520 w8001->pktlen = W8001_PKTLEN_TOUCH2FG; in w8001_setup_touch()
522 __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); in w8001_setup_touch()
525 dev_err(&w8001->serio->dev, in w8001_setup_touch()
531 0, touch.x, 0, 0); in w8001_setup_touch()
540 if (w8001->max_pen_x && w8001->max_pen_y) in w8001_setup_touch()
541 w8001->id = 0xE3; in w8001_setup_touch()
543 w8001->id = 0xE2; in w8001_setup_touch()
547 strlcat(basename, " Touchscreen", basename_sz); in w8001_setup_touch()
555 dev->phys = w8001->phys; in w8001_set_devdata()
556 dev->id.bustype = BUS_RS232; in w8001_set_devdata()
557 dev->id.product = w8001->id; in w8001_set_devdata()
558 dev->id.vendor = 0x056a; in w8001_set_devdata()
559 dev->id.version = 0x0100; in w8001_set_devdata()
560 dev->open = w8001_open; in w8001_set_devdata()
561 dev->close = w8001_close; in w8001_set_devdata()
563 dev->dev.parent = &serio->dev; in w8001_set_devdata()
578 if (w8001->pen_dev) in w8001_disconnect()
579 input_unregister_device(w8001->pen_dev); in w8001_disconnect()
580 if (w8001->touch_dev) in w8001_disconnect()
581 input_unregister_device(w8001->touch_dev); in w8001_disconnect()
605 err = -ENOMEM; in w8001_connect()
609 w8001->serio = serio; in w8001_connect()
610 w8001->pen_dev = input_dev_pen; in w8001_connect()
611 w8001->touch_dev = input_dev_touch; in w8001_connect()
612 mutex_init(&w8001->mutex); in w8001_connect()
613 init_completion(&w8001->cmd_done); in w8001_connect()
614 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); in w8001_connect()
625 /* For backwards-compatibility we compose the basename based on in w8001_connect()
633 err = -ENXIO; in w8001_connect()
638 strlcpy(w8001->pen_name, basename, sizeof(w8001->pen_name)); in w8001_connect()
639 strlcat(w8001->pen_name, " Pen", sizeof(w8001->pen_name)); in w8001_connect()
640 input_dev_pen->name = w8001->pen_name; in w8001_connect()
644 err = input_register_device(w8001->pen_dev); in w8001_connect()
650 w8001->pen_dev = NULL; in w8001_connect()
654 strlcpy(w8001->touch_name, basename, sizeof(w8001->touch_name)); in w8001_connect()
655 strlcat(w8001->touch_name, " Finger", in w8001_connect()
656 sizeof(w8001->touch_name)); in w8001_connect()
657 input_dev_touch->name = w8001->touch_name; in w8001_connect()
661 err = input_register_device(w8001->touch_dev); in w8001_connect()
667 w8001->touch_dev = NULL; in w8001_connect()
673 if (w8001->pen_dev) in w8001_connect()
674 input_unregister_device(w8001->pen_dev); in w8001_connect()