2 * HID driver for Cando dual-touch panels
4 * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
15 #include <linux/device.h>
16 #include <linux/hid.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
20 MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
21 MODULE_DESCRIPTION("Cando dual-touch panel");
22 MODULE_LICENSE("GPL");
29 __s8 oldest
; /* id of the oldest finger in previous frame */
30 bool valid
; /* valid finger data, or just placeholder? */
31 bool first
; /* is this the first finger in this frame? */
32 __s8 firstid
; /* id of the first finger in the frame */
33 __u16 firstx
, firsty
; /* (x, y) of the first finger in the frame */
36 static int cando_input_mapping(struct hid_device
*hdev
, struct hid_input
*hi
,
37 struct hid_field
*field
, struct hid_usage
*usage
,
38 unsigned long **bit
, int *max
)
40 switch (usage
->hid
& HID_USAGE_PAGE
) {
45 hid_map_usage(hi
, usage
, bit
, max
,
46 EV_ABS
, ABS_MT_POSITION_X
);
47 /* touchscreen emulation */
48 input_set_abs_params(hi
->input
, ABS_X
,
49 field
->logical_minimum
,
50 field
->logical_maximum
, 0, 0);
53 hid_map_usage(hi
, usage
, bit
, max
,
54 EV_ABS
, ABS_MT_POSITION_Y
);
55 /* touchscreen emulation */
56 input_set_abs_params(hi
->input
, ABS_Y
,
57 field
->logical_minimum
,
58 field
->logical_maximum
, 0, 0);
63 case HID_UP_DIGITIZER
:
65 case HID_DG_TIPSWITCH
:
66 case HID_DG_CONTACTMAX
:
69 /* touchscreen emulation */
70 hid_map_usage(hi
, usage
, bit
, max
, EV_KEY
, BTN_TOUCH
);
72 case HID_DG_CONTACTID
:
73 hid_map_usage(hi
, usage
, bit
, max
,
74 EV_ABS
, ABS_MT_TRACKING_ID
);
83 static int cando_input_mapped(struct hid_device
*hdev
, struct hid_input
*hi
,
84 struct hid_field
*field
, struct hid_usage
*usage
,
85 unsigned long **bit
, int *max
)
87 if (usage
->type
== EV_KEY
|| usage
->type
== EV_ABS
)
88 clear_bit(usage
->code
, *bit
);
94 * this function is called when a whole finger has been parsed,
95 * so that it can decide what to send to the input layer.
97 static void cando_filter_event(struct cando_data
*td
, struct input_dev
*input
)
99 td
->first
= !td
->first
; /* touchscreen emulation */
103 * touchscreen emulation: if this is the second finger and
104 * the first was valid, the first was the oldest; if the
105 * first was not valid and there was a valid finger in the
106 * previous frame, this is a release.
110 } else if (td
->firstid
>= 0) {
111 input_event(input
, EV_ABS
, ABS_X
, td
->firstx
);
112 input_event(input
, EV_ABS
, ABS_Y
, td
->firsty
);
113 td
->oldest
= td
->firstid
;
114 } else if (td
->oldest
>= 0) {
115 input_event(input
, EV_KEY
, BTN_TOUCH
, 0);
122 input_event(input
, EV_ABS
, ABS_MT_TRACKING_ID
, td
->id
);
123 input_event(input
, EV_ABS
, ABS_MT_POSITION_X
, td
->x
);
124 input_event(input
, EV_ABS
, ABS_MT_POSITION_Y
, td
->y
);
126 input_mt_sync(input
);
129 * touchscreen emulation: if there was no touching finger previously,
132 if (td
->oldest
< 0) {
133 input_event(input
, EV_KEY
, BTN_TOUCH
, 1);
138 * touchscreen emulation: if this is the first finger, wait for the
139 * second; the oldest is then the second if it was the oldest already
140 * or if there was no first, the first otherwise.
145 td
->firstid
= td
->id
;
148 if (td
->id
== td
->oldest
|| td
->firstid
< 0) {
155 oldest
= td
->firstid
;
157 input_event(input
, EV_ABS
, ABS_X
, x
);
158 input_event(input
, EV_ABS
, ABS_Y
, y
);
164 static int cando_event(struct hid_device
*hid
, struct hid_field
*field
,
165 struct hid_usage
*usage
, __s32 value
)
167 struct cando_data
*td
= hid_get_drvdata(hid
);
169 if (hid
->claimed
& HID_CLAIMED_INPUT
) {
170 struct input_dev
*input
= field
->hidinput
->input
;
172 switch (usage
->hid
) {
176 case HID_DG_CONTACTID
:
184 cando_filter_event(td
, input
);
186 case HID_DG_TIPSWITCH
:
187 /* avoid interference from generic hidinput handling */
191 /* fallback to the generic hidinput handling */
196 /* we have handled the hidinput part, now remains hiddev */
197 if (hid
->claimed
& HID_CLAIMED_HIDDEV
&& hid
->hiddev_hid_event
)
198 hid
->hiddev_hid_event(hid
, field
, usage
, value
);
203 static int cando_probe(struct hid_device
*hdev
, const struct hid_device_id
*id
)
206 struct cando_data
*td
;
208 td
= kmalloc(sizeof(struct cando_data
), GFP_KERNEL
);
210 hid_err(hdev
, "cannot allocate Cando Touch data\n");
213 hid_set_drvdata(hdev
, td
);
218 ret
= hid_parse(hdev
);
220 ret
= hid_hw_start(hdev
, HID_CONNECT_DEFAULT
);
228 static void cando_remove(struct hid_device
*hdev
)
231 kfree(hid_get_drvdata(hdev
));
232 hid_set_drvdata(hdev
, NULL
);
235 static const struct hid_device_id cando_devices
[] = {
236 { HID_USB_DEVICE(USB_VENDOR_ID_CANDO
,
237 USB_DEVICE_ID_CANDO_MULTI_TOUCH
) },
238 { HID_USB_DEVICE(USB_VENDOR_ID_CANDO
,
239 USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1
) },
240 { HID_USB_DEVICE(USB_VENDOR_ID_CANDO
,
241 USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6
) },
242 { HID_USB_DEVICE(USB_VENDOR_ID_CANDO
,
243 USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6
) },
246 MODULE_DEVICE_TABLE(hid
, cando_devices
);
248 static const struct hid_usage_id cando_grabbed_usages
[] = {
249 { HID_ANY_ID
, HID_ANY_ID
, HID_ANY_ID
},
250 { HID_ANY_ID
- 1, HID_ANY_ID
- 1, HID_ANY_ID
- 1}
253 static struct hid_driver cando_driver
= {
254 .name
= "cando-touch",
255 .id_table
= cando_devices
,
256 .probe
= cando_probe
,
257 .remove
= cando_remove
,
258 .input_mapping
= cando_input_mapping
,
259 .input_mapped
= cando_input_mapped
,
260 .usage_table
= cando_grabbed_usages
,
261 .event
= cando_event
,
264 static int __init
cando_init(void)
266 return hid_register_driver(&cando_driver
);
269 static void __exit
cando_exit(void)
271 hid_unregister_driver(&cando_driver
);
274 module_init(cando_init
);
275 module_exit(cando_exit
);