diff options
Diffstat (limited to 'drivers/input/input-mt.c')
-rw-r--r-- | drivers/input/input-mt.c | 70 |
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 | ||
17 | static 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 | } |
179 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); | 214 | EXPORT_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 | */ | ||
224 | void 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 | } | ||
245 | EXPORT_SYMBOL(input_mt_sync_frame); | ||