aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/device-drivers.tmpl4
-rw-r--r--Documentation/input/multi-touch-protocol.txt9
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/hid/Kconfig3
-rw-r--r--drivers/hid/hid-3m-pct.c36
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-egalax.c129
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/input/Makefile2
-rw-r--r--drivers/input/input-mt.c170
-rw-r--r--drivers/input/input.c48
-rw-r--r--drivers/input/misc/uinput.c4
-rw-r--r--drivers/input/tablet/wacom_wac.c26
-rw-r--r--drivers/input/tablet/wacom_wac.h4
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c25
-rw-r--r--include/linux/input.h22
-rw-r--r--include/linux/input/mt.h57
17 files changed, 329 insertions, 216 deletions
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index 22edcbb9ddaf..35447e081736 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -304,6 +304,10 @@ X!Idrivers/video/console/fonts.c
304!Edrivers/input/ff-core.c 304!Edrivers/input/ff-core.c
305!Edrivers/input/ff-memless.c 305!Edrivers/input/ff-memless.c
306 </sect1> 306 </sect1>
307 <sect1><title>Multitouch Library</title>
308!Iinclude/linux/input/mt.h
309!Edrivers/input/input-mt.c
310 </sect1>
307 <sect1><title>Polled input devices</title> 311 <sect1><title>Polled input devices</title>
308!Iinclude/linux/input-polldev.h 312!Iinclude/linux/input-polldev.h
309!Edrivers/input/input-polldev.c 313!Edrivers/input/input-polldev.c
diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt
index bdcba154b83e..07215fa0c588 100644
--- a/Documentation/input/multi-touch-protocol.txt
+++ b/Documentation/input/multi-touch-protocol.txt
@@ -161,7 +161,8 @@ against the glass. The inner region will increase, and in general, the
161ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than 161ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than
162unity, is related to the contact pressure. For pressure-based devices, 162unity, is related to the contact pressure. For pressure-based devices,
163ABS_MT_PRESSURE may be used to provide the pressure on the contact area 163ABS_MT_PRESSURE may be used to provide the pressure on the contact area
164instead. 164instead. Devices capable of contact hovering can use ABS_MT_DISTANCE to
165indicate the distance between the contact and the surface.
165 166
166In addition to the MAJOR parameters, the oval shape of the contact can be 167In addition to the MAJOR parameters, the oval shape of the contact can be
167described by adding the MINOR parameters, such that MAJOR and MINOR are the 168described by adding the MINOR parameters, such that MAJOR and MINOR are the
@@ -213,6 +214,12 @@ The pressure, in arbitrary units, on the contact area. May be used instead
213of TOUCH and WIDTH for pressure-based devices or any device with a spatial 214of TOUCH and WIDTH for pressure-based devices or any device with a spatial
214signal intensity distribution. 215signal intensity distribution.
215 216
217ABS_MT_DISTANCE
218
219The distance, in surface units, between the contact and the surface. Zero
220distance means the contact is touching the surface. A positive number means
221the contact is hovering above the surface.
222
216ABS_MT_ORIENTATION 223ABS_MT_ORIENTATION
217 224
218The orientation of the ellipse. The value should describe a signed quarter 225The orientation of the ellipse. The value should describe a signed quarter
diff --git a/MAINTAINERS b/MAINTAINERS
index 0094224ca79b..a9d3a1343698 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3020,8 +3020,10 @@ F: drivers/input/
3020INPUT MULTITOUCH (MT) PROTOCOL 3020INPUT MULTITOUCH (MT) PROTOCOL
3021M: Henrik Rydberg <rydberg@euromail.se> 3021M: Henrik Rydberg <rydberg@euromail.se>
3022L: linux-input@vger.kernel.org 3022L: linux-input@vger.kernel.org
3023T: git git://git.kernel.org/pub/scm/linux/kernel/git/rydberg/input-mt.git
3023S: Maintained 3024S: Maintained
3024F: Documentation/input/multi-touch-protocol.txt 3025F: Documentation/input/multi-touch-protocol.txt
3026F: drivers/input/input-mt.c
3025K: \b(ABS|SYN)_MT_ 3027K: \b(ABS|SYN)_MT_
3026 3028
3027INTEL IDLE DRIVER 3029INTEL IDLE DRIVER
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 3052e2969ad0..401acecc7f32 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -154,7 +154,8 @@ config HID_EGALAX
154 tristate "eGalax multi-touch panel" 154 tristate "eGalax multi-touch panel"
155 depends on USB_HID 155 depends on USB_HID
156 ---help--- 156 ---help---
157 Support for the eGalax dual-touch panel. 157 Support for the eGalax dual-touch panels, including the
158 Joojoo and Wetab tablets.
158 159
159config HID_ELECOM 160config HID_ELECOM
160 tristate "ELECOM BM084 bluetooth mouse" 161 tristate "ELECOM BM084 bluetooth mouse"
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index 02d8cd3b1b1b..4fb7c7528d16 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/usb.h> 21#include <linux/usb.h>
22#include <linux/input/mt.h>
22 23
23MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); 24MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
24MODULE_DESCRIPTION("3M PCT multitouch panels"); 25MODULE_DESCRIPTION("3M PCT multitouch panels");
@@ -27,8 +28,6 @@ MODULE_LICENSE("GPL");
27#include "hid-ids.h" 28#include "hid-ids.h"
28 29
29#define MAX_SLOTS 60 30#define MAX_SLOTS 60
30#define MAX_TRKID USHRT_MAX
31#define MAX_EVENTS 360
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,14 +113,7 @@ 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; 116 input_mt_init_slots(hi->input, MAX_SLOTS);
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 if (!hi->input->mt)
126 input_mt_create_slots(hi->input, MAX_SLOTS);
127 input_set_events_per_packet(hi->input, MAX_EVENTS);
128 return 1; 117 return 1;
129 } 118 }
130 /* let hid-input decide for the others */ 119 /* let hid-input decide for the others */
@@ -154,7 +143,6 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
154 */ 143 */
155static 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)
156{ 145{
157 struct mmm_finger *oldest = 0;
158 int i; 146 int i;
159 for (i = 0; i < MAX_SLOTS; ++i) { 147 for (i = 0; i < MAX_SLOTS; ++i) {
160 struct mmm_finger *f = &md->f[i]; 148 struct mmm_finger *f = &md->f[i];
@@ -163,6 +151,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
163 continue; 151 continue;
164 } 152 }
165 input_mt_slot(input, i); 153 input_mt_slot(input, i);
154 input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch);
166 if (f->touch) { 155 if (f->touch) {
167 /* this finger is on the screen */ 156 /* this finger is on the screen */
168 int wide = (f->w > f->h); 157 int wide = (f->w > f->h);
@@ -170,33 +159,16 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
170 int major = max(f->w, f->h) >> 1; 159 int major = max(f->w, f->h) >> 1;
171 int minor = min(f->w, f->h) >> 1; 160 int minor = min(f->w, f->h) >> 1;
172 161
173 if (!f->prev_touch)
174 f->id = md->id++;
175 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);
176 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); 162 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
177 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); 163 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
178 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 164 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
179 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 165 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
180 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); 166 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
181 /* touchscreen emulation: pick the oldest contact */
182 if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))
183 oldest = f;
184 } else {
185 /* this finger took off the screen */
186 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);
187 } 167 }
188 f->prev_touch = f->touch;
189 f->valid = 0; 168 f->valid = 0;
190 } 169 }
191 170
192 /* touchscreen emulation */ 171 input_mt_report_pointer_emulation(input, true);
193 if (oldest) {
194 input_event(input, EV_KEY, BTN_TOUCH, 1);
195 input_event(input, EV_ABS, ABS_X, oldest->x);
196 input_event(input, EV_ABS, ABS_Y, oldest->y);
197 } else {
198 input_event(input, EV_KEY, BTN_TOUCH, 0);
199 }
200 input_sync(input); 172 input_sync(input);
201} 173}
202 174
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 515345b11ac9..f4a37f842cfe 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1300,6 +1300,8 @@ static const struct hid_device_id hid_blacklist[] = {
1300 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, 1300 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
1301 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, 1301 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
1302 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, 1302 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
1303 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
1304 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
1303 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, 1305 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
1304 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, 1306 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
1305 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, 1307 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c
index 54b017ad258d..87878509f25e 100644
--- a/drivers/hid/hid-egalax.c
+++ b/drivers/hid/hid-egalax.c
@@ -2,6 +2,8 @@
2 * HID driver for eGalax dual-touch panels 2 * HID driver for eGalax dual-touch panels
3 * 3 *
4 * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr> 4 * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
5 * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
6 * Copyright (c) 2010 Canonical, Ltd.
5 * 7 *
6 */ 8 */
7 9
@@ -16,6 +18,7 @@
16#include <linux/hid.h> 18#include <linux/hid.h>
17#include <linux/module.h> 19#include <linux/module.h>
18#include <linux/usb.h> 20#include <linux/usb.h>
21#include <linux/input/mt.h>
19#include <linux/slab.h> 22#include <linux/slab.h>
20#include "usbhid/usbhid.h" 23#include "usbhid/usbhid.h"
21 24
@@ -25,38 +28,53 @@ MODULE_LICENSE("GPL");
25 28
26#include "hid-ids.h" 29#include "hid-ids.h"
27 30
31#define MAX_SLOTS 2
32
33/* estimated signal-to-noise ratios */
34#define SN_MOVE 4096
35#define SN_PRESSURE 32
36
28struct egalax_data { 37struct egalax_data {
29 __u16 x, y, z; 38 int valid;
30 __u8 id; 39 int slot;
31 bool first; /* is this the first finger in the frame? */ 40 int touch;
32 bool valid; /* valid finger data, or just placeholder? */ 41 int x, y, z;
33 bool activity; /* at least one active finger previously? */
34 __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */
35}; 42};
36 43
44static void set_abs(struct input_dev *input, unsigned int code,
45 struct hid_field *field, int snratio)
46{
47 int fmin = field->logical_minimum;
48 int fmax = field->logical_maximum;
49 int fuzz = snratio ? (fmax - fmin) / snratio : 0;
50 input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
51}
52
37static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, 53static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
38 struct hid_field *field, struct hid_usage *usage, 54 struct hid_field *field, struct hid_usage *usage,
39 unsigned long **bit, int *max) 55 unsigned long **bit, int *max)
40{ 56{
57 struct input_dev *input = hi->input;
58
41 switch (usage->hid & HID_USAGE_PAGE) { 59 switch (usage->hid & HID_USAGE_PAGE) {
42 60
43 case HID_UP_GENDESK: 61 case HID_UP_GENDESK:
44 switch (usage->hid) { 62 switch (usage->hid) {
45 case HID_GD_X: 63 case HID_GD_X:
64 field->logical_maximum = 32760;
46 hid_map_usage(hi, usage, bit, max, 65 hid_map_usage(hi, usage, bit, max,
47 EV_ABS, ABS_MT_POSITION_X); 66 EV_ABS, ABS_MT_POSITION_X);
67 set_abs(input, ABS_MT_POSITION_X, field, SN_MOVE);
48 /* touchscreen emulation */ 68 /* touchscreen emulation */
49 input_set_abs_params(hi->input, ABS_X, 69 set_abs(input, ABS_X, field, SN_MOVE);
50 field->logical_minimum,
51 field->logical_maximum, 0, 0);
52 return 1; 70 return 1;
53 case HID_GD_Y: 71 case HID_GD_Y:
72 field->logical_maximum = 32760;
54 hid_map_usage(hi, usage, bit, max, 73 hid_map_usage(hi, usage, bit, max,
55 EV_ABS, ABS_MT_POSITION_Y); 74 EV_ABS, ABS_MT_POSITION_Y);
75 set_abs(input, ABS_MT_POSITION_Y, field, SN_MOVE);
56 /* touchscreen emulation */ 76 /* touchscreen emulation */
57 input_set_abs_params(hi->input, ABS_Y, 77 set_abs(input, ABS_Y, field, SN_MOVE);
58 field->logical_minimum,
59 field->logical_maximum, 0, 0);
60 return 1; 78 return 1;
61 } 79 }
62 return 0; 80 return 0;
@@ -66,6 +84,7 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
66 case HID_DG_TIPSWITCH: 84 case HID_DG_TIPSWITCH:
67 /* touchscreen emulation */ 85 /* touchscreen emulation */
68 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); 86 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
87 input_set_capability(input, EV_KEY, BTN_TOUCH);
69 return 1; 88 return 1;
70 case HID_DG_INRANGE: 89 case HID_DG_INRANGE:
71 case HID_DG_CONFIDENCE: 90 case HID_DG_CONFIDENCE:
@@ -73,16 +92,15 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
73 case HID_DG_CONTACTMAX: 92 case HID_DG_CONTACTMAX:
74 return -1; 93 return -1;
75 case HID_DG_CONTACTID: 94 case HID_DG_CONTACTID:
76 hid_map_usage(hi, usage, bit, max, 95 input_mt_init_slots(input, MAX_SLOTS);
77 EV_ABS, ABS_MT_TRACKING_ID);
78 return 1; 96 return 1;
79 case HID_DG_TIPPRESSURE: 97 case HID_DG_TIPPRESSURE:
98 field->logical_minimum = 0;
80 hid_map_usage(hi, usage, bit, max, 99 hid_map_usage(hi, usage, bit, max,
81 EV_ABS, ABS_MT_PRESSURE); 100 EV_ABS, ABS_MT_PRESSURE);
101 set_abs(input, ABS_MT_PRESSURE, field, SN_PRESSURE);
82 /* touchscreen emulation */ 102 /* touchscreen emulation */
83 input_set_abs_params(hi->input, ABS_PRESSURE, 103 set_abs(input, ABS_PRESSURE, field, SN_PRESSURE);
84 field->logical_minimum,
85 field->logical_maximum, 0, 0);
86 return 1; 104 return 1;
87 } 105 }
88 return 0; 106 return 0;
@@ -96,10 +114,10 @@ static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi,
96 struct hid_field *field, struct hid_usage *usage, 114 struct hid_field *field, struct hid_usage *usage,
97 unsigned long **bit, int *max) 115 unsigned long **bit, int *max)
98{ 116{
117 /* tell hid-input to skip setup of these event types */
99 if (usage->type == EV_KEY || usage->type == EV_ABS) 118 if (usage->type == EV_KEY || usage->type == EV_ABS)
100 clear_bit(usage->code, *bit); 119 set_bit(usage->type, hi->input->evbit);
101 120 return -1;
102 return 0;
103} 121}
104 122
105/* 123/*
@@ -108,58 +126,16 @@ static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi,
108 */ 126 */
109static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) 127static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
110{ 128{
111 td->first = !td->first; /* touchscreen emulation */ 129 input_mt_slot(input, td->slot);
112 130 input_mt_report_slot_state(input, MT_TOOL_FINGER, td->touch);
113 if (td->valid) { 131 if (td->touch) {
114 /* emit multitouch events */ 132 input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
115 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); 133 input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
116 input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3);
117 input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3);
118 input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); 134 input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
119
120 input_mt_sync(input);
121
122 /*
123 * touchscreen emulation: store (x, y) as
124 * the last valid values in this frame
125 */
126 td->lastx = td->x;
127 td->lasty = td->y;
128 td->lastz = td->z;
129 }
130
131 /*
132 * touchscreen emulation: if this is the second finger and at least
133 * one in this frame is valid, the latest valid in the frame is
134 * the oldest on the panel, the one we want for single touch
135 */
136 if (!td->first && td->activity) {
137 input_event(input, EV_ABS, ABS_X, td->lastx >> 3);
138 input_event(input, EV_ABS, ABS_Y, td->lasty >> 3);
139 input_event(input, EV_ABS, ABS_PRESSURE, td->lastz);
140 }
141
142 if (!td->valid) {
143 /*
144 * touchscreen emulation: if the first finger is invalid
145 * and there previously was finger activity, this is a release
146 */
147 if (td->first && td->activity) {
148 input_event(input, EV_KEY, BTN_TOUCH, 0);
149 td->activity = false;
150 }
151 return;
152 }
153
154
155 /* touchscreen emulation: if no previous activity, emit touch event */
156 if (!td->activity) {
157 input_event(input, EV_KEY, BTN_TOUCH, 1);
158 td->activity = true;
159 } 135 }
136 input_mt_report_pointer_emulation(input, true);
160} 137}
161 138
162
163static int egalax_event(struct hid_device *hid, struct hid_field *field, 139static int egalax_event(struct hid_device *hid, struct hid_field *field,
164 struct hid_usage *usage, __s32 value) 140 struct hid_usage *usage, __s32 value)
165{ 141{
@@ -169,25 +145,26 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field,
169 * uses a standard parallel multitouch protocol (product ID == 145 * uses a standard parallel multitouch protocol (product ID ==
170 * 48xx). The second is capacitive and uses an unusual "serial" 146 * 48xx). The second is capacitive and uses an unusual "serial"
171 * protocol with a different message for each multitouch finger 147 * protocol with a different message for each multitouch finger
172 * (product ID == 72xx). We do not yet generate a correct event 148 * (product ID == 72xx).
173 * sequence for the capacitive/serial protocol.
174 */ 149 */
175 if (hid->claimed & HID_CLAIMED_INPUT) { 150 if (hid->claimed & HID_CLAIMED_INPUT) {
176 struct input_dev *input = field->hidinput->input; 151 struct input_dev *input = field->hidinput->input;
177 152
178 switch (usage->hid) { 153 switch (usage->hid) {
179 case HID_DG_INRANGE: 154 case HID_DG_INRANGE:
155 td->valid = value;
156 break;
180 case HID_DG_CONFIDENCE: 157 case HID_DG_CONFIDENCE:
181 /* avoid interference from generic hidinput handling */ 158 /* avoid interference from generic hidinput handling */
182 break; 159 break;
183 case HID_DG_TIPSWITCH: 160 case HID_DG_TIPSWITCH:
184 td->valid = value; 161 td->touch = value;
185 break; 162 break;
186 case HID_DG_TIPPRESSURE: 163 case HID_DG_TIPPRESSURE:
187 td->z = value; 164 td->z = value;
188 break; 165 break;
189 case HID_DG_CONTACTID: 166 case HID_DG_CONTACTID:
190 td->id = value; 167 td->slot = clamp_val(value, 0, MAX_SLOTS - 1);
191 break; 168 break;
192 case HID_GD_X: 169 case HID_GD_X:
193 td->x = value; 170 td->x = value;
@@ -195,11 +172,11 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field,
195 case HID_GD_Y: 172 case HID_GD_Y:
196 td->y = value; 173 td->y = value;
197 /* this is the last field in a finger */ 174 /* this is the last field in a finger */
198 egalax_filter_event(td, input); 175 if (td->valid)
176 egalax_filter_event(td, input);
199 break; 177 break;
200 case HID_DG_CONTACTCOUNT: 178 case HID_DG_CONTACTCOUNT:
201 /* touch emulation: this is the last field in a frame */ 179 /* touch emulation: this is the last field in a frame */
202 td->first = false;
203 break; 180 break;
204 181
205 default: 182 default:
@@ -261,6 +238,10 @@ static const struct hid_device_id egalax_devices[] = {
261 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, 238 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
262 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 239 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
263 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, 240 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
241 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
242 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
243 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
244 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
264 { } 245 { }
265}; 246};
266MODULE_DEVICE_TABLE(hid, egalax_devices); 247MODULE_DEVICE_TABLE(hid, egalax_devices);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 3341baa86a30..a95719b24756 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -196,6 +196,8 @@
196#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 196#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
197#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d 197#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
198#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c 198#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c
199#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2 0x72a1
200#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3 0x480e
199 201
200#define USB_VENDOR_ID_ELECOM 0x056e 202#define USB_VENDOR_ID_ELECOM 0x056e
201#define USB_DEVICE_ID_ELECOM_BM084 0x0061 203#define USB_DEVICE_ID_ELECOM_BM084 0x0061
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 9fd1cf2b705e..09614ce74961 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -5,7 +5,7 @@
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_INPUT) += input-core.o 7obj-$(CONFIG_INPUT) += input-core.o
8input-core-y := input.o input-compat.o ff-core.o 8input-core-y := input.o input-compat.o input-mt.o ff-core.o
9 9
10obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o 10obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
11obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o 11obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
new file mode 100644
index 000000000000..c48c81f0308d
--- /dev/null
+++ b/drivers/input/input-mt.c
@@ -0,0 +1,170 @@
1/*
2 * Input Multitouch Library
3 *
4 * Copyright (c) 2008-2010 Henrik Rydberg
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 */
10
11#include <linux/input/mt.h>
12#include <linux/slab.h>
13
14#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
15
16/**
17 * input_mt_init_slots() - initialize MT input slots
18 * @dev: input device supporting MT events and finger tracking
19 * @num_slots: number of slots used by the device
20 *
21 * This function allocates all necessary memory for MT slot handling
22 * in the input device, prepares the ABS_MT_SLOT and
23 * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
24 * May be called repeatedly. Returns -EINVAL if attempting to
25 * reinitialize with a different number of slots.
26 */
27int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
28{
29 int i;
30
31 if (!num_slots)
32 return 0;
33 if (dev->mt)
34 return dev->mtsize != num_slots ? -EINVAL : 0;
35
36 dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
37 if (!dev->mt)
38 return -ENOMEM;
39
40 dev->mtsize = num_slots;
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);
43 input_set_events_per_packet(dev, 6 * num_slots);
44
45 /* Mark slots as 'unused' */
46 for (i = 0; i < num_slots; i++)
47 input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1);
48
49 return 0;
50}
51EXPORT_SYMBOL(input_mt_init_slots);
52
53/**
54 * input_mt_destroy_slots() - frees the MT slots of the input device
55 * @dev: input device with allocated MT slots
56 *
57 * This function is only needed in error path as the input core will
58 * automatically free the MT slots when the device is destroyed.
59 */
60void input_mt_destroy_slots(struct input_dev *dev)
61{
62 kfree(dev->mt);
63 dev->mt = NULL;
64 dev->mtsize = 0;
65 dev->slot = 0;
66 dev->trkid = 0;
67}
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/input.c b/drivers/input/input.c
index c7a1e826c580..3312e20016bf 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -14,7 +14,7 @@
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/input.h> 17#include <linux/input/mt.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/random.h> 20#include <linux/random.h>
@@ -1726,52 +1726,6 @@ void input_free_device(struct input_dev *dev)
1726EXPORT_SYMBOL(input_free_device); 1726EXPORT_SYMBOL(input_free_device);
1727 1727
1728/** 1728/**
1729 * input_mt_create_slots() - create MT input slots
1730 * @dev: input device supporting MT events and finger tracking
1731 * @num_slots: number of slots used by the device
1732 *
1733 * This function allocates all necessary memory for MT slot handling in the
1734 * input device, and adds ABS_MT_SLOT to the device capabilities. All slots
1735 * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1.
1736 */
1737int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
1738{
1739 int i;
1740
1741 if (!num_slots)
1742 return 0;
1743
1744 dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
1745 if (!dev->mt)
1746 return -ENOMEM;
1747
1748 dev->mtsize = num_slots;
1749 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
1750
1751 /* Mark slots as 'unused' */
1752 for (i = 0; i < num_slots; i++)
1753 dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1;
1754
1755 return 0;
1756}
1757EXPORT_SYMBOL(input_mt_create_slots);
1758
1759/**
1760 * input_mt_destroy_slots() - frees the MT slots of the input device
1761 * @dev: input device with allocated MT slots
1762 *
1763 * This function is only needed in error path as the input core will
1764 * automatically free the MT slots when the device is destroyed.
1765 */
1766void input_mt_destroy_slots(struct input_dev *dev)
1767{
1768 kfree(dev->mt);
1769 dev->mt = NULL;
1770 dev->mtsize = 0;
1771}
1772EXPORT_SYMBOL(input_mt_destroy_slots);
1773
1774/**
1775 * input_set_capability - mark device as capable of a certain event 1729 * input_set_capability - mark device as capable of a certain event
1776 * @dev: device that is capable of emitting or accepting event 1730 * @dev: device that is capable of emitting or accepting event
1777 * @type: type of the event (EV_KEY, EV_REL, etc...) 1731 * @type: type of the event (EV_KEY, EV_REL, etc...)
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index b9410784e6a1..bea89722c4e9 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -37,6 +37,7 @@
37#include <linux/fs.h> 37#include <linux/fs.h>
38#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
39#include <linux/uinput.h> 39#include <linux/uinput.h>
40#include <linux/input/mt.h>
40#include "../input-compat.h" 41#include "../input-compat.h"
41 42
42static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 43static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -406,8 +407,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
406 goto exit; 407 goto exit;
407 if (test_bit(ABS_MT_SLOT, dev->absbit)) { 408 if (test_bit(ABS_MT_SLOT, dev->absbit)) {
408 int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; 409 int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
409 input_mt_create_slots(dev, nslot); 410 input_mt_init_slots(dev, nslot);
410 input_set_events_per_packet(dev, 6 * nslot);
411 } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { 411 } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
412 input_set_events_per_packet(dev, 60); 412 input_set_events_per_packet(dev, 60);
413 } 413 }
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index b3252ef1e279..0b0525486711 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -14,6 +14,7 @@
14 14
15#include "wacom_wac.h" 15#include "wacom_wac.h"
16#include "wacom.h" 16#include "wacom.h"
17#include <linux/input/mt.h>
17 18
18static int wacom_penpartner_irq(struct wacom_wac *wacom) 19static int wacom_penpartner_irq(struct wacom_wac *wacom)
19{ 20{
@@ -862,19 +863,21 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
862 struct wacom_features *features = &wacom->features; 863 struct wacom_features *features = &wacom->features;
863 struct input_dev *input = wacom->input; 864 struct input_dev *input = wacom->input;
864 unsigned char *data = wacom->data; 865 unsigned char *data = wacom->data;
865 int sp = 0, sx = 0, sy = 0, count = 0;
866 int i; 866 int i;
867 867
868 for (i = 0; i < 2; i++) { 868 for (i = 0; i < 2; i++) {
869 int p = data[9 * i + 2]; 869 int p = data[9 * i + 2];
870 bool touch = p && !wacom->shared->stylus_in_proximity;
871
870 input_mt_slot(input, i); 872 input_mt_slot(input, i);
873 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
871 /* 874 /*
872 * Touch events need to be disabled while stylus is 875 * Touch events need to be disabled while stylus is
873 * in proximity because user's hand is resting on touchpad 876 * in proximity because user's hand is resting on touchpad
874 * and sending unwanted events. User expects tablet buttons 877 * and sending unwanted events. User expects tablet buttons
875 * to continue working though. 878 * to continue working though.
876 */ 879 */
877 if (p && !wacom->shared->stylus_in_proximity) { 880 if (touch) {
878 int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; 881 int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
879 int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; 882 int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
880 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { 883 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
@@ -884,23 +887,10 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
884 input_report_abs(input, ABS_MT_PRESSURE, p); 887 input_report_abs(input, ABS_MT_PRESSURE, p);
885 input_report_abs(input, ABS_MT_POSITION_X, x); 888 input_report_abs(input, ABS_MT_POSITION_X, x);
886 input_report_abs(input, ABS_MT_POSITION_Y, y); 889 input_report_abs(input, ABS_MT_POSITION_Y, y);
887 if (wacom->id[i] < 0)
888 wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;
889 if (!count++)
890 sp = p, sx = x, sy = y;
891 } else {
892 wacom->id[i] = -1;
893 } 890 }
894 input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);
895 } 891 }
896 892
897 input_report_key(input, BTN_TOUCH, count > 0); 893 input_mt_report_pointer_emulation(input, true);
898 input_report_key(input, BTN_TOOL_FINGER, count == 1);
899 input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2);
900
901 input_report_abs(input, ABS_PRESSURE, sp);
902 input_report_abs(input, ABS_X, sx);
903 input_report_abs(input, ABS_Y, sy);
904 894
905 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); 895 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
906 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); 896 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
@@ -1272,7 +1262,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
1272 __set_bit(BTN_TOOL_FINGER, input_dev->keybit); 1262 __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
1273 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); 1263 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
1274 1264
1275 input_mt_create_slots(input_dev, 2); 1265 input_mt_init_slots(input_dev, 2);
1276 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 1266 input_set_abs_params(input_dev, ABS_MT_POSITION_X,
1277 0, features->x_max, 1267 0, features->x_max,
1278 features->x_fuzz, 0); 1268 features->x_fuzz, 0);
@@ -1282,8 +1272,6 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
1282 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 1272 input_set_abs_params(input_dev, ABS_MT_PRESSURE,
1283 0, features->pressure_max, 1273 0, features->pressure_max,
1284 features->pressure_fuzz, 0); 1274 features->pressure_fuzz, 0);
1285 input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
1286 MAX_TRACKING_ID, 0, 0);
1287 } else if (features->device_type == BTN_TOOL_PEN) { 1275 } else if (features->device_type == BTN_TOOL_PEN) {
1288 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); 1276 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1289 __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 9ae4c7b16ba7..2a0bec12d12a 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -15,7 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/input.h> 18#include <linux/input/mt.h>
19#include <linux/serio.h> 19#include <linux/serio.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/ctype.h> 21#include <linux/ctype.h>
@@ -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);
@@ -318,15 +310,13 @@ static int w8001_setup(struct w8001 *w8001)
318 case 5: 310 case 5:
319 w8001->pktlen = W8001_PKTLEN_TOUCH2FG; 311 w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
320 312
321 input_mt_create_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 6ef44465db8d..53f873e8556c 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -733,11 +733,12 @@ struct input_keymap_entry {
733#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ 733#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
734#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ 734#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
735#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */ 735#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
736#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
736 737
737#ifdef __KERNEL__ 738#ifdef __KERNEL__
738/* Implementation details, userspace should not care about these */ 739/* Implementation details, userspace should not care about these */
739#define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR 740#define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR
740#define ABS_MT_LAST ABS_MT_PRESSURE 741#define ABS_MT_LAST ABS_MT_DISTANCE
741#endif 742#endif
742 743
743#define ABS_MAX 0x3f 744#define ABS_MAX 0x3f
@@ -848,6 +849,7 @@ struct input_keymap_entry {
848 */ 849 */
849#define MT_TOOL_FINGER 0 850#define MT_TOOL_FINGER 0
850#define MT_TOOL_PEN 1 851#define MT_TOOL_PEN 1
852#define MT_TOOL_MAX 1
851 853
852/* 854/*
853 * Values describing the status of a force-feedback effect 855 * Values describing the status of a force-feedback effect
@@ -1083,14 +1085,6 @@ struct ff_effect {
1083#include <linux/mod_devicetable.h> 1085#include <linux/mod_devicetable.h>
1084 1086
1085/** 1087/**
1086 * struct input_mt_slot - represents the state of an input MT slot
1087 * @abs: holds current values of ABS_MT axes for this slot
1088 */
1089struct input_mt_slot {
1090 int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
1091};
1092
1093/**
1094 * struct input_dev - represents an input device 1088 * struct input_dev - represents an input device
1095 * @name: name of the device 1089 * @name: name of the device
1096 * @phys: physical path to the device in the system hierarchy 1090 * @phys: physical path to the device in the system hierarchy
@@ -1130,6 +1124,7 @@ struct input_mt_slot {
1130 * of tracked contacts 1124 * of tracked contacts
1131 * @mtsize: number of MT slots the device uses 1125 * @mtsize: number of MT slots the device uses
1132 * @slot: MT slot currently being transmitted 1126 * @slot: MT slot currently being transmitted
1127 * @trkid: stores MT tracking ID for the current contact
1133 * @absinfo: array of &struct absinfo elements holding information 1128 * @absinfo: array of &struct absinfo elements holding information
1134 * about absolute axes (current value, min, max, flat, fuzz, 1129 * about absolute axes (current value, min, max, flat, fuzz,
1135 * resolution) 1130 * resolution)
@@ -1214,6 +1209,7 @@ struct input_dev {
1214 struct input_mt_slot *mt; 1209 struct input_mt_slot *mt;
1215 int mtsize; 1210 int mtsize;
1216 int slot; 1211 int slot;
1212 int trkid;
1217 1213
1218 struct input_absinfo *absinfo; 1214 struct input_absinfo *absinfo;
1219 1215
@@ -1463,11 +1459,6 @@ static inline void input_mt_sync(struct input_dev *dev)
1463 input_event(dev, EV_SYN, SYN_MT_REPORT, 0); 1459 input_event(dev, EV_SYN, SYN_MT_REPORT, 0);
1464} 1460}
1465 1461
1466static inline void input_mt_slot(struct input_dev *dev, int slot)
1467{
1468 input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
1469}
1470
1471void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code); 1462void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code);
1472 1463
1473/** 1464/**
@@ -1580,8 +1571,5 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
1580int input_ff_create_memless(struct input_dev *dev, void *data, 1571int input_ff_create_memless(struct input_dev *dev, void *data,
1581 int (*play_effect)(struct input_dev *, void *, struct ff_effect *)); 1572 int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
1582 1573
1583int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots);
1584void input_mt_destroy_slots(struct input_dev *dev);
1585
1586#endif 1574#endif
1587#endif 1575#endif
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
new file mode 100644
index 000000000000..b3ac06a4435d
--- /dev/null
+++ b/include/linux/input/mt.h
@@ -0,0 +1,57 @@
1#ifndef _INPUT_MT_H
2#define _INPUT_MT_H
3
4/*
5 * Input Multitouch Library
6 *
7 * Copyright (c) 2010 Henrik Rydberg
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 */
13
14#include <linux/input.h>
15
16#define TRKID_MAX 0xffff
17
18/**
19 * struct input_mt_slot - represents the state of an input MT slot
20 * @abs: holds current values of ABS_MT axes for this slot
21 */
22struct input_mt_slot {
23 int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
24};
25
26static inline void input_mt_set_value(struct input_mt_slot *slot,
27 unsigned code, int value)
28{
29 slot->abs[code - ABS_MT_FIRST] = value;
30}
31
32static inline int input_mt_get_value(const struct input_mt_slot *slot,
33 unsigned code)
34{
35 return slot->abs[code - ABS_MT_FIRST];
36}
37
38int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);
39void input_mt_destroy_slots(struct input_dev *dev);
40
41static inline int input_mt_new_trkid(struct input_dev *dev)
42{
43 return dev->trkid++ & TRKID_MAX;
44}
45
46static inline void input_mt_slot(struct input_dev *dev, int slot)
47{
48 input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
49}
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
57#endif