2 * HID driver for N-Trig touchscreens
4 * Copyright (c) 2008 Rafi Rubin
5 * Copyright (c) 2009 Stephane Chatty
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
16 #include <linux/device.h>
17 #include <linux/hid.h>
18 #include <linux/module.h>
22 #define NTRIG_DUPLICATE_USAGES 0x001
24 #define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
29 char reading_a_point
, found_contact_id
;
36 * this driver is aimed at two firmware versions in circulation:
37 * - dual pen/finger single touch
38 * - finger multitouch, pen not working
41 static int ntrig_input_mapping(struct hid_device
*hdev
, struct hid_input
*hi
,
42 struct hid_field
*field
, struct hid_usage
*usage
,
43 unsigned long **bit
, int *max
)
45 switch (usage
->hid
& HID_USAGE_PAGE
) {
50 hid_map_usage(hi
, usage
, bit
, max
,
51 EV_ABS
, ABS_MT_POSITION_X
);
52 input_set_abs_params(hi
->input
, ABS_X
,
53 field
->logical_minimum
,
54 field
->logical_maximum
, 0, 0);
57 hid_map_usage(hi
, usage
, bit
, max
,
58 EV_ABS
, ABS_MT_POSITION_Y
);
59 input_set_abs_params(hi
->input
, ABS_Y
,
60 field
->logical_minimum
,
61 field
->logical_maximum
, 0, 0);
66 case HID_UP_DIGITIZER
:
68 /* we do not want to map these for now */
69 case HID_DG_CONTACTID
: /* value is useless */
70 case HID_DG_INPUTMODE
:
71 case HID_DG_DEVICEINDEX
:
72 case HID_DG_CONTACTCOUNT
:
73 case HID_DG_CONTACTMAX
:
76 /* original mapping by Rafi Rubin */
77 case HID_DG_CONFIDENCE
:
78 nt_map_key_clear(BTN_TOOL_DOUBLETAP
);
81 /* width/height mapped on TouchMajor/TouchMinor/Orientation */
83 hid_map_usage(hi
, usage
, bit
, max
,
84 EV_ABS
, ABS_MT_TOUCH_MAJOR
);
87 hid_map_usage(hi
, usage
, bit
, max
,
88 EV_ABS
, ABS_MT_TOUCH_MINOR
);
89 input_set_abs_params(hi
->input
, ABS_MT_ORIENTATION
,
96 /* we do not want to map these: no input-oriented meaning */
103 static int ntrig_input_mapped(struct hid_device
*hdev
, struct hid_input
*hi
,
104 struct hid_field
*field
, struct hid_usage
*usage
,
105 unsigned long **bit
, int *max
)
107 if (usage
->type
== EV_KEY
|| usage
->type
== EV_REL
108 || usage
->type
== EV_ABS
)
109 clear_bit(usage
->code
, *bit
);
115 * this function is called upon all reports
116 * so that we can filter contact point information,
117 * decide whether we are in multi or single touch mode
118 * and call input_mt_sync after each point if necessary
120 static int ntrig_event (struct hid_device
*hid
, struct hid_field
*field
,
121 struct hid_usage
*usage
, __s32 value
)
123 struct input_dev
*input
= field
->hidinput
->input
;
124 struct ntrig_data
*nd
= hid_get_drvdata(hid
);
126 if (hid
->claimed
& HID_CLAIMED_INPUT
) {
127 switch (usage
->hid
) {
130 if (field
->application
& 0x3)
131 nd
->pen_active
= (value
!= 0);
133 nd
->finger_active
= (value
!= 0);
137 nd
->inverted
= value
;
142 nd
->reading_a_point
= 1;
147 case HID_DG_CONTACTID
:
149 /* we receive this only when in multitouch mode */
150 nd
->found_contact_id
= 1;
158 * when in single touch mode, this is the last
159 * report received in a finger event. We want
160 * to emit a normal (X, Y) position
162 if (!nd
->found_contact_id
) {
163 if (nd
->pen_active
&& nd
->finger_active
) {
164 input_report_key(input
, BTN_TOOL_DOUBLETAP
, 0);
165 input_report_key(input
, BTN_TOOL_DOUBLETAP
, 1);
167 input_event(input
, EV_ABS
, ABS_X
, nd
->x
);
168 input_event(input
, EV_ABS
, ABS_Y
, nd
->y
);
171 case HID_DG_TIPPRESSURE
:
173 * when in single touch mode, this is the last
174 * report received in a pen event. We want
175 * to emit a normal (X, Y) position
177 if (! nd
->found_contact_id
) {
178 if (nd
->pen_active
&& nd
->finger_active
) {
179 input_report_key(input
,
180 nd
->inverted
? BTN_TOOL_RUBBER
: BTN_TOOL_PEN
182 input_report_key(input
,
183 nd
->inverted
? BTN_TOOL_RUBBER
: BTN_TOOL_PEN
186 input_event(input
, EV_ABS
, ABS_X
, nd
->x
);
187 input_event(input
, EV_ABS
, ABS_Y
, nd
->y
);
188 input_event(input
, EV_ABS
, ABS_PRESSURE
, value
);
193 * we receive this when the device is in multitouch
194 * mode. The first of the three values tagged with
195 * this usage tells if the contact point is real
198 if (!nd
->reading_a_point
|| value
!= 1)
200 /* emit a normal (X, Y) for the first point only */
202 input_event(input
, EV_ABS
, ABS_X
, nd
->x
);
203 input_event(input
, EV_ABS
, ABS_Y
, nd
->y
);
205 input_event(input
, EV_ABS
, ABS_MT_POSITION_X
, nd
->x
);
206 input_event(input
, EV_ABS
, ABS_MT_POSITION_Y
, nd
->y
);
208 input_event(input
, EV_ABS
,
209 ABS_MT_ORIENTATION
, 1);
210 input_event(input
, EV_ABS
,
211 ABS_MT_TOUCH_MAJOR
, nd
->w
);
212 input_event(input
, EV_ABS
,
213 ABS_MT_TOUCH_MINOR
, nd
->h
);
215 input_event(input
, EV_ABS
,
216 ABS_MT_ORIENTATION
, 0);
217 input_event(input
, EV_ABS
,
218 ABS_MT_TOUCH_MAJOR
, nd
->h
);
219 input_event(input
, EV_ABS
,
220 ABS_MT_TOUCH_MINOR
, nd
->w
);
222 input_mt_sync(field
->hidinput
->input
);
223 nd
->reading_a_point
= 0;
224 nd
->found_contact_id
= 0;
228 /* fallback to the generic hidinput handling */
233 /* we have handled the hidinput part, now remains hiddev */
234 if (hid
->claimed
& HID_CLAIMED_HIDDEV
&& hid
->hiddev_hid_event
)
235 hid
->hiddev_hid_event(hid
, field
, usage
, value
);
240 static int ntrig_probe(struct hid_device
*hdev
, const struct hid_device_id
*id
)
243 struct ntrig_data
*nd
;
245 nd
= kmalloc(sizeof(struct ntrig_data
), GFP_KERNEL
);
247 dev_err(&hdev
->dev
, "cannot allocate N-Trig data\n");
250 nd
->reading_a_point
= 0;
251 nd
->found_contact_id
= 0;
252 hid_set_drvdata(hdev
, nd
);
254 ret
= hid_parse(hdev
);
256 ret
= hid_hw_start(hdev
, HID_CONNECT_DEFAULT
);
264 static void ntrig_remove(struct hid_device
*hdev
)
267 kfree(hid_get_drvdata(hdev
));
270 static const struct hid_device_id ntrig_devices
[] = {
271 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG
, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN
),
272 .driver_data
= NTRIG_DUPLICATE_USAGES
},
275 MODULE_DEVICE_TABLE(hid
, ntrig_devices
);
277 static const struct hid_usage_id ntrig_grabbed_usages
[] = {
278 { HID_ANY_ID
, HID_ANY_ID
, HID_ANY_ID
},
279 { HID_ANY_ID
- 1, HID_ANY_ID
- 1, HID_ANY_ID
- 1}
282 static struct hid_driver ntrig_driver
= {
284 .id_table
= ntrig_devices
,
285 .probe
= ntrig_probe
,
286 .remove
= ntrig_remove
,
287 .input_mapping
= ntrig_input_mapping
,
288 .input_mapped
= ntrig_input_mapped
,
289 .usage_table
= ntrig_grabbed_usages
,
290 .event
= ntrig_event
,
293 static int __init
ntrig_init(void)
295 return hid_register_driver(&ntrig_driver
);
298 static void __exit
ntrig_exit(void)
300 hid_unregister_driver(&ntrig_driver
);
303 module_init(ntrig_init
);
304 module_exit(ntrig_exit
);
305 MODULE_LICENSE("GPL");