aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2012-08-22 14:43:22 -0400
committerHenrik Rydberg <rydberg@euromail.se>2012-09-19 13:50:19 -0400
commit55e49089f4589908eb688742d2d7eff33b74ac78 (patch)
treeea080c5831e489465378a37480d87c1125143b8c /drivers/input
parentb4adbbefc2099476a4f1020041c99f52cf3cd67d (diff)
Input: MT - Handle frame synchronization in core
Most MT drivers perform the same actions on frame synchronization. Some actions, like dropping unseen contacts, are also unnecessarily complex. Collect common frame synchronization tasks in a new function, input_mt_sync_frame(). Depending on the flags set, it drops unseen contacts and performs pointer emulation. With init flags and frame synchronization in place, most MT drivers can be simplified. First out are the bcm5974 and hid-multitouch drivers, following this patch. Reviewed-and-tested-by: Benjamin Tissoires <benjamin.tissoires@enac.fr> Tested-by: Ping Cheng <pingc@wacom.com> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'drivers/input')
-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);