diff options
author | Rafi Rubin <rafi@seas.upenn.edu> | 2010-02-11 22:14:05 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-02-16 07:53:22 -0500 |
commit | 943ed464f3722de0569cf41ba6ec094768ac046d (patch) | |
tree | 62963642301e4bb41aeb9128d731014214d378b6 /drivers/hid | |
parent | 858155fbcc0cd713f6382c527bb1c3abc0ed6d00 (diff) |
HID: hid-ntrig add multi input quirk and clean up
Added a quirk to enable distinct input devices. The digitizer utilizes
three inputs to represent pen, multitouch and a normal touch screen.
With the Pen partitioned, it behaves well and does not need special
handling.
Also, I set names to the input devices to clarify the functions of the
various inputs.
Signed-off-by: Rafi Rubin <rafi@seas.upenn.edu>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-ntrig.c | 69 |
1 files changed, 58 insertions, 11 deletions
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 49ce69d7bba7..38b2364c8867 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c | |||
@@ -26,10 +26,10 @@ | |||
26 | 26 | ||
27 | struct ntrig_data { | 27 | struct ntrig_data { |
28 | __s32 x, y, id, w, h; | 28 | __s32 x, y, id, w, h; |
29 | char reading_a_point, found_contact_id; | 29 | bool reading_a_point, found_contact_id; |
30 | char pen_active; | 30 | bool pen_active; |
31 | char finger_active; | 31 | bool finger_active; |
32 | char inverted; | 32 | bool inverted; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /* | 35 | /* |
@@ -42,6 +42,10 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
42 | struct hid_field *field, struct hid_usage *usage, | 42 | struct hid_field *field, struct hid_usage *usage, |
43 | unsigned long **bit, int *max) | 43 | unsigned long **bit, int *max) |
44 | { | 44 | { |
45 | /* No special mappings needed for the pen */ | ||
46 | if (field->application == HID_DG_PEN) | ||
47 | return 0; | ||
48 | |||
45 | switch (usage->hid & HID_USAGE_PAGE) { | 49 | switch (usage->hid & HID_USAGE_PAGE) { |
46 | 50 | ||
47 | case HID_UP_GENDESK: | 51 | case HID_UP_GENDESK: |
@@ -104,6 +108,9 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
104 | struct hid_field *field, struct hid_usage *usage, | 108 | struct hid_field *field, struct hid_usage *usage, |
105 | unsigned long **bit, int *max) | 109 | unsigned long **bit, int *max) |
106 | { | 110 | { |
111 | /* No special mappings needed for the pen */ | ||
112 | if (field->application == HID_DG_PEN) | ||
113 | return 0; | ||
107 | if (usage->type == EV_KEY || usage->type == EV_REL | 114 | if (usage->type == EV_KEY || usage->type == EV_REL |
108 | || usage->type == EV_ABS) | 115 | || usage->type == EV_ABS) |
109 | clear_bit(usage->code, *bit); | 116 | clear_bit(usage->code, *bit); |
@@ -123,6 +130,10 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
123 | struct input_dev *input = field->hidinput->input; | 130 | struct input_dev *input = field->hidinput->input; |
124 | struct ntrig_data *nd = hid_get_drvdata(hid); | 131 | struct ntrig_data *nd = hid_get_drvdata(hid); |
125 | 132 | ||
133 | /* No special handling needed for the pen */ | ||
134 | if (field->application == HID_DG_PEN) | ||
135 | return 0; | ||
136 | |||
126 | if (hid->claimed & HID_CLAIMED_INPUT) { | 137 | if (hid->claimed & HID_CLAIMED_INPUT) { |
127 | switch (usage->hid) { | 138 | switch (usage->hid) { |
128 | 139 | ||
@@ -231,8 +242,8 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
231 | } | 242 | } |
232 | 243 | ||
233 | /* we have handled the hidinput part, now remains hiddev */ | 244 | /* we have handled the hidinput part, now remains hiddev */ |
234 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | 245 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) |
235 | hid->hiddev_hid_event(hid, field, usage, value); | 246 | hid->hiddev_hid_event(hid, field, usage, value); |
236 | 247 | ||
237 | return 1; | 248 | return 1; |
238 | } | 249 | } |
@@ -241,6 +252,11 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
241 | { | 252 | { |
242 | int ret; | 253 | int ret; |
243 | struct ntrig_data *nd; | 254 | struct ntrig_data *nd; |
255 | struct hid_input *hidinput; | ||
256 | struct input_dev *input; | ||
257 | |||
258 | if (id->driver_data) | ||
259 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; | ||
244 | 260 | ||
245 | nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); | 261 | nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); |
246 | if (!nd) { | 262 | if (!nd) { |
@@ -252,12 +268,43 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
252 | hid_set_drvdata(hdev, nd); | 268 | hid_set_drvdata(hdev, nd); |
253 | 269 | ||
254 | ret = hid_parse(hdev); | 270 | ret = hid_parse(hdev); |
255 | if (!ret) | 271 | if (ret) { |
256 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 272 | dev_err(&hdev->dev, "parse failed\n"); |
273 | goto err_free; | ||
274 | } | ||
275 | |||
276 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); | ||
277 | if (ret) { | ||
278 | dev_err(&hdev->dev, "hw start failed\n"); | ||
279 | goto err_free; | ||
280 | } | ||
257 | 281 | ||
258 | if (ret) | ||
259 | kfree (nd); | ||
260 | 282 | ||
283 | list_for_each_entry(hidinput, &hdev->inputs, list) { | ||
284 | input = hidinput->input; | ||
285 | switch (hidinput->report->field[0]->application) { | ||
286 | case HID_DG_PEN: | ||
287 | input->name = "N-Trig Pen"; | ||
288 | break; | ||
289 | case HID_DG_TOUCHSCREEN: | ||
290 | /* | ||
291 | * The physical touchscreen (single touch) | ||
292 | * input has a value for physical, whereas | ||
293 | * the multitouch only has logical input | ||
294 | * fields. | ||
295 | */ | ||
296 | input->name = | ||
297 | (hidinput->report->field[0] | ||
298 | ->physical) ? | ||
299 | "N-Trig Touchscreen" : | ||
300 | "N-Trig MultiTouch"; | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | return 0; | ||
306 | err_free: | ||
307 | kfree(nd); | ||
261 | return ret; | 308 | return ret; |
262 | } | 309 | } |
263 | 310 | ||
@@ -276,7 +323,7 @@ MODULE_DEVICE_TABLE(hid, ntrig_devices); | |||
276 | 323 | ||
277 | static const struct hid_usage_id ntrig_grabbed_usages[] = { | 324 | static const struct hid_usage_id ntrig_grabbed_usages[] = { |
278 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | 325 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, |
279 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} | 326 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } |
280 | }; | 327 | }; |
281 | 328 | ||
282 | static struct hid_driver ntrig_driver = { | 329 | static struct hid_driver ntrig_driver = { |