aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/input.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-07-16 02:10:10 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-07-16 02:52:03 -0400
commit40d007e7df1dab17bf1ecf91e718218354d963d7 (patch)
treed8c12e13e71f411b4f66aa44ec9b23935156e49d /drivers/input/input.c
parenta8aef622929bbba4d89498fb41dd445c14fae1f7 (diff)
Input: introduce MT event slots
With the rapidly increasing number of intelligent multi-contact and multi-user devices, the need to send digested, filtered information from a set of different sources within the same device is imminent. This patch adds the concept of slots to the MT protocol. The slots enumerate a set of identified sources, such that all MT events can be passed independently and selectively per identified source. The protocol works like this: Instead of sending a SYN_MT_REPORT event immediately after the contact data, one sends an ABS_MT_SLOT event immediately before the contact data. The input core will only emit events for slots with modified MT events. It is assumed that the same slot is used for the duration of an initiated contact. Acked-by: Ping Cheng <pingc@wacom.com> Acked-by: Chase Douglas <chase.douglas@canonical.com> Acked-by: Rafi Rubin <rafi@seas.upenn.edu> Signed-off-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r--drivers/input/input.c135
1 files changed, 92 insertions, 43 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index a3d5485154e7..54109c33e36c 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -33,25 +33,6 @@ MODULE_LICENSE("GPL");
33 33
34#define INPUT_DEVICES 256 34#define INPUT_DEVICES 256
35 35
36/*
37 * EV_ABS events which should not be cached are listed here.
38 */
39static unsigned int input_abs_bypass_init_data[] __initdata = {
40 ABS_MT_TOUCH_MAJOR,
41 ABS_MT_TOUCH_MINOR,
42 ABS_MT_WIDTH_MAJOR,
43 ABS_MT_WIDTH_MINOR,
44 ABS_MT_ORIENTATION,
45 ABS_MT_POSITION_X,
46 ABS_MT_POSITION_Y,
47 ABS_MT_TOOL_TYPE,
48 ABS_MT_BLOB_ID,
49 ABS_MT_TRACKING_ID,
50 ABS_MT_PRESSURE,
51 0
52};
53static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
54
55static LIST_HEAD(input_dev_list); 36static LIST_HEAD(input_dev_list);
56static LIST_HEAD(input_handler_list); 37static LIST_HEAD(input_handler_list);
57 38
@@ -181,6 +162,56 @@ static void input_stop_autorepeat(struct input_dev *dev)
181#define INPUT_PASS_TO_DEVICE 2 162#define INPUT_PASS_TO_DEVICE 2
182#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) 163#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
183 164
165static int input_handle_abs_event(struct input_dev *dev,
166 unsigned int code, int *pval)
167{
168 bool is_mt_event;
169 int *pold;
170
171 if (code == ABS_MT_SLOT) {
172 /*
173 * "Stage" the event; we'll flush it later, when we
174 * get actiual touch data.
175 */
176 if (*pval >= 0 && *pval < dev->mtsize)
177 dev->slot = *pval;
178
179 return INPUT_IGNORE_EVENT;
180 }
181
182 is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST;
183
184 if (!is_mt_event) {
185 pold = &dev->abs[code];
186 } else if (dev->mt) {
187 struct input_mt_slot *mtslot = &dev->mt[dev->slot];
188 pold = &mtslot->abs[code - ABS_MT_FIRST];
189 } else {
190 /*
191 * Bypass filtering for multitouch events when
192 * not employing slots.
193 */
194 pold = NULL;
195 }
196
197 if (pold) {
198 *pval = input_defuzz_abs_event(*pval, *pold,
199 dev->absfuzz[code]);
200 if (*pold == *pval)
201 return INPUT_IGNORE_EVENT;
202
203 *pold = *pval;
204 }
205
206 /* Flush pending "slot" event */
207 if (is_mt_event && dev->slot != dev->abs[ABS_MT_SLOT]) {
208 dev->abs[ABS_MT_SLOT] = dev->slot;
209 input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
210 }
211
212 return INPUT_PASS_TO_HANDLERS;
213}
214
184static void input_handle_event(struct input_dev *dev, 215static void input_handle_event(struct input_dev *dev,
185 unsigned int type, unsigned int code, int value) 216 unsigned int type, unsigned int code, int value)
186{ 217{
@@ -233,21 +264,9 @@ static void input_handle_event(struct input_dev *dev,
233 break; 264 break;
234 265
235 case EV_ABS: 266 case EV_ABS:
236 if (is_event_supported(code, dev->absbit, ABS_MAX)) { 267 if (is_event_supported(code, dev->absbit, ABS_MAX))
237 268 disposition = input_handle_abs_event(dev, code, &value);
238 if (test_bit(code, input_abs_bypass)) {
239 disposition = INPUT_PASS_TO_HANDLERS;
240 break;
241 }
242 269
243 value = input_defuzz_abs_event(value,
244 dev->abs[code], dev->absfuzz[code]);
245
246 if (dev->abs[code] != value) {
247 dev->abs[code] = value;
248 disposition = INPUT_PASS_TO_HANDLERS;
249 }
250 }
251 break; 270 break;
252 271
253 case EV_REL: 272 case EV_REL:
@@ -1288,6 +1307,7 @@ static void input_dev_release(struct device *device)
1288 struct input_dev *dev = to_input_dev(device); 1307 struct input_dev *dev = to_input_dev(device);
1289 1308
1290 input_ff_destroy(dev); 1309 input_ff_destroy(dev);
1310 input_mt_destroy_slots(dev);
1291 kfree(dev); 1311 kfree(dev);
1292 1312
1293 module_put(THIS_MODULE); 1313 module_put(THIS_MODULE);
@@ -1537,6 +1557,45 @@ void input_free_device(struct input_dev *dev)
1537EXPORT_SYMBOL(input_free_device); 1557EXPORT_SYMBOL(input_free_device);
1538 1558
1539/** 1559/**
1560 * input_mt_create_slots() - create MT input slots
1561 * @dev: input device supporting MT events and finger tracking
1562 * @num_slots: number of slots used by the device
1563 *
1564 * This function allocates all necessary memory for MT slot handling
1565 * in the input device, and adds ABS_MT_SLOT to the device capabilities.
1566 */
1567int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
1568{
1569 if (!num_slots)
1570 return 0;
1571
1572 dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
1573 if (!dev->mt)
1574 return -ENOMEM;
1575
1576 dev->mtsize = num_slots;
1577 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
1578
1579 return 0;
1580}
1581EXPORT_SYMBOL(input_mt_create_slots);
1582
1583/**
1584 * input_mt_destroy_slots() - frees the MT slots of the input device
1585 * @dev: input device with allocated MT slots
1586 *
1587 * This function is only needed in error path as the input core will
1588 * automatically free the MT slots when the device is destroyed.
1589 */
1590void input_mt_destroy_slots(struct input_dev *dev)
1591{
1592 kfree(dev->mt);
1593 dev->mt = NULL;
1594 dev->mtsize = 0;
1595}
1596EXPORT_SYMBOL(input_mt_destroy_slots);
1597
1598/**
1540 * input_set_capability - mark device as capable of a certain event 1599 * input_set_capability - mark device as capable of a certain event
1541 * @dev: device that is capable of emitting or accepting event 1600 * @dev: device that is capable of emitting or accepting event
1542 * @type: type of the event (EV_KEY, EV_REL, etc...) 1601 * @type: type of the event (EV_KEY, EV_REL, etc...)
@@ -1945,20 +2004,10 @@ static const struct file_operations input_fops = {
1945 .open = input_open_file, 2004 .open = input_open_file,
1946}; 2005};
1947 2006
1948static void __init input_init_abs_bypass(void)
1949{
1950 const unsigned int *p;
1951
1952 for (p = input_abs_bypass_init_data; *p; p++)
1953 input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p);
1954}
1955
1956static int __init input_init(void) 2007static int __init input_init(void)
1957{ 2008{
1958 int err; 2009 int err;
1959 2010
1960 input_init_abs_bypass();
1961
1962 err = class_register(&input_class); 2011 err = class_register(&input_class);
1963 if (err) { 2012 if (err) {
1964 printk(KERN_ERR "input: unable to register input_dev class\n"); 2013 printk(KERN_ERR "input: unable to register input_dev class\n");