2 * HID driver for the multitouch panel on the Hanvon tablet
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>
19 #include <linux/usb.h>
20 #include "usbhid/usbhid.h"
22 MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
23 MODULE_DESCRIPTION("Hanvon dual-touch panel");
24 MODULE_LICENSE("GPL");
33 static int hanvon_input_mapping(struct hid_device *hdev, struct hid_input *hi,
34 struct hid_field *field, struct hid_usage *usage,
35 unsigned long **bit, int *max)
37 switch (usage->hid & HID_USAGE_PAGE) {
42 hid_map_usage(hi, usage, bit, max,
43 EV_ABS, ABS_MT_POSITION_X);
44 /* touchscreen emulation */
45 input_set_abs_params(hi->input, ABS_X,
46 field->logical_minimum,
47 field->logical_maximum, 0, 0);
50 hid_map_usage(hi, usage, bit, max,
51 EV_ABS, ABS_MT_POSITION_Y);
52 /* touchscreen emulation */
53 input_set_abs_params(hi->input, ABS_Y,
54 field->logical_minimum,
55 field->logical_maximum, 0, 0);
60 case HID_UP_DIGITIZER:
62 case HID_DG_TIPSWITCH:
63 hid_map_usage(hi, usage, bit, max, EV_ABS,
68 hid_map_usage(hi, usage, bit, max, EV_ABS,
72 case HID_DG_CONFIDENCE:
73 hid_map_usage(hi, usage, bit, max, EV_ABS,
77 case HID_DG_CONTACTID:
78 hid_map_usage(hi, usage, bit, max,
79 EV_ABS, ABS_MT_TRACKING_ID);
82 case HID_DG_CONTACTCOUNT:
83 hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MAJOR);
84 input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
85 hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR);
86 input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
89 case HID_DG_CONTACTMAX:
90 hid_map_usage(hi, usage, bit, max, EV_ABS,
100 static int hanvon_input_mapped(struct hid_device *hdev, struct hid_input *hi,
101 struct hid_field *field, struct hid_usage *usage,
102 unsigned long **bit, int *max)
104 if (usage->type == EV_KEY || usage->type == EV_ABS)
105 clear_bit(usage->code, *bit);
111 static int hanvon_event(struct hid_device *hid, struct hid_field *field,
112 struct hid_usage *usage, __s32 value)
114 // struct hanvon_data *td = hid_get_drvdata(hid);
116 if (hid->claimed & HID_CLAIMED_INPUT) {
117 struct input_dev *input = field->hidinput->input;
118 switch (usage->hid) {
119 case HID_DG_TIPSWITCH:
120 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, value);
123 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, value);
125 case HID_DG_CONFIDENCE:
126 input_event(input, EV_ABS, ABS_MT_WIDTH_MAJOR, value);
129 input_event(input, EV_ABS, ABS_MT_POSITION_X, value);
132 input_event(input, EV_ABS, ABS_MT_POSITION_Y, value);
133 input_mt_sync(input);
135 case HID_DG_CONTACTID:
136 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, value);
138 case HID_DG_CONTACTCOUNT:
139 input_event(input, EV_ABS, ABS_MT_WIDTH_MINOR, value);
141 case HID_DG_CONTACTMAX:
143 input_event(input, EV_ABS, ABS_MT_ORIENTATION, value);
146 /* fallback to the generic hidinput handling */
151 /* we have handled the hidinput part, now remains hiddev */
152 if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
153 hid->hiddev_hid_event(hid, field, usage, value);
158 static int hanvon_probe(struct hid_device *hdev, const struct hid_device_id *id)
161 struct hanvon_data *td;
164 td = kmalloc(sizeof(struct hanvon_data), GFP_KERNEL);
166 dev_err(&hdev->dev, "cannot allocate Hanvon data\n");
169 hid_set_drvdata(hdev, td);
171 ret = hid_parse(hdev);
173 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
181 static void hanvon_remove(struct hid_device *hdev)
184 kfree(hid_get_drvdata(hdev));
185 hid_set_drvdata(hdev, NULL);
188 static const struct hid_device_id hanvon_devices[] = {
189 { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
192 MODULE_DEVICE_TABLE(hid, hanvon_devices);
194 static const struct hid_usage_id hanvon_grabbed_usages[] = {
195 { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
196 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
199 static struct hid_driver hanvon_driver = {
201 .id_table = hanvon_devices,
202 .probe = hanvon_probe,
203 .remove = hanvon_remove,
204 .input_mapping = hanvon_input_mapping,
205 .input_mapped = hanvon_input_mapped,
206 .usage_table = hanvon_grabbed_usages,
207 .event = hanvon_event,
210 static int __init hanvon_init(void)
212 return hid_register_driver(&hanvon_driver);
215 static void __exit hanvon_exit(void)
217 hid_unregister_driver(&hanvon_driver);
220 module_init(hanvon_init);
221 module_exit(hanvon_exit);