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