aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/input-mt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/input-mt.c')
-rw-r--r--drivers/input/input-mt.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 1985f27f427a..96cc2e2a9be2 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -14,6 +14,14 @@
14 14
15#define TRKID_SGN ((TRKID_MAX + 1) >> 1) 15#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
16 16
17static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src)
18{
19 if (dev->absinfo && test_bit(src, dev->absbit)) {
20 dev->absinfo[dst] = dev->absinfo[src];
21 dev->absbit[BIT_WORD(dst)] |= BIT_MASK(dst);
22 }
23}
24
17/** 25/**
18 * input_mt_init_slots() - initialize MT input slots 26 * input_mt_init_slots() - initialize MT input slots
19 * @dev: input device supporting MT events and finger tracking 27 * @dev: input device supporting MT events and finger tracking
@@ -45,6 +53,28 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots,
45 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); 53 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
46 input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); 54 input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
47 55
56 if (flags & (INPUT_MT_POINTER | INPUT_MT_DIRECT)) {
57 __set_bit(EV_KEY, dev->evbit);
58 __set_bit(BTN_TOUCH, dev->keybit);
59
60 copy_abs(dev, ABS_X, ABS_MT_POSITION_X);
61 copy_abs(dev, ABS_Y, ABS_MT_POSITION_Y);
62 copy_abs(dev, ABS_PRESSURE, ABS_MT_PRESSURE);
63 }
64 if (flags & INPUT_MT_POINTER) {
65 __set_bit(BTN_TOOL_FINGER, dev->keybit);
66 __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
67 if (num_slots >= 3)
68 __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
69 if (num_slots >= 4)
70 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
71 if (num_slots >= 5)
72 __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
73 __set_bit(INPUT_PROP_POINTER, dev->propbit);
74 }
75 if (flags & INPUT_MT_DIRECT)
76 __set_bit(INPUT_PROP_DIRECT, dev->propbit);
77
48 /* Mark slots as 'unused' */ 78 /* Mark slots as 'unused' */
49 for (i = 0; i < num_slots; i++) 79 for (i = 0; i < num_slots; i++)
50 input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1); 80 input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1);
@@ -87,12 +117,17 @@ void input_mt_report_slot_state(struct input_dev *dev,
87 struct input_mt_slot *slot; 117 struct input_mt_slot *slot;
88 int id; 118 int id;
89 119
90 if (!mt || !active) { 120 if (!mt)
121 return;
122
123 slot = &mt->slots[mt->slot];
124 slot->frame = mt->frame;
125
126 if (!active) {
91 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); 127 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
92 return; 128 return;
93 } 129 }
94 130
95 slot = &mt->slots[mt->slot];
96 id = input_mt_get_value(slot, ABS_MT_TRACKING_ID); 131 id = input_mt_get_value(slot, ABS_MT_TRACKING_ID);
97 if (id < 0 || input_mt_get_value(slot, ABS_MT_TOOL_TYPE) != tool_type) 132 if (id < 0 || input_mt_get_value(slot, ABS_MT_TOOL_TYPE) != tool_type)
98 id = input_mt_new_trkid(mt); 133 id = input_mt_new_trkid(mt);
@@ -177,3 +212,34 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
177 } 212 }
178} 213}
179EXPORT_SYMBOL(input_mt_report_pointer_emulation); 214EXPORT_SYMBOL(input_mt_report_pointer_emulation);
215
216/**
217 * input_mt_sync_frame() - synchronize mt frame
218 * @dev: input device with allocated MT slots
219 *
220 * Close the frame and prepare the internal state for a new one.
221 * Depending on the flags, marks unused slots as inactive and performs
222 * pointer emulation.
223 */
224void input_mt_sync_frame(struct input_dev *dev)
225{
226 struct input_mt *mt = dev->mt;
227 struct input_mt_slot *s;
228
229 if (!mt)
230 return;
231
232 if (mt->flags & INPUT_MT_DROP_UNUSED) {
233 for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
234 if (s->frame == mt->frame)
235 continue;
236 input_mt_slot(dev, s - mt->slots);
237 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
238 }
239 }
240
241 input_mt_report_pointer_emulation(dev, (mt->flags & INPUT_MT_POINTER));
242
243 mt->frame++;
244}
245EXPORT_SYMBOL(input_mt_sync_frame);