aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-3m-pct.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-3m-pct.c')
-rw-r--r--drivers/hid/hid-3m-pct.c30
1 files changed, 2 insertions, 28 deletions
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index ea475964d05a..4fb7c7528d16 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -28,7 +28,6 @@ MODULE_LICENSE("GPL");
28#include "hid-ids.h" 28#include "hid-ids.h"
29 29
30#define MAX_SLOTS 60 30#define MAX_SLOTS 60
31#define MAX_TRKID USHRT_MAX
32 31
33/* estimated signal-to-noise ratios */ 32/* estimated signal-to-noise ratios */
34#define SN_MOVE 2048 33#define SN_MOVE 2048
@@ -36,14 +35,11 @@ MODULE_LICENSE("GPL");
36 35
37struct mmm_finger { 36struct mmm_finger {
38 __s32 x, y, w, h; 37 __s32 x, y, w, h;
39 __u16 id;
40 bool prev_touch;
41 bool touch, valid; 38 bool touch, valid;
42}; 39};
43 40
44struct mmm_data { 41struct mmm_data {
45 struct mmm_finger f[MAX_SLOTS]; 42 struct mmm_finger f[MAX_SLOTS];
46 __u16 id;
47 __u8 curid; 43 __u8 curid;
48 __u8 nexp, nreal; 44 __u8 nexp, nreal;
49 bool touch, valid; 45 bool touch, valid;
@@ -117,11 +113,6 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
117 0, 1, 0, 0); 113 0, 1, 0, 0);
118 return 1; 114 return 1;
119 case HID_DG_CONTACTID: 115 case HID_DG_CONTACTID:
120 field->logical_maximum = MAX_TRKID;
121 hid_map_usage(hi, usage, bit, max,
122 EV_ABS, ABS_MT_TRACKING_ID);
123 input_set_abs_params(hi->input, ABS_MT_TRACKING_ID,
124 0, MAX_TRKID, 0, 0);
125 input_mt_init_slots(hi->input, MAX_SLOTS); 116 input_mt_init_slots(hi->input, MAX_SLOTS);
126 return 1; 117 return 1;
127 } 118 }
@@ -152,7 +143,6 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
152 */ 143 */
153static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) 144static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
154{ 145{
155 struct mmm_finger *oldest = 0;
156 int i; 146 int i;
157 for (i = 0; i < MAX_SLOTS; ++i) { 147 for (i = 0; i < MAX_SLOTS; ++i) {
158 struct mmm_finger *f = &md->f[i]; 148 struct mmm_finger *f = &md->f[i];
@@ -161,6 +151,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
161 continue; 151 continue;
162 } 152 }
163 input_mt_slot(input, i); 153 input_mt_slot(input, i);
154 input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch);
164 if (f->touch) { 155 if (f->touch) {
165 /* this finger is on the screen */ 156 /* this finger is on the screen */
166 int wide = (f->w > f->h); 157 int wide = (f->w > f->h);
@@ -168,33 +159,16 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
168 int major = max(f->w, f->h) >> 1; 159 int major = max(f->w, f->h) >> 1;
169 int minor = min(f->w, f->h) >> 1; 160 int minor = min(f->w, f->h) >> 1;
170 161
171 if (!f->prev_touch)
172 f->id = md->id++;
173 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);
174 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); 162 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
175 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); 163 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
176 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 164 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
177 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 165 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
178 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); 166 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
179 /* touchscreen emulation: pick the oldest contact */
180 if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))
181 oldest = f;
182 } else {
183 /* this finger took off the screen */
184 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);
185 } 167 }
186 f->prev_touch = f->touch;
187 f->valid = 0; 168 f->valid = 0;
188 } 169 }
189 170
190 /* touchscreen emulation */ 171 input_mt_report_pointer_emulation(input, true);
191 if (oldest) {
192 input_event(input, EV_KEY, BTN_TOUCH, 1);
193 input_event(input, EV_ABS, ABS_X, oldest->x);
194 input_event(input, EV_ABS, ABS_Y, oldest->y);
195 } else {
196 input_event(input, EV_KEY, BTN_TOUCH, 0);
197 }
198 input_sync(input); 172 input_sync(input);
199} 173}
200 174