blob: 361e97da1169c169cebd75e7a482bf46632a6bfb [file] [log] [blame]
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001/*
2 * HIDPP protocol for Logitech Unifying receivers
3 *
4 * Copyright (c) 2011 Logitech (c)
5 * Copyright (c) 2012-2013 Google (c)
6 * Copyright (c) 2013-2014 Red Hat Inc.
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; version 2 of the License.
13 */
14
15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17#include <linux/device.h>
18#include <linux/hid.h>
19#include <linux/module.h>
20#include <linux/slab.h>
21#include <linux/sched.h>
22#include <linux/kfifo.h>
23#include <linux/input/mt.h>
24#include <asm/unaligned.h>
25#include "hid-ids.h"
26
27MODULE_LICENSE("GPL");
28MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
29MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>");
30
31#define REPORT_ID_HIDPP_SHORT 0x10
32#define REPORT_ID_HIDPP_LONG 0x11
33
34#define HIDPP_REPORT_SHORT_LENGTH 7
35#define HIDPP_REPORT_LONG_LENGTH 20
36
37#define HIDPP_QUIRK_CLASS_WTP BIT(0)
38
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -040039/* bits 1..20 are reserved for classes */
40#define HIDPP_QUIRK_DELAYED_INIT BIT(21)
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -040041#define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22)
Benjamin Tissoires3a61e972014-09-30 13:18:35 -040042#define HIDPP_QUIRK_MULTI_INPUT BIT(23)
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -040043
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040044/*
45 * There are two hidpp protocols in use, the first version hidpp10 is known
46 * as register access protocol or RAP, the second version hidpp20 is known as
47 * feature access protocol or FAP
48 *
49 * Most older devices (including the Unifying usb receiver) use the RAP protocol
50 * where as most newer devices use the FAP protocol. Both protocols are
51 * compatible with the underlying transport, which could be usb, Unifiying, or
52 * bluetooth. The message lengths are defined by the hid vendor specific report
53 * descriptor for the HIDPP_SHORT report type (total message lenth 7 bytes) and
54 * the HIDPP_LONG report type (total message length 20 bytes)
55 *
56 * The RAP protocol uses both report types, whereas the FAP only uses HIDPP_LONG
57 * messages. The Unifying receiver itself responds to RAP messages (device index
58 * is 0xFF for the receiver), and all messages (short or long) with a device
59 * index between 1 and 6 are passed untouched to the corresponding paired
60 * Unifying device.
61 *
62 * The paired device can be RAP or FAP, it will receive the message untouched
63 * from the Unifiying receiver.
64 */
65
66struct fap {
67 u8 feature_index;
68 u8 funcindex_clientid;
69 u8 params[HIDPP_REPORT_LONG_LENGTH - 4U];
70};
71
72struct rap {
73 u8 sub_id;
74 u8 reg_address;
75 u8 params[HIDPP_REPORT_LONG_LENGTH - 4U];
76};
77
78struct hidpp_report {
79 u8 report_id;
80 u8 device_index;
81 union {
82 struct fap fap;
83 struct rap rap;
84 u8 rawbytes[sizeof(struct fap)];
85 };
86} __packed;
87
88struct hidpp_device {
89 struct hid_device *hid_dev;
90 struct mutex send_mutex;
91 void *send_receive_buf;
92 wait_queue_head_t wait;
93 bool answer_available;
94 u8 protocol_major;
95 u8 protocol_minor;
96
97 void *private_data;
98
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -040099 struct work_struct work;
100 struct kfifo delayed_work_fifo;
101 atomic_t connected;
102 struct input_dev *delayed_input;
103
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400104 unsigned long quirks;
105};
106
107
108#define HIDPP_ERROR 0x8f
109#define HIDPP_ERROR_SUCCESS 0x00
110#define HIDPP_ERROR_INVALID_SUBID 0x01
111#define HIDPP_ERROR_INVALID_ADRESS 0x02
112#define HIDPP_ERROR_INVALID_VALUE 0x03
113#define HIDPP_ERROR_CONNECT_FAIL 0x04
114#define HIDPP_ERROR_TOO_MANY_DEVICES 0x05
115#define HIDPP_ERROR_ALREADY_EXISTS 0x06
116#define HIDPP_ERROR_BUSY 0x07
117#define HIDPP_ERROR_UNKNOWN_DEVICE 0x08
118#define HIDPP_ERROR_RESOURCE_ERROR 0x09
119#define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a
120#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b
121#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c
122
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400123static void hidpp_connect_event(struct hidpp_device *hidpp_dev);
124
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400125static int __hidpp_send_report(struct hid_device *hdev,
126 struct hidpp_report *hidpp_report)
127{
128 int fields_count, ret;
129
130 switch (hidpp_report->report_id) {
131 case REPORT_ID_HIDPP_SHORT:
132 fields_count = HIDPP_REPORT_SHORT_LENGTH;
133 break;
134 case REPORT_ID_HIDPP_LONG:
135 fields_count = HIDPP_REPORT_LONG_LENGTH;
136 break;
137 default:
138 return -ENODEV;
139 }
140
141 /*
142 * set the device_index as the receiver, it will be overwritten by
143 * hid_hw_request if needed
144 */
145 hidpp_report->device_index = 0xff;
146
147 ret = hid_hw_raw_request(hdev, hidpp_report->report_id,
148 (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT,
149 HID_REQ_SET_REPORT);
150
151 return ret == fields_count ? 0 : -1;
152}
153
154static int hidpp_send_message_sync(struct hidpp_device *hidpp,
155 struct hidpp_report *message,
156 struct hidpp_report *response)
157{
158 int ret;
159
160 mutex_lock(&hidpp->send_mutex);
161
162 hidpp->send_receive_buf = response;
163 hidpp->answer_available = false;
164
165 /*
166 * So that we can later validate the answer when it arrives
167 * in hidpp_raw_event
168 */
169 *response = *message;
170
171 ret = __hidpp_send_report(hidpp->hid_dev, message);
172
173 if (ret) {
174 dbg_hid("__hidpp_send_report returned err: %d\n", ret);
175 memset(response, 0, sizeof(struct hidpp_report));
176 goto exit;
177 }
178
179 if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
180 5*HZ)) {
181 dbg_hid("%s:timeout waiting for response\n", __func__);
182 memset(response, 0, sizeof(struct hidpp_report));
183 ret = -ETIMEDOUT;
184 }
185
186 if (response->report_id == REPORT_ID_HIDPP_SHORT &&
187 response->fap.feature_index == HIDPP_ERROR) {
188 ret = response->fap.params[1];
189 dbg_hid("__hidpp_send_report got hidpp error %02X\n", ret);
190 goto exit;
191 }
192
193exit:
194 mutex_unlock(&hidpp->send_mutex);
195 return ret;
196
197}
198
199static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp,
200 u8 feat_index, u8 funcindex_clientid, u8 *params, int param_count,
201 struct hidpp_report *response)
202{
203 struct hidpp_report *message = kzalloc(sizeof(struct hidpp_report),
204 GFP_KERNEL);
205 int ret;
206
207 if (param_count > sizeof(message->fap.params))
208 return -EINVAL;
209
210 message->report_id = REPORT_ID_HIDPP_LONG;
211 message->fap.feature_index = feat_index;
212 message->fap.funcindex_clientid = funcindex_clientid;
213 memcpy(&message->fap.params, params, param_count);
214
215 ret = hidpp_send_message_sync(hidpp, message, response);
216 kfree(message);
217 return ret;
218}
219
Benjamin Tissoires33797822014-09-30 13:18:30 -0400220static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev,
221 u8 report_id, u8 sub_id, u8 reg_address, u8 *params, int param_count,
222 struct hidpp_report *response)
223{
224 struct hidpp_report *message = kzalloc(sizeof(struct hidpp_report),
225 GFP_KERNEL);
226 int ret;
227
228 if ((report_id != REPORT_ID_HIDPP_SHORT) &&
229 (report_id != REPORT_ID_HIDPP_LONG))
230 return -EINVAL;
231
232 if (param_count > sizeof(message->rap.params))
233 return -EINVAL;
234
235 message->report_id = report_id;
236 message->rap.sub_id = sub_id;
237 message->rap.reg_address = reg_address;
238 memcpy(&message->rap.params, params, param_count);
239
240 ret = hidpp_send_message_sync(hidpp_dev, message, response);
241 kfree(message);
242 return ret;
243}
244
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400245static void delayed_work_cb(struct work_struct *work)
246{
247 struct hidpp_device *hidpp = container_of(work, struct hidpp_device,
248 work);
249 hidpp_connect_event(hidpp);
250}
251
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400252static inline bool hidpp_match_answer(struct hidpp_report *question,
253 struct hidpp_report *answer)
254{
255 return (answer->fap.feature_index == question->fap.feature_index) &&
256 (answer->fap.funcindex_clientid == question->fap.funcindex_clientid);
257}
258
259static inline bool hidpp_match_error(struct hidpp_report *question,
260 struct hidpp_report *answer)
261{
262 return (answer->fap.feature_index == HIDPP_ERROR) &&
263 (answer->fap.funcindex_clientid == question->fap.feature_index) &&
264 (answer->fap.params[0] == question->fap.funcindex_clientid);
265}
266
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400267static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
268{
269 return (report->report_id == REPORT_ID_HIDPP_SHORT) &&
270 (report->rap.sub_id == 0x41);
271}
272
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400273/* -------------------------------------------------------------------------- */
Benjamin Tissoires33797822014-09-30 13:18:30 -0400274/* HIDP++ 1.0 commands */
275/* -------------------------------------------------------------------------- */
276
277#define HIDPP_SET_REGISTER 0x80
278#define HIDPP_GET_REGISTER 0x81
279#define HIDPP_SET_LONG_REGISTER 0x82
280#define HIDPP_GET_LONG_REGISTER 0x83
281
282#define HIDPP_REG_PAIRING_INFORMATION 0xB5
283#define DEVICE_NAME 0x40
284
285static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)
286{
287 struct hidpp_report response;
288 int ret;
289 /* hid-logitech-dj is in charge of setting the right device index */
290 u8 params[1] = { DEVICE_NAME };
291 char *name;
292 int len;
293
294 ret = hidpp_send_rap_command_sync(hidpp_dev,
295 REPORT_ID_HIDPP_SHORT,
296 HIDPP_GET_LONG_REGISTER,
297 HIDPP_REG_PAIRING_INFORMATION,
298 params, 1, &response);
299 if (ret)
300 return NULL;
301
302 len = response.rap.params[1];
303
304 name = kzalloc(len + 1, GFP_KERNEL);
305 if (!name)
306 return NULL;
307
308 memcpy(name, &response.rap.params[2], len);
309 return name;
310}
311
312/* -------------------------------------------------------------------------- */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400313/* 0x0000: Root */
314/* -------------------------------------------------------------------------- */
315
316#define HIDPP_PAGE_ROOT 0x0000
317#define HIDPP_PAGE_ROOT_IDX 0x00
318
319#define CMD_ROOT_GET_FEATURE 0x01
320#define CMD_ROOT_GET_PROTOCOL_VERSION 0x11
321
322static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature,
323 u8 *feature_index, u8 *feature_type)
324{
325 struct hidpp_report response;
326 int ret;
327 u8 params[2] = { feature >> 8, feature & 0x00FF };
328
329 ret = hidpp_send_fap_command_sync(hidpp,
330 HIDPP_PAGE_ROOT_IDX,
331 CMD_ROOT_GET_FEATURE,
332 params, 2, &response);
333 if (ret)
334 return ret;
335
336 *feature_index = response.fap.params[0];
337 *feature_type = response.fap.params[1];
338
339 return ret;
340}
341
342static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
343{
344 struct hidpp_report response;
345 int ret;
346
347 ret = hidpp_send_fap_command_sync(hidpp,
348 HIDPP_PAGE_ROOT_IDX,
349 CMD_ROOT_GET_PROTOCOL_VERSION,
350 NULL, 0, &response);
351
352 if (ret == 1) {
353 hidpp->protocol_major = 1;
354 hidpp->protocol_minor = 0;
355 return 0;
356 }
357
358 if (ret)
359 return -ret;
360
361 hidpp->protocol_major = response.fap.params[0];
362 hidpp->protocol_minor = response.fap.params[1];
363
364 return ret;
365}
366
367static bool hidpp_is_connected(struct hidpp_device *hidpp)
368{
369 int ret;
370
371 ret = hidpp_root_get_protocol_version(hidpp);
372 if (!ret)
373 hid_dbg(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
374 hidpp->protocol_major, hidpp->protocol_minor);
375 return ret == 0;
376}
377
378/* -------------------------------------------------------------------------- */
379/* 0x0005: GetDeviceNameType */
380/* -------------------------------------------------------------------------- */
381
382#define HIDPP_PAGE_GET_DEVICE_NAME_TYPE 0x0005
383
384#define CMD_GET_DEVICE_NAME_TYPE_GET_COUNT 0x01
385#define CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11
386#define CMD_GET_DEVICE_NAME_TYPE_GET_TYPE 0x21
387
388static int hidpp_devicenametype_get_count(struct hidpp_device *hidpp,
389 u8 feature_index, u8 *nameLength)
390{
391 struct hidpp_report response;
392 int ret;
393
394 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
395 CMD_GET_DEVICE_NAME_TYPE_GET_COUNT, NULL, 0, &response);
396
397 if (ret)
398 return -ret;
399
400 *nameLength = response.fap.params[0];
401
402 return ret;
403}
404
405static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp,
406 u8 feature_index, u8 char_index, char *device_name, int len_buf)
407{
408 struct hidpp_report response;
409 int ret, i;
410 int count;
411
412 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
413 CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME, &char_index, 1,
414 &response);
415
416 if (ret)
417 return -ret;
418
419 if (response.report_id == REPORT_ID_HIDPP_LONG)
420 count = HIDPP_REPORT_LONG_LENGTH - 4;
421 else
422 count = HIDPP_REPORT_SHORT_LENGTH - 4;
423
424 if (len_buf < count)
425 count = len_buf;
426
427 for (i = 0; i < count; i++)
428 device_name[i] = response.fap.params[i];
429
430 return count;
431}
432
433static char *hidpp_get_device_name(struct hidpp_device *hidpp, u8 *name_length)
434{
435 u8 feature_type;
436 u8 feature_index;
437 u8 __name_length;
438 char *name;
439 unsigned index = 0;
440 int ret;
441
442 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_GET_DEVICE_NAME_TYPE,
443 &feature_index, &feature_type);
444 if (ret)
445 goto out_err;
446
447 ret = hidpp_devicenametype_get_count(hidpp, feature_index,
448 &__name_length);
449 if (ret)
450 goto out_err;
451
452 name = kzalloc(__name_length + 1, GFP_KERNEL);
453 if (!name)
454 goto out_err;
455
456 *name_length = __name_length + 1;
457 while (index < __name_length)
458 index += hidpp_devicenametype_get_device_name(hidpp,
459 feature_index, index, name + index,
460 __name_length - index);
461
462 return name;
463
464out_err:
465 *name_length = 0;
466 return NULL;
467}
468
469/* -------------------------------------------------------------------------- */
470/* 0x6100: TouchPadRawXY */
471/* -------------------------------------------------------------------------- */
472
473#define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100
474
475#define CMD_TOUCHPAD_GET_RAW_INFO 0x01
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400476#define CMD_TOUCHPAD_SET_RAW_REPORT_STATE 0x21
477
478#define EVENT_TOUCHPAD_RAW_XY 0x00
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400479
480#define TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT 0x01
481#define TOUCHPAD_RAW_XY_ORIGIN_UPPER_LEFT 0x03
482
483struct hidpp_touchpad_raw_info {
484 u16 x_size;
485 u16 y_size;
486 u8 z_range;
487 u8 area_range;
488 u8 timestamp_unit;
489 u8 maxcontacts;
490 u8 origin;
491 u16 res;
492};
493
494struct hidpp_touchpad_raw_xy_finger {
495 u8 contact_type;
496 u8 contact_status;
497 u16 x;
498 u16 y;
499 u8 z;
500 u8 area;
501 u8 finger_id;
502};
503
504struct hidpp_touchpad_raw_xy {
505 u16 timestamp;
506 struct hidpp_touchpad_raw_xy_finger fingers[2];
507 u8 spurious_flag;
508 u8 end_of_frame;
509 u8 finger_count;
510 u8 button;
511};
512
513static int hidpp_touchpad_get_raw_info(struct hidpp_device *hidpp,
514 u8 feature_index, struct hidpp_touchpad_raw_info *raw_info)
515{
516 struct hidpp_report response;
517 int ret;
518 u8 *params = (u8 *)response.fap.params;
519
520 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
521 CMD_TOUCHPAD_GET_RAW_INFO, NULL, 0, &response);
522
523 if (ret)
524 return -ret;
525
526 raw_info->x_size = get_unaligned_be16(&params[0]);
527 raw_info->y_size = get_unaligned_be16(&params[2]);
528 raw_info->z_range = params[4];
529 raw_info->area_range = params[5];
530 raw_info->maxcontacts = params[7];
531 raw_info->origin = params[8];
532 /* res is given in unit per inch */
533 raw_info->res = get_unaligned_be16(&params[13]) * 2 / 51;
534
535 return ret;
536}
537
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400538static int hidpp_touchpad_set_raw_report_state(struct hidpp_device *hidpp_dev,
539 u8 feature_index, bool send_raw_reports,
540 bool sensor_enhanced_settings)
541{
542 struct hidpp_report response;
543
544 /*
545 * Params:
546 * bit 0 - enable raw
547 * bit 1 - 16bit Z, no area
548 * bit 2 - enhanced sensitivity
549 * bit 3 - width, height (4 bits each) instead of area
550 * bit 4 - send raw + gestures (degrades smoothness)
551 * remaining bits - reserved
552 */
553 u8 params = send_raw_reports | (sensor_enhanced_settings << 2);
554
555 return hidpp_send_fap_command_sync(hidpp_dev, feature_index,
556 CMD_TOUCHPAD_SET_RAW_REPORT_STATE, &params, 1, &response);
557}
558
559static void hidpp_touchpad_touch_event(u8 *data,
560 struct hidpp_touchpad_raw_xy_finger *finger)
561{
562 u8 x_m = data[0] << 2;
563 u8 y_m = data[2] << 2;
564
565 finger->x = x_m << 6 | data[1];
566 finger->y = y_m << 6 | data[3];
567
568 finger->contact_type = data[0] >> 6;
569 finger->contact_status = data[2] >> 6;
570
571 finger->z = data[4];
572 finger->area = data[5];
573 finger->finger_id = data[6] >> 4;
574}
575
576static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev,
577 u8 *data, struct hidpp_touchpad_raw_xy *raw_xy)
578{
579 memset(raw_xy, 0, sizeof(struct hidpp_touchpad_raw_xy));
580 raw_xy->end_of_frame = data[8] & 0x01;
581 raw_xy->spurious_flag = (data[8] >> 1) & 0x01;
582 raw_xy->finger_count = data[15] & 0x0f;
583 raw_xy->button = (data[8] >> 2) & 0x01;
584
585 if (raw_xy->finger_count) {
586 hidpp_touchpad_touch_event(&data[2], &raw_xy->fingers[0]);
587 hidpp_touchpad_touch_event(&data[9], &raw_xy->fingers[1]);
588 }
589}
590
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400591/* ************************************************************************** */
592/* */
593/* Device Support */
594/* */
595/* ************************************************************************** */
596
597/* -------------------------------------------------------------------------- */
598/* Touchpad HID++ devices */
599/* -------------------------------------------------------------------------- */
600
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400601#define WTP_MANUAL_RESOLUTION 39
602
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400603struct wtp_data {
604 struct input_dev *input;
605 u16 x_size, y_size;
606 u8 finger_count;
607 u8 mt_feature_index;
608 u8 button_feature_index;
609 u8 maxcontacts;
610 bool flip_y;
611 unsigned int resolution;
612};
613
614static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
615 struct hid_field *field, struct hid_usage *usage,
616 unsigned long **bit, int *max)
617{
Benjamin Tissoires3a61e972014-09-30 13:18:35 -0400618 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
619
620 if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) &&
621 (field->application == HID_GD_KEYBOARD))
622 return 0;
623
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400624 return -1;
625}
626
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400627static void wtp_populate_input(struct hidpp_device *hidpp,
628 struct input_dev *input_dev, bool origin_is_hid_core)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400629{
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400630 struct wtp_data *wd = hidpp->private_data;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400631
Benjamin Tissoires3a61e972014-09-30 13:18:35 -0400632 if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && origin_is_hid_core)
633 /* this is the generic hid-input call */
634 return;
635
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400636 __set_bit(EV_ABS, input_dev->evbit);
637 __set_bit(EV_KEY, input_dev->evbit);
638 __clear_bit(EV_REL, input_dev->evbit);
639 __clear_bit(EV_LED, input_dev->evbit);
640
641 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, wd->x_size, 0, 0);
642 input_abs_set_res(input_dev, ABS_MT_POSITION_X, wd->resolution);
643 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, wd->y_size, 0, 0);
644 input_abs_set_res(input_dev, ABS_MT_POSITION_Y, wd->resolution);
645
646 /* Max pressure is not given by the devices, pick one */
647 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 50, 0, 0);
648
649 input_set_capability(input_dev, EV_KEY, BTN_LEFT);
650
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400651 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS)
652 input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
653 else
654 __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400655
656 input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER |
657 INPUT_MT_DROP_UNUSED);
658
659 wd->input = input_dev;
660}
661
662static void wtp_touch_event(struct wtp_data *wd,
663 struct hidpp_touchpad_raw_xy_finger *touch_report)
664{
665 int slot;
666
667 if (!touch_report->finger_id || touch_report->contact_type)
668 /* no actual data */
669 return;
670
671 slot = input_mt_get_slot_by_key(wd->input, touch_report->finger_id);
672
673 input_mt_slot(wd->input, slot);
674 input_mt_report_slot_state(wd->input, MT_TOOL_FINGER,
675 touch_report->contact_status);
676 if (touch_report->contact_status) {
677 input_event(wd->input, EV_ABS, ABS_MT_POSITION_X,
678 touch_report->x);
679 input_event(wd->input, EV_ABS, ABS_MT_POSITION_Y,
680 wd->flip_y ? wd->y_size - touch_report->y :
681 touch_report->y);
682 input_event(wd->input, EV_ABS, ABS_MT_PRESSURE,
683 touch_report->area);
684 }
685}
686
687static void wtp_send_raw_xy_event(struct hidpp_device *hidpp,
688 struct hidpp_touchpad_raw_xy *raw)
689{
690 struct wtp_data *wd = hidpp->private_data;
691 int i;
692
693 for (i = 0; i < 2; i++)
694 wtp_touch_event(wd, &(raw->fingers[i]));
695
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400696 if (raw->end_of_frame &&
697 !(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS))
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400698 input_event(wd->input, EV_KEY, BTN_LEFT, raw->button);
699
700 if (raw->end_of_frame || raw->finger_count <= 2) {
701 input_mt_sync_frame(wd->input);
702 input_sync(wd->input);
703 }
704}
705
706static int wtp_mouse_raw_xy_event(struct hidpp_device *hidpp, u8 *data)
707{
708 struct wtp_data *wd = hidpp->private_data;
709 u8 c1_area = ((data[7] & 0xf) * (data[7] & 0xf) +
710 (data[7] >> 4) * (data[7] >> 4)) / 2;
711 u8 c2_area = ((data[13] & 0xf) * (data[13] & 0xf) +
712 (data[13] >> 4) * (data[13] >> 4)) / 2;
713 struct hidpp_touchpad_raw_xy raw = {
714 .timestamp = data[1],
715 .fingers = {
716 {
717 .contact_type = 0,
718 .contact_status = !!data[7],
719 .x = get_unaligned_le16(&data[3]),
720 .y = get_unaligned_le16(&data[5]),
721 .z = c1_area,
722 .area = c1_area,
723 .finger_id = data[2],
724 }, {
725 .contact_type = 0,
726 .contact_status = !!data[13],
727 .x = get_unaligned_le16(&data[9]),
728 .y = get_unaligned_le16(&data[11]),
729 .z = c2_area,
730 .area = c2_area,
731 .finger_id = data[8],
732 }
733 },
734 .finger_count = wd->maxcontacts,
735 .spurious_flag = 0,
736 .end_of_frame = (data[0] >> 7) == 0,
737 .button = data[0] & 0x01,
738 };
739
740 wtp_send_raw_xy_event(hidpp, &raw);
741
742 return 1;
743}
744
745static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
746{
747 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
748 struct wtp_data *wd = hidpp->private_data;
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400749 struct hidpp_report *report = (struct hidpp_report *)data;
750 struct hidpp_touchpad_raw_xy raw;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400751
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400752 if (!wd || !wd->input)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400753 return 1;
754
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400755 switch (data[0]) {
756 case 0x02:
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400757 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
758 input_event(wd->input, EV_KEY, BTN_LEFT,
759 !!(data[1] & 0x01));
760 input_event(wd->input, EV_KEY, BTN_RIGHT,
761 !!(data[1] & 0x02));
762 input_sync(wd->input);
763 } else {
764 if (size < 21)
765 return 1;
766 return wtp_mouse_raw_xy_event(hidpp, &data[7]);
767 }
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400768 case REPORT_ID_HIDPP_LONG:
769 if ((report->fap.feature_index != wd->mt_feature_index) ||
770 (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
771 return 1;
772 hidpp_touchpad_raw_xy_event(hidpp, data + 4, &raw);
773
774 wtp_send_raw_xy_event(hidpp, &raw);
775 return 0;
776 }
777
778 return 0;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400779}
780
781static int wtp_get_config(struct hidpp_device *hidpp)
782{
783 struct wtp_data *wd = hidpp->private_data;
784 struct hidpp_touchpad_raw_info raw_info = {0};
785 u8 feature_type;
786 int ret;
787
788 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_TOUCHPAD_RAW_XY,
789 &wd->mt_feature_index, &feature_type);
790 if (ret)
791 /* means that the device is not powered up */
792 return ret;
793
794 ret = hidpp_touchpad_get_raw_info(hidpp, wd->mt_feature_index,
795 &raw_info);
796 if (ret)
797 return ret;
798
799 wd->x_size = raw_info.x_size;
800 wd->y_size = raw_info.y_size;
801 wd->maxcontacts = raw_info.maxcontacts;
802 wd->flip_y = raw_info.origin == TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT;
803 wd->resolution = raw_info.res;
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400804 if (!wd->resolution)
805 wd->resolution = WTP_MANUAL_RESOLUTION;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400806
807 return 0;
808}
809
810static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id)
811{
812 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
813 struct wtp_data *wd;
814
815 wd = devm_kzalloc(&hdev->dev, sizeof(struct wtp_data),
816 GFP_KERNEL);
817 if (!wd)
818 return -ENOMEM;
819
820 hidpp->private_data = wd;
821
822 return 0;
823};
824
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400825static void wtp_connect(struct hid_device *hdev, bool connected)
826{
827 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
828 struct wtp_data *wd = hidpp->private_data;
829 int ret;
830
831 if (!connected)
832 return;
833
834 if (!wd->x_size) {
835 ret = wtp_get_config(hidpp);
836 if (ret) {
837 hid_err(hdev, "Can not get wtp config: %d\n", ret);
838 return;
839 }
840 }
841
842 hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index,
843 true, true);
844}
845
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400846/* -------------------------------------------------------------------------- */
847/* Generic HID++ devices */
848/* -------------------------------------------------------------------------- */
849
850static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
851 struct hid_field *field, struct hid_usage *usage,
852 unsigned long **bit, int *max)
853{
854 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
855
856 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
857 return wtp_input_mapping(hdev, hi, field, usage, bit, max);
858
859 return 0;
860}
861
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400862static void hidpp_populate_input(struct hidpp_device *hidpp,
863 struct input_dev *input, bool origin_is_hid_core)
864{
865 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
866 wtp_populate_input(hidpp, input, origin_is_hid_core);
867}
868
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400869static void hidpp_input_configured(struct hid_device *hdev,
870 struct hid_input *hidinput)
871{
872 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400873 struct input_dev *input = hidinput->input;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400874
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400875 hidpp_populate_input(hidpp, input, true);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400876}
877
878static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
879 int size)
880{
881 struct hidpp_report *question = hidpp->send_receive_buf;
882 struct hidpp_report *answer = hidpp->send_receive_buf;
883 struct hidpp_report *report = (struct hidpp_report *)data;
884
885 /*
886 * If the mutex is locked then we have a pending answer from a
887 * previoulsly sent command
888 */
889 if (unlikely(mutex_is_locked(&hidpp->send_mutex))) {
890 /*
891 * Check for a correct hidpp20 answer or the corresponding
892 * error
893 */
894 if (hidpp_match_answer(question, report) ||
895 hidpp_match_error(question, report)) {
896 *answer = *report;
897 hidpp->answer_available = true;
898 wake_up(&hidpp->wait);
899 /*
900 * This was an answer to a command that this driver sent
901 * We return 1 to hid-core to avoid forwarding the
902 * command upstream as it has been treated by the driver
903 */
904
905 return 1;
906 }
907 }
908
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400909 if (unlikely(hidpp_report_is_connect_event(report))) {
910 atomic_set(&hidpp->connected,
911 !(report->rap.params[0] & (1 << 6)));
912 if ((hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) &&
913 (schedule_work(&hidpp->work) == 0))
914 dbg_hid("%s: connect event already queued\n", __func__);
915 return 1;
916 }
917
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400918 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
919 return wtp_raw_event(hidpp->hid_dev, data, size);
920
921 return 0;
922}
923
924static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
925 u8 *data, int size)
926{
927 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
928
929 switch (data[0]) {
930 case REPORT_ID_HIDPP_LONG:
931 if (size != HIDPP_REPORT_LONG_LENGTH) {
932 hid_err(hdev, "received hid++ report of bad size (%d)",
933 size);
934 return 1;
935 }
936 return hidpp_raw_hidpp_event(hidpp, data, size);
937 case REPORT_ID_HIDPP_SHORT:
938 if (size != HIDPP_REPORT_SHORT_LENGTH) {
939 hid_err(hdev, "received hid++ report of bad size (%d)",
940 size);
941 return 1;
942 }
943 return hidpp_raw_hidpp_event(hidpp, data, size);
944 }
945
946 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
947 return wtp_raw_event(hdev, data, size);
948
949 return 0;
950}
951
Benjamin Tissoires33797822014-09-30 13:18:30 -0400952static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400953{
954 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
955 char *name;
956 u8 name_length;
957
Benjamin Tissoires33797822014-09-30 13:18:30 -0400958 if (use_unifying)
959 /*
960 * the device is connected through an Unifying receiver, and
961 * might not be already connected.
962 * Ask the receiver for its name.
963 */
964 name = hidpp_get_unifying_name(hidpp);
965 else
966 name = hidpp_get_device_name(hidpp, &name_length);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400967
968 if (!name)
969 hid_err(hdev, "unable to retrieve the name of the device");
970 else
971 snprintf(hdev->name, sizeof(hdev->name), "%s", name);
972
973 kfree(name);
974}
975
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400976static int hidpp_input_open(struct input_dev *dev)
977{
978 struct hid_device *hid = input_get_drvdata(dev);
979
980 return hid_hw_open(hid);
981}
982
983static void hidpp_input_close(struct input_dev *dev)
984{
985 struct hid_device *hid = input_get_drvdata(dev);
986
987 hid_hw_close(hid);
988}
989
990static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
991{
992 struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev);
993
994 if (!input_dev)
995 return NULL;
996
997 input_set_drvdata(input_dev, hdev);
998 input_dev->open = hidpp_input_open;
999 input_dev->close = hidpp_input_close;
1000
1001 input_dev->name = hdev->name;
1002 input_dev->phys = hdev->phys;
1003 input_dev->uniq = hdev->uniq;
1004 input_dev->id.bustype = hdev->bus;
1005 input_dev->id.vendor = hdev->vendor;
1006 input_dev->id.product = hdev->product;
1007 input_dev->id.version = hdev->version;
1008 input_dev->dev.parent = &hdev->dev;
1009
1010 return input_dev;
1011}
1012
1013static void hidpp_connect_event(struct hidpp_device *hidpp)
1014{
1015 struct hid_device *hdev = hidpp->hid_dev;
1016 int ret = 0;
1017 bool connected = atomic_read(&hidpp->connected);
1018 struct input_dev *input;
1019 char *name, *devm_name;
1020 u8 name_length;
1021
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001022 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
1023 wtp_connect(hdev, connected);
1024
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001025 if (!connected || hidpp->delayed_input)
1026 return;
1027
1028 if (!hidpp->protocol_major) {
1029 ret = !hidpp_is_connected(hidpp);
1030 if (ret) {
1031 hid_err(hdev, "Can not get the protocol version.\n");
1032 return;
1033 }
1034 }
1035
1036 /* the device is already connected, we can ask for its name and
1037 * protocol */
1038 hid_info(hdev, "HID++ %u.%u device connected.\n",
1039 hidpp->protocol_major, hidpp->protocol_minor);
1040
1041 input = hidpp_allocate_input(hdev);
1042 if (!input) {
1043 hid_err(hdev, "cannot allocate new input device: %d\n", ret);
1044 return;
1045 }
1046
1047 name = hidpp_get_device_name(hidpp, &name_length);
1048 if (!name) {
1049 hid_err(hdev, "unable to retrieve the name of the device");
1050 } else {
1051 devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
1052 if (devm_name)
1053 input->name = devm_name;
1054 kfree(name);
1055 }
1056
1057 hidpp_populate_input(hidpp, input, false);
1058
1059 ret = input_register_device(input);
1060 if (ret)
1061 input_free_device(input);
1062
1063 hidpp->delayed_input = input;
1064}
1065
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001066static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
1067{
1068 struct hidpp_device *hidpp;
1069 int ret;
1070 bool connected;
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001071 unsigned int connect_mask = HID_CONNECT_DEFAULT;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001072
1073 hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device),
1074 GFP_KERNEL);
1075 if (!hidpp)
1076 return -ENOMEM;
1077
1078 hidpp->hid_dev = hdev;
1079 hid_set_drvdata(hdev, hidpp);
1080
1081 hidpp->quirks = id->driver_data;
1082
1083 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
1084 ret = wtp_allocate(hdev, id);
1085 if (ret)
1086 return ret;
1087 }
1088
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001089 INIT_WORK(&hidpp->work, delayed_work_cb);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001090 mutex_init(&hidpp->send_mutex);
1091 init_waitqueue_head(&hidpp->wait);
1092
1093 ret = hid_parse(hdev);
1094 if (ret) {
1095 hid_err(hdev, "%s:parse failed\n", __func__);
1096 goto hid_parse_fail;
1097 }
1098
1099 /* Allow incoming packets */
1100 hid_device_io_start(hdev);
1101
1102 connected = hidpp_is_connected(hidpp);
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001103 if (id->group != HID_GROUP_LOGITECH_DJ_DEVICE) {
1104 if (!connected) {
1105 hid_err(hdev, "Device not connected");
1106 goto hid_parse_fail;
1107 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001108
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001109 hid_info(hdev, "HID++ %u.%u device connected.\n",
1110 hidpp->protocol_major, hidpp->protocol_minor);
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001111 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001112
Benjamin Tissoires33797822014-09-30 13:18:30 -04001113 hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001114 atomic_set(&hidpp->connected, connected);
Benjamin Tissoires33797822014-09-30 13:18:30 -04001115
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001116 if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001117 ret = wtp_get_config(hidpp);
1118 if (ret)
1119 goto hid_parse_fail;
1120 }
1121
1122 /* Block incoming packets */
1123 hid_device_io_stop(hdev);
1124
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001125 if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT)
1126 connect_mask &= ~HID_CONNECT_HIDINPUT;
1127
Benjamin Tissoires3a61e972014-09-30 13:18:35 -04001128 /* Re-enable hidinput for multi-input devices */
1129 if (hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT)
1130 connect_mask |= HID_CONNECT_HIDINPUT;
1131
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001132 ret = hid_hw_start(hdev, connect_mask);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001133 if (ret) {
1134 hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
1135 goto hid_hw_start_fail;
1136 }
1137
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001138 if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) {
1139 /* Allow incoming packets */
1140 hid_device_io_start(hdev);
1141
1142 hidpp_connect_event(hidpp);
1143 }
1144
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001145 return ret;
1146
1147hid_hw_start_fail:
1148hid_parse_fail:
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001149 cancel_work_sync(&hidpp->work);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001150 mutex_destroy(&hidpp->send_mutex);
1151 hid_set_drvdata(hdev, NULL);
1152 return ret;
1153}
1154
1155static void hidpp_remove(struct hid_device *hdev)
1156{
1157 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1158
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001159 cancel_work_sync(&hidpp->work);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001160 mutex_destroy(&hidpp->send_mutex);
1161 hid_hw_stop(hdev);
1162}
1163
1164static const struct hid_device_id hidpp_devices[] = {
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04001165 { /* wireless touchpad */
1166 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1167 USB_VENDOR_ID_LOGITECH, 0x4011),
1168 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
1169 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001170 { /* wireless touchpad T650 */
1171 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1172 USB_VENDOR_ID_LOGITECH, 0x4101),
1173 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001174 { /* wireless touchpad T651 */
1175 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
1176 USB_DEVICE_ID_LOGITECH_T651),
1177 .driver_data = HIDPP_QUIRK_CLASS_WTP },
Benjamin Tissoires3a61e972014-09-30 13:18:35 -04001178 { /* Keyboard TK820 */
1179 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1180 USB_VENDOR_ID_LOGITECH, 0x4102),
1181 .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_MULTI_INPUT |
1182 HIDPP_QUIRK_CLASS_WTP },
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001183
1184 { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1185 USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001186 {}
1187};
1188
1189MODULE_DEVICE_TABLE(hid, hidpp_devices);
1190
1191static struct hid_driver hidpp_driver = {
1192 .name = "logitech-hidpp-device",
1193 .id_table = hidpp_devices,
1194 .probe = hidpp_probe,
1195 .remove = hidpp_remove,
1196 .raw_event = hidpp_raw_event,
1197 .input_configured = hidpp_input_configured,
1198 .input_mapping = hidpp_input_mapping,
1199};
1200
1201module_hid_driver(hidpp_driver);