blob: 394a6f41af0909780136a4d1dcb1b0c37062b5c7 [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
Benjamin Tissoires9188dba2015-03-26 12:41:57 -040031static bool disable_raw_mode;
32module_param(disable_raw_mode, bool, 0644);
33MODULE_PARM_DESC(disable_raw_mode,
34 "Disable Raw mode reporting for touchpads and keep firmware gestures.");
35
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040036#define REPORT_ID_HIDPP_SHORT 0x10
37#define REPORT_ID_HIDPP_LONG 0x11
38
39#define HIDPP_REPORT_SHORT_LENGTH 7
40#define HIDPP_REPORT_LONG_LENGTH 20
41
42#define HIDPP_QUIRK_CLASS_WTP BIT(0)
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +020043#define HIDPP_QUIRK_CLASS_M560 BIT(1)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040044
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +020045/* bits 2..20 are reserved for classes */
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -040046#define HIDPP_QUIRK_DELAYED_INIT BIT(21)
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -040047#define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22)
Benjamin Tissoires3a61e972014-09-30 13:18:35 -040048#define HIDPP_QUIRK_MULTI_INPUT BIT(23)
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -040049
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040050/*
51 * There are two hidpp protocols in use, the first version hidpp10 is known
52 * as register access protocol or RAP, the second version hidpp20 is known as
53 * feature access protocol or FAP
54 *
55 * Most older devices (including the Unifying usb receiver) use the RAP protocol
56 * where as most newer devices use the FAP protocol. Both protocols are
57 * compatible with the underlying transport, which could be usb, Unifiying, or
58 * bluetooth. The message lengths are defined by the hid vendor specific report
59 * descriptor for the HIDPP_SHORT report type (total message lenth 7 bytes) and
60 * the HIDPP_LONG report type (total message length 20 bytes)
61 *
62 * The RAP protocol uses both report types, whereas the FAP only uses HIDPP_LONG
63 * messages. The Unifying receiver itself responds to RAP messages (device index
64 * is 0xFF for the receiver), and all messages (short or long) with a device
65 * index between 1 and 6 are passed untouched to the corresponding paired
66 * Unifying device.
67 *
68 * The paired device can be RAP or FAP, it will receive the message untouched
69 * from the Unifiying receiver.
70 */
71
72struct fap {
73 u8 feature_index;
74 u8 funcindex_clientid;
75 u8 params[HIDPP_REPORT_LONG_LENGTH - 4U];
76};
77
78struct rap {
79 u8 sub_id;
80 u8 reg_address;
81 u8 params[HIDPP_REPORT_LONG_LENGTH - 4U];
82};
83
84struct hidpp_report {
85 u8 report_id;
86 u8 device_index;
87 union {
88 struct fap fap;
89 struct rap rap;
90 u8 rawbytes[sizeof(struct fap)];
91 };
92} __packed;
93
94struct hidpp_device {
95 struct hid_device *hid_dev;
96 struct mutex send_mutex;
97 void *send_receive_buf;
Benjamin Tissoires005b3f52015-01-08 14:37:12 -050098 char *name; /* will never be NULL and should not be freed */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040099 wait_queue_head_t wait;
100 bool answer_available;
101 u8 protocol_major;
102 u8 protocol_minor;
103
104 void *private_data;
105
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400106 struct work_struct work;
107 struct kfifo delayed_work_fifo;
108 atomic_t connected;
109 struct input_dev *delayed_input;
110
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400111 unsigned long quirks;
112};
113
114
Peter Wuf677bb12014-12-16 01:50:14 +0100115/* HID++ 1.0 error codes */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400116#define HIDPP_ERROR 0x8f
117#define HIDPP_ERROR_SUCCESS 0x00
118#define HIDPP_ERROR_INVALID_SUBID 0x01
119#define HIDPP_ERROR_INVALID_ADRESS 0x02
120#define HIDPP_ERROR_INVALID_VALUE 0x03
121#define HIDPP_ERROR_CONNECT_FAIL 0x04
122#define HIDPP_ERROR_TOO_MANY_DEVICES 0x05
123#define HIDPP_ERROR_ALREADY_EXISTS 0x06
124#define HIDPP_ERROR_BUSY 0x07
125#define HIDPP_ERROR_UNKNOWN_DEVICE 0x08
126#define HIDPP_ERROR_RESOURCE_ERROR 0x09
127#define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a
128#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b
129#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c
Peter Wuf677bb12014-12-16 01:50:14 +0100130/* HID++ 2.0 error codes */
131#define HIDPP20_ERROR 0xff
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400132
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400133static void hidpp_connect_event(struct hidpp_device *hidpp_dev);
134
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400135static int __hidpp_send_report(struct hid_device *hdev,
136 struct hidpp_report *hidpp_report)
137{
138 int fields_count, ret;
139
140 switch (hidpp_report->report_id) {
141 case REPORT_ID_HIDPP_SHORT:
142 fields_count = HIDPP_REPORT_SHORT_LENGTH;
143 break;
144 case REPORT_ID_HIDPP_LONG:
145 fields_count = HIDPP_REPORT_LONG_LENGTH;
146 break;
147 default:
148 return -ENODEV;
149 }
150
151 /*
152 * set the device_index as the receiver, it will be overwritten by
153 * hid_hw_request if needed
154 */
155 hidpp_report->device_index = 0xff;
156
157 ret = hid_hw_raw_request(hdev, hidpp_report->report_id,
158 (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT,
159 HID_REQ_SET_REPORT);
160
161 return ret == fields_count ? 0 : -1;
162}
163
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500164/**
165 * hidpp_send_message_sync() returns 0 in case of success, and something else
166 * in case of a failure.
167 * - If ' something else' is positive, that means that an error has been raised
168 * by the protocol itself.
169 * - If ' something else' is negative, that means that we had a classic error
170 * (-ENOMEM, -EPIPE, etc...)
171 */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400172static int hidpp_send_message_sync(struct hidpp_device *hidpp,
173 struct hidpp_report *message,
174 struct hidpp_report *response)
175{
176 int ret;
177
178 mutex_lock(&hidpp->send_mutex);
179
180 hidpp->send_receive_buf = response;
181 hidpp->answer_available = false;
182
183 /*
184 * So that we can later validate the answer when it arrives
185 * in hidpp_raw_event
186 */
187 *response = *message;
188
189 ret = __hidpp_send_report(hidpp->hid_dev, message);
190
191 if (ret) {
192 dbg_hid("__hidpp_send_report returned err: %d\n", ret);
193 memset(response, 0, sizeof(struct hidpp_report));
194 goto exit;
195 }
196
197 if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
198 5*HZ)) {
199 dbg_hid("%s:timeout waiting for response\n", __func__);
200 memset(response, 0, sizeof(struct hidpp_report));
201 ret = -ETIMEDOUT;
202 }
203
204 if (response->report_id == REPORT_ID_HIDPP_SHORT &&
Peter Wuf677bb12014-12-16 01:50:14 +0100205 response->rap.sub_id == HIDPP_ERROR) {
206 ret = response->rap.params[1];
207 dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
208 goto exit;
209 }
210
211 if (response->report_id == REPORT_ID_HIDPP_LONG &&
212 response->fap.feature_index == HIDPP20_ERROR) {
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400213 ret = response->fap.params[1];
Peter Wuf677bb12014-12-16 01:50:14 +0100214 dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400215 goto exit;
216 }
217
218exit:
219 mutex_unlock(&hidpp->send_mutex);
220 return ret;
221
222}
223
224static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp,
225 u8 feat_index, u8 funcindex_clientid, u8 *params, int param_count,
226 struct hidpp_report *response)
227{
Dan Carpenter3e7830c2014-10-31 12:14:39 +0300228 struct hidpp_report *message;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400229 int ret;
230
231 if (param_count > sizeof(message->fap.params))
232 return -EINVAL;
233
Dan Carpenter3e7830c2014-10-31 12:14:39 +0300234 message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL);
235 if (!message)
236 return -ENOMEM;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400237 message->report_id = REPORT_ID_HIDPP_LONG;
238 message->fap.feature_index = feat_index;
239 message->fap.funcindex_clientid = funcindex_clientid;
240 memcpy(&message->fap.params, params, param_count);
241
242 ret = hidpp_send_message_sync(hidpp, message, response);
243 kfree(message);
244 return ret;
245}
246
Benjamin Tissoires33797822014-09-30 13:18:30 -0400247static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev,
248 u8 report_id, u8 sub_id, u8 reg_address, u8 *params, int param_count,
249 struct hidpp_report *response)
250{
Dan Carpenter3e7830c2014-10-31 12:14:39 +0300251 struct hidpp_report *message;
Benjamin Tissoires33797822014-09-30 13:18:30 -0400252 int ret;
253
254 if ((report_id != REPORT_ID_HIDPP_SHORT) &&
255 (report_id != REPORT_ID_HIDPP_LONG))
256 return -EINVAL;
257
258 if (param_count > sizeof(message->rap.params))
259 return -EINVAL;
260
Dan Carpenter3e7830c2014-10-31 12:14:39 +0300261 message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL);
262 if (!message)
263 return -ENOMEM;
Benjamin Tissoires33797822014-09-30 13:18:30 -0400264 message->report_id = report_id;
265 message->rap.sub_id = sub_id;
266 message->rap.reg_address = reg_address;
267 memcpy(&message->rap.params, params, param_count);
268
269 ret = hidpp_send_message_sync(hidpp_dev, message, response);
270 kfree(message);
271 return ret;
272}
273
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400274static void delayed_work_cb(struct work_struct *work)
275{
276 struct hidpp_device *hidpp = container_of(work, struct hidpp_device,
277 work);
278 hidpp_connect_event(hidpp);
279}
280
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400281static inline bool hidpp_match_answer(struct hidpp_report *question,
282 struct hidpp_report *answer)
283{
284 return (answer->fap.feature_index == question->fap.feature_index) &&
285 (answer->fap.funcindex_clientid == question->fap.funcindex_clientid);
286}
287
288static inline bool hidpp_match_error(struct hidpp_report *question,
289 struct hidpp_report *answer)
290{
Peter Wuf677bb12014-12-16 01:50:14 +0100291 return ((answer->rap.sub_id == HIDPP_ERROR) ||
292 (answer->fap.feature_index == HIDPP20_ERROR)) &&
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400293 (answer->fap.funcindex_clientid == question->fap.feature_index) &&
294 (answer->fap.params[0] == question->fap.funcindex_clientid);
295}
296
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400297static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
298{
299 return (report->report_id == REPORT_ID_HIDPP_SHORT) &&
300 (report->rap.sub_id == 0x41);
301}
302
Benjamin Tissoiresa0e625f2014-12-11 17:39:59 -0500303/**
304 * hidpp_prefix_name() prefixes the current given name with "Logitech ".
305 */
306static void hidpp_prefix_name(char **name, int name_length)
307{
308#define PREFIX_LENGTH 9 /* "Logitech " */
309
310 int new_length;
311 char *new_name;
312
313 if (name_length > PREFIX_LENGTH &&
314 strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0)
315 /* The prefix has is already in the name */
316 return;
317
318 new_length = PREFIX_LENGTH + name_length;
319 new_name = kzalloc(new_length, GFP_KERNEL);
320 if (!new_name)
321 return;
322
323 snprintf(new_name, new_length, "Logitech %s", *name);
324
325 kfree(*name);
326
327 *name = new_name;
328}
329
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400330/* -------------------------------------------------------------------------- */
Benjamin Tissoires33797822014-09-30 13:18:30 -0400331/* HIDP++ 1.0 commands */
332/* -------------------------------------------------------------------------- */
333
334#define HIDPP_SET_REGISTER 0x80
335#define HIDPP_GET_REGISTER 0x81
336#define HIDPP_SET_LONG_REGISTER 0x82
337#define HIDPP_GET_LONG_REGISTER 0x83
338
339#define HIDPP_REG_PAIRING_INFORMATION 0xB5
340#define DEVICE_NAME 0x40
341
342static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)
343{
344 struct hidpp_report response;
345 int ret;
346 /* hid-logitech-dj is in charge of setting the right device index */
347 u8 params[1] = { DEVICE_NAME };
348 char *name;
349 int len;
350
351 ret = hidpp_send_rap_command_sync(hidpp_dev,
352 REPORT_ID_HIDPP_SHORT,
353 HIDPP_GET_LONG_REGISTER,
354 HIDPP_REG_PAIRING_INFORMATION,
355 params, 1, &response);
356 if (ret)
357 return NULL;
358
359 len = response.rap.params[1];
360
Peter Wu3a034a72014-12-11 13:51:19 +0100361 if (2 + len > sizeof(response.rap.params))
362 return NULL;
363
Benjamin Tissoires33797822014-09-30 13:18:30 -0400364 name = kzalloc(len + 1, GFP_KERNEL);
365 if (!name)
366 return NULL;
367
368 memcpy(name, &response.rap.params[2], len);
Benjamin Tissoiresa0e625f2014-12-11 17:39:59 -0500369
370 /* include the terminating '\0' */
371 hidpp_prefix_name(&name, len + 1);
372
Benjamin Tissoires33797822014-09-30 13:18:30 -0400373 return name;
374}
375
376/* -------------------------------------------------------------------------- */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400377/* 0x0000: Root */
378/* -------------------------------------------------------------------------- */
379
380#define HIDPP_PAGE_ROOT 0x0000
381#define HIDPP_PAGE_ROOT_IDX 0x00
382
383#define CMD_ROOT_GET_FEATURE 0x01
384#define CMD_ROOT_GET_PROTOCOL_VERSION 0x11
385
386static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature,
387 u8 *feature_index, u8 *feature_type)
388{
389 struct hidpp_report response;
390 int ret;
391 u8 params[2] = { feature >> 8, feature & 0x00FF };
392
393 ret = hidpp_send_fap_command_sync(hidpp,
394 HIDPP_PAGE_ROOT_IDX,
395 CMD_ROOT_GET_FEATURE,
396 params, 2, &response);
397 if (ret)
398 return ret;
399
400 *feature_index = response.fap.params[0];
401 *feature_type = response.fap.params[1];
402
403 return ret;
404}
405
406static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
407{
408 struct hidpp_report response;
409 int ret;
410
411 ret = hidpp_send_fap_command_sync(hidpp,
412 HIDPP_PAGE_ROOT_IDX,
413 CMD_ROOT_GET_PROTOCOL_VERSION,
414 NULL, 0, &response);
415
Benjamin Tissoires552f12e2014-11-03 16:09:59 -0500416 if (ret == HIDPP_ERROR_INVALID_SUBID) {
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400417 hidpp->protocol_major = 1;
418 hidpp->protocol_minor = 0;
419 return 0;
420 }
421
Benjamin Tissoires552f12e2014-11-03 16:09:59 -0500422 /* the device might not be connected */
423 if (ret == HIDPP_ERROR_RESOURCE_ERROR)
424 return -EIO;
425
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500426 if (ret > 0) {
427 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
428 __func__, ret);
429 return -EPROTO;
430 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400431 if (ret)
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500432 return ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400433
434 hidpp->protocol_major = response.fap.params[0];
435 hidpp->protocol_minor = response.fap.params[1];
436
437 return ret;
438}
439
440static bool hidpp_is_connected(struct hidpp_device *hidpp)
441{
442 int ret;
443
444 ret = hidpp_root_get_protocol_version(hidpp);
445 if (!ret)
446 hid_dbg(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
447 hidpp->protocol_major, hidpp->protocol_minor);
448 return ret == 0;
449}
450
451/* -------------------------------------------------------------------------- */
452/* 0x0005: GetDeviceNameType */
453/* -------------------------------------------------------------------------- */
454
455#define HIDPP_PAGE_GET_DEVICE_NAME_TYPE 0x0005
456
457#define CMD_GET_DEVICE_NAME_TYPE_GET_COUNT 0x01
458#define CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11
459#define CMD_GET_DEVICE_NAME_TYPE_GET_TYPE 0x21
460
461static int hidpp_devicenametype_get_count(struct hidpp_device *hidpp,
462 u8 feature_index, u8 *nameLength)
463{
464 struct hidpp_report response;
465 int ret;
466
467 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
468 CMD_GET_DEVICE_NAME_TYPE_GET_COUNT, NULL, 0, &response);
469
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500470 if (ret > 0) {
471 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
472 __func__, ret);
473 return -EPROTO;
474 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400475 if (ret)
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500476 return ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400477
478 *nameLength = response.fap.params[0];
479
480 return ret;
481}
482
483static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp,
484 u8 feature_index, u8 char_index, char *device_name, int len_buf)
485{
486 struct hidpp_report response;
487 int ret, i;
488 int count;
489
490 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
491 CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME, &char_index, 1,
492 &response);
493
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500494 if (ret > 0) {
495 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
496 __func__, ret);
497 return -EPROTO;
498 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400499 if (ret)
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500500 return ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400501
502 if (response.report_id == REPORT_ID_HIDPP_LONG)
503 count = HIDPP_REPORT_LONG_LENGTH - 4;
504 else
505 count = HIDPP_REPORT_SHORT_LENGTH - 4;
506
507 if (len_buf < count)
508 count = len_buf;
509
510 for (i = 0; i < count; i++)
511 device_name[i] = response.fap.params[i];
512
513 return count;
514}
515
Peter Wu02cc0972014-12-11 13:51:17 +0100516static char *hidpp_get_device_name(struct hidpp_device *hidpp)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400517{
518 u8 feature_type;
519 u8 feature_index;
520 u8 __name_length;
521 char *name;
522 unsigned index = 0;
523 int ret;
524
525 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_GET_DEVICE_NAME_TYPE,
526 &feature_index, &feature_type);
527 if (ret)
Peter Wu02cc0972014-12-11 13:51:17 +0100528 return NULL;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400529
530 ret = hidpp_devicenametype_get_count(hidpp, feature_index,
531 &__name_length);
532 if (ret)
Peter Wu02cc0972014-12-11 13:51:17 +0100533 return NULL;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400534
535 name = kzalloc(__name_length + 1, GFP_KERNEL);
536 if (!name)
Peter Wu02cc0972014-12-11 13:51:17 +0100537 return NULL;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400538
Peter Wu1430ee72014-12-11 13:51:18 +0100539 while (index < __name_length) {
540 ret = hidpp_devicenametype_get_device_name(hidpp,
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400541 feature_index, index, name + index,
542 __name_length - index);
Peter Wu1430ee72014-12-11 13:51:18 +0100543 if (ret <= 0) {
544 kfree(name);
545 return NULL;
546 }
547 index += ret;
548 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400549
Benjamin Tissoiresa0e625f2014-12-11 17:39:59 -0500550 /* include the terminating '\0' */
551 hidpp_prefix_name(&name, __name_length + 1);
552
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400553 return name;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400554}
555
556/* -------------------------------------------------------------------------- */
557/* 0x6100: TouchPadRawXY */
558/* -------------------------------------------------------------------------- */
559
560#define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100
561
562#define CMD_TOUCHPAD_GET_RAW_INFO 0x01
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400563#define CMD_TOUCHPAD_SET_RAW_REPORT_STATE 0x21
564
565#define EVENT_TOUCHPAD_RAW_XY 0x00
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400566
567#define TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT 0x01
568#define TOUCHPAD_RAW_XY_ORIGIN_UPPER_LEFT 0x03
569
570struct hidpp_touchpad_raw_info {
571 u16 x_size;
572 u16 y_size;
573 u8 z_range;
574 u8 area_range;
575 u8 timestamp_unit;
576 u8 maxcontacts;
577 u8 origin;
578 u16 res;
579};
580
581struct hidpp_touchpad_raw_xy_finger {
582 u8 contact_type;
583 u8 contact_status;
584 u16 x;
585 u16 y;
586 u8 z;
587 u8 area;
588 u8 finger_id;
589};
590
591struct hidpp_touchpad_raw_xy {
592 u16 timestamp;
593 struct hidpp_touchpad_raw_xy_finger fingers[2];
594 u8 spurious_flag;
595 u8 end_of_frame;
596 u8 finger_count;
597 u8 button;
598};
599
600static int hidpp_touchpad_get_raw_info(struct hidpp_device *hidpp,
601 u8 feature_index, struct hidpp_touchpad_raw_info *raw_info)
602{
603 struct hidpp_report response;
604 int ret;
605 u8 *params = (u8 *)response.fap.params;
606
607 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
608 CMD_TOUCHPAD_GET_RAW_INFO, NULL, 0, &response);
609
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500610 if (ret > 0) {
611 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
612 __func__, ret);
613 return -EPROTO;
614 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400615 if (ret)
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500616 return ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400617
618 raw_info->x_size = get_unaligned_be16(&params[0]);
619 raw_info->y_size = get_unaligned_be16(&params[2]);
620 raw_info->z_range = params[4];
621 raw_info->area_range = params[5];
622 raw_info->maxcontacts = params[7];
623 raw_info->origin = params[8];
624 /* res is given in unit per inch */
625 raw_info->res = get_unaligned_be16(&params[13]) * 2 / 51;
626
627 return ret;
628}
629
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400630static int hidpp_touchpad_set_raw_report_state(struct hidpp_device *hidpp_dev,
631 u8 feature_index, bool send_raw_reports,
632 bool sensor_enhanced_settings)
633{
634 struct hidpp_report response;
635
636 /*
637 * Params:
638 * bit 0 - enable raw
639 * bit 1 - 16bit Z, no area
640 * bit 2 - enhanced sensitivity
641 * bit 3 - width, height (4 bits each) instead of area
642 * bit 4 - send raw + gestures (degrades smoothness)
643 * remaining bits - reserved
644 */
645 u8 params = send_raw_reports | (sensor_enhanced_settings << 2);
646
647 return hidpp_send_fap_command_sync(hidpp_dev, feature_index,
648 CMD_TOUCHPAD_SET_RAW_REPORT_STATE, &params, 1, &response);
649}
650
651static void hidpp_touchpad_touch_event(u8 *data,
652 struct hidpp_touchpad_raw_xy_finger *finger)
653{
654 u8 x_m = data[0] << 2;
655 u8 y_m = data[2] << 2;
656
657 finger->x = x_m << 6 | data[1];
658 finger->y = y_m << 6 | data[3];
659
660 finger->contact_type = data[0] >> 6;
661 finger->contact_status = data[2] >> 6;
662
663 finger->z = data[4];
664 finger->area = data[5];
665 finger->finger_id = data[6] >> 4;
666}
667
668static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev,
669 u8 *data, struct hidpp_touchpad_raw_xy *raw_xy)
670{
671 memset(raw_xy, 0, sizeof(struct hidpp_touchpad_raw_xy));
672 raw_xy->end_of_frame = data[8] & 0x01;
673 raw_xy->spurious_flag = (data[8] >> 1) & 0x01;
674 raw_xy->finger_count = data[15] & 0x0f;
675 raw_xy->button = (data[8] >> 2) & 0x01;
676
677 if (raw_xy->finger_count) {
678 hidpp_touchpad_touch_event(&data[2], &raw_xy->fingers[0]);
679 hidpp_touchpad_touch_event(&data[9], &raw_xy->fingers[1]);
680 }
681}
682
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400683/* ************************************************************************** */
684/* */
685/* Device Support */
686/* */
687/* ************************************************************************** */
688
689/* -------------------------------------------------------------------------- */
690/* Touchpad HID++ devices */
691/* -------------------------------------------------------------------------- */
692
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400693#define WTP_MANUAL_RESOLUTION 39
694
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400695struct wtp_data {
696 struct input_dev *input;
697 u16 x_size, y_size;
698 u8 finger_count;
699 u8 mt_feature_index;
700 u8 button_feature_index;
701 u8 maxcontacts;
702 bool flip_y;
703 unsigned int resolution;
704};
705
706static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
707 struct hid_field *field, struct hid_usage *usage,
708 unsigned long **bit, int *max)
709{
Benjamin Tissoires3a61e972014-09-30 13:18:35 -0400710 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
711
712 if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) &&
713 (field->application == HID_GD_KEYBOARD))
714 return 0;
715
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400716 return -1;
717}
718
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400719static void wtp_populate_input(struct hidpp_device *hidpp,
720 struct input_dev *input_dev, bool origin_is_hid_core)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400721{
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400722 struct wtp_data *wd = hidpp->private_data;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400723
Benjamin Tissoires3a61e972014-09-30 13:18:35 -0400724 if ((hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT) && origin_is_hid_core)
725 /* this is the generic hid-input call */
726 return;
727
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400728 __set_bit(EV_ABS, input_dev->evbit);
729 __set_bit(EV_KEY, input_dev->evbit);
730 __clear_bit(EV_REL, input_dev->evbit);
731 __clear_bit(EV_LED, input_dev->evbit);
732
733 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, wd->x_size, 0, 0);
734 input_abs_set_res(input_dev, ABS_MT_POSITION_X, wd->resolution);
735 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, wd->y_size, 0, 0);
736 input_abs_set_res(input_dev, ABS_MT_POSITION_Y, wd->resolution);
737
738 /* Max pressure is not given by the devices, pick one */
739 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 50, 0, 0);
740
741 input_set_capability(input_dev, EV_KEY, BTN_LEFT);
742
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400743 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS)
744 input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
745 else
746 __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400747
748 input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER |
749 INPUT_MT_DROP_UNUSED);
750
751 wd->input = input_dev;
752}
753
754static void wtp_touch_event(struct wtp_data *wd,
755 struct hidpp_touchpad_raw_xy_finger *touch_report)
756{
757 int slot;
758
759 if (!touch_report->finger_id || touch_report->contact_type)
760 /* no actual data */
761 return;
762
763 slot = input_mt_get_slot_by_key(wd->input, touch_report->finger_id);
764
765 input_mt_slot(wd->input, slot);
766 input_mt_report_slot_state(wd->input, MT_TOOL_FINGER,
767 touch_report->contact_status);
768 if (touch_report->contact_status) {
769 input_event(wd->input, EV_ABS, ABS_MT_POSITION_X,
770 touch_report->x);
771 input_event(wd->input, EV_ABS, ABS_MT_POSITION_Y,
772 wd->flip_y ? wd->y_size - touch_report->y :
773 touch_report->y);
774 input_event(wd->input, EV_ABS, ABS_MT_PRESSURE,
775 touch_report->area);
776 }
777}
778
779static void wtp_send_raw_xy_event(struct hidpp_device *hidpp,
780 struct hidpp_touchpad_raw_xy *raw)
781{
782 struct wtp_data *wd = hidpp->private_data;
783 int i;
784
785 for (i = 0; i < 2; i++)
786 wtp_touch_event(wd, &(raw->fingers[i]));
787
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400788 if (raw->end_of_frame &&
789 !(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS))
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400790 input_event(wd->input, EV_KEY, BTN_LEFT, raw->button);
791
792 if (raw->end_of_frame || raw->finger_count <= 2) {
793 input_mt_sync_frame(wd->input);
794 input_sync(wd->input);
795 }
796}
797
798static int wtp_mouse_raw_xy_event(struct hidpp_device *hidpp, u8 *data)
799{
800 struct wtp_data *wd = hidpp->private_data;
801 u8 c1_area = ((data[7] & 0xf) * (data[7] & 0xf) +
802 (data[7] >> 4) * (data[7] >> 4)) / 2;
803 u8 c2_area = ((data[13] & 0xf) * (data[13] & 0xf) +
804 (data[13] >> 4) * (data[13] >> 4)) / 2;
805 struct hidpp_touchpad_raw_xy raw = {
806 .timestamp = data[1],
807 .fingers = {
808 {
809 .contact_type = 0,
810 .contact_status = !!data[7],
811 .x = get_unaligned_le16(&data[3]),
812 .y = get_unaligned_le16(&data[5]),
813 .z = c1_area,
814 .area = c1_area,
815 .finger_id = data[2],
816 }, {
817 .contact_type = 0,
818 .contact_status = !!data[13],
819 .x = get_unaligned_le16(&data[9]),
820 .y = get_unaligned_le16(&data[11]),
821 .z = c2_area,
822 .area = c2_area,
823 .finger_id = data[8],
824 }
825 },
826 .finger_count = wd->maxcontacts,
827 .spurious_flag = 0,
828 .end_of_frame = (data[0] >> 7) == 0,
829 .button = data[0] & 0x01,
830 };
831
832 wtp_send_raw_xy_event(hidpp, &raw);
833
834 return 1;
835}
836
837static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
838{
839 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
840 struct wtp_data *wd = hidpp->private_data;
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400841 struct hidpp_report *report = (struct hidpp_report *)data;
842 struct hidpp_touchpad_raw_xy raw;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400843
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400844 if (!wd || !wd->input)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400845 return 1;
846
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400847 switch (data[0]) {
848 case 0x02:
Peter Wu0b3f6562014-12-16 16:55:22 +0100849 if (size < 2) {
850 hid_err(hdev, "Received HID report of bad size (%d)",
851 size);
852 return 1;
853 }
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400854 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
855 input_event(wd->input, EV_KEY, BTN_LEFT,
856 !!(data[1] & 0x01));
857 input_event(wd->input, EV_KEY, BTN_RIGHT,
858 !!(data[1] & 0x02));
859 input_sync(wd->input);
Peter Wu8abd8202014-12-16 01:50:16 +0100860 return 0;
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400861 } else {
862 if (size < 21)
863 return 1;
864 return wtp_mouse_raw_xy_event(hidpp, &data[7]);
865 }
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400866 case REPORT_ID_HIDPP_LONG:
Peter Wu0b3f6562014-12-16 16:55:22 +0100867 /* size is already checked in hidpp_raw_event. */
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400868 if ((report->fap.feature_index != wd->mt_feature_index) ||
869 (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
870 return 1;
871 hidpp_touchpad_raw_xy_event(hidpp, data + 4, &raw);
872
873 wtp_send_raw_xy_event(hidpp, &raw);
874 return 0;
875 }
876
877 return 0;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400878}
879
880static int wtp_get_config(struct hidpp_device *hidpp)
881{
882 struct wtp_data *wd = hidpp->private_data;
883 struct hidpp_touchpad_raw_info raw_info = {0};
884 u8 feature_type;
885 int ret;
886
887 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_TOUCHPAD_RAW_XY,
888 &wd->mt_feature_index, &feature_type);
889 if (ret)
890 /* means that the device is not powered up */
891 return ret;
892
893 ret = hidpp_touchpad_get_raw_info(hidpp, wd->mt_feature_index,
894 &raw_info);
895 if (ret)
896 return ret;
897
898 wd->x_size = raw_info.x_size;
899 wd->y_size = raw_info.y_size;
900 wd->maxcontacts = raw_info.maxcontacts;
901 wd->flip_y = raw_info.origin == TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT;
902 wd->resolution = raw_info.res;
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -0400903 if (!wd->resolution)
904 wd->resolution = WTP_MANUAL_RESOLUTION;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400905
906 return 0;
907}
908
909static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id)
910{
911 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
912 struct wtp_data *wd;
913
914 wd = devm_kzalloc(&hdev->dev, sizeof(struct wtp_data),
915 GFP_KERNEL);
916 if (!wd)
917 return -ENOMEM;
918
919 hidpp->private_data = wd;
920
921 return 0;
922};
923
Benjamin Tissoiresbf159442014-12-16 17:06:01 -0500924static int wtp_connect(struct hid_device *hdev, bool connected)
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400925{
926 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
927 struct wtp_data *wd = hidpp->private_data;
928 int ret;
929
930 if (!connected)
Benjamin Tissoiresbf159442014-12-16 17:06:01 -0500931 return 0;
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400932
933 if (!wd->x_size) {
934 ret = wtp_get_config(hidpp);
935 if (ret) {
936 hid_err(hdev, "Can not get wtp config: %d\n", ret);
Benjamin Tissoiresbf159442014-12-16 17:06:01 -0500937 return ret;
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400938 }
939 }
940
Benjamin Tissoiresbf159442014-12-16 17:06:01 -0500941 return hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index,
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400942 true, true);
943}
944
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +0200945/* ------------------------------------------------------------------------- */
946/* Logitech M560 devices */
947/* ------------------------------------------------------------------------- */
948
949/*
950 * Logitech M560 protocol overview
951 *
952 * The Logitech M560 mouse, is designed for windows 8. When the middle and/or
953 * the sides buttons are pressed, it sends some keyboard keys events
954 * instead of buttons ones.
955 * To complicate things further, the middle button keys sequence
956 * is different from the odd press and the even press.
957 *
958 * forward button -> Super_R
959 * backward button -> Super_L+'d' (press only)
960 * middle button -> 1st time: Alt_L+SuperL+XF86TouchpadOff (press only)
961 * 2nd time: left-click (press only)
962 * NB: press-only means that when the button is pressed, the
963 * KeyPress/ButtonPress and KeyRelease/ButtonRelease events are generated
964 * together sequentially; instead when the button is released, no event is
965 * generated !
966 *
967 * With the command
968 * 10<xx>0a 3500af03 (where <xx> is the mouse id),
969 * the mouse reacts differently:
970 * - it never sends a keyboard key event
971 * - for the three mouse button it sends:
972 * middle button press 11<xx>0a 3500af00...
973 * side 1 button (forward) press 11<xx>0a 3500b000...
974 * side 2 button (backward) press 11<xx>0a 3500ae00...
975 * middle/side1/side2 button release 11<xx>0a 35000000...
976 */
977
978static const u8 m560_config_parameter[] = {0x00, 0xaf, 0x03};
979
980struct m560_private_data {
981 struct input_dev *input;
982};
983
984/* how buttons are mapped in the report */
985#define M560_MOUSE_BTN_LEFT 0x01
986#define M560_MOUSE_BTN_RIGHT 0x02
987#define M560_MOUSE_BTN_WHEEL_LEFT 0x08
988#define M560_MOUSE_BTN_WHEEL_RIGHT 0x10
989
990#define M560_SUB_ID 0x0a
991#define M560_BUTTON_MODE_REGISTER 0x35
992
993static int m560_send_config_command(struct hid_device *hdev, bool connected)
994{
995 struct hidpp_report response;
996 struct hidpp_device *hidpp_dev;
997
998 hidpp_dev = hid_get_drvdata(hdev);
999
1000 if (!connected)
1001 return -ENODEV;
1002
1003 return hidpp_send_rap_command_sync(
1004 hidpp_dev,
1005 REPORT_ID_HIDPP_SHORT,
1006 M560_SUB_ID,
1007 M560_BUTTON_MODE_REGISTER,
1008 (u8 *)m560_config_parameter,
1009 sizeof(m560_config_parameter),
1010 &response
1011 );
1012}
1013
1014static int m560_allocate(struct hid_device *hdev)
1015{
1016 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1017 struct m560_private_data *d;
1018
1019 d = devm_kzalloc(&hdev->dev, sizeof(struct m560_private_data),
1020 GFP_KERNEL);
1021 if (!d)
1022 return -ENOMEM;
1023
1024 hidpp->private_data = d;
1025
1026 return 0;
1027};
1028
1029static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
1030{
1031 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1032 struct m560_private_data *mydata = hidpp->private_data;
1033
1034 /* sanity check */
1035 if (!mydata || !mydata->input) {
1036 hid_err(hdev, "error in parameter\n");
1037 return -EINVAL;
1038 }
1039
1040 if (size < 7) {
1041 hid_err(hdev, "error in report\n");
1042 return 0;
1043 }
1044
1045 if (data[0] == REPORT_ID_HIDPP_LONG &&
1046 data[2] == M560_SUB_ID && data[6] == 0x00) {
1047 /*
1048 * m560 mouse report for middle, forward and backward button
1049 *
1050 * data[0] = 0x11
1051 * data[1] = device-id
1052 * data[2] = 0x0a
1053 * data[5] = 0xaf -> middle
1054 * 0xb0 -> forward
1055 * 0xae -> backward
1056 * 0x00 -> release all
1057 * data[6] = 0x00
1058 */
1059
1060 switch (data[5]) {
1061 case 0xaf:
1062 input_report_key(mydata->input, BTN_MIDDLE, 1);
1063 break;
1064 case 0xb0:
1065 input_report_key(mydata->input, BTN_FORWARD, 1);
1066 break;
1067 case 0xae:
1068 input_report_key(mydata->input, BTN_BACK, 1);
1069 break;
1070 case 0x00:
1071 input_report_key(mydata->input, BTN_BACK, 0);
1072 input_report_key(mydata->input, BTN_FORWARD, 0);
1073 input_report_key(mydata->input, BTN_MIDDLE, 0);
1074 break;
1075 default:
1076 hid_err(hdev, "error in report\n");
1077 return 0;
1078 }
1079 input_sync(mydata->input);
1080
1081 } else if (data[0] == 0x02) {
1082 /*
1083 * Logitech M560 mouse report
1084 *
1085 * data[0] = type (0x02)
1086 * data[1..2] = buttons
1087 * data[3..5] = xy
1088 * data[6] = wheel
1089 */
1090
1091 int v;
1092
1093 input_report_key(mydata->input, BTN_LEFT,
1094 !!(data[1] & M560_MOUSE_BTN_LEFT));
1095 input_report_key(mydata->input, BTN_RIGHT,
1096 !!(data[1] & M560_MOUSE_BTN_RIGHT));
1097
1098 if (data[1] & M560_MOUSE_BTN_WHEEL_LEFT)
1099 input_report_rel(mydata->input, REL_HWHEEL, -1);
1100 else if (data[1] & M560_MOUSE_BTN_WHEEL_RIGHT)
1101 input_report_rel(mydata->input, REL_HWHEEL, 1);
1102
1103 v = hid_snto32(hid_field_extract(hdev, data+3, 0, 12), 12);
1104 input_report_rel(mydata->input, REL_X, v);
1105
1106 v = hid_snto32(hid_field_extract(hdev, data+3, 12, 12), 12);
1107 input_report_rel(mydata->input, REL_Y, v);
1108
1109 v = hid_snto32(data[6], 8);
1110 input_report_rel(mydata->input, REL_WHEEL, v);
1111
1112 input_sync(mydata->input);
1113 }
1114
1115 return 1;
1116}
1117
1118static void m560_populate_input(struct hidpp_device *hidpp,
1119 struct input_dev *input_dev, bool origin_is_hid_core)
1120{
1121 struct m560_private_data *mydata = hidpp->private_data;
1122
1123 mydata->input = input_dev;
1124
1125 __set_bit(EV_KEY, mydata->input->evbit);
1126 __set_bit(BTN_MIDDLE, mydata->input->keybit);
1127 __set_bit(BTN_RIGHT, mydata->input->keybit);
1128 __set_bit(BTN_LEFT, mydata->input->keybit);
1129 __set_bit(BTN_BACK, mydata->input->keybit);
1130 __set_bit(BTN_FORWARD, mydata->input->keybit);
1131
1132 __set_bit(EV_REL, mydata->input->evbit);
1133 __set_bit(REL_X, mydata->input->relbit);
1134 __set_bit(REL_Y, mydata->input->relbit);
1135 __set_bit(REL_WHEEL, mydata->input->relbit);
1136 __set_bit(REL_HWHEEL, mydata->input->relbit);
1137}
1138
1139static int m560_input_mapping(struct hid_device *hdev, struct hid_input *hi,
1140 struct hid_field *field, struct hid_usage *usage,
1141 unsigned long **bit, int *max)
1142{
1143 return -1;
1144}
1145
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001146/* -------------------------------------------------------------------------- */
1147/* Generic HID++ devices */
1148/* -------------------------------------------------------------------------- */
1149
1150static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
1151 struct hid_field *field, struct hid_usage *usage,
1152 unsigned long **bit, int *max)
1153{
1154 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1155
1156 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
1157 return wtp_input_mapping(hdev, hi, field, usage, bit, max);
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001158 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560 &&
1159 field->application != HID_GD_MOUSE)
1160 return m560_input_mapping(hdev, hi, field, usage, bit, max);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001161
1162 return 0;
1163}
1164
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001165static void hidpp_populate_input(struct hidpp_device *hidpp,
1166 struct input_dev *input, bool origin_is_hid_core)
1167{
1168 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
1169 wtp_populate_input(hidpp, input, origin_is_hid_core);
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001170 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
1171 m560_populate_input(hidpp, input, origin_is_hid_core);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001172}
1173
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001174static void hidpp_input_configured(struct hid_device *hdev,
1175 struct hid_input *hidinput)
1176{
1177 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001178 struct input_dev *input = hidinput->input;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001179
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001180 hidpp_populate_input(hidpp, input, true);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001181}
1182
1183static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
1184 int size)
1185{
1186 struct hidpp_report *question = hidpp->send_receive_buf;
1187 struct hidpp_report *answer = hidpp->send_receive_buf;
1188 struct hidpp_report *report = (struct hidpp_report *)data;
1189
1190 /*
1191 * If the mutex is locked then we have a pending answer from a
Peter Wue529fea2014-12-17 00:23:51 +01001192 * previously sent command.
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001193 */
1194 if (unlikely(mutex_is_locked(&hidpp->send_mutex))) {
1195 /*
1196 * Check for a correct hidpp20 answer or the corresponding
1197 * error
1198 */
1199 if (hidpp_match_answer(question, report) ||
1200 hidpp_match_error(question, report)) {
1201 *answer = *report;
1202 hidpp->answer_available = true;
1203 wake_up(&hidpp->wait);
1204 /*
1205 * This was an answer to a command that this driver sent
1206 * We return 1 to hid-core to avoid forwarding the
1207 * command upstream as it has been treated by the driver
1208 */
1209
1210 return 1;
1211 }
1212 }
1213
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001214 if (unlikely(hidpp_report_is_connect_event(report))) {
1215 atomic_set(&hidpp->connected,
1216 !(report->rap.params[0] & (1 << 6)));
1217 if ((hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) &&
1218 (schedule_work(&hidpp->work) == 0))
1219 dbg_hid("%s: connect event already queued\n", __func__);
1220 return 1;
1221 }
1222
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001223 return 0;
1224}
1225
1226static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
1227 u8 *data, int size)
1228{
1229 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
Peter Wue529fea2014-12-17 00:23:51 +01001230 int ret = 0;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001231
Peter Wue529fea2014-12-17 00:23:51 +01001232 /* Generic HID++ processing. */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001233 switch (data[0]) {
1234 case REPORT_ID_HIDPP_LONG:
1235 if (size != HIDPP_REPORT_LONG_LENGTH) {
1236 hid_err(hdev, "received hid++ report of bad size (%d)",
1237 size);
1238 return 1;
1239 }
Peter Wue529fea2014-12-17 00:23:51 +01001240 ret = hidpp_raw_hidpp_event(hidpp, data, size);
1241 break;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001242 case REPORT_ID_HIDPP_SHORT:
1243 if (size != HIDPP_REPORT_SHORT_LENGTH) {
1244 hid_err(hdev, "received hid++ report of bad size (%d)",
1245 size);
1246 return 1;
1247 }
Peter Wue529fea2014-12-17 00:23:51 +01001248 ret = hidpp_raw_hidpp_event(hidpp, data, size);
1249 break;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001250 }
1251
Peter Wue529fea2014-12-17 00:23:51 +01001252 /* If no report is available for further processing, skip calling
1253 * raw_event of subclasses. */
1254 if (ret != 0)
1255 return ret;
1256
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001257 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
1258 return wtp_raw_event(hdev, data, size);
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001259 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
1260 return m560_raw_event(hdev, data, size);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001261
1262 return 0;
1263}
1264
Benjamin Tissoires33797822014-09-30 13:18:30 -04001265static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001266{
1267 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1268 char *name;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001269
Benjamin Tissoires33797822014-09-30 13:18:30 -04001270 if (use_unifying)
1271 /*
1272 * the device is connected through an Unifying receiver, and
1273 * might not be already connected.
1274 * Ask the receiver for its name.
1275 */
1276 name = hidpp_get_unifying_name(hidpp);
1277 else
Peter Wu02cc0972014-12-11 13:51:17 +01001278 name = hidpp_get_device_name(hidpp);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001279
1280 if (!name)
1281 hid_err(hdev, "unable to retrieve the name of the device");
1282 else
1283 snprintf(hdev->name, sizeof(hdev->name), "%s", name);
1284
1285 kfree(name);
1286}
1287
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001288static int hidpp_input_open(struct input_dev *dev)
1289{
1290 struct hid_device *hid = input_get_drvdata(dev);
1291
1292 return hid_hw_open(hid);
1293}
1294
1295static void hidpp_input_close(struct input_dev *dev)
1296{
1297 struct hid_device *hid = input_get_drvdata(dev);
1298
1299 hid_hw_close(hid);
1300}
1301
1302static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
1303{
1304 struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev);
Benjamin Tissoires005b3f52015-01-08 14:37:12 -05001305 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001306
1307 if (!input_dev)
1308 return NULL;
1309
1310 input_set_drvdata(input_dev, hdev);
1311 input_dev->open = hidpp_input_open;
1312 input_dev->close = hidpp_input_close;
1313
Benjamin Tissoires005b3f52015-01-08 14:37:12 -05001314 input_dev->name = hidpp->name;
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001315 input_dev->phys = hdev->phys;
1316 input_dev->uniq = hdev->uniq;
1317 input_dev->id.bustype = hdev->bus;
1318 input_dev->id.vendor = hdev->vendor;
1319 input_dev->id.product = hdev->product;
1320 input_dev->id.version = hdev->version;
1321 input_dev->dev.parent = &hdev->dev;
1322
1323 return input_dev;
1324}
1325
1326static void hidpp_connect_event(struct hidpp_device *hidpp)
1327{
1328 struct hid_device *hdev = hidpp->hid_dev;
1329 int ret = 0;
1330 bool connected = atomic_read(&hidpp->connected);
1331 struct input_dev *input;
1332 char *name, *devm_name;
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001333
Benjamin Tissoiresbf159442014-12-16 17:06:01 -05001334 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
1335 ret = wtp_connect(hdev, connected);
1336 if (ret)
1337 return;
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001338 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) {
1339 ret = m560_send_config_command(hdev, connected);
1340 if (ret)
1341 return;
Benjamin Tissoiresbf159442014-12-16 17:06:01 -05001342 }
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001343
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001344 if (!connected || hidpp->delayed_input)
1345 return;
1346
1347 if (!hidpp->protocol_major) {
1348 ret = !hidpp_is_connected(hidpp);
1349 if (ret) {
1350 hid_err(hdev, "Can not get the protocol version.\n");
1351 return;
1352 }
1353 }
1354
1355 /* the device is already connected, we can ask for its name and
1356 * protocol */
1357 hid_info(hdev, "HID++ %u.%u device connected.\n",
1358 hidpp->protocol_major, hidpp->protocol_minor);
1359
Benjamin Tissoires005b3f52015-01-08 14:37:12 -05001360 if (!hidpp->name || hidpp->name == hdev->name) {
1361 name = hidpp_get_device_name(hidpp);
1362 if (!name) {
1363 hid_err(hdev,
1364 "unable to retrieve the name of the device");
1365 return;
1366 }
1367
1368 devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
1369 kfree(name);
1370 if (!devm_name)
1371 return;
1372
1373 hidpp->name = devm_name;
1374 }
1375
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001376 input = hidpp_allocate_input(hdev);
1377 if (!input) {
1378 hid_err(hdev, "cannot allocate new input device: %d\n", ret);
1379 return;
1380 }
1381
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001382 hidpp_populate_input(hidpp, input, false);
1383
1384 ret = input_register_device(input);
1385 if (ret)
1386 input_free_device(input);
1387
1388 hidpp->delayed_input = input;
1389}
1390
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001391static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
1392{
1393 struct hidpp_device *hidpp;
1394 int ret;
1395 bool connected;
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001396 unsigned int connect_mask = HID_CONNECT_DEFAULT;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001397
1398 hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device),
1399 GFP_KERNEL);
1400 if (!hidpp)
1401 return -ENOMEM;
1402
1403 hidpp->hid_dev = hdev;
Benjamin Tissoires005b3f52015-01-08 14:37:12 -05001404 hidpp->name = hdev->name;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001405 hid_set_drvdata(hdev, hidpp);
1406
1407 hidpp->quirks = id->driver_data;
1408
Benjamin Tissoires9188dba2015-03-26 12:41:57 -04001409 if (disable_raw_mode) {
1410 hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP;
1411 hidpp->quirks &= ~HIDPP_QUIRK_DELAYED_INIT;
1412 }
1413
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001414 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
1415 ret = wtp_allocate(hdev, id);
1416 if (ret)
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001417 goto allocate_fail;
1418 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) {
1419 ret = m560_allocate(hdev);
1420 if (ret)
1421 goto allocate_fail;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001422 }
1423
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001424 INIT_WORK(&hidpp->work, delayed_work_cb);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001425 mutex_init(&hidpp->send_mutex);
1426 init_waitqueue_head(&hidpp->wait);
1427
1428 ret = hid_parse(hdev);
1429 if (ret) {
1430 hid_err(hdev, "%s:parse failed\n", __func__);
1431 goto hid_parse_fail;
1432 }
1433
1434 /* Allow incoming packets */
1435 hid_device_io_start(hdev);
1436
1437 connected = hidpp_is_connected(hidpp);
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001438 if (id->group != HID_GROUP_LOGITECH_DJ_DEVICE) {
1439 if (!connected) {
Julia Lawallb832da52015-04-05 14:06:29 +02001440 ret = -ENODEV;
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001441 hid_err(hdev, "Device not connected");
Peter Wuf486d9d2014-12-11 13:51:20 +01001442 hid_device_io_stop(hdev);
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001443 goto hid_parse_fail;
1444 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001445
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001446 hid_info(hdev, "HID++ %u.%u device connected.\n",
1447 hidpp->protocol_major, hidpp->protocol_minor);
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001448 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001449
Benjamin Tissoires33797822014-09-30 13:18:30 -04001450 hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001451 atomic_set(&hidpp->connected, connected);
Benjamin Tissoires33797822014-09-30 13:18:30 -04001452
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001453 if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001454 ret = wtp_get_config(hidpp);
1455 if (ret)
1456 goto hid_parse_fail;
1457 }
1458
1459 /* Block incoming packets */
1460 hid_device_io_stop(hdev);
1461
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001462 if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT)
1463 connect_mask &= ~HID_CONNECT_HIDINPUT;
1464
Benjamin Tissoires3a61e972014-09-30 13:18:35 -04001465 /* Re-enable hidinput for multi-input devices */
1466 if (hidpp->quirks & HIDPP_QUIRK_MULTI_INPUT)
1467 connect_mask |= HID_CONNECT_HIDINPUT;
1468
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001469 ret = hid_hw_start(hdev, connect_mask);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001470 if (ret) {
1471 hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
1472 goto hid_hw_start_fail;
1473 }
1474
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001475 if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) {
1476 /* Allow incoming packets */
1477 hid_device_io_start(hdev);
1478
1479 hidpp_connect_event(hidpp);
1480 }
1481
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001482 return ret;
1483
1484hid_hw_start_fail:
1485hid_parse_fail:
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001486 cancel_work_sync(&hidpp->work);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001487 mutex_destroy(&hidpp->send_mutex);
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001488allocate_fail:
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001489 hid_set_drvdata(hdev, NULL);
1490 return ret;
1491}
1492
1493static void hidpp_remove(struct hid_device *hdev)
1494{
1495 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1496
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001497 cancel_work_sync(&hidpp->work);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001498 mutex_destroy(&hidpp->send_mutex);
1499 hid_hw_stop(hdev);
1500}
1501
1502static const struct hid_device_id hidpp_devices[] = {
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04001503 { /* wireless touchpad */
1504 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1505 USB_VENDOR_ID_LOGITECH, 0x4011),
1506 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
1507 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001508 { /* wireless touchpad T650 */
1509 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1510 USB_VENDOR_ID_LOGITECH, 0x4101),
1511 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001512 { /* wireless touchpad T651 */
1513 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
1514 USB_DEVICE_ID_LOGITECH_T651),
1515 .driver_data = HIDPP_QUIRK_CLASS_WTP },
Benjamin Tissoires3a61e972014-09-30 13:18:35 -04001516 { /* Keyboard TK820 */
1517 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1518 USB_VENDOR_ID_LOGITECH, 0x4102),
1519 .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_MULTI_INPUT |
1520 HIDPP_QUIRK_CLASS_WTP },
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001521 { /* Mouse logitech M560 */
1522 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1523 USB_VENDOR_ID_LOGITECH, 0x402d),
1524 .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 },
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04001525
1526 { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
1527 USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001528 {}
1529};
1530
1531MODULE_DEVICE_TABLE(hid, hidpp_devices);
1532
1533static struct hid_driver hidpp_driver = {
1534 .name = "logitech-hidpp-device",
1535 .id_table = hidpp_devices,
1536 .probe = hidpp_probe,
1537 .remove = hidpp_remove,
1538 .raw_event = hidpp_raw_event,
1539 .input_configured = hidpp_input_configured,
1540 .input_mapping = hidpp_input_mapping,
1541};
1542
1543module_hid_driver(hidpp_driver);