HID: add driver for ELO 4000/4500
[linux-2.6-block.git] / drivers / hid / hid-elo.c
CommitLineData
d23efc19
JS
1/*
2 * HID driver for ELO usb touchscreen 4000/4500
3 *
4 * Copyright (c) 2013 Jiri Slaby
5 *
6 * Data parsing taken from elousb driver by Vojtech Pavlik.
7 *
8 * This driver is licensed under the terms of GPLv2.
9 */
10
11#include <linux/hid.h>
12#include <linux/input.h>
13#include <linux/module.h>
14
15#include "hid-ids.h"
16
17static void elo_input_configured(struct hid_device *hdev,
18 struct hid_input *hidinput)
19{
20 struct input_dev *input = hidinput->input;
21
22 set_bit(BTN_TOUCH, input->keybit);
23 set_bit(ABS_PRESSURE, input->absbit);
24 input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0);
25}
26
27static void elo_process_data(struct input_dev *input, const u8 *data, int size)
28{
29 int press;
30
31 input_report_abs(input, ABS_X, (data[3] << 8) | data[2]);
32 input_report_abs(input, ABS_Y, (data[5] << 8) | data[4]);
33
34 press = 0;
35 if (data[1] & 0x80)
36 press = (data[7] << 8) | data[6];
37 input_report_abs(input, ABS_PRESSURE, press);
38
39 if (data[1] & 0x03) {
40 input_report_key(input, BTN_TOUCH, 1);
41 input_sync(input);
42 }
43
44 if (data[1] & 0x04)
45 input_report_key(input, BTN_TOUCH, 0);
46
47 input_sync(input);
48}
49
50static int elo_raw_event(struct hid_device *hdev, struct hid_report *report,
51 u8 *data, int size)
52{
53 struct hid_input *hidinput;
54
55 if (!(hdev->claimed & HID_CLAIMED_INPUT) || list_empty(&hdev->inputs))
56 return 0;
57
58 hidinput = list_first_entry(&hdev->inputs, struct hid_input, list);
59
60 switch (report->id) {
61 case 0:
62 if (data[0] == 'T') { /* Mandatory ELO packet marker */
63 elo_process_data(hidinput->input, data, size);
64 return 1;
65 }
66 break;
67 default: /* unknown report */
68 /* Unknown report type; pass upstream */
69 hid_info(hdev, "unknown report type %d\n", report->id);
70 break;
71 }
72
73 return 0;
74}
75
76static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
77{
78 int ret;
79
80 ret = hid_parse(hdev);
81 if (ret) {
82 hid_err(hdev, "parse failed\n");
83 goto err_free;
84 }
85
86 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
87 if (ret) {
88 hid_err(hdev, "hw start failed\n");
89 goto err_free;
90 }
91
92 return 0;
93err_free:
94 return ret;
95}
96
97static void elo_remove(struct hid_device *hdev)
98{
99 hid_hw_stop(hdev);
100}
101
102static const struct hid_device_id elo_devices[] = {
103 { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009), },
104 { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030), },
105 { }
106};
107MODULE_DEVICE_TABLE(hid, elo_devices);
108
109static struct hid_driver elo_driver = {
110 .name = "elo",
111 .id_table = elo_devices,
112 .probe = elo_probe,
113 .remove = elo_remove,
114 .raw_event = elo_raw_event,
115 .input_configured = elo_input_configured,
116};
117
118static int __init elo_driver_init(void)
119{
120 return hid_register_driver(&elo_driver);
121}
122module_init(elo_driver_init);
123
124static void __exit elo_driver_exit(void)
125{
126 hid_unregister_driver(&elo_driver);
127}
128module_exit(elo_driver_exit);
129
130MODULE_AUTHOR("Jiri Slaby <jslaby@suse.cz>");
131MODULE_LICENSE("GPL");