summaryrefslogtreecommitdiff
path: root/usr/src/dkms_source_tree/hid-3m-pct.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/dkms_source_tree/hid-3m-pct.c')
-rw-r--r--usr/src/dkms_source_tree/hid-3m-pct.c174
1 files changed, 99 insertions, 75 deletions
diff --git a/usr/src/dkms_source_tree/hid-3m-pct.c b/usr/src/dkms_source_tree/hid-3m-pct.c
index fc57c0c..1a6b02b 100644
--- a/usr/src/dkms_source_tree/hid-3m-pct.c
+++ b/usr/src/dkms_source_tree/hid-3m-pct.c
@@ -24,22 +24,30 @@ MODULE_LICENSE("GPL");
24 24
25#include "hid-ids.h" 25#include "hid-ids.h"
26 26
27#define MAX_SLOTS 20
28#define MAX_TRACKING_ID 0xfff
29#define SN_MOVE 2048
30#define SN_WIDTH 512
31
27struct mmm_finger { 32struct mmm_finger {
28 __s32 x, y, w, h; 33 __s32 x, y, w, h;
29 __u8 rank; 34 int touch, valid;
30 bool touch, valid; 35 int last_touch, id;
31}; 36};
32 37
33struct mmm_data { 38struct mmm_data {
34 struct mmm_finger f[10]; 39 struct mmm_finger f[MAX_SLOTS];
35 __u8 curid, num; 40 int touch, valid;
36 bool touch, valid; 41 int slot;
37}; 42};
38 43
39static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, 44static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
40 struct hid_field *field, struct hid_usage *usage, 45 struct hid_field *field, struct hid_usage *usage,
41 unsigned long **bit, int *max) 46 unsigned long **bit, int *max)
42{ 47{
48 struct input_dev *input = hi->input;
49 int delta = field->logical_maximum - field->logical_minimum;
50
43 switch (usage->hid & HID_USAGE_PAGE) { 51 switch (usage->hid & HID_USAGE_PAGE) {
44 52
45 case HID_UP_BUTTON: 53 case HID_UP_BUTTON:
@@ -49,19 +57,27 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
49 switch (usage->hid) { 57 switch (usage->hid) {
50 case HID_GD_X: 58 case HID_GD_X:
51 hid_map_usage(hi, usage, bit, max, 59 hid_map_usage(hi, usage, bit, max,
52 EV_ABS, ABS_MT_POSITION_X); 60 EV_ABS, ABS_MT_POSITION_X);
53 /* touchscreen emulation */ 61 input_set_abs_params(input, ABS_MT_POSITION_X,
54 input_set_abs_params(hi->input, ABS_X, 62 field->logical_minimum,
55 field->logical_minimum, 63 field->logical_maximum,
56 field->logical_maximum, 0, 0); 64 delta / SN_MOVE, 0);
65 input_set_abs_params(input, ABS_X,
66 field->logical_minimum,
67 field->logical_maximum,
68 delta / SN_MOVE, 0);
57 return 1; 69 return 1;
58 case HID_GD_Y: 70 case HID_GD_Y:
59 hid_map_usage(hi, usage, bit, max, 71 hid_map_usage(hi, usage, bit, max,
60 EV_ABS, ABS_MT_POSITION_Y); 72 EV_ABS, ABS_MT_POSITION_Y);
61 /* touchscreen emulation */ 73 input_set_abs_params(input, ABS_MT_POSITION_Y,
62 input_set_abs_params(hi->input, ABS_Y, 74 field->logical_minimum,
63 field->logical_minimum, 75 field->logical_maximum,
64 field->logical_maximum, 0, 0); 76 delta / SN_MOVE, 0);
77 input_set_abs_params(input, ABS_Y,
78 field->logical_minimum,
79 field->logical_maximum,
80 delta / SN_MOVE, 0);
65 return 1; 81 return 1;
66 } 82 }
67 return 0; 83 return 0;
@@ -79,23 +95,37 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
79 case HID_DG_CONFIDENCE: 95 case HID_DG_CONFIDENCE:
80 return -1; 96 return -1;
81 case HID_DG_TIPSWITCH: 97 case HID_DG_TIPSWITCH:
82 /* touchscreen emulation */
83 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); 98 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
99 input_set_capability(input, EV_KEY, BTN_TOUCH);
84 return 1; 100 return 1;
85 case HID_DG_WIDTH: 101 case HID_DG_WIDTH:
86 hid_map_usage(hi, usage, bit, max, 102 hid_map_usage(hi, usage, bit, max,
87 EV_ABS, ABS_MT_TOUCH_MAJOR); 103 EV_ABS, ABS_MT_TOUCH_MAJOR);
104 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
105 field->logical_minimum,
106 field->logical_maximum,
107 delta / SN_WIDTH, 0);
88 return 1; 108 return 1;
89 case HID_DG_HEIGHT: 109 case HID_DG_HEIGHT:
90 hid_map_usage(hi, usage, bit, max, 110 hid_map_usage(hi, usage, bit, max,
91 EV_ABS, ABS_MT_TOUCH_MINOR); 111 EV_ABS, ABS_MT_TOUCH_MINOR);
92 input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 112 input_set_abs_params(input, ABS_MT_TOUCH_MINOR,
93 1, 1, 0, 0); 113 field->logical_minimum,
114 field->logical_maximum,
115 delta / SN_WIDTH, 0);
116 input_set_abs_params(input, ABS_MT_ORIENTATION,
117 1, 1, 0, 0);
94 return 1; 118 return 1;
95 case HID_DG_CONTACTID: 119 case HID_DG_CONTACTID:
96 field->logical_maximum = 59; 120 field->logical_maximum = MAX_TRACKING_ID;
97 hid_map_usage(hi, usage, bit, max, 121 hid_map_usage(hi, usage, bit, max,
98 EV_ABS, ABS_MT_TRACKING_ID); 122 EV_ABS, ABS_MT_TRACKING_ID);
123 input_set_abs_params(input, ABS_MT_TRACKING_ID,
124 0, MAX_TRACKING_ID, 0, 0);
125 if (!input->mt) {
126 input_mt_create_slots(input, MAX_SLOTS);
127 input_set_events_per_packet(input, 150);
128 }
99 return 1; 129 return 1;
100 } 130 }
101 /* let hid-input decide for the others */ 131 /* let hid-input decide for the others */
@@ -114,9 +144,8 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
114 unsigned long **bit, int *max) 144 unsigned long **bit, int *max)
115{ 145{
116 if (usage->type == EV_KEY || usage->type == EV_ABS) 146 if (usage->type == EV_KEY || usage->type == EV_ABS)
117 clear_bit(usage->code, *bit); 147 set_bit(usage->type, hi->input->evbit);
118 148 return -1;
119 return 0;
120} 149}
121 150
122/* 151/*
@@ -125,44 +154,42 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
125 */ 154 */
126static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) 155static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
127{ 156{
128 int i, index = -1; 157 static int trkid;
129 158 int i, sx = 0, sy = 0, count = 0;
130 /* 159 for (i = 0; i < MAX_SLOTS; ++i) {
131 * we need to iterate on all fingers to decide if we have a press
132 * or a release event in our touchscreen emulation.
133 */
134 for (i = 0; i < 10; ++i) {
135 struct mmm_finger *f = &md->f[i]; 160 struct mmm_finger *f = &md->f[i];
136 if (!f->valid) { 161 if (!f->valid)
137 /* this finger is just placeholder data, ignore */ 162 continue;
138 } else if (f->touch) { 163 input_mt_slot(input, i);
139 /* this finger is on the screen */ 164 if (f->touch) {
140 int wide = (f->w > f->h); 165 int wide = f->w > f->h;
141 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i); 166 int major = wide ? f->w : f->h;
167 int minor = wide ? f->h : f->w;
142 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); 168 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
143 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); 169 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
144 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 170 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
145 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, 171 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
146 wide ? f->w : f->h); 172 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
147 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, 173 if (!f->last_touch)
148 wide ? f->h : f->w); 174 f->id = trkid++ & MAX_TRACKING_ID;
149 input_mt_sync(input); 175 if (!count++)
150 176 sx = f->x, sy = f->y;
151 if (index < 0) 177 } else {
152 index = i; 178 f->id = -1;
153 } 179 }
154 f->valid = 0; 180 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);
181 f->last_touch = f->touch;
155 } 182 }
156 183 for (i = 0; i < MAX_SLOTS; ++i) {
157 /* touchscreen emulation */ 184 struct mmm_finger *f = &md->f[i];
158 if (index >= 0) { 185 f->valid = f->touch = 0;
159 struct mmm_finger *f = &md->f[index]; 186 }
160 input_event(input, EV_KEY, BTN_TOUCH, 1); 187 input_report_key(input, BTN_TOUCH, count > 0);
161 input_event(input, EV_ABS, ABS_X, f->x); 188 if (count > 0) {
162 input_event(input, EV_ABS, ABS_Y, f->y); 189 input_report_abs(input, ABS_X, sx);
163 } else { 190 input_report_abs(input, ABS_Y, sy);
164 input_event(input, EV_KEY, BTN_TOUCH, 0);
165 } 191 }
192 input_sync(input);
166} 193}
167 194
168/* 195/*
@@ -181,37 +208,32 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
181 if (hid->claimed & HID_CLAIMED_INPUT) { 208 if (hid->claimed & HID_CLAIMED_INPUT) {
182 struct input_dev *input = field->hidinput->input; 209 struct input_dev *input = field->hidinput->input;
183 switch (usage->hid) { 210 switch (usage->hid) {
211 case HID_DG_CONTACTCOUNT:
212 break;
184 case HID_DG_TIPSWITCH: 213 case HID_DG_TIPSWITCH:
185 md->touch = value; 214 md->touch = value;
186 break; 215 break;
187 case HID_DG_CONFIDENCE: 216 case HID_DG_CONFIDENCE:
217 if (md->valid && !value)
218 mmm_filter_event(md, input);
188 md->valid = value; 219 md->valid = value;
189 break; 220 break;
190 case HID_DG_WIDTH:
191 if (md->valid)
192 md->f[md->curid].w = value;
193 break;
194 case HID_DG_HEIGHT:
195 if (md->valid)
196 md->f[md->curid].h = value;
197 break;
198 case HID_DG_CONTACTID: 221 case HID_DG_CONTACTID:
199 if (md->valid) { 222 md->slot = value < MAX_SLOTS ? value : 0;
200 md->curid = value; 223 md->f[md->slot].touch = md->touch;
201 md->f[value].touch = md->touch; 224 md->f[md->slot].valid = md->valid;
202 md->f[value].valid = 1;
203 }
204 break; 225 break;
205 case HID_GD_X: 226 case HID_GD_X:
206 if (md->valid) 227 md->f[md->slot].x = value;
207 md->f[md->curid].x = value;
208 break; 228 break;
209 case HID_GD_Y: 229 case HID_GD_Y:
210 if (md->valid) 230 md->f[md->slot].y = value;
211 md->f[md->curid].y = value;
212 break; 231 break;
213 case HID_DG_CONTACTCOUNT: 232 case HID_DG_WIDTH:
214 mmm_filter_event(md, input); 233 md->f[md->slot].w = value;
234 break;
235 case HID_DG_HEIGHT:
236 md->f[md->slot].h = value;
215 break; 237 break;
216 } 238 }
217 } 239 }
@@ -228,6 +250,8 @@ static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id)
228 int ret; 250 int ret;
229 struct mmm_data *md; 251 struct mmm_data *md;
230 252
253 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
254
231 md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); 255 md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
232 if (!md) { 256 if (!md) {
233 dev_err(&hdev->dev, "cannot allocate 3M data\n"); 257 dev_err(&hdev->dev, "cannot allocate 3M data\n");