1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/hid.h>
15#include <linux/input/mt.h>
16#include <linux/leds.h>
17#include <linux/module.h>
18#include <linux/usb.h>
19
20#include "hid-ids.h"
21
22#define ELAN_MT_I2C 0x5d
23#define ELAN_SINGLE_FINGER 0x81
24#define ELAN_MT_FIRST_FINGER 0x82
25#define ELAN_MT_SECOND_FINGER 0x83
26#define ELAN_INPUT_REPORT_SIZE 8
27#define ELAN_I2C_REPORT_SIZE 32
28#define ELAN_FINGER_DATA_LEN 5
29#define ELAN_MAX_FINGERS 5
30#define ELAN_MAX_PRESSURE 255
31#define ELAN_TP_USB_INTF 1
32
33#define ELAN_FEATURE_REPORT 0x0d
34#define ELAN_FEATURE_SIZE 5
35#define ELAN_PARAM_MAX_X 6
36#define ELAN_PARAM_MAX_Y 7
37#define ELAN_PARAM_RES 8
38
39#define ELAN_MUTE_LED_REPORT 0xBC
40#define ELAN_LED_REPORT_SIZE 8
41
42#define ELAN_HAS_LED BIT(0)
43
44struct elan_drvdata {
45 struct input_dev *input;
46 u8 prev_report[ELAN_INPUT_REPORT_SIZE];
47 struct led_classdev mute_led;
48 u8 mute_led_state;
49 u16 max_x;
50 u16 max_y;
51 u16 res_x;
52 u16 res_y;
53};
54
55static int is_not_elan_touchpad(struct hid_device *hdev)
56{
57 if (hdev->bus == BUS_USB) {
58 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
59
60 return (intf->altsetting->desc.bInterfaceNumber !=
61 ELAN_TP_USB_INTF);
62 }
63
64 return 0;
65}
66
67static int elan_input_mapping(struct hid_device *hdev, struct hid_input *hi,
68 struct hid_field *field, struct hid_usage *usage,
69 unsigned long **bit, int *max)
70{
71 if (is_not_elan_touchpad(hdev))
72 return 0;
73
74 if (field->report->id == ELAN_SINGLE_FINGER ||
75 field->report->id == ELAN_MT_FIRST_FINGER ||
76 field->report->id == ELAN_MT_SECOND_FINGER ||
77 field->report->id == ELAN_MT_I2C)
78 return -1;
79
80 return 0;
81}
82
83static int elan_get_device_param(struct hid_device *hdev,
84 unsigned char *dmabuf, unsigned char param)
85{
86 int ret;
87
88 dmabuf[0] = ELAN_FEATURE_REPORT;
89 dmabuf[1] = 0x05;
90 dmabuf[2] = 0x03;
91 dmabuf[3] = param;
92 dmabuf[4] = 0x01;
93
94 ret = hid_hw_raw_request(hdev, ELAN_FEATURE_REPORT, dmabuf,
95 ELAN_FEATURE_SIZE, HID_FEATURE_REPORT,
96 HID_REQ_SET_REPORT);
97 if (ret != ELAN_FEATURE_SIZE) {
98 hid_err(hdev, "Set report error for parm %d: %d\n", param, ret);
99 return ret;
100 }
101
102 ret = hid_hw_raw_request(hdev, ELAN_FEATURE_REPORT, dmabuf,
103 ELAN_FEATURE_SIZE, HID_FEATURE_REPORT,
104 HID_REQ_GET_REPORT);
105 if (ret != ELAN_FEATURE_SIZE) {
106 hid_err(hdev, "Get report error for parm %d: %d\n", param, ret);
107 return ret;
108 }
109
110 return 0;
111}
112
113static unsigned int elan_convert_res(char val)
114{
115
116
117
118
119 return (val * 10 + 790) * 10 / 254;
120}
121
122static int elan_get_device_params(struct hid_device *hdev)
123{
124 struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
125 unsigned char *dmabuf;
126 int ret;
127
128 dmabuf = kmalloc(ELAN_FEATURE_SIZE, GFP_KERNEL);
129 if (!dmabuf)
130 return -ENOMEM;
131
132 ret = elan_get_device_param(hdev, dmabuf, ELAN_PARAM_MAX_X);
133 if (ret)
134 goto err;
135
136 drvdata->max_x = (dmabuf[4] << 8) | dmabuf[3];
137
138 ret = elan_get_device_param(hdev, dmabuf, ELAN_PARAM_MAX_Y);
139 if (ret)
140 goto err;
141
142 drvdata->max_y = (dmabuf[4] << 8) | dmabuf[3];
143
144 ret = elan_get_device_param(hdev, dmabuf, ELAN_PARAM_RES);
145 if (ret)
146 goto err;
147
148 drvdata->res_x = elan_convert_res(dmabuf[3]);
149 drvdata->res_y = elan_convert_res(dmabuf[4]);
150
151err:
152 kfree(dmabuf);
153 return ret;
154}
155
156static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi)
157{
158 int ret;
159 struct input_dev *input;
160 struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
161
162 if (is_not_elan_touchpad(hdev))
163 return 0;
164
165 ret = elan_get_device_params(hdev);
166 if (ret)
167 return ret;
168
169 input = devm_input_allocate_device(&hdev->dev);
170 if (!input)
171 return -ENOMEM;
172
173 input->name = "Elan Touchpad";
174 input->phys = hdev->phys;
175 input->uniq = hdev->uniq;
176 input->id.bustype = hdev->bus;
177 input->id.vendor = hdev->vendor;
178 input->id.product = hdev->product;
179 input->id.version = hdev->version;
180 input->dev.parent = &hdev->dev;
181
182 input_set_abs_params(input, ABS_MT_POSITION_X, 0, drvdata->max_x,
183 0, 0);
184 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, drvdata->max_y,
185 0, 0);
186 input_set_abs_params(input, ABS_MT_PRESSURE, 0, ELAN_MAX_PRESSURE,
187 0, 0);
188
189 __set_bit(BTN_LEFT, input->keybit);
190 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
191
192 ret = input_mt_init_slots(input, ELAN_MAX_FINGERS, INPUT_MT_POINTER);
193 if (ret) {
194 hid_err(hdev, "Failed to init elan MT slots: %d\n", ret);
195 return ret;
196 }
197
198 input_abs_set_res(input, ABS_X, drvdata->res_x);
199 input_abs_set_res(input, ABS_Y, drvdata->res_y);
200
201 ret = input_register_device(input);
202 if (ret) {
203 hid_err(hdev, "Failed to register elan input device: %d\n",
204 ret);
205 input_free_device(input);
206 return ret;
207 }
208
209 drvdata->input = input;
210
211 return 0;
212}
213
214static void elan_report_mt_slot(struct elan_drvdata *drvdata, u8 *data,
215 unsigned int slot_num)
216{
217 struct input_dev *input = drvdata->input;
218 int x, y, p;
219
220 bool active = !!data;
221
222 input_mt_slot(input, slot_num);
223 input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
224 if (active) {
225 x = ((data[0] & 0xF0) << 4) | data[1];
226 y = drvdata->max_y -
227 (((data[0] & 0x07) << 8) | data[2]);
228 p = data[4];
229
230 input_report_abs(input, ABS_MT_POSITION_X, x);
231 input_report_abs(input, ABS_MT_POSITION_Y, y);
232 input_report_abs(input, ABS_MT_PRESSURE, p);
233 }
234}
235
236static void elan_usb_report_input(struct elan_drvdata *drvdata, u8 *data)
237{
238 int i;
239 struct input_dev *input = drvdata->input;
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276 if (data[0] == ELAN_SINGLE_FINGER) {
277 for (i = 0; i < ELAN_MAX_FINGERS; i++) {
278 if (data[2] & BIT(i + 3))
279 elan_report_mt_slot(drvdata, data + 3, i);
280 else
281 elan_report_mt_slot(drvdata, NULL, i);
282 }
283 input_report_key(input, BTN_LEFT, data[2] & 0x01);
284 }
285
286
287
288
289
290
291 if (data[0] == ELAN_MT_FIRST_FINGER) {
292 memcpy(drvdata->prev_report, data,
293 sizeof(drvdata->prev_report));
294 return;
295 }
296
297 if (data[0] == ELAN_MT_SECOND_FINGER) {
298 int first = 0;
299 u8 *prev_report = drvdata->prev_report;
300
301 if (prev_report[0] != ELAN_MT_FIRST_FINGER)
302 return;
303
304 for (i = 0; i < ELAN_MAX_FINGERS; i++) {
305 if (prev_report[2] & BIT(i + 3)) {
306 if (!first) {
307 first = 1;
308 elan_report_mt_slot(drvdata, prev_report + 3, i);
309 } else {
310 elan_report_mt_slot(drvdata, data + 1, i);
311 }
312 } else {
313 elan_report_mt_slot(drvdata, NULL, i);
314 }
315 }
316 input_report_key(input, BTN_LEFT, prev_report[2] & 0x01);
317 }
318
319 input_mt_sync_frame(input);
320 input_sync(input);
321}
322
323static void elan_i2c_report_input(struct elan_drvdata *drvdata, u8 *data)
324{
325 struct input_dev *input = drvdata->input;
326 u8 *finger_data;
327 int i;
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348 finger_data = data + 2;
349 for (i = 0; i < ELAN_MAX_FINGERS; i++) {
350 if (data[1] & BIT(i + 3)) {
351 elan_report_mt_slot(drvdata, finger_data, i);
352 finger_data += ELAN_FINGER_DATA_LEN;
353 } else {
354 elan_report_mt_slot(drvdata, NULL, i);
355 }
356 }
357
358 input_report_key(input, BTN_LEFT, data[1] & 0x01);
359 input_mt_sync_frame(input);
360 input_sync(input);
361}
362
363static int elan_raw_event(struct hid_device *hdev,
364 struct hid_report *report, u8 *data, int size)
365{
366 struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
367
368 if (is_not_elan_touchpad(hdev))
369 return 0;
370
371 if (data[0] == ELAN_SINGLE_FINGER ||
372 data[0] == ELAN_MT_FIRST_FINGER ||
373 data[0] == ELAN_MT_SECOND_FINGER) {
374 if (size == ELAN_INPUT_REPORT_SIZE) {
375 elan_usb_report_input(drvdata, data);
376 return 1;
377 }
378 }
379
380 if (data[0] == ELAN_MT_I2C && size == ELAN_I2C_REPORT_SIZE) {
381 elan_i2c_report_input(drvdata, data);
382 return 1;
383 }
384
385 return 0;
386}
387
388static int elan_start_multitouch(struct hid_device *hdev)
389{
390 int ret;
391
392
393
394
395
396 static const unsigned char buf[] = { 0x0D, 0x00, 0x03, 0x21, 0x00 };
397 unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
398
399 if (!dmabuf)
400 return -ENOMEM;
401
402 ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, sizeof(buf),
403 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
404
405 kfree(dmabuf);
406
407 if (ret != sizeof(buf)) {
408 hid_err(hdev, "Failed to start multitouch: %d\n", ret);
409 return ret;
410 }
411
412 return 0;
413}
414
415static enum led_brightness elan_mute_led_get_brigtness(struct led_classdev *led_cdev)
416{
417 struct device *dev = led_cdev->dev->parent;
418 struct hid_device *hdev = to_hid_device(dev);
419 struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
420
421 return drvdata->mute_led_state;
422}
423
424static int elan_mute_led_set_brigtness(struct led_classdev *led_cdev,
425 enum led_brightness value)
426{
427 int ret;
428 u8 led_state;
429 struct device *dev = led_cdev->dev->parent;
430 struct hid_device *hdev = to_hid_device(dev);
431 struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
432
433 unsigned char *dmabuf = kzalloc(ELAN_LED_REPORT_SIZE, GFP_KERNEL);
434
435 if (!dmabuf)
436 return -ENOMEM;
437
438 led_state = !!value;
439
440 dmabuf[0] = ELAN_MUTE_LED_REPORT;
441 dmabuf[1] = 0x02;
442 dmabuf[2] = led_state;
443
444 ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, ELAN_LED_REPORT_SIZE,
445 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
446
447 kfree(dmabuf);
448
449 if (ret != ELAN_LED_REPORT_SIZE) {
450 hid_err(hdev, "Failed to set mute led brightness: %d\n", ret);
451 return ret;
452 }
453
454 drvdata->mute_led_state = led_state;
455 return 0;
456}
457
458static int elan_init_mute_led(struct hid_device *hdev)
459{
460 struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
461 struct led_classdev *mute_led = &drvdata->mute_led;
462
463 mute_led->name = "elan:red:mute";
464 mute_led->brightness_get = elan_mute_led_get_brigtness;
465 mute_led->brightness_set_blocking = elan_mute_led_set_brigtness;
466 mute_led->max_brightness = LED_ON;
467 mute_led->dev = &hdev->dev;
468
469 return devm_led_classdev_register(&hdev->dev, mute_led);
470}
471
472static int elan_probe(struct hid_device *hdev, const struct hid_device_id *id)
473{
474 int ret;
475 struct elan_drvdata *drvdata;
476
477 drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
478
479 if (!drvdata)
480 return -ENOMEM;
481
482 hid_set_drvdata(hdev, drvdata);
483
484 ret = hid_parse(hdev);
485 if (ret) {
486 hid_err(hdev, "Hid Parse failed\n");
487 return ret;
488 }
489
490 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
491 if (ret) {
492 hid_err(hdev, "Hid hw start failed\n");
493 return ret;
494 }
495
496 if (is_not_elan_touchpad(hdev))
497 return 0;
498
499 if (!drvdata->input) {
500 hid_err(hdev, "Input device is not registered\n");
501 ret = -ENAVAIL;
502 goto err;
503 }
504
505 ret = elan_start_multitouch(hdev);
506 if (ret)
507 goto err;
508
509 if (id->driver_data & ELAN_HAS_LED) {
510 ret = elan_init_mute_led(hdev);
511 if (ret)
512 goto err;
513 }
514
515 return 0;
516err:
517 hid_hw_stop(hdev);
518 return ret;
519}
520
521static void elan_remove(struct hid_device *hdev)
522{
523 hid_hw_stop(hdev);
524}
525
526static const struct hid_device_id elan_devices[] = {
527 { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2),
528 .driver_data = ELAN_HAS_LED },
529 { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2_10_COVER),
530 .driver_data = ELAN_HAS_LED },
531 { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_TOSHIBA_CLICK_L9W) },
532 { }
533};
534MODULE_DEVICE_TABLE(hid, elan_devices);
535
536static struct hid_driver elan_driver = {
537 .name = "elan",
538 .id_table = elan_devices,
539 .input_mapping = elan_input_mapping,
540 .input_configured = elan_input_configured,
541 .raw_event = elan_raw_event,
542 .probe = elan_probe,
543 .remove = elan_remove,
544};
545
546module_hid_driver(elan_driver);
547
548MODULE_LICENSE("GPL");
549MODULE_AUTHOR("Alexandrov Stanislav");
550MODULE_DESCRIPTION("Driver for HID ELAN Touchpads");
551