aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2012-09-15 09:15:58 -0400
committerHenrik Rydberg <rydberg@euromail.se>2012-09-19 13:50:17 -0400
commit8d18fba282120a4a8e4416d1202522ffae8cad58 (patch)
tree22e3ddabba314c9ad544b9fefe004194205c2940
parent4cbe5a555fa58a79b6ecbb6c531b8bab0650778d (diff)
Input: Break out MT data
Move all MT-related things to a separate place. This saves some bytes for non-mt input devices, and prepares for new MT features. 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>
-rw-r--r--drivers/input/evdev.c10
-rw-r--r--drivers/input/input-mt.c48
-rw-r--r--drivers/input/input.c20
-rw-r--r--include/linux/input.h11
-rw-r--r--include/linux/input/mt.h18
5 files changed, 61 insertions, 46 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 6c58bfff01a3..a0692c551be5 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -653,20 +653,22 @@ static int evdev_handle_mt_request(struct input_dev *dev,
653 unsigned int size, 653 unsigned int size,
654 int __user *ip) 654 int __user *ip)
655{ 655{
656 const struct input_mt_slot *mt = dev->mt; 656 const struct input_mt *mt = dev->mt;
657 unsigned int code; 657 unsigned int code;
658 int max_slots; 658 int max_slots;
659 int i; 659 int i;
660 660
661 if (get_user(code, &ip[0])) 661 if (get_user(code, &ip[0]))
662 return -EFAULT; 662 return -EFAULT;
663 if (!input_is_mt_value(code)) 663 if (!mt || !input_is_mt_value(code))
664 return -EINVAL; 664 return -EINVAL;
665 665
666 max_slots = (size - sizeof(__u32)) / sizeof(__s32); 666 max_slots = (size - sizeof(__u32)) / sizeof(__s32);
667 for (i = 0; i < dev->mtsize && i < max_slots; i++) 667 for (i = 0; i < mt->num_slots && i < max_slots; i++) {
668 if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i])) 668 int value = input_mt_get_value(&mt->slots[i], code);
669 if (put_user(value, &ip[1 + i]))
669 return -EFAULT; 670 return -EFAULT;
671 }
670 672
671 return 0; 673 return 0;
672} 674}
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 70a16c7da8cc..37ee1f925d23 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -27,26 +27,28 @@
27 */ 27 */
28int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) 28int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
29{ 29{
30 struct input_mt *mt = dev->mt;
30 int i; 31 int i;
31 32
32 if (!num_slots) 33 if (!num_slots)
33 return 0; 34 return 0;
34 if (dev->mt) 35 if (mt)
35 return dev->mtsize != num_slots ? -EINVAL : 0; 36 return mt->num_slots != num_slots ? -EINVAL : 0;
36 37
37 dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL); 38 mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL);
38 if (!dev->mt) 39 if (!mt)
39 return -ENOMEM; 40 return -ENOMEM;
40 41
41 dev->mtsize = num_slots; 42 mt->num_slots = num_slots;
42 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); 43 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
43 input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); 44 input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
44 input_set_events_per_packet(dev, 6 * num_slots); 45 input_set_events_per_packet(dev, 6 * num_slots);
45 46
46 /* Mark slots as 'unused' */ 47 /* Mark slots as 'unused' */
47 for (i = 0; i < num_slots; i++) 48 for (i = 0; i < num_slots; i++)
48 input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1); 49 input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1);
49 50
51 dev->mt = mt;
50 return 0; 52 return 0;
51} 53}
52EXPORT_SYMBOL(input_mt_init_slots); 54EXPORT_SYMBOL(input_mt_init_slots);
@@ -62,9 +64,6 @@ void input_mt_destroy_slots(struct input_dev *dev)
62{ 64{
63 kfree(dev->mt); 65 kfree(dev->mt);
64 dev->mt = NULL; 66 dev->mt = NULL;
65 dev->mtsize = 0;
66 dev->slot = 0;
67 dev->trkid = 0;
68} 67}
69EXPORT_SYMBOL(input_mt_destroy_slots); 68EXPORT_SYMBOL(input_mt_destroy_slots);
70 69
@@ -83,18 +82,19 @@ EXPORT_SYMBOL(input_mt_destroy_slots);
83void input_mt_report_slot_state(struct input_dev *dev, 82void input_mt_report_slot_state(struct input_dev *dev,
84 unsigned int tool_type, bool active) 83 unsigned int tool_type, bool active)
85{ 84{
86 struct input_mt_slot *mt; 85 struct input_mt *mt = dev->mt;
86 struct input_mt_slot *slot;
87 int id; 87 int id;
88 88
89 if (!dev->mt || !active) { 89 if (!mt || !active) {
90 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); 90 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
91 return; 91 return;
92 } 92 }
93 93
94 mt = &dev->mt[dev->slot]; 94 slot = &mt->slots[mt->slot];
95 id = input_mt_get_value(mt, ABS_MT_TRACKING_ID); 95 id = input_mt_get_value(slot, ABS_MT_TRACKING_ID);
96 if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type) 96 if (id < 0 || input_mt_get_value(slot, ABS_MT_TOOL_TYPE) != tool_type)
97 id = input_mt_new_trkid(dev); 97 id = input_mt_new_trkid(mt);
98 98
99 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); 99 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
100 input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type); 100 input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
@@ -135,13 +135,19 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
135 */ 135 */
136void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) 136void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
137{ 137{
138 struct input_mt_slot *oldest = NULL; 138 struct input_mt *mt = dev->mt;
139 int oldid = dev->trkid; 139 struct input_mt_slot *oldest;
140 int count = 0; 140 int oldid, count, i;
141 int i; 141
142 if (!mt)
143 return;
144
145 oldest = 0;
146 oldid = mt->trkid;
147 count = 0;
142 148
143 for (i = 0; i < dev->mtsize; ++i) { 149 for (i = 0; i < mt->num_slots; ++i) {
144 struct input_mt_slot *ps = &dev->mt[i]; 150 struct input_mt_slot *ps = &mt->slots[i];
145 int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); 151 int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
146 152
147 if (id < 0) 153 if (id < 0)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 8921c6180c51..79a4a2ad74de 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -166,6 +166,7 @@ static void input_stop_autorepeat(struct input_dev *dev)
166static int input_handle_abs_event(struct input_dev *dev, 166static int input_handle_abs_event(struct input_dev *dev,
167 unsigned int code, int *pval) 167 unsigned int code, int *pval)
168{ 168{
169 struct input_mt *mt = dev->mt;
169 bool is_mt_event; 170 bool is_mt_event;
170 int *pold; 171 int *pold;
171 172
@@ -174,8 +175,8 @@ static int input_handle_abs_event(struct input_dev *dev,
174 * "Stage" the event; we'll flush it later, when we 175 * "Stage" the event; we'll flush it later, when we
175 * get actual touch data. 176 * get actual touch data.
176 */ 177 */
177 if (*pval >= 0 && *pval < dev->mtsize) 178 if (mt && *pval >= 0 && *pval < mt->num_slots)
178 dev->slot = *pval; 179 mt->slot = *pval;
179 180
180 return INPUT_IGNORE_EVENT; 181 return INPUT_IGNORE_EVENT;
181 } 182 }
@@ -184,9 +185,8 @@ static int input_handle_abs_event(struct input_dev *dev,
184 185
185 if (!is_mt_event) { 186 if (!is_mt_event) {
186 pold = &dev->absinfo[code].value; 187 pold = &dev->absinfo[code].value;
187 } else if (dev->mt) { 188 } else if (mt) {
188 struct input_mt_slot *mtslot = &dev->mt[dev->slot]; 189 pold = &mt->slots[mt->slot].abs[code - ABS_MT_FIRST];
189 pold = &mtslot->abs[code - ABS_MT_FIRST];
190 } else { 190 } else {
191 /* 191 /*
192 * Bypass filtering for multi-touch events when 192 * Bypass filtering for multi-touch events when
@@ -205,9 +205,9 @@ static int input_handle_abs_event(struct input_dev *dev,
205 } 205 }
206 206
207 /* Flush pending "slot" event */ 207 /* Flush pending "slot" event */
208 if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { 208 if (is_mt_event && mt && mt->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
209 input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); 209 input_abs_set_val(dev, ABS_MT_SLOT, mt->slot);
210 input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); 210 input_pass_event(dev, EV_ABS, ABS_MT_SLOT, mt->slot);
211 } 211 }
212 212
213 return INPUT_PASS_TO_HANDLERS; 213 return INPUT_PASS_TO_HANDLERS;
@@ -1751,8 +1751,8 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
1751 int i; 1751 int i;
1752 unsigned int events; 1752 unsigned int events;
1753 1753
1754 if (dev->mtsize) { 1754 if (dev->mt) {
1755 mt_slots = dev->mtsize; 1755 mt_slots = dev->mt->num_slots;
1756 } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { 1756 } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) {
1757 mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - 1757 mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum -
1758 dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, 1758 dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1,
diff --git a/include/linux/input.h b/include/linux/input.h
index 725dcd0f63a4..9da4f5796fd6 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1203,11 +1203,7 @@ struct ff_effect {
1203 * software autorepeat 1203 * software autorepeat
1204 * @timer: timer for software autorepeat 1204 * @timer: timer for software autorepeat
1205 * @rep: current values for autorepeat parameters (delay, rate) 1205 * @rep: current values for autorepeat parameters (delay, rate)
1206 * @mt: pointer to array of struct input_mt_slot holding current values 1206 * @mt: pointer to multitouch state
1207 * of tracked contacts
1208 * @mtsize: number of MT slots the device uses
1209 * @slot: MT slot currently being transmitted
1210 * @trkid: stores MT tracking ID for the current contact
1211 * @absinfo: array of &struct input_absinfo elements holding information 1207 * @absinfo: array of &struct input_absinfo elements holding information
1212 * about absolute axes (current value, min, max, flat, fuzz, 1208 * about absolute axes (current value, min, max, flat, fuzz,
1213 * resolution) 1209 * resolution)
@@ -1287,10 +1283,7 @@ struct input_dev {
1287 1283
1288 int rep[REP_CNT]; 1284 int rep[REP_CNT];
1289 1285
1290 struct input_mt_slot *mt; 1286 struct input_mt *mt;
1291 int mtsize;
1292 int slot;
1293 int trkid;
1294 1287
1295 struct input_absinfo *absinfo; 1288 struct input_absinfo *absinfo;
1296 1289
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index f86737586e19..63458bced77d 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -23,6 +23,20 @@ struct input_mt_slot {
23 int abs[ABS_MT_LAST - ABS_MT_FIRST + 1]; 23 int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
24}; 24};
25 25
26/**
27 * struct input_mt - state of tracked contacts
28 * @trkid: stores MT tracking ID for the next contact
29 * @num_slots: number of MT slots the device uses
30 * @slot: MT slot currently being transmitted
31 * @slots: array of slots holding current values of tracked contacts
32 */
33struct input_mt {
34 int trkid;
35 int num_slots;
36 int slot;
37 struct input_mt_slot slots[];
38};
39
26static inline void input_mt_set_value(struct input_mt_slot *slot, 40static inline void input_mt_set_value(struct input_mt_slot *slot,
27 unsigned code, int value) 41 unsigned code, int value)
28{ 42{
@@ -38,9 +52,9 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot,
38int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots); 52int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);
39void input_mt_destroy_slots(struct input_dev *dev); 53void input_mt_destroy_slots(struct input_dev *dev);
40 54
41static inline int input_mt_new_trkid(struct input_dev *dev) 55static inline int input_mt_new_trkid(struct input_mt *mt)
42{ 56{
43 return dev->trkid++ & TRKID_MAX; 57 return mt->trkid++ & TRKID_MAX;
44} 58}
45 59
46static inline void input_mt_slot(struct input_dev *dev, int slot) 60static inline void input_mt_slot(struct input_dev *dev, int slot)