aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-12-15 07:50:34 -0500
committerHenrik Rydberg <rydberg@euromail.se>2010-12-16 04:41:38 -0500
commitc5f4dec1ceb6ab773bbbefbe64a7c990c7d6b17f (patch)
treefdc8b67537b73474bd34b65d0d1c5bc7a9de3c7a
parent8cde81001626c4c60b26ef2eb5fc522885ed9fd0 (diff)
input: mt: Move tracking and pointer emulation to input-mt
The drivers using the type B protocol all report tracking information the same way. The contact id is semantically equivalent to ABS_MT_SLOT, and the handling of ABS_MT_TRACKING_ID only complicates the driver. The situation can be improved upon by providing a common pointer emulation code, thereby removing the need for the tracking id in the driver. This patch moves all tracking event handling over to the input core, simplifying both the existing drivers and the ones currently in preparation. Acked-by: Ping Cheng <pingc@wacom.com> Acked-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
-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