diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-12-16 12:17:48 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-12-16 12:17:48 -0500 |
commit | 67b989a0c17e34a7c2c095e58a2f3d1b4408e3cb (patch) | |
tree | c076d2f0b5d4ae8726a50206042d3e3a41620fe4 /drivers | |
parent | 56a8bd6dcf81693e61a712097216904f3a4ab536 (diff) | |
parent | 69479f8da68f1930b2078b2ebf6533fb00339918 (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/Kconfig | 3 | ||||
-rw-r--r-- | drivers/hid/hid-3m-pct.c | 36 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-egalax.c | 129 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 2 | ||||
-rw-r--r-- | drivers/input/Makefile | 2 | ||||
-rw-r--r-- | drivers/input/input-mt.c | 170 | ||||
-rw-r--r-- | drivers/input/input.c | 48 | ||||
-rw-r--r-- | drivers/input/misc/uinput.c | 4 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 26 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.h | 4 | ||||
-rw-r--r-- | drivers/input/touchscreen/wacom_w8001.c | 25 |
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 | ||
159 | config HID_ELECOM | 160 | config 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 | ||
23 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | 24 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); |
24 | MODULE_DESCRIPTION("3M PCT multitouch panels"); | 25 | MODULE_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 | ||
37 | struct mmm_finger { | 36 | struct 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 | ||
44 | struct mmm_data { | 41 | struct 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 | */ |
155 | static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) | 144 | static 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 | |||
28 | struct egalax_data { | 37 | struct 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 | ||
44 | static 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 | |||
37 | static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 53 | static 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 | */ |
109 | static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) | 127 | static 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 | |||
163 | static int egalax_event(struct hid_device *hid, struct hid_field *field, | 139 | static 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 | }; |
266 | MODULE_DEVICE_TABLE(hid, egalax_devices); | 247 | MODULE_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 | ||
7 | obj-$(CONFIG_INPUT) += input-core.o | 7 | obj-$(CONFIG_INPUT) += input-core.o |
8 | input-core-y := input.o input-compat.o ff-core.o | 8 | input-core-y := input.o input-compat.o input-mt.o ff-core.o |
9 | 9 | ||
10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o | 10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o |
11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o | 11 | obj-$(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 | */ | ||
27 | int 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 | } | ||
51 | EXPORT_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 | */ | ||
60 | void 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 | } | ||
68 | EXPORT_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 | */ | ||
82 | void 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 | } | ||
101 | EXPORT_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 | */ | ||
114 | void 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 | } | ||
121 | EXPORT_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 | */ | ||
134 | void 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 | } | ||
170 | EXPORT_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) | |||
1726 | EXPORT_SYMBOL(input_free_device); | 1726 | EXPORT_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 | */ | ||
1737 | int 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 | } | ||
1757 | EXPORT_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 | */ | ||
1766 | void input_mt_destroy_slots(struct input_dev *dev) | ||
1767 | { | ||
1768 | kfree(dev->mt); | ||
1769 | dev->mt = NULL; | ||
1770 | dev->mtsize = 0; | ||
1771 | } | ||
1772 | EXPORT_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 | ||
42 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 43 | static 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 | ||
18 | static int wacom_penpartner_irq(struct wacom_wac *wacom) | 19 | static 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 | |||
48 | enum { | 45 | enum { |
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 | |||
53 | struct w8001_coord { | 51 | struct 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 | ||
93 | static void parse_data(u8 *data, struct w8001_coord *coord) | 90 | static 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 | ||
117 | static void parse_touch(struct w8001 *w8001) | 114 | static 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 | ||