Lines Matching +full:event +full:- +full:touch
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * HID driver for N-Trig touchscreens
5 * Copyright (c) 2008-2010 Rafi Rubin
6 * Copyright (c) 2009-2010 Stephane Chatty
19 #include "hid-ids.h"
25 MODULE_PARM_DESC(min_width, "Minimum touch contact width to accept.");
29 MODULE_PARM_DESC(min_height, "Minimum touch contact height to accept.");
33 MODULE_PARM_DESC(activate_slack, "Number of touch frames to ignore at "
34 "the start of touch input.");
39 "deactivating touch.");
44 "processing touch events.");
49 "processing touch events.");
111 struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. in ntrig_get_mode()
114 if (!report || report->maxfield < 1 || in ntrig_get_mode()
115 report->field[0]->report_count < 1) in ntrig_get_mode()
116 return -EINVAL; in ntrig_get_mode()
120 return (int)report->field[0]->value[0]; in ntrig_get_mode()
131 report = hdev->report_enum[HID_FEATURE_REPORT]. in ntrig_set_mode()
175 return sprintf(buf, "%d\n", nd->sensor_physical_width); in show_phys_width()
187 return sprintf(buf, "%d\n", nd->sensor_physical_height); in show_phys_height()
199 return sprintf(buf, "%d\n", nd->sensor_logical_width); in show_log_width()
211 return sprintf(buf, "%d\n", nd->sensor_logical_height); in show_log_height()
223 return sprintf(buf, "%d\n", nd->min_width * in show_min_width()
224 nd->sensor_physical_width / in show_min_width()
225 nd->sensor_logical_width); in show_min_width()
238 return -EINVAL; in set_min_width()
240 if (val > nd->sensor_physical_width) in set_min_width()
241 return -EINVAL; in set_min_width()
243 nd->min_width = val * nd->sensor_logical_width / in set_min_width()
244 nd->sensor_physical_width; in set_min_width()
258 return sprintf(buf, "%d\n", nd->min_height * in show_min_height()
259 nd->sensor_physical_height / in show_min_height()
260 nd->sensor_logical_height); in show_min_height()
273 return -EINVAL; in set_min_height()
275 if (val > nd->sensor_physical_height) in set_min_height()
276 return -EINVAL; in set_min_height()
278 nd->min_height = val * nd->sensor_logical_height / in set_min_height()
279 nd->sensor_physical_height; in set_min_height()
294 return sprintf(buf, "%d\n", nd->activate_slack); in show_activate_slack()
307 return -EINVAL; in set_activate_slack()
310 return -EINVAL; in set_activate_slack()
312 nd->activate_slack = val; in set_activate_slack()
327 return sprintf(buf, "%d\n", nd->activation_width * in show_activation_width()
328 nd->sensor_physical_width / in show_activation_width()
329 nd->sensor_logical_width); in show_activation_width()
342 return -EINVAL; in set_activation_width()
344 if (val > nd->sensor_physical_width) in set_activation_width()
345 return -EINVAL; in set_activation_width()
347 nd->activation_width = val * nd->sensor_logical_width / in set_activation_width()
348 nd->sensor_physical_width; in set_activation_width()
363 return sprintf(buf, "%d\n", nd->activation_height * in show_activation_height()
364 nd->sensor_physical_height / in show_activation_height()
365 nd->sensor_logical_height); in show_activation_height()
378 return -EINVAL; in set_activation_height()
380 if (val > nd->sensor_physical_height) in set_activation_height()
381 return -EINVAL; in set_activation_height()
383 nd->activation_height = val * nd->sensor_logical_height / in set_activation_height()
384 nd->sensor_physical_height; in set_activation_height()
399 return sprintf(buf, "%d\n", -nd->deactivate_slack); in show_deactivate_slack()
412 return -EINVAL; in set_deactivate_slack()
417 * touch emulation stuck down. in set_deactivate_slack()
420 return -EINVAL; in set_deactivate_slack()
422 nd->deactivate_slack = -val; in set_deactivate_slack()
450 * - dual pen/finger single touch
451 * - finger multitouch, pen not working
460 /* No special mappings needed for the pen and single touch */ in ntrig_input_mapping()
461 if (field->physical) in ntrig_input_mapping()
464 switch (usage->hid & HID_USAGE_PAGE) { in ntrig_input_mapping()
466 switch (usage->hid) { in ntrig_input_mapping()
470 input_set_abs_params(hi->input, ABS_X, in ntrig_input_mapping()
471 field->logical_minimum, in ntrig_input_mapping()
472 field->logical_maximum, 0, 0); in ntrig_input_mapping()
474 if (!nd->sensor_logical_width) { in ntrig_input_mapping()
475 nd->sensor_logical_width = in ntrig_input_mapping()
476 field->logical_maximum - in ntrig_input_mapping()
477 field->logical_minimum; in ntrig_input_mapping()
478 nd->sensor_physical_width = in ntrig_input_mapping()
479 field->physical_maximum - in ntrig_input_mapping()
480 field->physical_minimum; in ntrig_input_mapping()
481 nd->activation_width = activation_width * in ntrig_input_mapping()
482 nd->sensor_logical_width / in ntrig_input_mapping()
483 nd->sensor_physical_width; in ntrig_input_mapping()
484 nd->min_width = min_width * in ntrig_input_mapping()
485 nd->sensor_logical_width / in ntrig_input_mapping()
486 nd->sensor_physical_width; in ntrig_input_mapping()
492 input_set_abs_params(hi->input, ABS_Y, in ntrig_input_mapping()
493 field->logical_minimum, in ntrig_input_mapping()
494 field->logical_maximum, 0, 0); in ntrig_input_mapping()
496 if (!nd->sensor_logical_height) { in ntrig_input_mapping()
497 nd->sensor_logical_height = in ntrig_input_mapping()
498 field->logical_maximum - in ntrig_input_mapping()
499 field->logical_minimum; in ntrig_input_mapping()
500 nd->sensor_physical_height = in ntrig_input_mapping()
501 field->physical_maximum - in ntrig_input_mapping()
502 field->physical_minimum; in ntrig_input_mapping()
503 nd->activation_height = activation_height * in ntrig_input_mapping()
504 nd->sensor_logical_height / in ntrig_input_mapping()
505 nd->sensor_physical_height; in ntrig_input_mapping()
506 nd->min_height = min_height * in ntrig_input_mapping()
507 nd->sensor_logical_height / in ntrig_input_mapping()
508 nd->sensor_physical_height; in ntrig_input_mapping()
515 switch (usage->hid) { in ntrig_input_mapping()
521 return -1; in ntrig_input_mapping()
531 input_set_abs_params(hi->input, ABS_MT_ORIENTATION, in ntrig_input_mapping()
538 /* we do not want to map these: no input-oriented meaning */ in ntrig_input_mapping()
539 return -1; in ntrig_input_mapping()
549 /* No special mappings needed for the pen and single touch */ in ntrig_input_mapped()
550 if (field->physical) in ntrig_input_mapped()
553 if (usage->type == EV_KEY || usage->type == EV_REL in ntrig_input_mapped()
554 || usage->type == EV_ABS) in ntrig_input_mapped()
555 clear_bit(usage->code, *bit); in ntrig_input_mapped()
563 * decide whether we are in multi or single touch mode
573 if (!(hid->claimed & HID_CLAIMED_INPUT)) in ntrig_event()
578 if(!(field->hidinput && field->hidinput->input)) in ntrig_event()
579 return -EINVAL; in ntrig_event()
581 input = field->hidinput->input; in ntrig_event()
584 if (field->application == HID_DG_PEN) in ntrig_event()
587 switch (usage->hid) { in ntrig_event()
590 nd->reading_mt = true; in ntrig_event()
591 nd->first_contact_touch = false; in ntrig_event()
594 nd->tipswitch = value; in ntrig_event()
595 /* Prevent emission of touch until validated */ in ntrig_event()
598 nd->confidence = value; in ntrig_event()
601 nd->x = value; in ntrig_event()
603 nd->mt_foot_count = 0; in ntrig_event()
606 nd->y = value; in ntrig_event()
609 nd->id = value; in ntrig_event()
612 nd->w = value; in ntrig_event()
615 nd->h = value; in ntrig_event()
617 * when in single touch mode, this is the last in ntrig_event()
618 * report received in a finger event. We want in ntrig_event()
621 if (!nd->reading_mt) { in ntrig_event()
624 * finger in single touch mode. in ntrig_event()
627 nd->tipswitch); in ntrig_event()
629 nd->tipswitch); in ntrig_event()
630 input_event(input, EV_ABS, ABS_X, nd->x); in ntrig_event()
631 input_event(input, EV_ABS, ABS_Y, nd->y); in ntrig_event()
643 if (nd->mt_foot_count >= 4) in ntrig_event()
646 nd->mt_footer[nd->mt_foot_count++] = value; in ntrig_event()
649 if (nd->mt_foot_count != 4) in ntrig_event()
653 if (nd->mt_footer[2]) { in ntrig_event()
655 * When the pen deactivates touch, we see a in ntrig_event()
661 nd->act_state = deactivate_slack - 1; in ntrig_event()
662 nd->confidence = false; in ntrig_event()
670 if (nd->mt_footer[0]) { in ntrig_event()
676 if (nd->w < nd->min_width || in ntrig_event()
677 nd->h < nd->min_height) in ntrig_event()
678 nd->confidence = false; in ntrig_event()
682 if (nd->act_state > 0) { in ntrig_event()
686 if (nd->w >= nd->activation_width && in ntrig_event()
687 nd->h >= nd->activation_height) { in ntrig_event()
688 if (nd->id) in ntrig_event()
692 nd->act_state = 0; in ntrig_event()
699 nd->act_state = 1; in ntrig_event()
711 if (!nd->confidence) in ntrig_event()
715 if (nd->id == 0) { in ntrig_event()
722 nd->first_contact_touch = nd->confidence; in ntrig_event()
723 input_event(input, EV_ABS, ABS_X, nd->x); in ntrig_event()
724 input_event(input, EV_ABS, ABS_Y, nd->y); in ntrig_event()
728 input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); in ntrig_event()
729 input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); in ntrig_event()
735 if (nd->w > nd->h) { in ntrig_event()
739 ABS_MT_TOUCH_MAJOR, nd->w); in ntrig_event()
741 ABS_MT_TOUCH_MINOR, nd->h); in ntrig_event()
746 ABS_MT_TOUCH_MAJOR, nd->h); in ntrig_event()
748 ABS_MT_TOUCH_MINOR, nd->w); in ntrig_event()
750 input_mt_sync(field->hidinput->input); in ntrig_event()
754 if (!nd->reading_mt) /* Just to be sure */ in ntrig_event()
757 nd->reading_mt = false; in ntrig_event()
766 * state < -deactivate_slack: in ntrig_event()
767 * Pen termination of touch in ntrig_event()
776 * state == -deactivate_slack in ntrig_event()
781 if (nd->act_state > 0) { /* Currently inactive */ in ntrig_event()
787 nd->act_state = (nd->act_state > value) in ntrig_event()
788 ? nd->act_state - value in ntrig_event()
795 nd->act_state = nd->activate_slack; in ntrig_event()
804 if (value && nd->act_state >= in ntrig_event()
805 nd->deactivate_slack) in ntrig_event()
810 nd->act_state = 0; in ntrig_event()
811 else if (nd->act_state <= nd->deactivate_slack) in ntrig_event()
816 nd->act_state = in ntrig_event()
817 nd->activate_slack; in ntrig_event()
819 nd->act_state--; in ntrig_event()
824 if (nd->first_contact_touch && nd->act_state <= 0) { in ntrig_event()
827 * emitting touch events. in ntrig_event()
845 /* fall-back to the generic hidinput handling */ in ntrig_event()
852 if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) in ntrig_event()
853 hid->hiddev_hid_event(hid, field, usage, value); in ntrig_event()
862 struct input_dev *input = hidinput->input; in ntrig_input_configured()
864 if (hidinput->report->maxfield < 1) in ntrig_input_configured()
867 switch (hidinput->report->field[0]->application) { in ntrig_input_configured()
869 input->name = "N-Trig Pen"; in ntrig_input_configured()
874 __clear_bit(BTN_TOOL_PEN, input->keybit); in ntrig_input_configured()
875 __clear_bit(BTN_TOOL_FINGER, input->keybit); in ntrig_input_configured()
876 __clear_bit(BTN_0, input->keybit); in ntrig_input_configured()
877 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); in ntrig_input_configured()
879 * The physical touchscreen (single touch) in ntrig_input_configured()
884 input->name = (hidinput->report->field[0]->physical) ? in ntrig_input_configured()
885 "N-Trig Touchscreen" : in ntrig_input_configured()
886 "N-Trig MultiTouch"; in ntrig_input_configured()
899 if (id->driver_data) in ntrig_probe()
900 hdev->quirks |= HID_QUIRK_MULTI_INPUT in ntrig_probe()
905 hid_err(hdev, "cannot allocate N-Trig data\n"); in ntrig_probe()
906 return -ENOMEM; in ntrig_probe()
909 nd->reading_mt = false; in ntrig_probe()
910 nd->min_width = 0; in ntrig_probe()
911 nd->min_height = 0; in ntrig_probe()
912 nd->activate_slack = activate_slack; in ntrig_probe()
913 nd->act_state = activate_slack; in ntrig_probe()
914 nd->deactivate_slack = -deactivate_slack; in ntrig_probe()
915 nd->sensor_logical_width = 1; in ntrig_probe()
916 nd->sensor_logical_height = 1; in ntrig_probe()
917 nd->sensor_physical_width = 1; in ntrig_probe()
918 nd->sensor_physical_height = 1; in ntrig_probe()
935 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; in ntrig_probe()
952 ret = sysfs_create_group(&hdev->dev.kobj, in ntrig_probe()
965 sysfs_remove_group(&hdev->dev.kobj, in ntrig_remove()
1016 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 }
1028 .event = ntrig_event,