aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-12-16 12:17:48 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-12-16 12:17:48 -0500
commit67b989a0c17e34a7c2c095e58a2f3d1b4408e3cb (patch)
treec076d2f0b5d4ae8726a50206042d3e3a41620fe4 /drivers
parent56a8bd6dcf81693e61a712097216904f3a4ab536 (diff)
parent69479f8da68f1930b2078b2ebf6533fb00339918 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rydberg/input-mt into next
Conflicts: drivers/input/Makefile
Diffstat (limited to 'drivers')
-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
12 files changed, 253 insertions, 198 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 3052e2969ad..401acecc7f3 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 02d8cd3b1b1..4fb7c7528d1 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 515345b11ac..f4a37f842cf 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 54b017ad258..87878509f25 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 3341baa86a3..a95719b2475 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 9fd1cf2b705..09614ce7496 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 00000000000..c48c81f0308
--- /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 c7a1e826c58..3312e20016b 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 b9410784e6a..bea89722c4e 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 b3252ef1e27..0b052548671 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 00ca01541d8..b1310ec9720 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 9ae4c7b16ba..2a0bec12d12 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