Lines Matching refs:w8001
84 struct w8001 { struct
138 static void scale_touch_coordinates(struct w8001 *w8001, 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()
148 static void parse_multi_touch(struct w8001 *w8001) in parse_multi_touch() argument
150 struct input_dev *dev = w8001->touch_dev; in parse_multi_touch()
151 unsigned char *data = w8001->data; in parse_multi_touch()
167 scale_touch_coordinates(w8001, &x, &y); 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()
214 static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) in report_pen_events() argument
216 struct input_dev *dev = w8001->pen_dev; in report_pen_events()
228 switch (w8001->type) { 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()
256 input_report_key(dev, w8001->type, coord->rdy); in report_pen_events()
260 w8001->type = KEY_RESERVED; in report_pen_events()
263 static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord) in report_single_touch() argument
265 struct input_dev *dev = w8001->touch_dev; in report_single_touch()
270 scale_touch_coordinates(w8001, &x, &y); in report_single_touch()
278 w8001->type = coord->tsw ? BTN_TOOL_FINGER : KEY_RESERVED; in report_single_touch()
284 struct w8001 *w8001 = serio_get_drvdata(serio); in w8001_interrupt() local
288 w8001->data[w8001->idx] = data; in w8001_interrupt()
289 switch (w8001->idx++) { in w8001_interrupt()
293 w8001->idx = 0; 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()
308 report_single_touch(w8001, &coord); 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()
325 report_pen_events(w8001, &coord); 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()
342 w8001->idx = 0; in w8001_interrupt()
343 parse_multi_touch(w8001); in w8001_interrupt()
352 if (!w8001->touch_dev && w8001->idx > W8001_PKTLEN_TPCPEN - 1) in w8001_interrupt()
353 w8001->idx = 0; in w8001_interrupt()
359 static int w8001_command(struct w8001 *w8001, unsigned char command, in w8001_command() argument
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()
380 struct w8001 *w8001 = input_get_drvdata(dev); in w8001_open() local
383 err = mutex_lock_interruptible(&w8001->mutex); in w8001_open()
387 if (w8001->open_count++ == 0) { in w8001_open()
388 err = w8001_command(w8001, W8001_CMD_START, false); in w8001_open()
390 w8001->open_count--; in w8001_open()
393 mutex_unlock(&w8001->mutex); in w8001_open()
399 struct w8001 *w8001 = input_get_drvdata(dev); in w8001_close() local
401 mutex_lock(&w8001->mutex); in w8001_close()
403 if (--w8001->open_count == 0) in w8001_close()
404 w8001_command(w8001, W8001_CMD_STOP, false); in w8001_close()
406 mutex_unlock(&w8001->mutex); in w8001_close()
409 static int w8001_detect(struct w8001 *w8001) in w8001_detect() argument
413 error = w8001_command(w8001, W8001_CMD_STOP, false); in w8001_detect()
422 static int w8001_setup_pen(struct w8001 *w8001, char *basename, in w8001_setup_pen() argument
425 struct input_dev *dev = w8001->pen_dev; in w8001_setup_pen()
430 error = w8001_command(w8001, W8001_CMD_QUERY, true); 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()
457 w8001->id = 0x90; in w8001_setup_pen()
463 static int w8001_setup_touch(struct w8001 *w8001, char *basename, in w8001_setup_touch() argument
466 struct input_dev *dev = w8001->touch_dev; in w8001_setup_touch()
472 error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); in w8001_setup_touch()
479 if (!w8001->response[1]) 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()
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()
525 dev_err(&w8001->serio->dev, 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()
552 static void w8001_set_devdata(struct input_dev *dev, struct w8001 *w8001, in w8001_set_devdata() argument
555 dev->phys = w8001->phys; in w8001_set_devdata()
557 dev->id.product = w8001->id; in w8001_set_devdata()
565 input_set_drvdata(dev, w8001); in w8001_set_devdata()
574 struct w8001 *w8001 = serio_get_drvdata(serio); in w8001_disconnect() local
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()
582 kfree(w8001); in w8001_disconnect()
595 struct w8001 *w8001; in w8001_connect() local
601 w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL); in w8001_connect()
604 if (!w8001 || !input_dev_pen || !input_dev_touch) { 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()
616 serio_set_drvdata(serio, w8001); in w8001_connect()
621 err = w8001_detect(w8001); in w8001_connect()
630 err_pen = w8001_setup_pen(w8001, basename, sizeof(basename)); in w8001_connect()
631 err_touch = w8001_setup_touch(w8001, basename, sizeof(basename)); in w8001_connect()
638 strscpy(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()
642 w8001_set_devdata(input_dev_pen, w8001, serio); in w8001_connect()
644 err = input_register_device(w8001->pen_dev); in w8001_connect()
650 w8001->pen_dev = NULL; in w8001_connect()
654 strscpy(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()
659 w8001_set_devdata(input_dev_touch, w8001, serio); 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()
682 kfree(w8001); in w8001_connect()