diff options
Diffstat (limited to 'drivers/hid/hid-ntrig.c')
-rw-r--r-- | drivers/hid/hid-ntrig.c | 526 |
1 files changed, 517 insertions, 9 deletions
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 4777bbfa1cc2..b6b0caeeac58 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c | |||
@@ -24,6 +24,34 @@ | |||
24 | 24 | ||
25 | #define NTRIG_DUPLICATE_USAGES 0x001 | 25 | #define NTRIG_DUPLICATE_USAGES 0x001 |
26 | 26 | ||
27 | static unsigned int min_width; | ||
28 | module_param(min_width, uint, 0644); | ||
29 | MODULE_PARM_DESC(min_width, "Minimum touch contact width to accept."); | ||
30 | |||
31 | static unsigned int min_height; | ||
32 | module_param(min_height, uint, 0644); | ||
33 | MODULE_PARM_DESC(min_height, "Minimum touch contact height to accept."); | ||
34 | |||
35 | static unsigned int activate_slack = 1; | ||
36 | module_param(activate_slack, uint, 0644); | ||
37 | MODULE_PARM_DESC(activate_slack, "Number of touch frames to ignore at " | ||
38 | "the start of touch input."); | ||
39 | |||
40 | static unsigned int deactivate_slack = 4; | ||
41 | module_param(deactivate_slack, uint, 0644); | ||
42 | MODULE_PARM_DESC(deactivate_slack, "Number of empty frames to ignore before " | ||
43 | "deactivating touch."); | ||
44 | |||
45 | static unsigned int activation_width = 64; | ||
46 | module_param(activation_width, uint, 0644); | ||
47 | MODULE_PARM_DESC(activation_width, "Width threshold to immediately start " | ||
48 | "processing touch events."); | ||
49 | |||
50 | static unsigned int activation_height = 32; | ||
51 | module_param(activation_height, uint, 0644); | ||
52 | MODULE_PARM_DESC(activation_height, "Height threshold to immediately start " | ||
53 | "processing touch events."); | ||
54 | |||
27 | struct ntrig_data { | 55 | struct ntrig_data { |
28 | /* Incoming raw values for a single contact */ | 56 | /* Incoming raw values for a single contact */ |
29 | __u16 x, y, w, h; | 57 | __u16 x, y, w, h; |
@@ -37,6 +65,309 @@ struct ntrig_data { | |||
37 | 65 | ||
38 | __u8 mt_footer[4]; | 66 | __u8 mt_footer[4]; |
39 | __u8 mt_foot_count; | 67 | __u8 mt_foot_count; |
68 | |||
69 | /* The current activation state. */ | ||
70 | __s8 act_state; | ||
71 | |||
72 | /* Empty frames to ignore before recognizing the end of activity */ | ||
73 | __s8 deactivate_slack; | ||
74 | |||
75 | /* Frames to ignore before acknowledging the start of activity */ | ||
76 | __s8 activate_slack; | ||
77 | |||
78 | /* Minimum size contact to accept */ | ||
79 | __u16 min_width; | ||
80 | __u16 min_height; | ||
81 | |||
82 | /* Threshold to override activation slack */ | ||
83 | __u16 activation_width; | ||
84 | __u16 activation_height; | ||
85 | |||
86 | __u16 sensor_logical_width; | ||
87 | __u16 sensor_logical_height; | ||
88 | __u16 sensor_physical_width; | ||
89 | __u16 sensor_physical_height; | ||
90 | }; | ||
91 | |||
92 | |||
93 | static ssize_t show_phys_width(struct device *dev, | ||
94 | struct device_attribute *attr, | ||
95 | char *buf) | ||
96 | { | ||
97 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
98 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
99 | |||
100 | return sprintf(buf, "%d\n", nd->sensor_physical_width); | ||
101 | } | ||
102 | |||
103 | static DEVICE_ATTR(sensor_physical_width, S_IRUGO, show_phys_width, NULL); | ||
104 | |||
105 | static ssize_t show_phys_height(struct device *dev, | ||
106 | struct device_attribute *attr, | ||
107 | char *buf) | ||
108 | { | ||
109 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
110 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
111 | |||
112 | return sprintf(buf, "%d\n", nd->sensor_physical_height); | ||
113 | } | ||
114 | |||
115 | static DEVICE_ATTR(sensor_physical_height, S_IRUGO, show_phys_height, NULL); | ||
116 | |||
117 | static ssize_t show_log_width(struct device *dev, | ||
118 | struct device_attribute *attr, | ||
119 | char *buf) | ||
120 | { | ||
121 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
122 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
123 | |||
124 | return sprintf(buf, "%d\n", nd->sensor_logical_width); | ||
125 | } | ||
126 | |||
127 | static DEVICE_ATTR(sensor_logical_width, S_IRUGO, show_log_width, NULL); | ||
128 | |||
129 | static ssize_t show_log_height(struct device *dev, | ||
130 | struct device_attribute *attr, | ||
131 | char *buf) | ||
132 | { | ||
133 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
134 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
135 | |||
136 | return sprintf(buf, "%d\n", nd->sensor_logical_height); | ||
137 | } | ||
138 | |||
139 | static DEVICE_ATTR(sensor_logical_height, S_IRUGO, show_log_height, NULL); | ||
140 | |||
141 | static ssize_t show_min_width(struct device *dev, | ||
142 | struct device_attribute *attr, | ||
143 | char *buf) | ||
144 | { | ||
145 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
146 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
147 | |||
148 | return sprintf(buf, "%d\n", nd->min_width * | ||
149 | nd->sensor_physical_width / | ||
150 | nd->sensor_logical_width); | ||
151 | } | ||
152 | |||
153 | static ssize_t set_min_width(struct device *dev, | ||
154 | struct device_attribute *attr, | ||
155 | const char *buf, size_t count) | ||
156 | { | ||
157 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
158 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
159 | |||
160 | unsigned long val; | ||
161 | |||
162 | if (strict_strtoul(buf, 0, &val)) | ||
163 | return -EINVAL; | ||
164 | |||
165 | if (val > nd->sensor_physical_width) | ||
166 | return -EINVAL; | ||
167 | |||
168 | nd->min_width = val * nd->sensor_logical_width / | ||
169 | nd->sensor_physical_width; | ||
170 | |||
171 | return count; | ||
172 | } | ||
173 | |||
174 | static DEVICE_ATTR(min_width, S_IWUSR | S_IRUGO, show_min_width, set_min_width); | ||
175 | |||
176 | static ssize_t show_min_height(struct device *dev, | ||
177 | struct device_attribute *attr, | ||
178 | char *buf) | ||
179 | { | ||
180 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
181 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
182 | |||
183 | return sprintf(buf, "%d\n", nd->min_height * | ||
184 | nd->sensor_physical_height / | ||
185 | nd->sensor_logical_height); | ||
186 | } | ||
187 | |||
188 | static ssize_t set_min_height(struct device *dev, | ||
189 | struct device_attribute *attr, | ||
190 | const char *buf, size_t count) | ||
191 | { | ||
192 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
193 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
194 | |||
195 | unsigned long val; | ||
196 | |||
197 | if (strict_strtoul(buf, 0, &val)) | ||
198 | return -EINVAL; | ||
199 | |||
200 | if (val > nd->sensor_physical_height) | ||
201 | return -EINVAL; | ||
202 | |||
203 | nd->min_height = val * nd->sensor_logical_height / | ||
204 | nd->sensor_physical_height; | ||
205 | |||
206 | return count; | ||
207 | } | ||
208 | |||
209 | static DEVICE_ATTR(min_height, S_IWUSR | S_IRUGO, show_min_height, | ||
210 | set_min_height); | ||
211 | |||
212 | static ssize_t show_activate_slack(struct device *dev, | ||
213 | struct device_attribute *attr, | ||
214 | char *buf) | ||
215 | { | ||
216 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
217 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
218 | |||
219 | return sprintf(buf, "%d\n", nd->activate_slack); | ||
220 | } | ||
221 | |||
222 | static ssize_t set_activate_slack(struct device *dev, | ||
223 | struct device_attribute *attr, | ||
224 | const char *buf, size_t count) | ||
225 | { | ||
226 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
227 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
228 | |||
229 | unsigned long val; | ||
230 | |||
231 | if (strict_strtoul(buf, 0, &val)) | ||
232 | return -EINVAL; | ||
233 | |||
234 | if (val > 0x7f) | ||
235 | return -EINVAL; | ||
236 | |||
237 | nd->activate_slack = val; | ||
238 | |||
239 | return count; | ||
240 | } | ||
241 | |||
242 | static DEVICE_ATTR(activate_slack, S_IWUSR | S_IRUGO, show_activate_slack, | ||
243 | set_activate_slack); | ||
244 | |||
245 | static ssize_t show_activation_width(struct device *dev, | ||
246 | struct device_attribute *attr, | ||
247 | char *buf) | ||
248 | { | ||
249 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
250 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
251 | |||
252 | return sprintf(buf, "%d\n", nd->activation_width * | ||
253 | nd->sensor_physical_width / | ||
254 | nd->sensor_logical_width); | ||
255 | } | ||
256 | |||
257 | static ssize_t set_activation_width(struct device *dev, | ||
258 | struct device_attribute *attr, | ||
259 | const char *buf, size_t count) | ||
260 | { | ||
261 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
262 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
263 | |||
264 | unsigned long val; | ||
265 | |||
266 | if (strict_strtoul(buf, 0, &val)) | ||
267 | return -EINVAL; | ||
268 | |||
269 | if (val > nd->sensor_physical_width) | ||
270 | return -EINVAL; | ||
271 | |||
272 | nd->activation_width = val * nd->sensor_logical_width / | ||
273 | nd->sensor_physical_width; | ||
274 | |||
275 | return count; | ||
276 | } | ||
277 | |||
278 | static DEVICE_ATTR(activation_width, S_IWUSR | S_IRUGO, show_activation_width, | ||
279 | set_activation_width); | ||
280 | |||
281 | static ssize_t show_activation_height(struct device *dev, | ||
282 | struct device_attribute *attr, | ||
283 | char *buf) | ||
284 | { | ||
285 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
286 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
287 | |||
288 | return sprintf(buf, "%d\n", nd->activation_height * | ||
289 | nd->sensor_physical_height / | ||
290 | nd->sensor_logical_height); | ||
291 | } | ||
292 | |||
293 | static ssize_t set_activation_height(struct device *dev, | ||
294 | struct device_attribute *attr, | ||
295 | const char *buf, size_t count) | ||
296 | { | ||
297 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
298 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
299 | |||
300 | unsigned long val; | ||
301 | |||
302 | if (strict_strtoul(buf, 0, &val)) | ||
303 | return -EINVAL; | ||
304 | |||
305 | if (val > nd->sensor_physical_height) | ||
306 | return -EINVAL; | ||
307 | |||
308 | nd->activation_height = val * nd->sensor_logical_height / | ||
309 | nd->sensor_physical_height; | ||
310 | |||
311 | return count; | ||
312 | } | ||
313 | |||
314 | static DEVICE_ATTR(activation_height, S_IWUSR | S_IRUGO, | ||
315 | show_activation_height, set_activation_height); | ||
316 | |||
317 | static ssize_t show_deactivate_slack(struct device *dev, | ||
318 | struct device_attribute *attr, | ||
319 | char *buf) | ||
320 | { | ||
321 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
322 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
323 | |||
324 | return sprintf(buf, "%d\n", -nd->deactivate_slack); | ||
325 | } | ||
326 | |||
327 | static ssize_t set_deactivate_slack(struct device *dev, | ||
328 | struct device_attribute *attr, | ||
329 | const char *buf, size_t count) | ||
330 | { | ||
331 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
332 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
333 | |||
334 | unsigned long val; | ||
335 | |||
336 | if (strict_strtoul(buf, 0, &val)) | ||
337 | return -EINVAL; | ||
338 | |||
339 | /* | ||
340 | * No more than 8 terminal frames have been observed so far | ||
341 | * and higher slack is highly likely to leave the single | ||
342 | * touch emulation stuck down. | ||
343 | */ | ||
344 | if (val > 7) | ||
345 | return -EINVAL; | ||
346 | |||
347 | nd->deactivate_slack = -val; | ||
348 | |||
349 | return count; | ||
350 | } | ||
351 | |||
352 | static DEVICE_ATTR(deactivate_slack, S_IWUSR | S_IRUGO, show_deactivate_slack, | ||
353 | set_deactivate_slack); | ||
354 | |||
355 | static struct attribute *sysfs_attrs[] = { | ||
356 | &dev_attr_sensor_physical_width.attr, | ||
357 | &dev_attr_sensor_physical_height.attr, | ||
358 | &dev_attr_sensor_logical_width.attr, | ||
359 | &dev_attr_sensor_logical_height.attr, | ||
360 | &dev_attr_min_height.attr, | ||
361 | &dev_attr_min_width.attr, | ||
362 | &dev_attr_activate_slack.attr, | ||
363 | &dev_attr_activation_width.attr, | ||
364 | &dev_attr_activation_height.attr, | ||
365 | &dev_attr_deactivate_slack.attr, | ||
366 | NULL | ||
367 | }; | ||
368 | |||
369 | static struct attribute_group ntrig_attribute_group = { | ||
370 | .attrs = sysfs_attrs | ||
40 | }; | 371 | }; |
41 | 372 | ||
42 | /* | 373 | /* |
@@ -49,6 +380,8 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
49 | struct hid_field *field, struct hid_usage *usage, | 380 | struct hid_field *field, struct hid_usage *usage, |
50 | unsigned long **bit, int *max) | 381 | unsigned long **bit, int *max) |
51 | { | 382 | { |
383 | struct ntrig_data *nd = hid_get_drvdata(hdev); | ||
384 | |||
52 | /* No special mappings needed for the pen and single touch */ | 385 | /* No special mappings needed for the pen and single touch */ |
53 | if (field->physical) | 386 | if (field->physical) |
54 | return 0; | 387 | return 0; |
@@ -62,6 +395,21 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
62 | input_set_abs_params(hi->input, ABS_X, | 395 | input_set_abs_params(hi->input, ABS_X, |
63 | field->logical_minimum, | 396 | field->logical_minimum, |
64 | field->logical_maximum, 0, 0); | 397 | field->logical_maximum, 0, 0); |
398 | |||
399 | if (!nd->sensor_logical_width) { | ||
400 | nd->sensor_logical_width = | ||
401 | field->logical_maximum - | ||
402 | field->logical_minimum; | ||
403 | nd->sensor_physical_width = | ||
404 | field->physical_maximum - | ||
405 | field->physical_minimum; | ||
406 | nd->activation_width = activation_width * | ||
407 | nd->sensor_logical_width / | ||
408 | nd->sensor_physical_width; | ||
409 | nd->min_width = min_width * | ||
410 | nd->sensor_logical_width / | ||
411 | nd->sensor_physical_width; | ||
412 | } | ||
65 | return 1; | 413 | return 1; |
66 | case HID_GD_Y: | 414 | case HID_GD_Y: |
67 | hid_map_usage(hi, usage, bit, max, | 415 | hid_map_usage(hi, usage, bit, max, |
@@ -69,6 +417,21 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
69 | input_set_abs_params(hi->input, ABS_Y, | 417 | input_set_abs_params(hi->input, ABS_Y, |
70 | field->logical_minimum, | 418 | field->logical_minimum, |
71 | field->logical_maximum, 0, 0); | 419 | field->logical_maximum, 0, 0); |
420 | |||
421 | if (!nd->sensor_logical_height) { | ||
422 | nd->sensor_logical_height = | ||
423 | field->logical_maximum - | ||
424 | field->logical_minimum; | ||
425 | nd->sensor_physical_height = | ||
426 | field->physical_maximum - | ||
427 | field->physical_minimum; | ||
428 | nd->activation_height = activation_height * | ||
429 | nd->sensor_logical_height / | ||
430 | nd->sensor_physical_height; | ||
431 | nd->min_height = min_height * | ||
432 | nd->sensor_logical_height / | ||
433 | nd->sensor_physical_height; | ||
434 | } | ||
72 | return 1; | 435 | return 1; |
73 | } | 436 | } |
74 | return 0; | 437 | return 0; |
@@ -201,20 +564,68 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
201 | if (nd->mt_foot_count != 4) | 564 | if (nd->mt_foot_count != 4) |
202 | break; | 565 | break; |
203 | 566 | ||
204 | /* Pen activity signal, trigger end of touch. */ | 567 | /* Pen activity signal. */ |
205 | if (nd->mt_footer[2]) { | 568 | if (nd->mt_footer[2]) { |
569 | /* | ||
570 | * When the pen deactivates touch, we see a | ||
571 | * bogus frame with ContactCount > 0. | ||
572 | * We can | ||
573 | * save a bit of work by ensuring act_state < 0 | ||
574 | * even if deactivation slack is turned off. | ||
575 | */ | ||
576 | nd->act_state = deactivate_slack - 1; | ||
206 | nd->confidence = 0; | 577 | nd->confidence = 0; |
207 | break; | 578 | break; |
208 | } | 579 | } |
209 | 580 | ||
210 | /* If the contact was invalid */ | 581 | /* |
211 | if (!(nd->confidence && nd->mt_footer[0]) | 582 | * The first footer value indicates the presence of a |
212 | || nd->w <= 250 | 583 | * finger. |
213 | || nd->h <= 190) { | 584 | */ |
214 | nd->confidence = 0; | 585 | if (nd->mt_footer[0]) { |
586 | /* | ||
587 | * We do not want to process contacts under | ||
588 | * the size threshold, but do not want to | ||
589 | * ignore them for activation state | ||
590 | */ | ||
591 | if (nd->w < nd->min_width || | ||
592 | nd->h < nd->min_height) | ||
593 | nd->confidence = 0; | ||
594 | } else | ||
215 | break; | 595 | break; |
596 | |||
597 | if (nd->act_state > 0) { | ||
598 | /* | ||
599 | * Contact meets the activation size threshold | ||
600 | */ | ||
601 | if (nd->w >= nd->activation_width && | ||
602 | nd->h >= nd->activation_height) { | ||
603 | if (nd->id) | ||
604 | /* | ||
605 | * first contact, activate now | ||
606 | */ | ||
607 | nd->act_state = 0; | ||
608 | else { | ||
609 | /* | ||
610 | * avoid corrupting this frame | ||
611 | * but ensure next frame will | ||
612 | * be active | ||
613 | */ | ||
614 | nd->act_state = 1; | ||
615 | break; | ||
616 | } | ||
617 | } else | ||
618 | /* | ||
619 | * Defer adjusting the activation state | ||
620 | * until the end of the frame. | ||
621 | */ | ||
622 | break; | ||
216 | } | 623 | } |
217 | 624 | ||
625 | /* Discarding this contact */ | ||
626 | if (!nd->confidence) | ||
627 | break; | ||
628 | |||
218 | /* emit a normal (X, Y) for the first point only */ | 629 | /* emit a normal (X, Y) for the first point only */ |
219 | if (nd->id == 0) { | 630 | if (nd->id == 0) { |
220 | /* | 631 | /* |
@@ -227,8 +638,15 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
227 | input_event(input, EV_ABS, ABS_X, nd->x); | 638 | input_event(input, EV_ABS, ABS_X, nd->x); |
228 | input_event(input, EV_ABS, ABS_Y, nd->y); | 639 | input_event(input, EV_ABS, ABS_Y, nd->y); |
229 | } | 640 | } |
641 | |||
642 | /* Emit MT events */ | ||
230 | input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); | 643 | input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); |
231 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); | 644 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); |
645 | |||
646 | /* | ||
647 | * Translate from height and width to size | ||
648 | * and orientation. | ||
649 | */ | ||
232 | if (nd->w > nd->h) { | 650 | if (nd->w > nd->h) { |
233 | input_event(input, EV_ABS, | 651 | input_event(input, EV_ABS, |
234 | ABS_MT_ORIENTATION, 1); | 652 | ABS_MT_ORIENTATION, 1); |
@@ -248,12 +666,88 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
248 | break; | 666 | break; |
249 | 667 | ||
250 | case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ | 668 | case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ |
251 | if (!nd->reading_mt) | 669 | if (!nd->reading_mt) /* Just to be sure */ |
252 | break; | 670 | break; |
253 | 671 | ||
254 | nd->reading_mt = 0; | 672 | nd->reading_mt = 0; |
255 | 673 | ||
256 | if (nd->first_contact_touch) { | 674 | |
675 | /* | ||
676 | * Activation state machine logic: | ||
677 | * | ||
678 | * Fundamental states: | ||
679 | * state > 0: Inactive | ||
680 | * state <= 0: Active | ||
681 | * state < -deactivate_slack: | ||
682 | * Pen termination of touch | ||
683 | * | ||
684 | * Specific values of interest | ||
685 | * state == activate_slack | ||
686 | * no valid input since the last reset | ||
687 | * | ||
688 | * state == 0 | ||
689 | * general operational state | ||
690 | * | ||
691 | * state == -deactivate_slack | ||
692 | * read sufficient empty frames to accept | ||
693 | * the end of input and reset | ||
694 | */ | ||
695 | |||
696 | if (nd->act_state > 0) { /* Currently inactive */ | ||
697 | if (value) | ||
698 | /* | ||
699 | * Consider each live contact as | ||
700 | * evidence of intentional activity. | ||
701 | */ | ||
702 | nd->act_state = (nd->act_state > value) | ||
703 | ? nd->act_state - value | ||
704 | : 0; | ||
705 | else | ||
706 | /* | ||
707 | * Empty frame before we hit the | ||
708 | * activity threshold, reset. | ||
709 | */ | ||
710 | nd->act_state = nd->activate_slack; | ||
711 | |||
712 | /* | ||
713 | * Entered this block inactive and no | ||
714 | * coordinates sent this frame, so hold off | ||
715 | * on button state. | ||
716 | */ | ||
717 | break; | ||
718 | } else { /* Currently active */ | ||
719 | if (value && nd->act_state >= | ||
720 | nd->deactivate_slack) | ||
721 | /* | ||
722 | * Live point: clear accumulated | ||
723 | * deactivation count. | ||
724 | */ | ||
725 | nd->act_state = 0; | ||
726 | else if (nd->act_state <= nd->deactivate_slack) | ||
727 | /* | ||
728 | * We've consumed the deactivation | ||
729 | * slack, time to deactivate and reset. | ||
730 | */ | ||
731 | nd->act_state = | ||
732 | nd->activate_slack; | ||
733 | else { /* Move towards deactivation */ | ||
734 | nd->act_state--; | ||
735 | break; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | if (nd->first_contact_touch && nd->act_state <= 0) { | ||
740 | /* | ||
741 | * Check to see if we're ready to start | ||
742 | * emitting touch events. | ||
743 | * | ||
744 | * Note: activation slack will decrease over | ||
745 | * the course of the frame, and it will be | ||
746 | * inconsistent from the start to the end of | ||
747 | * the frame. However if the frame starts | ||
748 | * with slack, first_contact_touch will still | ||
749 | * be 0 and we will not get to this point. | ||
750 | */ | ||
257 | input_report_key(input, BTN_TOOL_DOUBLETAP, 1); | 751 | input_report_key(input, BTN_TOOL_DOUBLETAP, 1); |
258 | input_report_key(input, BTN_TOUCH, 1); | 752 | input_report_key(input, BTN_TOUCH, 1); |
259 | } else { | 753 | } else { |
@@ -263,7 +757,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
263 | break; | 757 | break; |
264 | 758 | ||
265 | default: | 759 | default: |
266 | /* fallback to the generic hidinput handling */ | 760 | /* fall-back to the generic hidinput handling */ |
267 | return 0; | 761 | return 0; |
268 | } | 762 | } |
269 | } | 763 | } |
@@ -293,6 +787,16 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
293 | } | 787 | } |
294 | 788 | ||
295 | nd->reading_mt = 0; | 789 | nd->reading_mt = 0; |
790 | nd->min_width = 0; | ||
791 | nd->min_height = 0; | ||
792 | nd->activate_slack = activate_slack; | ||
793 | nd->act_state = activate_slack; | ||
794 | nd->deactivate_slack = -deactivate_slack; | ||
795 | nd->sensor_logical_width = 0; | ||
796 | nd->sensor_logical_height = 0; | ||
797 | nd->sensor_physical_width = 0; | ||
798 | nd->sensor_physical_height = 0; | ||
799 | |||
296 | hid_set_drvdata(hdev, nd); | 800 | hid_set_drvdata(hdev, nd); |
297 | 801 | ||
298 | ret = hid_parse(hdev); | 802 | ret = hid_parse(hdev); |
@@ -344,6 +848,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
344 | if (report) | 848 | if (report) |
345 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 849 | usbhid_submit_report(hdev, report, USB_DIR_OUT); |
346 | 850 | ||
851 | ret = sysfs_create_group(&hdev->dev.kobj, | ||
852 | &ntrig_attribute_group); | ||
347 | 853 | ||
348 | return 0; | 854 | return 0; |
349 | err_free: | 855 | err_free: |
@@ -353,6 +859,8 @@ err_free: | |||
353 | 859 | ||
354 | static void ntrig_remove(struct hid_device *hdev) | 860 | static void ntrig_remove(struct hid_device *hdev) |
355 | { | 861 | { |
862 | sysfs_remove_group(&hdev->dev.kobj, | ||
863 | &ntrig_attribute_group); | ||
356 | hid_hw_stop(hdev); | 864 | hid_hw_stop(hdev); |
357 | kfree(hid_get_drvdata(hdev)); | 865 | kfree(hid_get_drvdata(hdev)); |
358 | } | 866 | } |