1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * HID driver for ELO usb touchscreen 4000/4500 |
4 | * |
5 | * Copyright (c) 2013 Jiri Slaby |
6 | * |
7 | * Data parsing taken from elousb driver by Vojtech Pavlik. |
8 | */ |
9 | |
10 | #include <linux/hid.h> |
11 | #include <linux/input.h> |
12 | #include <linux/module.h> |
13 | #include <linux/usb.h> |
14 | #include <linux/workqueue.h> |
15 | |
16 | #include "hid-ids.h" |
17 | |
18 | #define ELO_PERIODIC_READ_INTERVAL HZ |
19 | #define ELO_SMARTSET_CMD_TIMEOUT 2000 /* msec */ |
20 | |
21 | /* Elo SmartSet commands */ |
22 | #define ELO_FLUSH_SMARTSET_RESPONSES 0x02 /* Flush all pending smartset responses */ |
23 | #define ELO_SEND_SMARTSET_COMMAND 0x05 /* Send a smartset command */ |
24 | #define ELO_GET_SMARTSET_RESPONSE 0x06 /* Get a smartset response */ |
25 | #define ELO_DIAG 0x64 /* Diagnostics command */ |
26 | #define ELO_SMARTSET_PACKET_SIZE 8 |
27 | |
28 | struct elo_priv { |
29 | struct usb_device *usbdev; |
30 | struct delayed_work work; |
31 | unsigned char buffer[ELO_SMARTSET_PACKET_SIZE]; |
32 | }; |
33 | |
34 | static struct workqueue_struct *wq; |
35 | static bool use_fw_quirk = true; |
36 | module_param(use_fw_quirk, bool, S_IRUGO); |
37 | MODULE_PARM_DESC(use_fw_quirk, "Do periodic pokes for broken M firmwares (default = true)" ); |
38 | |
39 | static int elo_input_configured(struct hid_device *hdev, |
40 | struct hid_input *hidinput) |
41 | { |
42 | struct input_dev *input = hidinput->input; |
43 | |
44 | /* |
45 | * ELO devices have one Button usage in GenDesk field, which makes |
46 | * hid-input map it to BTN_LEFT; that confuses userspace, which then |
47 | * considers the device to be a mouse/touchpad instead of touchscreen. |
48 | */ |
49 | clear_bit(BTN_LEFT, addr: input->keybit); |
50 | set_bit(BTN_TOUCH, addr: input->keybit); |
51 | set_bit(ABS_PRESSURE, addr: input->absbit); |
52 | input_set_abs_params(dev: input, ABS_PRESSURE, min: 0, max: 256, fuzz: 0, flat: 0); |
53 | |
54 | return 0; |
55 | } |
56 | |
57 | static void elo_process_data(struct input_dev *input, const u8 *data, int size) |
58 | { |
59 | int press; |
60 | |
61 | input_report_abs(dev: input, ABS_X, value: (data[3] << 8) | data[2]); |
62 | input_report_abs(dev: input, ABS_Y, value: (data[5] << 8) | data[4]); |
63 | |
64 | press = 0; |
65 | if (data[1] & 0x80) |
66 | press = (data[7] << 8) | data[6]; |
67 | input_report_abs(dev: input, ABS_PRESSURE, value: press); |
68 | |
69 | if (data[1] & 0x03) { |
70 | input_report_key(dev: input, BTN_TOUCH, value: 1); |
71 | input_sync(dev: input); |
72 | } |
73 | |
74 | if (data[1] & 0x04) |
75 | input_report_key(dev: input, BTN_TOUCH, value: 0); |
76 | |
77 | input_sync(dev: input); |
78 | } |
79 | |
80 | static int elo_raw_event(struct hid_device *hdev, struct hid_report *report, |
81 | u8 *data, int size) |
82 | { |
83 | struct hid_input *hidinput; |
84 | |
85 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || list_empty(head: &hdev->inputs)) |
86 | return 0; |
87 | |
88 | hidinput = list_first_entry(&hdev->inputs, struct hid_input, list); |
89 | |
90 | switch (report->id) { |
91 | case 0: |
92 | if (data[0] == 'T') { /* Mandatory ELO packet marker */ |
93 | elo_process_data(input: hidinput->input, data, size); |
94 | return 1; |
95 | } |
96 | break; |
97 | default: /* unknown report */ |
98 | /* Unknown report type; pass upstream */ |
99 | hid_info(hdev, "unknown report type %d\n" , report->id); |
100 | break; |
101 | } |
102 | |
103 | return 0; |
104 | } |
105 | |
106 | static int elo_smartset_send_get(struct usb_device *dev, u8 command, |
107 | void *data) |
108 | { |
109 | unsigned int pipe; |
110 | u8 dir; |
111 | |
112 | if (command == ELO_SEND_SMARTSET_COMMAND) { |
113 | pipe = usb_sndctrlpipe(dev, 0); |
114 | dir = USB_DIR_OUT; |
115 | } else if (command == ELO_GET_SMARTSET_RESPONSE) { |
116 | pipe = usb_rcvctrlpipe(dev, 0); |
117 | dir = USB_DIR_IN; |
118 | } else |
119 | return -EINVAL; |
120 | |
121 | return usb_control_msg(dev, pipe, request: command, |
122 | requesttype: dir | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
123 | value: 0, index: 0, data, ELO_SMARTSET_PACKET_SIZE, |
124 | ELO_SMARTSET_CMD_TIMEOUT); |
125 | } |
126 | |
127 | static int elo_flush_smartset_responses(struct usb_device *dev) |
128 | { |
129 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
130 | ELO_FLUSH_SMARTSET_RESPONSES, |
131 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
132 | value: 0, index: 0, NULL, size: 0, USB_CTRL_SET_TIMEOUT); |
133 | } |
134 | |
135 | static void elo_work(struct work_struct *work) |
136 | { |
137 | struct elo_priv *priv = container_of(work, struct elo_priv, work.work); |
138 | struct usb_device *dev = priv->usbdev; |
139 | unsigned char *buffer = priv->buffer; |
140 | int ret; |
141 | |
142 | ret = elo_flush_smartset_responses(dev); |
143 | if (ret < 0) { |
144 | dev_err(&dev->dev, "initial FLUSH_SMARTSET_RESPONSES failed, error %d\n" , |
145 | ret); |
146 | goto fail; |
147 | } |
148 | |
149 | /* send Diagnostics command */ |
150 | *buffer = ELO_DIAG; |
151 | ret = elo_smartset_send_get(dev, ELO_SEND_SMARTSET_COMMAND, data: buffer); |
152 | if (ret < 0) { |
153 | dev_err(&dev->dev, "send Diagnostics Command failed, error %d\n" , |
154 | ret); |
155 | goto fail; |
156 | } |
157 | |
158 | /* get the result */ |
159 | ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE, data: buffer); |
160 | if (ret < 0) { |
161 | dev_err(&dev->dev, "get Diagnostics Command response failed, error %d\n" , |
162 | ret); |
163 | goto fail; |
164 | } |
165 | |
166 | /* read the ack */ |
167 | if (*buffer != 'A') { |
168 | ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE, |
169 | data: buffer); |
170 | if (ret < 0) { |
171 | dev_err(&dev->dev, "get acknowledge response failed, error %d\n" , |
172 | ret); |
173 | goto fail; |
174 | } |
175 | } |
176 | |
177 | fail: |
178 | ret = elo_flush_smartset_responses(dev); |
179 | if (ret < 0) |
180 | dev_err(&dev->dev, "final FLUSH_SMARTSET_RESPONSES failed, error %d\n" , |
181 | ret); |
182 | queue_delayed_work(wq, dwork: &priv->work, ELO_PERIODIC_READ_INTERVAL); |
183 | } |
184 | |
185 | /* |
186 | * Not all Elo devices need the periodic HID descriptor reads. |
187 | * Only firmware version M needs this. |
188 | */ |
189 | static bool elo_broken_firmware(struct usb_device *dev) |
190 | { |
191 | struct usb_device *hub = dev->parent; |
192 | struct usb_device *child = NULL; |
193 | u16 fw_lvl = le16_to_cpu(dev->descriptor.bcdDevice); |
194 | u16 child_vid, child_pid; |
195 | int i; |
196 | |
197 | if (!use_fw_quirk) |
198 | return false; |
199 | if (fw_lvl != 0x10d) |
200 | return false; |
201 | |
202 | /* iterate sibling devices of the touch controller */ |
203 | usb_hub_for_each_child(hub, i, child) { |
204 | child_vid = le16_to_cpu(child->descriptor.idVendor); |
205 | child_pid = le16_to_cpu(child->descriptor.idProduct); |
206 | |
207 | /* |
208 | * If one of the devices below is present attached as a sibling of |
209 | * the touch controller then this is a newer IBM 4820 monitor that |
210 | * does not need the IBM-requested workaround if fw level is |
211 | * 0x010d - aka 'M'. |
212 | * No other HW can have this combination. |
213 | */ |
214 | if (child_vid==0x04b3) { |
215 | switch (child_pid) { |
216 | case 0x4676: /* 4820 21x Video */ |
217 | case 0x4677: /* 4820 51x Video */ |
218 | case 0x4678: /* 4820 2Lx Video */ |
219 | case 0x4679: /* 4820 5Lx Video */ |
220 | return false; |
221 | } |
222 | } |
223 | } |
224 | return true; |
225 | } |
226 | |
227 | static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) |
228 | { |
229 | struct elo_priv *priv; |
230 | int ret; |
231 | |
232 | if (!hid_is_usb(hdev)) |
233 | return -EINVAL; |
234 | |
235 | priv = kzalloc(size: sizeof(*priv), GFP_KERNEL); |
236 | if (!priv) |
237 | return -ENOMEM; |
238 | |
239 | INIT_DELAYED_WORK(&priv->work, elo_work); |
240 | priv->usbdev = interface_to_usbdev(to_usb_interface(hdev->dev.parent)); |
241 | |
242 | hid_set_drvdata(hdev, data: priv); |
243 | |
244 | ret = hid_parse(hdev); |
245 | if (ret) { |
246 | hid_err(hdev, "parse failed\n" ); |
247 | goto err_free; |
248 | } |
249 | |
250 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
251 | if (ret) { |
252 | hid_err(hdev, "hw start failed\n" ); |
253 | goto err_free; |
254 | } |
255 | |
256 | if (elo_broken_firmware(dev: priv->usbdev)) { |
257 | hid_info(hdev, "broken firmware found, installing workaround\n" ); |
258 | queue_delayed_work(wq, dwork: &priv->work, ELO_PERIODIC_READ_INTERVAL); |
259 | } |
260 | |
261 | return 0; |
262 | err_free: |
263 | kfree(objp: priv); |
264 | return ret; |
265 | } |
266 | |
267 | static void elo_remove(struct hid_device *hdev) |
268 | { |
269 | struct elo_priv *priv = hid_get_drvdata(hdev); |
270 | |
271 | hid_hw_stop(hdev); |
272 | cancel_delayed_work_sync(dwork: &priv->work); |
273 | kfree(objp: priv); |
274 | } |
275 | |
276 | static const struct hid_device_id elo_devices[] = { |
277 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009), }, |
278 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030), }, |
279 | { } |
280 | }; |
281 | MODULE_DEVICE_TABLE(hid, elo_devices); |
282 | |
283 | static struct hid_driver elo_driver = { |
284 | .name = "elo" , |
285 | .id_table = elo_devices, |
286 | .probe = elo_probe, |
287 | .remove = elo_remove, |
288 | .raw_event = elo_raw_event, |
289 | .input_configured = elo_input_configured, |
290 | }; |
291 | |
292 | static int __init elo_driver_init(void) |
293 | { |
294 | int ret; |
295 | |
296 | wq = create_singlethread_workqueue("elousb" ); |
297 | if (!wq) |
298 | return -ENOMEM; |
299 | |
300 | ret = hid_register_driver(&elo_driver); |
301 | if (ret) |
302 | destroy_workqueue(wq); |
303 | |
304 | return ret; |
305 | } |
306 | module_init(elo_driver_init); |
307 | |
308 | static void __exit elo_driver_exit(void) |
309 | { |
310 | hid_unregister_driver(&elo_driver); |
311 | destroy_workqueue(wq); |
312 | } |
313 | module_exit(elo_driver_exit); |
314 | |
315 | MODULE_AUTHOR("Jiri Slaby <jslaby@suse.cz>" ); |
316 | MODULE_LICENSE("GPL" ); |
317 | |