aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-3m-pct.c30
-rw-r--r--drivers/input/input-mt.c115
-rw-r--r--drivers/input/tablet/wacom_wac.c23
-rw-r--r--drivers/input/tablet/wacom_wac.h4
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c21
-rw-r--r--include/linux/input.h3
-rw-r--r--include/linux/input/mt.h13
7 files changed, 138 insertions, 71 deletions
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index ea475964d05a..4fb7c7528d16 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -28,7 +28,6 @@ MODULE_LICENSE("GPL");
28#include "hid-ids.h" 28#include "hid-ids.h"
29 29
30#define MAX_SLOTS 60 30#define MAX_SLOTS 60
31#define MAX_TRKID USHRT_MAX
32 31
33/* estimated signal-to-noise ratios */ 32/* estimated signal-to-noise ratios */
34#define SN_MOVE 2048 33#define SN_MOVE 2048
@@ -36,14 +35,11 @@ MODULE_LICENSE("GPL");
36 35
37struct mmm_finger { 36struct mmm_finger {
38 __s32 x, y, w, h; 37 __s32 x, y, w, h;
39 __u16 id;
40 bool prev_touch;
41 bool touch, valid; 38 bool touch, valid;
42}; 39};
43 40
44struct mmm_data { 41struct mmm_data {
45 struct mmm_finger f[MAX_SLOTS]; 42 struct mmm_finger f[MAX_SLOTS];
46 __u16 id;
47 __u8 curid; 43 __u8 curid;
48 __u8 nexp, nreal; 44 __u8 nexp, nreal;
49 bool touch, valid; 45 bool touch, valid;
@@ -117,11 +113,6 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
117 0, 1, 0, 0); 113 0, 1, 0, 0);
118 return 1; 114 return 1;
119 case HID_DG_CONTACTID: 115 case HID_DG_CONTACTID:
120 field->logical_maximum = MAX_TRKID;
121 hid_map_usage(hi, usage, bit, max,
122 EV_ABS, ABS_MT_TRACKING_ID);
123 input_set_abs_params(hi->input, ABS_MT_TRACKING_ID,
124 0, MAX_TRKID, 0, 0);
125 input_mt_init_slots(hi->input, MAX_SLOTS); 116 input_mt_init_slots(hi->input, MAX_SLOTS);
126 return 1; 117 return 1;
127 } 118 }
@@ -152,7 +143,6 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
152 */ 143 */
153static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) 144static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
154{ 145{
155 struct mmm_finger *oldest = 0;
156 int i; 146 int i;
157 for (i = 0; i < MAX_SLOTS; ++i) { 147 for (i = 0; i < MAX_SLOTS; ++i) {
158 struct mmm_finger *f = &md->f[i]; 148 struct mmm_finger *f = &md->f[i];
@@ -161,6 +151,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
161 continue; 151 continue;
162 } 152 }
163 input_mt_slot(input, i); 153 input_mt_slot(input, i);
154 input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch);
164 if (f->touch) { 155 if (f->touch) {
165 /* this finger is on the screen */ 156 /* this finger is on the screen */
166 int wide = (f->w > f->h); 157 int wide = (f->w > f->h);
@@ -168,33 +159,16 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
168 int major = max(f->w, f->h) >> 1; 159 int major = max(f->w, f->h) >> 1;
169 int minor = min(f->w, f->h) >> 1; 160 int minor = min(f->w, f->h) >> 1;
170 161
171 if (!f->prev_touch)
172 f->id = md->id++;
173 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);
174 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); 162 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
175 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); 163 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
176 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 164 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
177 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 165 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
178 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); 166 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
179 /* touchscreen emulation: pick the oldest contact */
180 if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))
181 oldest = f;
182 } else {
183 /* this finger took off the screen */
184 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);
185 } 167 }
186 f->prev_touch = f->touch;
187 f->valid = 0; 168 f->valid = 0;
188 } 169 }
189 170
190 /* touchscreen emulation */ 171 input_mt_report_pointer_emulation(input, true);
191 if (oldest) {
192 input_event(input, EV_KEY, BTN_TOUCH, 1);
193 input_event(input, EV_ABS, ABS_X, oldest->x);
194 input_event(input, EV_ABS, ABS_Y, oldest->y);
195 } else {
196 input_event(input, EV_KEY, BTN_TOUCH, 0);
197 }
198 input_sync(input); 172 input_sync(input);
199} 173}
200 174
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index f400e47092c4..c48c81f0308d 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -11,17 +11,18 @@
11#include <linux/input/mt.h> 11#include <linux/input/mt.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13 13
14#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
15
14/** 16/**
15 * input_mt_init_slots() - initialize MT input slots 17 * input_mt_init_slots() - initialize MT input slots
16 * @dev: input device supporting MT events and finger tracking 18 * @dev: input device supporting MT events and finger tracking
17 * @num_slots: number of slots used by the device 19 * @num_slots: number of slots used by the device
18 * 20 *
19 * This function allocates all necessary memory for MT slot handling 21 * This function allocates all necessary memory for MT slot handling
20 * in the input device, adds ABS_MT_SLOT to the device capabilities 22 * in the input device, prepares the ABS_MT_SLOT and
21 * and sets up appropriate event buffers. All slots are initially 23 * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
22 * marked as unused by setting ABS_MT_TRACKING_ID to -1. May be called 24 * May be called repeatedly. Returns -EINVAL if attempting to
23 * repeatedly. Returns -EINVAL if attempting to reinitialize with a 25 * reinitialize with a different number of slots.
24 * different number of slots.
25 */ 26 */
26int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) 27int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
27{ 28{
@@ -38,6 +39,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
38 39
39 dev->mtsize = num_slots; 40 dev->mtsize = num_slots;
40 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); 41 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
42 input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
41 input_set_events_per_packet(dev, 6 * num_slots); 43 input_set_events_per_packet(dev, 6 * num_slots);
42 44
43 /* Mark slots as 'unused' */ 45 /* Mark slots as 'unused' */
@@ -61,5 +63,108 @@ void input_mt_destroy_slots(struct input_dev *dev)
61 dev->mt = NULL; 63 dev->mt = NULL;
62 dev->mtsize = 0; 64 dev->mtsize = 0;
63 dev->slot = 0; 65 dev->slot = 0;
66 dev->trkid = 0;
64} 67}
65EXPORT_SYMBOL(input_mt_destroy_slots); 68EXPORT_SYMBOL(input_mt_destroy_slots);
69
70/**
71 * input_mt_report_slot_state() - report contact state
72 * @dev: input device with allocated MT slots
73 * @tool_type: the tool type to use in this slot
74 * @active: true if contact is active, false otherwise
75 *
76 * Reports a contact via ABS_MT_TRACKING_ID, and optionally
77 * ABS_MT_TOOL_TYPE. If active is true and the slot is currently
78 * inactive, or if the tool type is changed, a new tracking id is
79 * assigned to the slot. The tool type is only reported if the
80 * corresponding absbit field is set.
81 */
82void input_mt_report_slot_state(struct input_dev *dev,
83 unsigned int tool_type, bool active)
84{
85 struct input_mt_slot *mt;
86 int id;
87
88 if (!dev->mt || !active) {
89 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
90 return;
91 }
92
93 mt = &dev->mt[dev->slot];
94 id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);
95 if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)
96 id = input_mt_new_trkid(dev);
97
98 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
99 input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
100}
101EXPORT_SYMBOL(input_mt_report_slot_state);
102
103/**
104 * input_mt_report_finger_count() - report contact count
105 * @dev: input device with allocated MT slots
106 * @count: the number of contacts
107 *
108 * Reports the contact count via BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP,
109 * BTN_TOOL_TRIPLETAP and BTN_TOOL_QUADTAP.
110 *
111 * The input core ensures only the KEY events already setup for
112 * this device will produce output.
113 */
114void input_mt_report_finger_count(struct input_dev *dev, int count)
115{
116 input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1);
117 input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);
118 input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);
119 input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);
120}
121EXPORT_SYMBOL(input_mt_report_finger_count);
122
123/**
124 * input_mt_report_pointer_emulation() - common pointer emulation
125 * @dev: input device with allocated MT slots
126 * @use_count: report number of active contacts as finger count
127 *
128 * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
129 * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
130 *
131 * The input core ensures only the KEY and ABS axes already setup for
132 * this device will produce output.
133 */
134void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
135{
136 struct input_mt_slot *oldest = 0;
137 int oldid = dev->trkid;
138 int count = 0;
139 int i;
140
141 for (i = 0; i < dev->mtsize; ++i) {
142 struct input_mt_slot *ps = &dev->mt[i];
143 int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
144
145 if (id < 0)
146 continue;
147 if ((id - oldid) & TRKID_SGN) {
148 oldest = ps;
149 oldid = id;
150 }
151 count++;
152 }
153
154 input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
155 if (use_count)
156 input_mt_report_finger_count(dev, count);
157
158 if (oldest) {
159 int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
160 int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);
161 int p = input_mt_get_value(oldest, ABS_MT_PRESSURE);
162
163 input_event(dev, EV_ABS, ABS_X, x);
164 input_event(dev, EV_ABS, ABS_Y, y);
165 input_event(dev, EV_ABS, ABS_PRESSURE, p);
166 } else {
167 input_event(dev, EV_ABS, ABS_PRESSURE, 0);
168 }
169}
170EXPORT_SYMBOL(input_mt_report_pointer_emulation);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index f26e2238f6ca..0b0525486711 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -863,19 +863,21 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
863 struct wacom_features *features = &wacom->features; 863 struct wacom_features *features = &wacom->features;
864 struct input_dev *input = wacom->input; 864 struct input_dev *input = wacom->input;
865 unsigned char *data = wacom->data; 865 unsigned char *data = wacom->data;
866 int sp = 0, sx = 0, sy = 0, count = 0;
867 int i; 866 int i;
868 867
869 for (i = 0; i < 2; i++) { 868 for (i = 0; i < 2; i++) {
870 int p = data[9 * i + 2]; 869 int p = data[9 * i + 2];
870 bool touch = p && !wacom->shared->stylus_in_proximity;
871
871 input_mt_slot(input, i); 872 input_mt_slot(input, i);
873 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
872 /* 874 /*
873 * Touch events need to be disabled while stylus is 875 * Touch events need to be disabled while stylus is
874 * in proximity because user's hand is resting on touchpad 876 * in proximity because user's hand is resting on touchpad
875 * and sending unwanted events. User expects tablet buttons 877 * and sending unwanted events. User expects tablet buttons
876 * to continue working though. 878 * to continue working though.
877 */ 879 */
878 if (p && !wacom->shared->stylus_in_proximity) { 880 if (touch) {
879 int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; 881 int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
880 int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; 882 int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
881 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { 883 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
@@ -885,23 +887,10 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
885 input_report_abs(input, ABS_MT_PRESSURE, p); 887 input_report_abs(input, ABS_MT_PRESSURE, p);
886 input_report_abs(input, ABS_MT_POSITION_X, x); 888 input_report_abs(input, ABS_MT_POSITION_X, x);
887 input_report_abs(input, ABS_MT_POSITION_Y, y); 889 input_report_abs(input, ABS_MT_POSITION_Y, y);
888 if (wacom->id[i] < 0)
889 wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;
890 if (!count++)
891 sp = p, sx = x, sy = y;
892 } else {
893 wacom->id[i] = -1;
894 } 890 }
895 input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);
896 } 891 }
897 892
898 input_report_key(input, BTN_TOUCH, count > 0); 893 input_mt_report_pointer_emulation(input, true);
899 input_report_key(input, BTN_TOOL_FINGER, count == 1);
900 input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2);
901
902 input_report_abs(input, ABS_PRESSURE, sp);
903 input_report_abs(input, ABS_X, sx);
904 input_report_abs(input, ABS_Y, sy);
905 894
906 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); 895 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
907 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); 896 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
@@ -1283,8 +1272,6 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
1283 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 1272 input_set_abs_params(input_dev, ABS_MT_PRESSURE,
1284 0, features->pressure_max, 1273 0, features->pressure_max,
1285 features->pressure_fuzz, 0); 1274 features->pressure_fuzz, 0);
1286 input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
1287 MAX_TRACKING_ID, 0, 0);
1288 } else if (features->device_type == BTN_TOOL_PEN) { 1275 } else if (features->device_type == BTN_TOOL_PEN) {
1289 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); 1276 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1290 __set_bit(BTN_TOOL_PEN, input_dev->keybit); 1277 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 00ca01541d89..b1310ec9720c 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -42,9 +42,6 @@
42#define WACOM_QUIRK_MULTI_INPUT 0x0001 42#define WACOM_QUIRK_MULTI_INPUT 0x0001
43#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 43#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
44 44
45/* largest reported tracking id */
46#define MAX_TRACKING_ID 0xfff
47
48enum { 45enum {
49 PENPARTNER = 0, 46 PENPARTNER = 0,
50 GRAPHIRE, 47 GRAPHIRE,
@@ -100,7 +97,6 @@ struct wacom_wac {
100 int id[3]; 97 int id[3];
101 __u32 serial[2]; 98 __u32 serial[2];
102 int last_finger; 99 int last_finger;
103 int trk_id;
104 struct wacom_features features; 100 struct wacom_features features;
105 struct wacom_shared *shared; 101 struct wacom_shared *shared;
106 struct input_dev *input; 102 struct input_dev *input;
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 4a2e8cf4c8ef..2a0bec12d12a 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -48,8 +48,6 @@ MODULE_LICENSE("GPL");
48#define W8001_PKTLEN_TPCCTL 11 /* control packet */ 48#define W8001_PKTLEN_TPCCTL 11 /* control packet */
49#define W8001_PKTLEN_TOUCH2FG 13 49#define W8001_PKTLEN_TOUCH2FG 13
50 50
51#define MAX_TRACKING_ID 0xFF /* arbitrarily chosen */
52
53struct w8001_coord { 51struct w8001_coord {
54 u8 rdy; 52 u8 rdy;
55 u8 tsw; 53 u8 tsw;
@@ -87,7 +85,6 @@ struct w8001 {
87 char phys[32]; 85 char phys[32];
88 int type; 86 int type;
89 unsigned int pktlen; 87 unsigned int pktlen;
90 int trkid[2];
91}; 88};
92 89
93static void parse_data(u8 *data, struct w8001_coord *coord) 90static void parse_data(u8 *data, struct w8001_coord *coord)
@@ -116,28 +113,23 @@ static void parse_data(u8 *data, struct w8001_coord *coord)
116 113
117static void parse_touch(struct w8001 *w8001) 114static void parse_touch(struct w8001 *w8001)
118{ 115{
119 static int trkid;
120 struct input_dev *dev = w8001->dev; 116 struct input_dev *dev = w8001->dev;
121 unsigned char *data = w8001->data; 117 unsigned char *data = w8001->data;
122 int i; 118 int i;
123 119
124 for (i = 0; i < 2; i++) { 120 for (i = 0; i < 2; i++) {
125 input_mt_slot(dev, i); 121 bool touch = data[0] & (1 << i);
126 122
127 if (data[0] & (1 << i)) { 123 input_mt_slot(dev, i);
124 input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch);
125 if (touch) {
128 int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]); 126 int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]);
129 int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]); 127 int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]);
130 /* data[5,6] and [11,12] is finger capacity */ 128 /* data[5,6] and [11,12] is finger capacity */
131 129
132 input_report_abs(dev, ABS_MT_POSITION_X, x); 130 input_report_abs(dev, ABS_MT_POSITION_X, x);
133 input_report_abs(dev, ABS_MT_POSITION_Y, y); 131 input_report_abs(dev, ABS_MT_POSITION_Y, y);
134 input_report_abs(dev, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
135 if (w8001->trkid[i] < 0)
136 w8001->trkid[i] = trkid++ & MAX_TRACKING_ID;
137 } else {
138 w8001->trkid[i] = -1;
139 } 132 }
140 input_report_abs(dev, ABS_MT_TRACKING_ID, w8001->trkid[i]);
141 } 133 }
142 134
143 input_sync(dev); 135 input_sync(dev);
@@ -319,14 +311,12 @@ static int w8001_setup(struct w8001 *w8001)
319 w8001->pktlen = W8001_PKTLEN_TOUCH2FG; 311 w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
320 312
321 input_mt_init_slots(dev, 2); 313 input_mt_init_slots(dev, 2);
322 input_set_abs_params(dev, ABS_MT_TRACKING_ID,
323 0, MAX_TRACKING_ID, 0, 0);
324 input_set_abs_params(dev, ABS_MT_POSITION_X, 314 input_set_abs_params(dev, ABS_MT_POSITION_X,
325 0, touch.x, 0, 0); 315 0, touch.x, 0, 0);
326 input_set_abs_params(dev, ABS_MT_POSITION_Y, 316 input_set_abs_params(dev, ABS_MT_POSITION_Y,
327 0, touch.y, 0, 0); 317 0, touch.y, 0, 0);
328 input_set_abs_params(dev, ABS_MT_TOOL_TYPE, 318 input_set_abs_params(dev, ABS_MT_TOOL_TYPE,
329 0, 0, 0, 0); 319 0, MT_TOOL_MAX, 0, 0);
330 break; 320 break;
331 } 321 }
332 } 322 }
@@ -372,7 +362,6 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
372 w8001->serio = serio; 362 w8001->serio = serio;
373 w8001->id = serio->id.id; 363 w8001->id = serio->id.id;
374 w8001->dev = input_dev; 364 w8001->dev = input_dev;
375 w8001->trkid[0] = w8001->trkid[1] = -1;
376 init_completion(&w8001->cmd_done); 365 init_completion(&w8001->cmd_done);
377 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); 366 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
378 367
diff --git a/include/linux/input.h b/include/linux/input.h
index 99e2a52c0509..6de145df4c1c 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -848,6 +848,7 @@ struct input_keymap_entry {
848 */ 848 */
849#define MT_TOOL_FINGER 0 849#define MT_TOOL_FINGER 0
850#define MT_TOOL_PEN 1 850#define MT_TOOL_PEN 1
851#define MT_TOOL_MAX 1
851 852
852/* 853/*
853 * Values describing the status of a force-feedback effect 854 * Values describing the status of a force-feedback effect
@@ -1122,6 +1123,7 @@ struct ff_effect {
1122 * of tracked contacts 1123 * of tracked contacts
1123 * @mtsize: number of MT slots the device uses 1124 * @mtsize: number of MT slots the device uses
1124 * @slot: MT slot currently being transmitted 1125 * @slot: MT slot currently being transmitted
1126 * @trkid: stores MT tracking ID for the current contact
1125 * @absinfo: array of &struct absinfo elements holding information 1127 * @absinfo: array of &struct absinfo elements holding information
1126 * about absolute axes (current value, min, max, flat, fuzz, 1128 * about absolute axes (current value, min, max, flat, fuzz,
1127 * resolution) 1129 * resolution)
@@ -1206,6 +1208,7 @@ struct input_dev {
1206 struct input_mt_slot *mt; 1208 struct input_mt_slot *mt;
1207 int mtsize; 1209 int mtsize;
1208 int slot; 1210 int slot;
1211 int trkid;
1209 1212
1210 struct input_absinfo *absinfo; 1213 struct input_absinfo *absinfo;
1211 1214
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index d7f6518e3222..b3ac06a4435d 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -13,6 +13,8 @@
13 13
14#include <linux/input.h> 14#include <linux/input.h>
15 15
16#define TRKID_MAX 0xffff
17
16/** 18/**
17 * struct input_mt_slot - represents the state of an input MT slot 19 * struct input_mt_slot - represents the state of an input MT slot
18 * @abs: holds current values of ABS_MT axes for this slot 20 * @abs: holds current values of ABS_MT axes for this slot
@@ -36,9 +38,20 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot,
36int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots); 38int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);
37void input_mt_destroy_slots(struct input_dev *dev); 39void input_mt_destroy_slots(struct input_dev *dev);
38 40
41static inline int input_mt_new_trkid(struct input_dev *dev)
42{
43 return dev->trkid++ & TRKID_MAX;
44}
45
39static inline void input_mt_slot(struct input_dev *dev, int slot) 46static inline void input_mt_slot(struct input_dev *dev, int slot)
40{ 47{
41 input_event(dev, EV_ABS, ABS_MT_SLOT, slot); 48 input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
42} 49}
43 50
51void input_mt_report_slot_state(struct input_dev *dev,
52 unsigned int tool_type, bool active);
53
54void input_mt_report_finger_count(struct input_dev *dev, int count);
55void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count);
56
44#endif 57#endif