blob: 7e4445a3d7aac5b55340ff34c7c8a9fe562f8d45 [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>
Edwin Veldsff21a632016-01-11 00:25:15 +010018#include <linux/input.h>
19#include <linux/usb.h>
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040020#include <linux/hid.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/sched.h>
24#include <linux/kfifo.h>
25#include <linux/input/mt.h>
Edwin Veldsff21a632016-01-11 00:25:15 +010026#include <linux/workqueue.h>
27#include <linux/atomic.h>
28#include <linux/fixp-arith.h>
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040029#include <asm/unaligned.h>
Edwin Veldsff21a632016-01-11 00:25:15 +010030#include "usbhid/usbhid.h"
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040031#include "hid-ids.h"
32
33MODULE_LICENSE("GPL");
34MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
35MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>");
36
Benjamin Tissoires9188dba2015-03-26 12:41:57 -040037static bool disable_raw_mode;
38module_param(disable_raw_mode, bool, 0644);
39MODULE_PARM_DESC(disable_raw_mode,
40 "Disable Raw mode reporting for touchpads and keep firmware gestures.");
41
Benjamin Tissoires90cdd982015-09-03 09:08:30 -040042static bool disable_tap_to_click;
43module_param(disable_tap_to_click, bool, 0644);
44MODULE_PARM_DESC(disable_tap_to_click,
45 "Disable Tap-To-Click mode reporting for touchpads (only on the K400 currently).");
46
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040047#define REPORT_ID_HIDPP_SHORT 0x10
48#define REPORT_ID_HIDPP_LONG 0x11
Simon Wooda5ce8f52015-11-19 16:42:11 -070049#define REPORT_ID_HIDPP_VERY_LONG 0x12
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040050
51#define HIDPP_REPORT_SHORT_LENGTH 7
52#define HIDPP_REPORT_LONG_LENGTH 20
Simon Wooda5ce8f52015-11-19 16:42:11 -070053#define HIDPP_REPORT_VERY_LONG_LENGTH 64
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040054
55#define HIDPP_QUIRK_CLASS_WTP BIT(0)
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +020056#define HIDPP_QUIRK_CLASS_M560 BIT(1)
Benjamin Tissoires90cdd982015-09-03 09:08:30 -040057#define HIDPP_QUIRK_CLASS_K400 BIT(2)
Simon Wood7bfd2922015-11-19 16:42:12 -070058#define HIDPP_QUIRK_CLASS_G920 BIT(3)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040059
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +020060/* bits 2..20 are reserved for classes */
Benjamin Tissoires6bd4e652016-06-29 19:28:02 +100061/* #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) disabled */
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -040062#define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22)
Benjamin Tissoires580a7e82015-09-03 09:08:29 -040063#define HIDPP_QUIRK_NO_HIDINPUT BIT(23)
Simon Wood7bfd2922015-11-19 16:42:12 -070064#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24)
Benjamin Tissoires843c6242017-03-27 16:59:26 +020065#define HIDPP_QUIRK_UNIFYING BIT(25)
Benjamin Tissoires580a7e82015-09-03 09:08:29 -040066
Benjamin Tissoires6bd4e652016-06-29 19:28:02 +100067#define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -040068
Benjamin Tissoires206d7c62017-03-27 16:59:25 +020069#define HIDPP_CAPABILITY_HIDPP10_BATTERY BIT(0)
70#define HIDPP_CAPABILITY_HIDPP20_BATTERY BIT(1)
71
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040072/*
73 * There are two hidpp protocols in use, the first version hidpp10 is known
74 * as register access protocol or RAP, the second version hidpp20 is known as
75 * feature access protocol or FAP
76 *
77 * Most older devices (including the Unifying usb receiver) use the RAP protocol
78 * where as most newer devices use the FAP protocol. Both protocols are
79 * compatible with the underlying transport, which could be usb, Unifiying, or
80 * bluetooth. The message lengths are defined by the hid vendor specific report
81 * descriptor for the HIDPP_SHORT report type (total message lenth 7 bytes) and
82 * the HIDPP_LONG report type (total message length 20 bytes)
83 *
84 * The RAP protocol uses both report types, whereas the FAP only uses HIDPP_LONG
85 * messages. The Unifying receiver itself responds to RAP messages (device index
86 * is 0xFF for the receiver), and all messages (short or long) with a device
87 * index between 1 and 6 are passed untouched to the corresponding paired
88 * Unifying device.
89 *
90 * The paired device can be RAP or FAP, it will receive the message untouched
91 * from the Unifiying receiver.
92 */
93
94struct fap {
95 u8 feature_index;
96 u8 funcindex_clientid;
Simon Wooda5ce8f52015-11-19 16:42:11 -070097 u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U];
Benjamin Tissoires2f31c522014-09-30 13:18:27 -040098};
99
100struct rap {
101 u8 sub_id;
102 u8 reg_address;
Simon Wooda5ce8f52015-11-19 16:42:11 -0700103 u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U];
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400104};
105
106struct hidpp_report {
107 u8 report_id;
108 u8 device_index;
109 union {
110 struct fap fap;
111 struct rap rap;
112 u8 rawbytes[sizeof(struct fap)];
113 };
114} __packed;
115
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000116struct hidpp_battery {
117 u8 feature_index;
118 struct power_supply_desc desc;
119 struct power_supply *ps;
120 char name[64];
121 int status;
122 int level;
Benjamin Tissoires284f8d72017-03-27 16:59:34 +0200123 bool online;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000124};
125
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400126struct hidpp_device {
127 struct hid_device *hid_dev;
128 struct mutex send_mutex;
129 void *send_receive_buf;
Benjamin Tissoires005b3f52015-01-08 14:37:12 -0500130 char *name; /* will never be NULL and should not be freed */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400131 wait_queue_head_t wait;
132 bool answer_available;
133 u8 protocol_major;
134 u8 protocol_minor;
135
136 void *private_data;
137
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400138 struct work_struct work;
139 struct kfifo delayed_work_fifo;
140 atomic_t connected;
141 struct input_dev *delayed_input;
142
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400143 unsigned long quirks;
Benjamin Tissoires206d7c62017-03-27 16:59:25 +0200144 unsigned long capabilities;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400145
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000146 struct hidpp_battery battery;
147};
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400148
Peter Wuf677bb12014-12-16 01:50:14 +0100149/* HID++ 1.0 error codes */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400150#define HIDPP_ERROR 0x8f
151#define HIDPP_ERROR_SUCCESS 0x00
152#define HIDPP_ERROR_INVALID_SUBID 0x01
153#define HIDPP_ERROR_INVALID_ADRESS 0x02
154#define HIDPP_ERROR_INVALID_VALUE 0x03
155#define HIDPP_ERROR_CONNECT_FAIL 0x04
156#define HIDPP_ERROR_TOO_MANY_DEVICES 0x05
157#define HIDPP_ERROR_ALREADY_EXISTS 0x06
158#define HIDPP_ERROR_BUSY 0x07
159#define HIDPP_ERROR_UNKNOWN_DEVICE 0x08
160#define HIDPP_ERROR_RESOURCE_ERROR 0x09
161#define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a
162#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b
163#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c
Peter Wuf677bb12014-12-16 01:50:14 +0100164/* HID++ 2.0 error codes */
165#define HIDPP20_ERROR 0xff
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400166
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400167static void hidpp_connect_event(struct hidpp_device *hidpp_dev);
168
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400169static int __hidpp_send_report(struct hid_device *hdev,
170 struct hidpp_report *hidpp_report)
171{
Simon Wood7bfd2922015-11-19 16:42:12 -0700172 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400173 int fields_count, ret;
174
Simon Wood7bfd2922015-11-19 16:42:12 -0700175 hidpp = hid_get_drvdata(hdev);
176
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400177 switch (hidpp_report->report_id) {
178 case REPORT_ID_HIDPP_SHORT:
179 fields_count = HIDPP_REPORT_SHORT_LENGTH;
180 break;
181 case REPORT_ID_HIDPP_LONG:
182 fields_count = HIDPP_REPORT_LONG_LENGTH;
183 break;
Simon Wooda5ce8f52015-11-19 16:42:11 -0700184 case REPORT_ID_HIDPP_VERY_LONG:
185 fields_count = HIDPP_REPORT_VERY_LONG_LENGTH;
186 break;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400187 default:
188 return -ENODEV;
189 }
190
191 /*
192 * set the device_index as the receiver, it will be overwritten by
193 * hid_hw_request if needed
194 */
195 hidpp_report->device_index = 0xff;
196
Simon Wood7bfd2922015-11-19 16:42:12 -0700197 if (hidpp->quirks & HIDPP_QUIRK_FORCE_OUTPUT_REPORTS) {
198 ret = hid_hw_output_report(hdev, (u8 *)hidpp_report, fields_count);
199 } else {
200 ret = hid_hw_raw_request(hdev, hidpp_report->report_id,
201 (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT,
202 HID_REQ_SET_REPORT);
203 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400204
205 return ret == fields_count ? 0 : -1;
206}
207
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500208/**
209 * hidpp_send_message_sync() returns 0 in case of success, and something else
210 * in case of a failure.
211 * - If ' something else' is positive, that means that an error has been raised
212 * by the protocol itself.
213 * - If ' something else' is negative, that means that we had a classic error
214 * (-ENOMEM, -EPIPE, etc...)
215 */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400216static int hidpp_send_message_sync(struct hidpp_device *hidpp,
217 struct hidpp_report *message,
218 struct hidpp_report *response)
219{
220 int ret;
221
222 mutex_lock(&hidpp->send_mutex);
223
224 hidpp->send_receive_buf = response;
225 hidpp->answer_available = false;
226
227 /*
228 * So that we can later validate the answer when it arrives
229 * in hidpp_raw_event
230 */
231 *response = *message;
232
233 ret = __hidpp_send_report(hidpp->hid_dev, message);
234
235 if (ret) {
236 dbg_hid("__hidpp_send_report returned err: %d\n", ret);
237 memset(response, 0, sizeof(struct hidpp_report));
238 goto exit;
239 }
240
241 if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
242 5*HZ)) {
243 dbg_hid("%s:timeout waiting for response\n", __func__);
244 memset(response, 0, sizeof(struct hidpp_report));
245 ret = -ETIMEDOUT;
246 }
247
248 if (response->report_id == REPORT_ID_HIDPP_SHORT &&
Peter Wuf677bb12014-12-16 01:50:14 +0100249 response->rap.sub_id == HIDPP_ERROR) {
250 ret = response->rap.params[1];
251 dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
252 goto exit;
253 }
254
Simon Wooda5ce8f52015-11-19 16:42:11 -0700255 if ((response->report_id == REPORT_ID_HIDPP_LONG ||
256 response->report_id == REPORT_ID_HIDPP_VERY_LONG) &&
257 response->fap.feature_index == HIDPP20_ERROR) {
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400258 ret = response->fap.params[1];
Peter Wuf677bb12014-12-16 01:50:14 +0100259 dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400260 goto exit;
261 }
262
263exit:
264 mutex_unlock(&hidpp->send_mutex);
265 return ret;
266
267}
268
269static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp,
270 u8 feat_index, u8 funcindex_clientid, u8 *params, int param_count,
271 struct hidpp_report *response)
272{
Dan Carpenter3e7830c2014-10-31 12:14:39 +0300273 struct hidpp_report *message;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400274 int ret;
275
276 if (param_count > sizeof(message->fap.params))
277 return -EINVAL;
278
Dan Carpenter3e7830c2014-10-31 12:14:39 +0300279 message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL);
280 if (!message)
281 return -ENOMEM;
Simon Wooda5ce8f52015-11-19 16:42:11 -0700282
283 if (param_count > (HIDPP_REPORT_LONG_LENGTH - 4))
284 message->report_id = REPORT_ID_HIDPP_VERY_LONG;
285 else
286 message->report_id = REPORT_ID_HIDPP_LONG;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400287 message->fap.feature_index = feat_index;
288 message->fap.funcindex_clientid = funcindex_clientid;
289 memcpy(&message->fap.params, params, param_count);
290
291 ret = hidpp_send_message_sync(hidpp, message, response);
292 kfree(message);
293 return ret;
294}
295
Benjamin Tissoires33797822014-09-30 13:18:30 -0400296static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev,
297 u8 report_id, u8 sub_id, u8 reg_address, u8 *params, int param_count,
298 struct hidpp_report *response)
299{
Dan Carpenter3e7830c2014-10-31 12:14:39 +0300300 struct hidpp_report *message;
Simon Wooda5ce8f52015-11-19 16:42:11 -0700301 int ret, max_count;
Benjamin Tissoires33797822014-09-30 13:18:30 -0400302
Simon Wooda5ce8f52015-11-19 16:42:11 -0700303 switch (report_id) {
304 case REPORT_ID_HIDPP_SHORT:
305 max_count = HIDPP_REPORT_SHORT_LENGTH - 4;
306 break;
307 case REPORT_ID_HIDPP_LONG:
308 max_count = HIDPP_REPORT_LONG_LENGTH - 4;
309 break;
310 case REPORT_ID_HIDPP_VERY_LONG:
311 max_count = HIDPP_REPORT_VERY_LONG_LENGTH - 4;
312 break;
313 default:
Benjamin Tissoires33797822014-09-30 13:18:30 -0400314 return -EINVAL;
Simon Wooda5ce8f52015-11-19 16:42:11 -0700315 }
Benjamin Tissoires33797822014-09-30 13:18:30 -0400316
Simon Wooda5ce8f52015-11-19 16:42:11 -0700317 if (param_count > max_count)
Benjamin Tissoires33797822014-09-30 13:18:30 -0400318 return -EINVAL;
319
Dan Carpenter3e7830c2014-10-31 12:14:39 +0300320 message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL);
321 if (!message)
322 return -ENOMEM;
Benjamin Tissoires33797822014-09-30 13:18:30 -0400323 message->report_id = report_id;
324 message->rap.sub_id = sub_id;
325 message->rap.reg_address = reg_address;
326 memcpy(&message->rap.params, params, param_count);
327
328 ret = hidpp_send_message_sync(hidpp_dev, message, response);
329 kfree(message);
330 return ret;
331}
332
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400333static void delayed_work_cb(struct work_struct *work)
334{
335 struct hidpp_device *hidpp = container_of(work, struct hidpp_device,
336 work);
337 hidpp_connect_event(hidpp);
338}
339
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400340static inline bool hidpp_match_answer(struct hidpp_report *question,
341 struct hidpp_report *answer)
342{
343 return (answer->fap.feature_index == question->fap.feature_index) &&
344 (answer->fap.funcindex_clientid == question->fap.funcindex_clientid);
345}
346
347static inline bool hidpp_match_error(struct hidpp_report *question,
348 struct hidpp_report *answer)
349{
Peter Wuf677bb12014-12-16 01:50:14 +0100350 return ((answer->rap.sub_id == HIDPP_ERROR) ||
351 (answer->fap.feature_index == HIDPP20_ERROR)) &&
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400352 (answer->fap.funcindex_clientid == question->fap.feature_index) &&
353 (answer->fap.params[0] == question->fap.funcindex_clientid);
354}
355
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -0400356static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
357{
358 return (report->report_id == REPORT_ID_HIDPP_SHORT) &&
359 (report->rap.sub_id == 0x41);
360}
361
Benjamin Tissoiresa0e625f2014-12-11 17:39:59 -0500362/**
363 * hidpp_prefix_name() prefixes the current given name with "Logitech ".
364 */
365static void hidpp_prefix_name(char **name, int name_length)
366{
367#define PREFIX_LENGTH 9 /* "Logitech " */
368
369 int new_length;
370 char *new_name;
371
372 if (name_length > PREFIX_LENGTH &&
373 strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0)
374 /* The prefix has is already in the name */
375 return;
376
377 new_length = PREFIX_LENGTH + name_length;
378 new_name = kzalloc(new_length, GFP_KERNEL);
379 if (!new_name)
380 return;
381
382 snprintf(new_name, new_length, "Logitech %s", *name);
383
384 kfree(*name);
385
386 *name = new_name;
387}
388
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400389/* -------------------------------------------------------------------------- */
Benjamin Tissoires33797822014-09-30 13:18:30 -0400390/* HIDP++ 1.0 commands */
391/* -------------------------------------------------------------------------- */
392
393#define HIDPP_SET_REGISTER 0x80
394#define HIDPP_GET_REGISTER 0x81
395#define HIDPP_SET_LONG_REGISTER 0x82
396#define HIDPP_GET_LONG_REGISTER 0x83
397
398#define HIDPP_REG_PAIRING_INFORMATION 0xB5
Benjamin Tissoires843c6242017-03-27 16:59:26 +0200399#define HIDPP_EXTENDED_PAIRING 0x30
400#define HIDPP_DEVICE_NAME 0x40
Benjamin Tissoires33797822014-09-30 13:18:30 -0400401
Benjamin Tissoires843c6242017-03-27 16:59:26 +0200402static char *hidpp_unifying_get_name(struct hidpp_device *hidpp_dev)
Benjamin Tissoires33797822014-09-30 13:18:30 -0400403{
404 struct hidpp_report response;
405 int ret;
Benjamin Tissoires843c6242017-03-27 16:59:26 +0200406 u8 params[1] = { HIDPP_DEVICE_NAME };
Benjamin Tissoires33797822014-09-30 13:18:30 -0400407 char *name;
408 int len;
409
410 ret = hidpp_send_rap_command_sync(hidpp_dev,
411 REPORT_ID_HIDPP_SHORT,
412 HIDPP_GET_LONG_REGISTER,
413 HIDPP_REG_PAIRING_INFORMATION,
414 params, 1, &response);
415 if (ret)
416 return NULL;
417
418 len = response.rap.params[1];
419
Peter Wu3a034a72014-12-11 13:51:19 +0100420 if (2 + len > sizeof(response.rap.params))
421 return NULL;
422
Benjamin Tissoires33797822014-09-30 13:18:30 -0400423 name = kzalloc(len + 1, GFP_KERNEL);
424 if (!name)
425 return NULL;
426
427 memcpy(name, &response.rap.params[2], len);
Benjamin Tissoiresa0e625f2014-12-11 17:39:59 -0500428
429 /* include the terminating '\0' */
430 hidpp_prefix_name(&name, len + 1);
431
Benjamin Tissoires33797822014-09-30 13:18:30 -0400432 return name;
433}
434
Benjamin Tissoires843c6242017-03-27 16:59:26 +0200435static int hidpp_unifying_get_serial(struct hidpp_device *hidpp, u32 *serial)
436{
437 struct hidpp_report response;
438 int ret;
439 u8 params[1] = { HIDPP_EXTENDED_PAIRING };
440
441 ret = hidpp_send_rap_command_sync(hidpp,
442 REPORT_ID_HIDPP_SHORT,
443 HIDPP_GET_LONG_REGISTER,
444 HIDPP_REG_PAIRING_INFORMATION,
445 params, 1, &response);
446 if (ret)
447 return ret;
448
449 /*
450 * We don't care about LE or BE, we will output it as a string
451 * with %4phD, so we need to keep the order.
452 */
453 *serial = *((u32 *)&response.rap.params[1]);
454 return 0;
455}
456
457static int hidpp_unifying_init(struct hidpp_device *hidpp)
458{
459 struct hid_device *hdev = hidpp->hid_dev;
460 const char *name;
461 u32 serial;
462 int ret;
463
464 ret = hidpp_unifying_get_serial(hidpp, &serial);
465 if (ret)
466 return ret;
467
468 snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
469 hdev->product, &serial);
470 dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq);
471
472 name = hidpp_unifying_get_name(hidpp);
473 if (!name)
474 return -EIO;
475
476 snprintf(hdev->name, sizeof(hdev->name), "%s", name);
477 dbg_hid("HID++ Unifying: Got name: %s\n", name);
478
479 kfree(name);
480 return 0;
481}
482
Benjamin Tissoires33797822014-09-30 13:18:30 -0400483/* -------------------------------------------------------------------------- */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400484/* 0x0000: Root */
485/* -------------------------------------------------------------------------- */
486
487#define HIDPP_PAGE_ROOT 0x0000
488#define HIDPP_PAGE_ROOT_IDX 0x00
489
490#define CMD_ROOT_GET_FEATURE 0x01
491#define CMD_ROOT_GET_PROTOCOL_VERSION 0x11
492
493static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature,
494 u8 *feature_index, u8 *feature_type)
495{
496 struct hidpp_report response;
497 int ret;
498 u8 params[2] = { feature >> 8, feature & 0x00FF };
499
500 ret = hidpp_send_fap_command_sync(hidpp,
501 HIDPP_PAGE_ROOT_IDX,
502 CMD_ROOT_GET_FEATURE,
503 params, 2, &response);
504 if (ret)
505 return ret;
506
Benjamin Tissoiresa9525b82017-03-27 16:59:32 +0200507 if (response.fap.params[0] == 0)
508 return -ENOENT;
509
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400510 *feature_index = response.fap.params[0];
511 *feature_type = response.fap.params[1];
512
513 return ret;
514}
515
516static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
517{
518 struct hidpp_report response;
519 int ret;
520
521 ret = hidpp_send_fap_command_sync(hidpp,
522 HIDPP_PAGE_ROOT_IDX,
523 CMD_ROOT_GET_PROTOCOL_VERSION,
524 NULL, 0, &response);
525
Benjamin Tissoires552f12e2014-11-03 16:09:59 -0500526 if (ret == HIDPP_ERROR_INVALID_SUBID) {
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400527 hidpp->protocol_major = 1;
528 hidpp->protocol_minor = 0;
529 return 0;
530 }
531
Benjamin Tissoires552f12e2014-11-03 16:09:59 -0500532 /* the device might not be connected */
533 if (ret == HIDPP_ERROR_RESOURCE_ERROR)
534 return -EIO;
535
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500536 if (ret > 0) {
537 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
538 __func__, ret);
539 return -EPROTO;
540 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400541 if (ret)
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500542 return ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400543
544 hidpp->protocol_major = response.fap.params[0];
545 hidpp->protocol_minor = response.fap.params[1];
546
547 return ret;
548}
549
550static bool hidpp_is_connected(struct hidpp_device *hidpp)
551{
552 int ret;
553
554 ret = hidpp_root_get_protocol_version(hidpp);
555 if (!ret)
556 hid_dbg(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
557 hidpp->protocol_major, hidpp->protocol_minor);
558 return ret == 0;
559}
560
561/* -------------------------------------------------------------------------- */
562/* 0x0005: GetDeviceNameType */
563/* -------------------------------------------------------------------------- */
564
565#define HIDPP_PAGE_GET_DEVICE_NAME_TYPE 0x0005
566
567#define CMD_GET_DEVICE_NAME_TYPE_GET_COUNT 0x01
568#define CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11
569#define CMD_GET_DEVICE_NAME_TYPE_GET_TYPE 0x21
570
571static int hidpp_devicenametype_get_count(struct hidpp_device *hidpp,
572 u8 feature_index, u8 *nameLength)
573{
574 struct hidpp_report response;
575 int ret;
576
577 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
578 CMD_GET_DEVICE_NAME_TYPE_GET_COUNT, NULL, 0, &response);
579
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500580 if (ret > 0) {
581 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
582 __func__, ret);
583 return -EPROTO;
584 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400585 if (ret)
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500586 return ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400587
588 *nameLength = response.fap.params[0];
589
590 return ret;
591}
592
593static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp,
594 u8 feature_index, u8 char_index, char *device_name, int len_buf)
595{
596 struct hidpp_report response;
597 int ret, i;
598 int count;
599
600 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
601 CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME, &char_index, 1,
602 &response);
603
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500604 if (ret > 0) {
605 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
606 __func__, ret);
607 return -EPROTO;
608 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400609 if (ret)
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500610 return ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400611
Simon Wooda5ce8f52015-11-19 16:42:11 -0700612 switch (response.report_id) {
613 case REPORT_ID_HIDPP_VERY_LONG:
614 count = HIDPP_REPORT_VERY_LONG_LENGTH - 4;
615 break;
616 case REPORT_ID_HIDPP_LONG:
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400617 count = HIDPP_REPORT_LONG_LENGTH - 4;
Simon Wooda5ce8f52015-11-19 16:42:11 -0700618 break;
619 case REPORT_ID_HIDPP_SHORT:
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400620 count = HIDPP_REPORT_SHORT_LENGTH - 4;
Simon Wooda5ce8f52015-11-19 16:42:11 -0700621 break;
622 default:
623 return -EPROTO;
624 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400625
626 if (len_buf < count)
627 count = len_buf;
628
629 for (i = 0; i < count; i++)
630 device_name[i] = response.fap.params[i];
631
632 return count;
633}
634
Peter Wu02cc0972014-12-11 13:51:17 +0100635static char *hidpp_get_device_name(struct hidpp_device *hidpp)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400636{
637 u8 feature_type;
638 u8 feature_index;
639 u8 __name_length;
640 char *name;
641 unsigned index = 0;
642 int ret;
643
644 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_GET_DEVICE_NAME_TYPE,
645 &feature_index, &feature_type);
646 if (ret)
Peter Wu02cc0972014-12-11 13:51:17 +0100647 return NULL;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400648
649 ret = hidpp_devicenametype_get_count(hidpp, feature_index,
650 &__name_length);
651 if (ret)
Peter Wu02cc0972014-12-11 13:51:17 +0100652 return NULL;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400653
654 name = kzalloc(__name_length + 1, GFP_KERNEL);
655 if (!name)
Peter Wu02cc0972014-12-11 13:51:17 +0100656 return NULL;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400657
Peter Wu1430ee72014-12-11 13:51:18 +0100658 while (index < __name_length) {
659 ret = hidpp_devicenametype_get_device_name(hidpp,
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400660 feature_index, index, name + index,
661 __name_length - index);
Peter Wu1430ee72014-12-11 13:51:18 +0100662 if (ret <= 0) {
663 kfree(name);
664 return NULL;
665 }
666 index += ret;
667 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400668
Benjamin Tissoiresa0e625f2014-12-11 17:39:59 -0500669 /* include the terminating '\0' */
670 hidpp_prefix_name(&name, __name_length + 1);
671
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400672 return name;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400673}
674
675/* -------------------------------------------------------------------------- */
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000676/* 0x1000: Battery level status */
677/* -------------------------------------------------------------------------- */
678
679#define HIDPP_PAGE_BATTERY_LEVEL_STATUS 0x1000
680
681#define CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS 0x00
682#define CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_CAPABILITY 0x10
683
684#define EVENT_BATTERY_LEVEL_STATUS_BROADCAST 0x00
685
686static int hidpp20_batterylevel_map_status_level(u8 data[3], int *level,
687 int *next_level)
688{
689 int status;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000690
691 *level = data[0];
692 *next_level = data[1];
693
694 /* When discharging, we can rely on the device reported level.
695 * For all other states the device reports level 0 (unknown). Make up
696 * a number instead
697 */
698 switch (data[2]) {
699 case 0: /* discharging (in use) */
700 status = POWER_SUPPLY_STATUS_DISCHARGING;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000701 break;
702 case 1: /* recharging */
703 status = POWER_SUPPLY_STATUS_CHARGING;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000704 break;
705 case 2: /* charge in final stage */
706 status = POWER_SUPPLY_STATUS_CHARGING;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000707 break;
708 case 3: /* charge complete */
709 status = POWER_SUPPLY_STATUS_FULL;
Benjamin Tissoires284f8d72017-03-27 16:59:34 +0200710 *level = 100;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000711 break;
712 case 4: /* recharging below optimal speed */
713 status = POWER_SUPPLY_STATUS_CHARGING;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000714 break;
715 /* 5 = invalid battery type
716 6 = thermal error
717 7 = other charging error */
718 default:
719 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000720 break;
721 }
722
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000723 return status;
724}
725
726static int hidpp20_batterylevel_get_battery_level(struct hidpp_device *hidpp,
727 u8 feature_index,
728 int *status,
729 int *level,
730 int *next_level)
731{
732 struct hidpp_report response;
733 int ret;
734 u8 *params = (u8 *)response.fap.params;
735
736 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
737 CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS,
738 NULL, 0, &response);
739 if (ret > 0) {
740 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
741 __func__, ret);
742 return -EPROTO;
743 }
744 if (ret)
745 return ret;
746
747 *status = hidpp20_batterylevel_map_status_level(params, level,
748 next_level);
749
750 return 0;
751}
752
753static int hidpp20_query_battery_info(struct hidpp_device *hidpp)
754{
755 u8 feature_type;
756 int ret;
757 int status, level, next_level;
758
759 if (hidpp->battery.feature_index == 0) {
760 ret = hidpp_root_get_feature(hidpp,
761 HIDPP_PAGE_BATTERY_LEVEL_STATUS,
762 &hidpp->battery.feature_index,
763 &feature_type);
764 if (ret)
765 return ret;
766 }
767
768 ret = hidpp20_batterylevel_get_battery_level(hidpp,
769 hidpp->battery.feature_index,
770 &status, &level, &next_level);
771 if (ret)
772 return ret;
773
774 hidpp->battery.status = status;
775 hidpp->battery.level = level;
Benjamin Tissoires284f8d72017-03-27 16:59:34 +0200776 /* the capacity is only available when discharging or full */
777 hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING ||
778 status == POWER_SUPPLY_STATUS_FULL;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000779
780 return 0;
781}
782
783static int hidpp20_battery_event(struct hidpp_device *hidpp,
784 u8 *data, int size)
785{
786 struct hidpp_report *report = (struct hidpp_report *)data;
787 int status, level, next_level;
788 bool changed;
789
790 if (report->fap.feature_index != hidpp->battery.feature_index ||
791 report->fap.funcindex_clientid != EVENT_BATTERY_LEVEL_STATUS_BROADCAST)
792 return 0;
793
794 status = hidpp20_batterylevel_map_status_level(report->fap.params,
795 &level, &next_level);
796
Benjamin Tissoires284f8d72017-03-27 16:59:34 +0200797 /* the capacity is only available when discharging or full */
798 hidpp->battery.online = status == POWER_SUPPLY_STATUS_DISCHARGING ||
799 status == POWER_SUPPLY_STATUS_FULL;
800
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000801 changed = level != hidpp->battery.level ||
802 status != hidpp->battery.status;
803
804 if (changed) {
805 hidpp->battery.level = level;
806 hidpp->battery.status = status;
807 if (hidpp->battery.ps)
808 power_supply_changed(hidpp->battery.ps);
809 }
810
811 return 0;
812}
813
814static enum power_supply_property hidpp_battery_props[] = {
Benjamin Tissoires284f8d72017-03-27 16:59:34 +0200815 POWER_SUPPLY_PROP_ONLINE,
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000816 POWER_SUPPLY_PROP_STATUS,
817 POWER_SUPPLY_PROP_CAPACITY,
Bastien Nocera3861e6c2017-03-27 16:59:22 +0200818 POWER_SUPPLY_PROP_SCOPE,
Benjamin Tissoires32043d02017-03-27 16:59:30 +0200819 POWER_SUPPLY_PROP_MODEL_NAME,
820 POWER_SUPPLY_PROP_MANUFACTURER,
821 POWER_SUPPLY_PROP_SERIAL_NUMBER,
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000822};
823
824static int hidpp_battery_get_property(struct power_supply *psy,
825 enum power_supply_property psp,
826 union power_supply_propval *val)
827{
828 struct hidpp_device *hidpp = power_supply_get_drvdata(psy);
829 int ret = 0;
830
831 switch(psp) {
832 case POWER_SUPPLY_PROP_STATUS:
833 val->intval = hidpp->battery.status;
834 break;
835 case POWER_SUPPLY_PROP_CAPACITY:
836 val->intval = hidpp->battery.level;
837 break;
Bastien Nocera3861e6c2017-03-27 16:59:22 +0200838 case POWER_SUPPLY_PROP_SCOPE:
839 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
840 break;
Benjamin Tissoires284f8d72017-03-27 16:59:34 +0200841 case POWER_SUPPLY_PROP_ONLINE:
842 val->intval = hidpp->battery.online;
843 break;
Benjamin Tissoires32043d02017-03-27 16:59:30 +0200844 case POWER_SUPPLY_PROP_MODEL_NAME:
845 if (!strncmp(hidpp->name, "Logitech ", 9))
846 val->strval = hidpp->name + 9;
847 else
848 val->strval = hidpp->name;
849 break;
850 case POWER_SUPPLY_PROP_MANUFACTURER:
851 val->strval = "Logitech";
852 break;
853 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
854 val->strval = hidpp->hid_dev->uniq;
855 break;
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000856 default:
857 ret = -EINVAL;
858 break;
859 }
860
861 return ret;
862}
863
Peter Hutterer5a2b1902016-06-29 19:28:01 +1000864/* -------------------------------------------------------------------------- */
Benjamin Tissoires90cdd982015-09-03 09:08:30 -0400865/* 0x6010: Touchpad FW items */
866/* -------------------------------------------------------------------------- */
867
868#define HIDPP_PAGE_TOUCHPAD_FW_ITEMS 0x6010
869
870#define CMD_TOUCHPAD_FW_ITEMS_SET 0x10
871
872struct hidpp_touchpad_fw_items {
873 uint8_t presence;
874 uint8_t desired_state;
875 uint8_t state;
876 uint8_t persistent;
877};
878
879/**
880 * send a set state command to the device by reading the current items->state
881 * field. items is then filled with the current state.
882 */
883static int hidpp_touchpad_fw_items_set(struct hidpp_device *hidpp,
884 u8 feature_index,
885 struct hidpp_touchpad_fw_items *items)
886{
887 struct hidpp_report response;
888 int ret;
889 u8 *params = (u8 *)response.fap.params;
890
891 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
892 CMD_TOUCHPAD_FW_ITEMS_SET, &items->state, 1, &response);
893
894 if (ret > 0) {
895 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
896 __func__, ret);
897 return -EPROTO;
898 }
899 if (ret)
900 return ret;
901
902 items->presence = params[0];
903 items->desired_state = params[1];
904 items->state = params[2];
905 items->persistent = params[3];
906
907 return 0;
908}
909
910/* -------------------------------------------------------------------------- */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400911/* 0x6100: TouchPadRawXY */
912/* -------------------------------------------------------------------------- */
913
914#define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100
915
916#define CMD_TOUCHPAD_GET_RAW_INFO 0x01
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400917#define CMD_TOUCHPAD_SET_RAW_REPORT_STATE 0x21
918
919#define EVENT_TOUCHPAD_RAW_XY 0x00
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400920
921#define TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT 0x01
922#define TOUCHPAD_RAW_XY_ORIGIN_UPPER_LEFT 0x03
923
924struct hidpp_touchpad_raw_info {
925 u16 x_size;
926 u16 y_size;
927 u8 z_range;
928 u8 area_range;
929 u8 timestamp_unit;
930 u8 maxcontacts;
931 u8 origin;
932 u16 res;
933};
934
935struct hidpp_touchpad_raw_xy_finger {
936 u8 contact_type;
937 u8 contact_status;
938 u16 x;
939 u16 y;
940 u8 z;
941 u8 area;
942 u8 finger_id;
943};
944
945struct hidpp_touchpad_raw_xy {
946 u16 timestamp;
947 struct hidpp_touchpad_raw_xy_finger fingers[2];
948 u8 spurious_flag;
949 u8 end_of_frame;
950 u8 finger_count;
951 u8 button;
952};
953
954static int hidpp_touchpad_get_raw_info(struct hidpp_device *hidpp,
955 u8 feature_index, struct hidpp_touchpad_raw_info *raw_info)
956{
957 struct hidpp_report response;
958 int ret;
959 u8 *params = (u8 *)response.fap.params;
960
961 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
962 CMD_TOUCHPAD_GET_RAW_INFO, NULL, 0, &response);
963
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500964 if (ret > 0) {
965 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
966 __func__, ret);
967 return -EPROTO;
968 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400969 if (ret)
Benjamin Tissoires8c9952b2014-11-03 16:09:58 -0500970 return ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -0400971
972 raw_info->x_size = get_unaligned_be16(&params[0]);
973 raw_info->y_size = get_unaligned_be16(&params[2]);
974 raw_info->z_range = params[4];
975 raw_info->area_range = params[5];
976 raw_info->maxcontacts = params[7];
977 raw_info->origin = params[8];
978 /* res is given in unit per inch */
979 raw_info->res = get_unaligned_be16(&params[13]) * 2 / 51;
980
981 return ret;
982}
983
Benjamin Tissoires586bdc42014-09-30 13:18:33 -0400984static int hidpp_touchpad_set_raw_report_state(struct hidpp_device *hidpp_dev,
985 u8 feature_index, bool send_raw_reports,
986 bool sensor_enhanced_settings)
987{
988 struct hidpp_report response;
989
990 /*
991 * Params:
992 * bit 0 - enable raw
993 * bit 1 - 16bit Z, no area
994 * bit 2 - enhanced sensitivity
995 * bit 3 - width, height (4 bits each) instead of area
996 * bit 4 - send raw + gestures (degrades smoothness)
997 * remaining bits - reserved
998 */
999 u8 params = send_raw_reports | (sensor_enhanced_settings << 2);
1000
1001 return hidpp_send_fap_command_sync(hidpp_dev, feature_index,
1002 CMD_TOUCHPAD_SET_RAW_REPORT_STATE, &params, 1, &response);
1003}
1004
1005static void hidpp_touchpad_touch_event(u8 *data,
1006 struct hidpp_touchpad_raw_xy_finger *finger)
1007{
1008 u8 x_m = data[0] << 2;
1009 u8 y_m = data[2] << 2;
1010
1011 finger->x = x_m << 6 | data[1];
1012 finger->y = y_m << 6 | data[3];
1013
1014 finger->contact_type = data[0] >> 6;
1015 finger->contact_status = data[2] >> 6;
1016
1017 finger->z = data[4];
1018 finger->area = data[5];
1019 finger->finger_id = data[6] >> 4;
1020}
1021
1022static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev,
1023 u8 *data, struct hidpp_touchpad_raw_xy *raw_xy)
1024{
1025 memset(raw_xy, 0, sizeof(struct hidpp_touchpad_raw_xy));
1026 raw_xy->end_of_frame = data[8] & 0x01;
1027 raw_xy->spurious_flag = (data[8] >> 1) & 0x01;
1028 raw_xy->finger_count = data[15] & 0x0f;
1029 raw_xy->button = (data[8] >> 2) & 0x01;
1030
1031 if (raw_xy->finger_count) {
1032 hidpp_touchpad_touch_event(&data[2], &raw_xy->fingers[0]);
1033 hidpp_touchpad_touch_event(&data[9], &raw_xy->fingers[1]);
1034 }
1035}
1036
Edwin Veldsff21a632016-01-11 00:25:15 +01001037/* -------------------------------------------------------------------------- */
1038/* 0x8123: Force feedback support */
1039/* -------------------------------------------------------------------------- */
1040
1041#define HIDPP_FF_GET_INFO 0x01
1042#define HIDPP_FF_RESET_ALL 0x11
1043#define HIDPP_FF_DOWNLOAD_EFFECT 0x21
1044#define HIDPP_FF_SET_EFFECT_STATE 0x31
1045#define HIDPP_FF_DESTROY_EFFECT 0x41
1046#define HIDPP_FF_GET_APERTURE 0x51
1047#define HIDPP_FF_SET_APERTURE 0x61
1048#define HIDPP_FF_GET_GLOBAL_GAINS 0x71
1049#define HIDPP_FF_SET_GLOBAL_GAINS 0x81
1050
1051#define HIDPP_FF_EFFECT_STATE_GET 0x00
1052#define HIDPP_FF_EFFECT_STATE_STOP 0x01
1053#define HIDPP_FF_EFFECT_STATE_PLAY 0x02
1054#define HIDPP_FF_EFFECT_STATE_PAUSE 0x03
1055
1056#define HIDPP_FF_EFFECT_CONSTANT 0x00
1057#define HIDPP_FF_EFFECT_PERIODIC_SINE 0x01
1058#define HIDPP_FF_EFFECT_PERIODIC_SQUARE 0x02
1059#define HIDPP_FF_EFFECT_PERIODIC_TRIANGLE 0x03
1060#define HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHUP 0x04
1061#define HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHDOWN 0x05
1062#define HIDPP_FF_EFFECT_SPRING 0x06
1063#define HIDPP_FF_EFFECT_DAMPER 0x07
1064#define HIDPP_FF_EFFECT_FRICTION 0x08
1065#define HIDPP_FF_EFFECT_INERTIA 0x09
1066#define HIDPP_FF_EFFECT_RAMP 0x0A
1067
1068#define HIDPP_FF_EFFECT_AUTOSTART 0x80
1069
1070#define HIDPP_FF_EFFECTID_NONE -1
1071#define HIDPP_FF_EFFECTID_AUTOCENTER -2
1072
1073#define HIDPP_FF_MAX_PARAMS 20
1074#define HIDPP_FF_RESERVED_SLOTS 1
1075
1076struct hidpp_ff_private_data {
1077 struct hidpp_device *hidpp;
1078 u8 feature_index;
1079 u8 version;
1080 u16 gain;
1081 s16 range;
1082 u8 slot_autocenter;
1083 u8 num_effects;
1084 int *effect_ids;
1085 struct workqueue_struct *wq;
1086 atomic_t workqueue_size;
1087};
1088
1089struct hidpp_ff_work_data {
1090 struct work_struct work;
1091 struct hidpp_ff_private_data *data;
1092 int effect_id;
1093 u8 command;
1094 u8 params[HIDPP_FF_MAX_PARAMS];
1095 u8 size;
1096};
1097
1098static const signed short hiddpp_ff_effects[] = {
1099 FF_CONSTANT,
1100 FF_PERIODIC,
1101 FF_SINE,
1102 FF_SQUARE,
1103 FF_SAW_UP,
1104 FF_SAW_DOWN,
1105 FF_TRIANGLE,
1106 FF_SPRING,
1107 FF_DAMPER,
1108 FF_AUTOCENTER,
1109 FF_GAIN,
1110 -1
1111};
1112
1113static const signed short hiddpp_ff_effects_v2[] = {
1114 FF_RAMP,
1115 FF_FRICTION,
1116 FF_INERTIA,
1117 -1
1118};
1119
1120static const u8 HIDPP_FF_CONDITION_CMDS[] = {
1121 HIDPP_FF_EFFECT_SPRING,
1122 HIDPP_FF_EFFECT_FRICTION,
1123 HIDPP_FF_EFFECT_DAMPER,
1124 HIDPP_FF_EFFECT_INERTIA
1125};
1126
1127static const char *HIDPP_FF_CONDITION_NAMES[] = {
1128 "spring",
1129 "friction",
1130 "damper",
1131 "inertia"
1132};
1133
1134
1135static u8 hidpp_ff_find_effect(struct hidpp_ff_private_data *data, int effect_id)
1136{
1137 int i;
1138
1139 for (i = 0; i < data->num_effects; i++)
1140 if (data->effect_ids[i] == effect_id)
1141 return i+1;
1142
1143 return 0;
1144}
1145
1146static void hidpp_ff_work_handler(struct work_struct *w)
1147{
1148 struct hidpp_ff_work_data *wd = container_of(w, struct hidpp_ff_work_data, work);
1149 struct hidpp_ff_private_data *data = wd->data;
1150 struct hidpp_report response;
1151 u8 slot;
1152 int ret;
1153
1154 /* add slot number if needed */
1155 switch (wd->effect_id) {
1156 case HIDPP_FF_EFFECTID_AUTOCENTER:
1157 wd->params[0] = data->slot_autocenter;
1158 break;
1159 case HIDPP_FF_EFFECTID_NONE:
1160 /* leave slot as zero */
1161 break;
1162 default:
1163 /* find current slot for effect */
1164 wd->params[0] = hidpp_ff_find_effect(data, wd->effect_id);
1165 break;
1166 }
1167
1168 /* send command and wait for reply */
1169 ret = hidpp_send_fap_command_sync(data->hidpp, data->feature_index,
1170 wd->command, wd->params, wd->size, &response);
1171
1172 if (ret) {
1173 hid_err(data->hidpp->hid_dev, "Failed to send command to device!\n");
1174 goto out;
1175 }
1176
1177 /* parse return data */
1178 switch (wd->command) {
1179 case HIDPP_FF_DOWNLOAD_EFFECT:
1180 slot = response.fap.params[0];
1181 if (slot > 0 && slot <= data->num_effects) {
1182 if (wd->effect_id >= 0)
1183 /* regular effect uploaded */
1184 data->effect_ids[slot-1] = wd->effect_id;
1185 else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER)
1186 /* autocenter spring uploaded */
1187 data->slot_autocenter = slot;
1188 }
1189 break;
1190 case HIDPP_FF_DESTROY_EFFECT:
1191 if (wd->effect_id >= 0)
1192 /* regular effect destroyed */
1193 data->effect_ids[wd->params[0]-1] = -1;
1194 else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER)
1195 /* autocenter spring destoyed */
1196 data->slot_autocenter = 0;
1197 break;
1198 case HIDPP_FF_SET_GLOBAL_GAINS:
1199 data->gain = (wd->params[0] << 8) + wd->params[1];
1200 break;
1201 case HIDPP_FF_SET_APERTURE:
1202 data->range = (wd->params[0] << 8) + wd->params[1];
1203 break;
1204 default:
1205 /* no action needed */
1206 break;
1207 }
1208
1209out:
1210 atomic_dec(&data->workqueue_size);
1211 kfree(wd);
1212}
1213
1214static int hidpp_ff_queue_work(struct hidpp_ff_private_data *data, int effect_id, u8 command, u8 *params, u8 size)
1215{
1216 struct hidpp_ff_work_data *wd = kzalloc(sizeof(*wd), GFP_KERNEL);
1217 int s;
1218
1219 if (!wd)
1220 return -ENOMEM;
1221
1222 INIT_WORK(&wd->work, hidpp_ff_work_handler);
1223
1224 wd->data = data;
1225 wd->effect_id = effect_id;
1226 wd->command = command;
1227 wd->size = size;
1228 memcpy(wd->params, params, size);
1229
1230 atomic_inc(&data->workqueue_size);
1231 queue_work(data->wq, &wd->work);
1232
1233 /* warn about excessive queue size */
1234 s = atomic_read(&data->workqueue_size);
1235 if (s >= 20 && s % 20 == 0)
1236 hid_warn(data->hidpp->hid_dev, "Force feedback command queue contains %d commands, causing substantial delays!", s);
1237
1238 return 0;
1239}
1240
1241static int hidpp_ff_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
1242{
1243 struct hidpp_ff_private_data *data = dev->ff->private;
1244 u8 params[20];
1245 u8 size;
1246 int force;
1247
1248 /* set common parameters */
1249 params[2] = effect->replay.length >> 8;
1250 params[3] = effect->replay.length & 255;
1251 params[4] = effect->replay.delay >> 8;
1252 params[5] = effect->replay.delay & 255;
1253
1254 switch (effect->type) {
1255 case FF_CONSTANT:
1256 force = (effect->u.constant.level * fixp_sin16((effect->direction * 360) >> 16)) >> 15;
1257 params[1] = HIDPP_FF_EFFECT_CONSTANT;
1258 params[6] = force >> 8;
1259 params[7] = force & 255;
1260 params[8] = effect->u.constant.envelope.attack_level >> 7;
1261 params[9] = effect->u.constant.envelope.attack_length >> 8;
1262 params[10] = effect->u.constant.envelope.attack_length & 255;
1263 params[11] = effect->u.constant.envelope.fade_level >> 7;
1264 params[12] = effect->u.constant.envelope.fade_length >> 8;
1265 params[13] = effect->u.constant.envelope.fade_length & 255;
1266 size = 14;
1267 dbg_hid("Uploading constant force level=%d in dir %d = %d\n",
1268 effect->u.constant.level,
1269 effect->direction, force);
1270 dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n",
1271 effect->u.constant.envelope.attack_level,
1272 effect->u.constant.envelope.attack_length,
1273 effect->u.constant.envelope.fade_level,
1274 effect->u.constant.envelope.fade_length);
1275 break;
1276 case FF_PERIODIC:
1277 {
1278 switch (effect->u.periodic.waveform) {
1279 case FF_SINE:
1280 params[1] = HIDPP_FF_EFFECT_PERIODIC_SINE;
1281 break;
1282 case FF_SQUARE:
1283 params[1] = HIDPP_FF_EFFECT_PERIODIC_SQUARE;
1284 break;
1285 case FF_SAW_UP:
1286 params[1] = HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHUP;
1287 break;
1288 case FF_SAW_DOWN:
1289 params[1] = HIDPP_FF_EFFECT_PERIODIC_SAWTOOTHDOWN;
1290 break;
1291 case FF_TRIANGLE:
1292 params[1] = HIDPP_FF_EFFECT_PERIODIC_TRIANGLE;
1293 break;
1294 default:
1295 hid_err(data->hidpp->hid_dev, "Unexpected periodic waveform type %i!\n", effect->u.periodic.waveform);
1296 return -EINVAL;
1297 }
1298 force = (effect->u.periodic.magnitude * fixp_sin16((effect->direction * 360) >> 16)) >> 15;
1299 params[6] = effect->u.periodic.magnitude >> 8;
1300 params[7] = effect->u.periodic.magnitude & 255;
1301 params[8] = effect->u.periodic.offset >> 8;
1302 params[9] = effect->u.periodic.offset & 255;
1303 params[10] = effect->u.periodic.period >> 8;
1304 params[11] = effect->u.periodic.period & 255;
1305 params[12] = effect->u.periodic.phase >> 8;
1306 params[13] = effect->u.periodic.phase & 255;
1307 params[14] = effect->u.periodic.envelope.attack_level >> 7;
1308 params[15] = effect->u.periodic.envelope.attack_length >> 8;
1309 params[16] = effect->u.periodic.envelope.attack_length & 255;
1310 params[17] = effect->u.periodic.envelope.fade_level >> 7;
1311 params[18] = effect->u.periodic.envelope.fade_length >> 8;
1312 params[19] = effect->u.periodic.envelope.fade_length & 255;
1313 size = 20;
1314 dbg_hid("Uploading periodic force mag=%d/dir=%d, offset=%d, period=%d ms, phase=%d\n",
1315 effect->u.periodic.magnitude, effect->direction,
1316 effect->u.periodic.offset,
1317 effect->u.periodic.period,
1318 effect->u.periodic.phase);
1319 dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n",
1320 effect->u.periodic.envelope.attack_level,
1321 effect->u.periodic.envelope.attack_length,
1322 effect->u.periodic.envelope.fade_level,
1323 effect->u.periodic.envelope.fade_length);
1324 break;
1325 }
1326 case FF_RAMP:
1327 params[1] = HIDPP_FF_EFFECT_RAMP;
1328 force = (effect->u.ramp.start_level * fixp_sin16((effect->direction * 360) >> 16)) >> 15;
1329 params[6] = force >> 8;
1330 params[7] = force & 255;
1331 force = (effect->u.ramp.end_level * fixp_sin16((effect->direction * 360) >> 16)) >> 15;
1332 params[8] = force >> 8;
1333 params[9] = force & 255;
1334 params[10] = effect->u.ramp.envelope.attack_level >> 7;
1335 params[11] = effect->u.ramp.envelope.attack_length >> 8;
1336 params[12] = effect->u.ramp.envelope.attack_length & 255;
1337 params[13] = effect->u.ramp.envelope.fade_level >> 7;
1338 params[14] = effect->u.ramp.envelope.fade_length >> 8;
1339 params[15] = effect->u.ramp.envelope.fade_length & 255;
1340 size = 16;
1341 dbg_hid("Uploading ramp force level=%d -> %d in dir %d = %d\n",
1342 effect->u.ramp.start_level,
1343 effect->u.ramp.end_level,
1344 effect->direction, force);
1345 dbg_hid(" envelope attack=(%d, %d ms) fade=(%d, %d ms)\n",
1346 effect->u.ramp.envelope.attack_level,
1347 effect->u.ramp.envelope.attack_length,
1348 effect->u.ramp.envelope.fade_level,
1349 effect->u.ramp.envelope.fade_length);
1350 break;
1351 case FF_FRICTION:
1352 case FF_INERTIA:
1353 case FF_SPRING:
1354 case FF_DAMPER:
1355 params[1] = HIDPP_FF_CONDITION_CMDS[effect->type - FF_SPRING];
1356 params[6] = effect->u.condition[0].left_saturation >> 9;
1357 params[7] = (effect->u.condition[0].left_saturation >> 1) & 255;
1358 params[8] = effect->u.condition[0].left_coeff >> 8;
1359 params[9] = effect->u.condition[0].left_coeff & 255;
1360 params[10] = effect->u.condition[0].deadband >> 9;
1361 params[11] = (effect->u.condition[0].deadband >> 1) & 255;
1362 params[12] = effect->u.condition[0].center >> 8;
1363 params[13] = effect->u.condition[0].center & 255;
1364 params[14] = effect->u.condition[0].right_coeff >> 8;
1365 params[15] = effect->u.condition[0].right_coeff & 255;
1366 params[16] = effect->u.condition[0].right_saturation >> 9;
1367 params[17] = (effect->u.condition[0].right_saturation >> 1) & 255;
1368 size = 18;
1369 dbg_hid("Uploading %s force left coeff=%d, left sat=%d, right coeff=%d, right sat=%d\n",
1370 HIDPP_FF_CONDITION_NAMES[effect->type - FF_SPRING],
1371 effect->u.condition[0].left_coeff,
1372 effect->u.condition[0].left_saturation,
1373 effect->u.condition[0].right_coeff,
1374 effect->u.condition[0].right_saturation);
1375 dbg_hid(" deadband=%d, center=%d\n",
1376 effect->u.condition[0].deadband,
1377 effect->u.condition[0].center);
1378 break;
1379 default:
1380 hid_err(data->hidpp->hid_dev, "Unexpected force type %i!\n", effect->type);
1381 return -EINVAL;
1382 }
1383
1384 return hidpp_ff_queue_work(data, effect->id, HIDPP_FF_DOWNLOAD_EFFECT, params, size);
1385}
1386
1387static int hidpp_ff_playback(struct input_dev *dev, int effect_id, int value)
1388{
1389 struct hidpp_ff_private_data *data = dev->ff->private;
1390 u8 params[2];
1391
1392 params[1] = value ? HIDPP_FF_EFFECT_STATE_PLAY : HIDPP_FF_EFFECT_STATE_STOP;
1393
1394 dbg_hid("St%sing playback of effect %d.\n", value?"art":"opp", effect_id);
1395
1396 return hidpp_ff_queue_work(data, effect_id, HIDPP_FF_SET_EFFECT_STATE, params, ARRAY_SIZE(params));
1397}
1398
1399static int hidpp_ff_erase_effect(struct input_dev *dev, int effect_id)
1400{
1401 struct hidpp_ff_private_data *data = dev->ff->private;
1402 u8 slot = 0;
1403
1404 dbg_hid("Erasing effect %d.\n", effect_id);
1405
1406 return hidpp_ff_queue_work(data, effect_id, HIDPP_FF_DESTROY_EFFECT, &slot, 1);
1407}
1408
1409static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude)
1410{
1411 struct hidpp_ff_private_data *data = dev->ff->private;
1412 u8 params[18];
1413
1414 dbg_hid("Setting autocenter to %d.\n", magnitude);
1415
1416 /* start a standard spring effect */
1417 params[1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART;
1418 /* zero delay and duration */
1419 params[2] = params[3] = params[4] = params[5] = 0;
1420 /* set coeff to 25% of saturation */
1421 params[8] = params[14] = magnitude >> 11;
1422 params[9] = params[15] = (magnitude >> 3) & 255;
1423 params[6] = params[16] = magnitude >> 9;
1424 params[7] = params[17] = (magnitude >> 1) & 255;
1425 /* zero deadband and center */
1426 params[10] = params[11] = params[12] = params[13] = 0;
1427
1428 hidpp_ff_queue_work(data, HIDPP_FF_EFFECTID_AUTOCENTER, HIDPP_FF_DOWNLOAD_EFFECT, params, ARRAY_SIZE(params));
1429}
1430
1431static void hidpp_ff_set_gain(struct input_dev *dev, u16 gain)
1432{
1433 struct hidpp_ff_private_data *data = dev->ff->private;
1434 u8 params[4];
1435
1436 dbg_hid("Setting gain to %d.\n", gain);
1437
1438 params[0] = gain >> 8;
1439 params[1] = gain & 255;
1440 params[2] = 0; /* no boost */
1441 params[3] = 0;
1442
1443 hidpp_ff_queue_work(data, HIDPP_FF_EFFECTID_NONE, HIDPP_FF_SET_GLOBAL_GAINS, params, ARRAY_SIZE(params));
1444}
1445
1446static ssize_t hidpp_ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
1447{
1448 struct hid_device *hid = to_hid_device(dev);
1449 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1450 struct input_dev *idev = hidinput->input;
1451 struct hidpp_ff_private_data *data = idev->ff->private;
1452
1453 return scnprintf(buf, PAGE_SIZE, "%u\n", data->range);
1454}
1455
1456static ssize_t hidpp_ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1457{
1458 struct hid_device *hid = to_hid_device(dev);
1459 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1460 struct input_dev *idev = hidinput->input;
1461 struct hidpp_ff_private_data *data = idev->ff->private;
1462 u8 params[2];
1463 int range = simple_strtoul(buf, NULL, 10);
1464
1465 range = clamp(range, 180, 900);
1466
1467 params[0] = range >> 8;
1468 params[1] = range & 0x00FF;
1469
1470 hidpp_ff_queue_work(data, -1, HIDPP_FF_SET_APERTURE, params, ARRAY_SIZE(params));
1471
1472 return count;
1473}
1474
1475static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, hidpp_ff_range_show, hidpp_ff_range_store);
1476
1477static void hidpp_ff_destroy(struct ff_device *ff)
1478{
1479 struct hidpp_ff_private_data *data = ff->private;
1480
1481 kfree(data->effect_ids);
1482}
1483
Jiri Kosinaaf2e6282016-01-28 14:28:39 +01001484static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
Edwin Veldsff21a632016-01-11 00:25:15 +01001485{
1486 struct hid_device *hid = hidpp->hid_dev;
1487 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1488 struct input_dev *dev = hidinput->input;
1489 const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
1490 const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
1491 struct ff_device *ff;
1492 struct hidpp_report response;
1493 struct hidpp_ff_private_data *data;
1494 int error, j, num_slots;
1495 u8 version;
1496
1497 if (!dev) {
1498 hid_err(hid, "Struct input_dev not set!\n");
1499 return -EINVAL;
1500 }
1501
1502 /* Get firmware release */
1503 version = bcdDevice & 255;
1504
1505 /* Set supported force feedback capabilities */
1506 for (j = 0; hiddpp_ff_effects[j] >= 0; j++)
1507 set_bit(hiddpp_ff_effects[j], dev->ffbit);
1508 if (version > 1)
1509 for (j = 0; hiddpp_ff_effects_v2[j] >= 0; j++)
1510 set_bit(hiddpp_ff_effects_v2[j], dev->ffbit);
1511
1512 /* Read number of slots available in device */
1513 error = hidpp_send_fap_command_sync(hidpp, feature_index,
1514 HIDPP_FF_GET_INFO, NULL, 0, &response);
1515 if (error) {
1516 if (error < 0)
1517 return error;
1518 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
1519 __func__, error);
1520 return -EPROTO;
1521 }
1522
1523 num_slots = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
1524
1525 error = input_ff_create(dev, num_slots);
1526
1527 if (error) {
1528 hid_err(dev, "Failed to create FF device!\n");
1529 return error;
1530 }
1531
1532 data = kzalloc(sizeof(*data), GFP_KERNEL);
1533 if (!data)
1534 return -ENOMEM;
1535 data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL);
1536 if (!data->effect_ids) {
1537 kfree(data);
1538 return -ENOMEM;
1539 }
1540 data->hidpp = hidpp;
1541 data->feature_index = feature_index;
1542 data->version = version;
1543 data->slot_autocenter = 0;
1544 data->num_effects = num_slots;
1545 for (j = 0; j < num_slots; j++)
1546 data->effect_ids[j] = -1;
1547
1548 ff = dev->ff;
1549 ff->private = data;
1550
1551 ff->upload = hidpp_ff_upload_effect;
1552 ff->erase = hidpp_ff_erase_effect;
1553 ff->playback = hidpp_ff_playback;
1554 ff->set_gain = hidpp_ff_set_gain;
1555 ff->set_autocenter = hidpp_ff_set_autocenter;
1556 ff->destroy = hidpp_ff_destroy;
1557
1558
1559 /* reset all forces */
1560 error = hidpp_send_fap_command_sync(hidpp, feature_index,
1561 HIDPP_FF_RESET_ALL, NULL, 0, &response);
1562
1563 /* Read current Range */
1564 error = hidpp_send_fap_command_sync(hidpp, feature_index,
1565 HIDPP_FF_GET_APERTURE, NULL, 0, &response);
1566 if (error)
1567 hid_warn(hidpp->hid_dev, "Failed to read range from device!\n");
1568 data->range = error ? 900 : get_unaligned_be16(&response.fap.params[0]);
1569
1570 /* Create sysfs interface */
1571 error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range);
1572 if (error)
1573 hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error);
1574
1575 /* Read the current gain values */
1576 error = hidpp_send_fap_command_sync(hidpp, feature_index,
1577 HIDPP_FF_GET_GLOBAL_GAINS, NULL, 0, &response);
1578 if (error)
1579 hid_warn(hidpp->hid_dev, "Failed to read gain values from device!\n");
1580 data->gain = error ? 0xffff : get_unaligned_be16(&response.fap.params[0]);
1581 /* ignore boost value at response.fap.params[2] */
1582
1583 /* init the hardware command queue */
1584 data->wq = create_singlethread_workqueue("hidpp-ff-sendqueue");
1585 atomic_set(&data->workqueue_size, 0);
1586
1587 /* initialize with zero autocenter to get wheel in usable state */
1588 hidpp_ff_set_autocenter(dev, 0);
1589
1590 hid_info(hid, "Force feeback support loaded (firmware release %d).\n", version);
1591
1592 return 0;
1593}
1594
Jiri Kosinaaf2e6282016-01-28 14:28:39 +01001595static int hidpp_ff_deinit(struct hid_device *hid)
Edwin Veldsff21a632016-01-11 00:25:15 +01001596{
1597 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1598 struct input_dev *dev = hidinput->input;
1599 struct hidpp_ff_private_data *data;
1600
1601 if (!dev) {
1602 hid_err(hid, "Struct input_dev not found!\n");
1603 return -EINVAL;
1604 }
1605
1606 hid_info(hid, "Unloading HID++ force feedback.\n");
1607 data = dev->ff->private;
1608 if (!data) {
1609 hid_err(hid, "Private data not found!\n");
1610 return -EINVAL;
1611 }
1612
1613 destroy_workqueue(data->wq);
1614 device_remove_file(&hid->dev, &dev_attr_range);
1615
1616 return 0;
1617}
1618
1619
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001620/* ************************************************************************** */
1621/* */
1622/* Device Support */
1623/* */
1624/* ************************************************************************** */
1625
1626/* -------------------------------------------------------------------------- */
1627/* Touchpad HID++ devices */
1628/* -------------------------------------------------------------------------- */
1629
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04001630#define WTP_MANUAL_RESOLUTION 39
1631
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001632struct wtp_data {
1633 struct input_dev *input;
1634 u16 x_size, y_size;
1635 u8 finger_count;
1636 u8 mt_feature_index;
1637 u8 button_feature_index;
1638 u8 maxcontacts;
1639 bool flip_y;
1640 unsigned int resolution;
1641};
1642
1643static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
1644 struct hid_field *field, struct hid_usage *usage,
1645 unsigned long **bit, int *max)
1646{
1647 return -1;
1648}
1649
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04001650static void wtp_populate_input(struct hidpp_device *hidpp,
1651 struct input_dev *input_dev, bool origin_is_hid_core)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001652{
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001653 struct wtp_data *wd = hidpp->private_data;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001654
1655 __set_bit(EV_ABS, input_dev->evbit);
1656 __set_bit(EV_KEY, input_dev->evbit);
1657 __clear_bit(EV_REL, input_dev->evbit);
1658 __clear_bit(EV_LED, input_dev->evbit);
1659
1660 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, wd->x_size, 0, 0);
1661 input_abs_set_res(input_dev, ABS_MT_POSITION_X, wd->resolution);
1662 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, wd->y_size, 0, 0);
1663 input_abs_set_res(input_dev, ABS_MT_POSITION_Y, wd->resolution);
1664
1665 /* Max pressure is not given by the devices, pick one */
1666 input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 50, 0, 0);
1667
1668 input_set_capability(input_dev, EV_KEY, BTN_LEFT);
1669
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04001670 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS)
1671 input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
1672 else
1673 __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001674
1675 input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER |
1676 INPUT_MT_DROP_UNUSED);
1677
1678 wd->input = input_dev;
1679}
1680
1681static void wtp_touch_event(struct wtp_data *wd,
1682 struct hidpp_touchpad_raw_xy_finger *touch_report)
1683{
1684 int slot;
1685
1686 if (!touch_report->finger_id || touch_report->contact_type)
1687 /* no actual data */
1688 return;
1689
1690 slot = input_mt_get_slot_by_key(wd->input, touch_report->finger_id);
1691
1692 input_mt_slot(wd->input, slot);
1693 input_mt_report_slot_state(wd->input, MT_TOOL_FINGER,
1694 touch_report->contact_status);
1695 if (touch_report->contact_status) {
1696 input_event(wd->input, EV_ABS, ABS_MT_POSITION_X,
1697 touch_report->x);
1698 input_event(wd->input, EV_ABS, ABS_MT_POSITION_Y,
1699 wd->flip_y ? wd->y_size - touch_report->y :
1700 touch_report->y);
1701 input_event(wd->input, EV_ABS, ABS_MT_PRESSURE,
1702 touch_report->area);
1703 }
1704}
1705
1706static void wtp_send_raw_xy_event(struct hidpp_device *hidpp,
1707 struct hidpp_touchpad_raw_xy *raw)
1708{
1709 struct wtp_data *wd = hidpp->private_data;
1710 int i;
1711
1712 for (i = 0; i < 2; i++)
1713 wtp_touch_event(wd, &(raw->fingers[i]));
1714
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04001715 if (raw->end_of_frame &&
1716 !(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS))
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001717 input_event(wd->input, EV_KEY, BTN_LEFT, raw->button);
1718
1719 if (raw->end_of_frame || raw->finger_count <= 2) {
1720 input_mt_sync_frame(wd->input);
1721 input_sync(wd->input);
1722 }
1723}
1724
1725static int wtp_mouse_raw_xy_event(struct hidpp_device *hidpp, u8 *data)
1726{
1727 struct wtp_data *wd = hidpp->private_data;
1728 u8 c1_area = ((data[7] & 0xf) * (data[7] & 0xf) +
1729 (data[7] >> 4) * (data[7] >> 4)) / 2;
1730 u8 c2_area = ((data[13] & 0xf) * (data[13] & 0xf) +
1731 (data[13] >> 4) * (data[13] >> 4)) / 2;
1732 struct hidpp_touchpad_raw_xy raw = {
1733 .timestamp = data[1],
1734 .fingers = {
1735 {
1736 .contact_type = 0,
1737 .contact_status = !!data[7],
1738 .x = get_unaligned_le16(&data[3]),
1739 .y = get_unaligned_le16(&data[5]),
1740 .z = c1_area,
1741 .area = c1_area,
1742 .finger_id = data[2],
1743 }, {
1744 .contact_type = 0,
1745 .contact_status = !!data[13],
1746 .x = get_unaligned_le16(&data[9]),
1747 .y = get_unaligned_le16(&data[11]),
1748 .z = c2_area,
1749 .area = c2_area,
1750 .finger_id = data[8],
1751 }
1752 },
1753 .finger_count = wd->maxcontacts,
1754 .spurious_flag = 0,
1755 .end_of_frame = (data[0] >> 7) == 0,
1756 .button = data[0] & 0x01,
1757 };
1758
1759 wtp_send_raw_xy_event(hidpp, &raw);
1760
1761 return 1;
1762}
1763
1764static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
1765{
1766 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1767 struct wtp_data *wd = hidpp->private_data;
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001768 struct hidpp_report *report = (struct hidpp_report *)data;
1769 struct hidpp_touchpad_raw_xy raw;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001770
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001771 if (!wd || !wd->input)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001772 return 1;
1773
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001774 switch (data[0]) {
1775 case 0x02:
Peter Wu0b3f6562014-12-16 16:55:22 +01001776 if (size < 2) {
1777 hid_err(hdev, "Received HID report of bad size (%d)",
1778 size);
1779 return 1;
1780 }
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04001781 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
1782 input_event(wd->input, EV_KEY, BTN_LEFT,
1783 !!(data[1] & 0x01));
1784 input_event(wd->input, EV_KEY, BTN_RIGHT,
1785 !!(data[1] & 0x02));
1786 input_sync(wd->input);
Peter Wu8abd8202014-12-16 01:50:16 +01001787 return 0;
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04001788 } else {
1789 if (size < 21)
1790 return 1;
1791 return wtp_mouse_raw_xy_event(hidpp, &data[7]);
1792 }
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001793 case REPORT_ID_HIDPP_LONG:
Peter Wu0b3f6562014-12-16 16:55:22 +01001794 /* size is already checked in hidpp_raw_event. */
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001795 if ((report->fap.feature_index != wd->mt_feature_index) ||
1796 (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
1797 return 1;
1798 hidpp_touchpad_raw_xy_event(hidpp, data + 4, &raw);
1799
1800 wtp_send_raw_xy_event(hidpp, &raw);
1801 return 0;
1802 }
1803
1804 return 0;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001805}
1806
1807static int wtp_get_config(struct hidpp_device *hidpp)
1808{
1809 struct wtp_data *wd = hidpp->private_data;
1810 struct hidpp_touchpad_raw_info raw_info = {0};
1811 u8 feature_type;
1812 int ret;
1813
1814 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_TOUCHPAD_RAW_XY,
1815 &wd->mt_feature_index, &feature_type);
1816 if (ret)
1817 /* means that the device is not powered up */
1818 return ret;
1819
1820 ret = hidpp_touchpad_get_raw_info(hidpp, wd->mt_feature_index,
1821 &raw_info);
1822 if (ret)
1823 return ret;
1824
1825 wd->x_size = raw_info.x_size;
1826 wd->y_size = raw_info.y_size;
1827 wd->maxcontacts = raw_info.maxcontacts;
1828 wd->flip_y = raw_info.origin == TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT;
1829 wd->resolution = raw_info.res;
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04001830 if (!wd->resolution)
1831 wd->resolution = WTP_MANUAL_RESOLUTION;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04001832
1833 return 0;
1834}
1835
1836static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id)
1837{
1838 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1839 struct wtp_data *wd;
1840
1841 wd = devm_kzalloc(&hdev->dev, sizeof(struct wtp_data),
1842 GFP_KERNEL);
1843 if (!wd)
1844 return -ENOMEM;
1845
1846 hidpp->private_data = wd;
1847
1848 return 0;
1849};
1850
Benjamin Tissoiresbf159442014-12-16 17:06:01 -05001851static int wtp_connect(struct hid_device *hdev, bool connected)
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001852{
1853 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1854 struct wtp_data *wd = hidpp->private_data;
1855 int ret;
1856
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001857 if (!wd->x_size) {
1858 ret = wtp_get_config(hidpp);
1859 if (ret) {
1860 hid_err(hdev, "Can not get wtp config: %d\n", ret);
Benjamin Tissoiresbf159442014-12-16 17:06:01 -05001861 return ret;
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001862 }
1863 }
1864
Benjamin Tissoiresbf159442014-12-16 17:06:01 -05001865 return hidpp_touchpad_set_raw_report_state(hidpp, wd->mt_feature_index,
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04001866 true, true);
1867}
1868
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001869/* ------------------------------------------------------------------------- */
1870/* Logitech M560 devices */
1871/* ------------------------------------------------------------------------- */
1872
1873/*
1874 * Logitech M560 protocol overview
1875 *
1876 * The Logitech M560 mouse, is designed for windows 8. When the middle and/or
1877 * the sides buttons are pressed, it sends some keyboard keys events
1878 * instead of buttons ones.
1879 * To complicate things further, the middle button keys sequence
1880 * is different from the odd press and the even press.
1881 *
1882 * forward button -> Super_R
1883 * backward button -> Super_L+'d' (press only)
1884 * middle button -> 1st time: Alt_L+SuperL+XF86TouchpadOff (press only)
1885 * 2nd time: left-click (press only)
1886 * NB: press-only means that when the button is pressed, the
1887 * KeyPress/ButtonPress and KeyRelease/ButtonRelease events are generated
1888 * together sequentially; instead when the button is released, no event is
1889 * generated !
1890 *
1891 * With the command
1892 * 10<xx>0a 3500af03 (where <xx> is the mouse id),
1893 * the mouse reacts differently:
1894 * - it never sends a keyboard key event
1895 * - for the three mouse button it sends:
1896 * middle button press 11<xx>0a 3500af00...
1897 * side 1 button (forward) press 11<xx>0a 3500b000...
1898 * side 2 button (backward) press 11<xx>0a 3500ae00...
1899 * middle/side1/side2 button release 11<xx>0a 35000000...
1900 */
1901
1902static const u8 m560_config_parameter[] = {0x00, 0xaf, 0x03};
1903
1904struct m560_private_data {
1905 struct input_dev *input;
1906};
1907
1908/* how buttons are mapped in the report */
1909#define M560_MOUSE_BTN_LEFT 0x01
1910#define M560_MOUSE_BTN_RIGHT 0x02
1911#define M560_MOUSE_BTN_WHEEL_LEFT 0x08
1912#define M560_MOUSE_BTN_WHEEL_RIGHT 0x10
1913
1914#define M560_SUB_ID 0x0a
1915#define M560_BUTTON_MODE_REGISTER 0x35
1916
1917static int m560_send_config_command(struct hid_device *hdev, bool connected)
1918{
1919 struct hidpp_report response;
1920 struct hidpp_device *hidpp_dev;
1921
1922 hidpp_dev = hid_get_drvdata(hdev);
1923
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02001924 return hidpp_send_rap_command_sync(
1925 hidpp_dev,
1926 REPORT_ID_HIDPP_SHORT,
1927 M560_SUB_ID,
1928 M560_BUTTON_MODE_REGISTER,
1929 (u8 *)m560_config_parameter,
1930 sizeof(m560_config_parameter),
1931 &response
1932 );
1933}
1934
1935static int m560_allocate(struct hid_device *hdev)
1936{
1937 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1938 struct m560_private_data *d;
1939
1940 d = devm_kzalloc(&hdev->dev, sizeof(struct m560_private_data),
1941 GFP_KERNEL);
1942 if (!d)
1943 return -ENOMEM;
1944
1945 hidpp->private_data = d;
1946
1947 return 0;
1948};
1949
1950static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
1951{
1952 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1953 struct m560_private_data *mydata = hidpp->private_data;
1954
1955 /* sanity check */
1956 if (!mydata || !mydata->input) {
1957 hid_err(hdev, "error in parameter\n");
1958 return -EINVAL;
1959 }
1960
1961 if (size < 7) {
1962 hid_err(hdev, "error in report\n");
1963 return 0;
1964 }
1965
1966 if (data[0] == REPORT_ID_HIDPP_LONG &&
1967 data[2] == M560_SUB_ID && data[6] == 0x00) {
1968 /*
1969 * m560 mouse report for middle, forward and backward button
1970 *
1971 * data[0] = 0x11
1972 * data[1] = device-id
1973 * data[2] = 0x0a
1974 * data[5] = 0xaf -> middle
1975 * 0xb0 -> forward
1976 * 0xae -> backward
1977 * 0x00 -> release all
1978 * data[6] = 0x00
1979 */
1980
1981 switch (data[5]) {
1982 case 0xaf:
1983 input_report_key(mydata->input, BTN_MIDDLE, 1);
1984 break;
1985 case 0xb0:
1986 input_report_key(mydata->input, BTN_FORWARD, 1);
1987 break;
1988 case 0xae:
1989 input_report_key(mydata->input, BTN_BACK, 1);
1990 break;
1991 case 0x00:
1992 input_report_key(mydata->input, BTN_BACK, 0);
1993 input_report_key(mydata->input, BTN_FORWARD, 0);
1994 input_report_key(mydata->input, BTN_MIDDLE, 0);
1995 break;
1996 default:
1997 hid_err(hdev, "error in report\n");
1998 return 0;
1999 }
2000 input_sync(mydata->input);
2001
2002 } else if (data[0] == 0x02) {
2003 /*
2004 * Logitech M560 mouse report
2005 *
2006 * data[0] = type (0x02)
2007 * data[1..2] = buttons
2008 * data[3..5] = xy
2009 * data[6] = wheel
2010 */
2011
2012 int v;
2013
2014 input_report_key(mydata->input, BTN_LEFT,
2015 !!(data[1] & M560_MOUSE_BTN_LEFT));
2016 input_report_key(mydata->input, BTN_RIGHT,
2017 !!(data[1] & M560_MOUSE_BTN_RIGHT));
2018
2019 if (data[1] & M560_MOUSE_BTN_WHEEL_LEFT)
2020 input_report_rel(mydata->input, REL_HWHEEL, -1);
2021 else if (data[1] & M560_MOUSE_BTN_WHEEL_RIGHT)
2022 input_report_rel(mydata->input, REL_HWHEEL, 1);
2023
2024 v = hid_snto32(hid_field_extract(hdev, data+3, 0, 12), 12);
2025 input_report_rel(mydata->input, REL_X, v);
2026
2027 v = hid_snto32(hid_field_extract(hdev, data+3, 12, 12), 12);
2028 input_report_rel(mydata->input, REL_Y, v);
2029
2030 v = hid_snto32(data[6], 8);
2031 input_report_rel(mydata->input, REL_WHEEL, v);
2032
2033 input_sync(mydata->input);
2034 }
2035
2036 return 1;
2037}
2038
2039static void m560_populate_input(struct hidpp_device *hidpp,
2040 struct input_dev *input_dev, bool origin_is_hid_core)
2041{
2042 struct m560_private_data *mydata = hidpp->private_data;
2043
2044 mydata->input = input_dev;
2045
2046 __set_bit(EV_KEY, mydata->input->evbit);
2047 __set_bit(BTN_MIDDLE, mydata->input->keybit);
2048 __set_bit(BTN_RIGHT, mydata->input->keybit);
2049 __set_bit(BTN_LEFT, mydata->input->keybit);
2050 __set_bit(BTN_BACK, mydata->input->keybit);
2051 __set_bit(BTN_FORWARD, mydata->input->keybit);
2052
2053 __set_bit(EV_REL, mydata->input->evbit);
2054 __set_bit(REL_X, mydata->input->relbit);
2055 __set_bit(REL_Y, mydata->input->relbit);
2056 __set_bit(REL_WHEEL, mydata->input->relbit);
2057 __set_bit(REL_HWHEEL, mydata->input->relbit);
2058}
2059
2060static int m560_input_mapping(struct hid_device *hdev, struct hid_input *hi,
2061 struct hid_field *field, struct hid_usage *usage,
2062 unsigned long **bit, int *max)
2063{
2064 return -1;
2065}
2066
Benjamin Tissoires90cdd982015-09-03 09:08:30 -04002067/* ------------------------------------------------------------------------- */
2068/* Logitech K400 devices */
2069/* ------------------------------------------------------------------------- */
2070
2071/*
2072 * The Logitech K400 keyboard has an embedded touchpad which is seen
2073 * as a mouse from the OS point of view. There is a hardware shortcut to disable
2074 * tap-to-click but the setting is not remembered accross reset, annoying some
2075 * users.
2076 *
2077 * We can toggle this feature from the host by using the feature 0x6010:
2078 * Touchpad FW items
2079 */
2080
2081struct k400_private_data {
2082 u8 feature_index;
2083};
2084
2085static int k400_disable_tap_to_click(struct hidpp_device *hidpp)
2086{
2087 struct k400_private_data *k400 = hidpp->private_data;
2088 struct hidpp_touchpad_fw_items items = {};
2089 int ret;
2090 u8 feature_type;
2091
2092 if (!k400->feature_index) {
2093 ret = hidpp_root_get_feature(hidpp,
2094 HIDPP_PAGE_TOUCHPAD_FW_ITEMS,
2095 &k400->feature_index, &feature_type);
2096 if (ret)
2097 /* means that the device is not powered up */
2098 return ret;
2099 }
2100
2101 ret = hidpp_touchpad_fw_items_set(hidpp, k400->feature_index, &items);
2102 if (ret)
2103 return ret;
2104
2105 return 0;
2106}
2107
2108static int k400_allocate(struct hid_device *hdev)
2109{
2110 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2111 struct k400_private_data *k400;
2112
2113 k400 = devm_kzalloc(&hdev->dev, sizeof(struct k400_private_data),
2114 GFP_KERNEL);
2115 if (!k400)
2116 return -ENOMEM;
2117
2118 hidpp->private_data = k400;
2119
2120 return 0;
2121};
2122
2123static int k400_connect(struct hid_device *hdev, bool connected)
2124{
2125 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2126
Benjamin Tissoires90cdd982015-09-03 09:08:30 -04002127 if (!disable_tap_to_click)
2128 return 0;
2129
2130 return k400_disable_tap_to_click(hidpp);
2131}
2132
Simon Wood7f4b49f2015-11-19 16:42:13 -07002133/* ------------------------------------------------------------------------- */
2134/* Logitech G920 Driving Force Racing Wheel for Xbox One */
2135/* ------------------------------------------------------------------------- */
2136
2137#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123
2138
Simon Wood7f4b49f2015-11-19 16:42:13 -07002139static int g920_get_config(struct hidpp_device *hidpp)
2140{
Simon Wood7f4b49f2015-11-19 16:42:13 -07002141 u8 feature_type;
2142 u8 feature_index;
2143 int ret;
2144
Simon Wood7f4b49f2015-11-19 16:42:13 -07002145 /* Find feature and store for later use */
2146 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK,
2147 &feature_index, &feature_type);
2148 if (ret)
2149 return ret;
2150
Edwin Veldsff21a632016-01-11 00:25:15 +01002151 ret = hidpp_ff_init(hidpp, feature_index);
Simon Wood7f4b49f2015-11-19 16:42:13 -07002152 if (ret)
Edwin Veldsff21a632016-01-11 00:25:15 +01002153 hid_warn(hidpp->hid_dev, "Unable to initialize force feedback support, errno %d\n",
2154 ret);
Simon Wood7f4b49f2015-11-19 16:42:13 -07002155
2156 return 0;
2157}
2158
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002159/* -------------------------------------------------------------------------- */
2160/* Generic HID++ devices */
2161/* -------------------------------------------------------------------------- */
2162
2163static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
2164 struct hid_field *field, struct hid_usage *usage,
2165 unsigned long **bit, int *max)
2166{
2167 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2168
2169 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
2170 return wtp_input_mapping(hdev, hi, field, usage, bit, max);
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02002171 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560 &&
2172 field->application != HID_GD_MOUSE)
2173 return m560_input_mapping(hdev, hi, field, usage, bit, max);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002174
2175 return 0;
2176}
2177
Simon Wood0b1804e2015-11-19 16:42:15 -07002178static int hidpp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
2179 struct hid_field *field, struct hid_usage *usage,
2180 unsigned long **bit, int *max)
2181{
2182 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2183
2184 /* Ensure that Logitech G920 is not given a default fuzz/flat value */
2185 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
2186 if (usage->type == EV_ABS && (usage->code == ABS_X ||
2187 usage->code == ABS_Y || usage->code == ABS_Z ||
2188 usage->code == ABS_RZ)) {
2189 field->application = HID_GD_MULTIAXIS;
2190 }
2191 }
2192
2193 return 0;
2194}
2195
2196
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002197static void hidpp_populate_input(struct hidpp_device *hidpp,
2198 struct input_dev *input, bool origin_is_hid_core)
2199{
2200 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
2201 wtp_populate_input(hidpp, input, origin_is_hid_core);
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02002202 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
2203 m560_populate_input(hidpp, input, origin_is_hid_core);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002204}
2205
Dmitry Torokhovb2c68a22015-09-29 15:52:59 -07002206static int hidpp_input_configured(struct hid_device *hdev,
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002207 struct hid_input *hidinput)
2208{
2209 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002210 struct input_dev *input = hidinput->input;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002211
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002212 hidpp_populate_input(hidpp, input, true);
Dmitry Torokhovb2c68a22015-09-29 15:52:59 -07002213
2214 return 0;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002215}
2216
2217static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
2218 int size)
2219{
2220 struct hidpp_report *question = hidpp->send_receive_buf;
2221 struct hidpp_report *answer = hidpp->send_receive_buf;
2222 struct hidpp_report *report = (struct hidpp_report *)data;
Benjamin Tissoireseb626c52017-03-27 16:59:29 +02002223 int ret;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002224
2225 /*
2226 * If the mutex is locked then we have a pending answer from a
Peter Wue529fea2014-12-17 00:23:51 +01002227 * previously sent command.
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002228 */
2229 if (unlikely(mutex_is_locked(&hidpp->send_mutex))) {
2230 /*
2231 * Check for a correct hidpp20 answer or the corresponding
2232 * error
2233 */
2234 if (hidpp_match_answer(question, report) ||
2235 hidpp_match_error(question, report)) {
2236 *answer = *report;
2237 hidpp->answer_available = true;
2238 wake_up(&hidpp->wait);
2239 /*
2240 * This was an answer to a command that this driver sent
2241 * We return 1 to hid-core to avoid forwarding the
2242 * command upstream as it has been treated by the driver
2243 */
2244
2245 return 1;
2246 }
2247 }
2248
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002249 if (unlikely(hidpp_report_is_connect_event(report))) {
2250 atomic_set(&hidpp->connected,
2251 !(report->rap.params[0] & (1 << 6)));
Benjamin Tissoires6bd4e652016-06-29 19:28:02 +10002252 if (schedule_work(&hidpp->work) == 0)
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002253 dbg_hid("%s: connect event already queued\n", __func__);
2254 return 1;
2255 }
2256
Benjamin Tissoireseb626c52017-03-27 16:59:29 +02002257 if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) {
2258 ret = hidpp20_battery_event(hidpp, data, size);
2259 if (ret != 0)
2260 return ret;
2261 }
2262
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002263 return 0;
2264}
2265
2266static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
2267 u8 *data, int size)
2268{
2269 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
Peter Wue529fea2014-12-17 00:23:51 +01002270 int ret = 0;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002271
Peter Wue529fea2014-12-17 00:23:51 +01002272 /* Generic HID++ processing. */
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002273 switch (data[0]) {
Simon Wooda5ce8f52015-11-19 16:42:11 -07002274 case REPORT_ID_HIDPP_VERY_LONG:
2275 if (size != HIDPP_REPORT_VERY_LONG_LENGTH) {
2276 hid_err(hdev, "received hid++ report of bad size (%d)",
2277 size);
2278 return 1;
2279 }
2280 ret = hidpp_raw_hidpp_event(hidpp, data, size);
2281 break;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002282 case REPORT_ID_HIDPP_LONG:
2283 if (size != HIDPP_REPORT_LONG_LENGTH) {
2284 hid_err(hdev, "received hid++ report of bad size (%d)",
2285 size);
2286 return 1;
2287 }
Peter Wue529fea2014-12-17 00:23:51 +01002288 ret = hidpp_raw_hidpp_event(hidpp, data, size);
2289 break;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002290 case REPORT_ID_HIDPP_SHORT:
2291 if (size != HIDPP_REPORT_SHORT_LENGTH) {
2292 hid_err(hdev, "received hid++ report of bad size (%d)",
2293 size);
2294 return 1;
2295 }
Peter Wue529fea2014-12-17 00:23:51 +01002296 ret = hidpp_raw_hidpp_event(hidpp, data, size);
2297 break;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002298 }
2299
Peter Wue529fea2014-12-17 00:23:51 +01002300 /* If no report is available for further processing, skip calling
2301 * raw_event of subclasses. */
2302 if (ret != 0)
2303 return ret;
2304
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002305 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
2306 return wtp_raw_event(hdev, data, size);
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02002307 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
2308 return m560_raw_event(hdev, data, size);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002309
2310 return 0;
2311}
2312
Benjamin Tissoiresa52ec102017-03-27 16:59:31 +02002313static int hidpp_initialize_battery(struct hidpp_device *hidpp)
2314{
2315 static atomic_t battery_no = ATOMIC_INIT(0);
2316 struct power_supply_config cfg = { .drv_data = hidpp };
2317 struct power_supply_desc *desc = &hidpp->battery.desc;
2318 struct hidpp_battery *battery;
2319 unsigned long n;
2320 int ret;
2321
2322 if (hidpp->battery.ps)
2323 return 0;
2324
2325 if (hidpp->protocol_major >= 2) {
2326 ret = hidpp20_query_battery_info(hidpp);
2327 if (ret)
2328 return ret;
2329 hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP20_BATTERY;
2330 } else {
2331 return -ENOENT;
2332 }
2333
2334 battery = &hidpp->battery;
2335
2336 n = atomic_inc_return(&battery_no) - 1;
2337 desc->properties = hidpp_battery_props;
2338 desc->num_properties = ARRAY_SIZE(hidpp_battery_props);
2339 desc->get_property = hidpp_battery_get_property;
2340 sprintf(battery->name, "hidpp_battery_%ld", n);
2341 desc->name = battery->name;
2342 desc->type = POWER_SUPPLY_TYPE_BATTERY;
2343 desc->use_for_apm = 0;
2344
2345 battery->ps = devm_power_supply_register(&hidpp->hid_dev->dev,
2346 &battery->desc,
2347 &cfg);
2348 if (IS_ERR(battery->ps))
2349 return PTR_ERR(battery->ps);
2350
2351 power_supply_powers(battery->ps, &hidpp->hid_dev->dev);
2352
2353 return ret;
2354}
2355
Benjamin Tissoires843c6242017-03-27 16:59:26 +02002356static void hidpp_overwrite_name(struct hid_device *hdev)
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002357{
2358 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2359 char *name;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002360
Benjamin Tissoires843c6242017-03-27 16:59:26 +02002361 if (hidpp->protocol_major < 2)
Benjamin Tissoiresb4f8ce02017-03-27 16:59:24 +02002362 return;
Benjamin Tissoires843c6242017-03-27 16:59:26 +02002363
2364 name = hidpp_get_device_name(hidpp);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002365
Simon Wood7bfd2922015-11-19 16:42:12 -07002366 if (!name) {
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002367 hid_err(hdev, "unable to retrieve the name of the device");
Simon Wood7bfd2922015-11-19 16:42:12 -07002368 } else {
2369 dbg_hid("HID++: Got name: %s\n", name);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002370 snprintf(hdev->name, sizeof(hdev->name), "%s", name);
Simon Wood7bfd2922015-11-19 16:42:12 -07002371 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002372
2373 kfree(name);
2374}
2375
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002376static int hidpp_input_open(struct input_dev *dev)
2377{
2378 struct hid_device *hid = input_get_drvdata(dev);
2379
2380 return hid_hw_open(hid);
2381}
2382
2383static void hidpp_input_close(struct input_dev *dev)
2384{
2385 struct hid_device *hid = input_get_drvdata(dev);
2386
2387 hid_hw_close(hid);
2388}
2389
2390static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
2391{
2392 struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev);
Benjamin Tissoires005b3f52015-01-08 14:37:12 -05002393 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002394
2395 if (!input_dev)
2396 return NULL;
2397
2398 input_set_drvdata(input_dev, hdev);
2399 input_dev->open = hidpp_input_open;
2400 input_dev->close = hidpp_input_close;
2401
Benjamin Tissoires005b3f52015-01-08 14:37:12 -05002402 input_dev->name = hidpp->name;
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002403 input_dev->phys = hdev->phys;
2404 input_dev->uniq = hdev->uniq;
2405 input_dev->id.bustype = hdev->bus;
2406 input_dev->id.vendor = hdev->vendor;
2407 input_dev->id.product = hdev->product;
2408 input_dev->id.version = hdev->version;
2409 input_dev->dev.parent = &hdev->dev;
2410
2411 return input_dev;
2412}
2413
2414static void hidpp_connect_event(struct hidpp_device *hidpp)
2415{
2416 struct hid_device *hdev = hidpp->hid_dev;
2417 int ret = 0;
2418 bool connected = atomic_read(&hidpp->connected);
2419 struct input_dev *input;
2420 char *name, *devm_name;
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002421
Benjamin Tissoires284f8d72017-03-27 16:59:34 +02002422 if (!connected) {
2423 if (hidpp->battery.ps) {
2424 hidpp->battery.online = false;
2425 hidpp->battery.status = POWER_SUPPLY_STATUS_UNKNOWN;
2426 power_supply_changed(hidpp->battery.ps);
2427 }
Benjamin Tissoires29368362017-03-27 16:59:28 +02002428 return;
Benjamin Tissoires284f8d72017-03-27 16:59:34 +02002429 }
Benjamin Tissoires29368362017-03-27 16:59:28 +02002430
Benjamin Tissoiresbf159442014-12-16 17:06:01 -05002431 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
2432 ret = wtp_connect(hdev, connected);
2433 if (ret)
2434 return;
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02002435 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) {
2436 ret = m560_send_config_command(hdev, connected);
2437 if (ret)
2438 return;
Benjamin Tissoires90cdd982015-09-03 09:08:30 -04002439 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) {
2440 ret = k400_connect(hdev, connected);
2441 if (ret)
2442 return;
Benjamin Tissoiresbf159442014-12-16 17:06:01 -05002443 }
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04002444
Benjamin Tissoires580a7e82015-09-03 09:08:29 -04002445 /* the device is already connected, we can ask for its name and
2446 * protocol */
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002447 if (!hidpp->protocol_major) {
2448 ret = !hidpp_is_connected(hidpp);
2449 if (ret) {
2450 hid_err(hdev, "Can not get the protocol version.\n");
2451 return;
2452 }
Benjamin Tissoires580a7e82015-09-03 09:08:29 -04002453 hid_info(hdev, "HID++ %u.%u device connected.\n",
2454 hidpp->protocol_major, hidpp->protocol_minor);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002455 }
2456
Benjamin Tissoires187f2bb2017-03-27 16:59:27 +02002457 if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) {
Benjamin Tissoires005b3f52015-01-08 14:37:12 -05002458 name = hidpp_get_device_name(hidpp);
2459 if (!name) {
2460 hid_err(hdev,
2461 "unable to retrieve the name of the device");
2462 return;
2463 }
2464
2465 devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
2466 kfree(name);
2467 if (!devm_name)
2468 return;
2469
2470 hidpp->name = devm_name;
2471 }
2472
Benjamin Tissoires187f2bb2017-03-27 16:59:27 +02002473 hidpp_initialize_battery(hidpp);
2474
Benjamin Tissoires9b9c5192017-03-27 16:59:33 +02002475 /* forward current battery state */
2476 if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) {
2477 hidpp20_query_battery_info(hidpp);
2478 if (hidpp->battery.ps)
2479 power_supply_changed(hidpp->battery.ps);
2480 }
2481
Benjamin Tissoires29368362017-03-27 16:59:28 +02002482 if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
2483 /* if the input nodes are already created, we can stop now */
Benjamin Tissoires187f2bb2017-03-27 16:59:27 +02002484 return;
2485
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002486 input = hidpp_allocate_input(hdev);
2487 if (!input) {
2488 hid_err(hdev, "cannot allocate new input device: %d\n", ret);
2489 return;
2490 }
2491
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002492 hidpp_populate_input(hidpp, input, false);
2493
2494 ret = input_register_device(input);
2495 if (ret)
2496 input_free_device(input);
2497
2498 hidpp->delayed_input = input;
2499}
2500
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002501static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
2502{
2503 struct hidpp_device *hidpp;
2504 int ret;
2505 bool connected;
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002506 unsigned int connect_mask = HID_CONNECT_DEFAULT;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002507
2508 hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device),
2509 GFP_KERNEL);
2510 if (!hidpp)
2511 return -ENOMEM;
2512
2513 hidpp->hid_dev = hdev;
Benjamin Tissoires005b3f52015-01-08 14:37:12 -05002514 hidpp->name = hdev->name;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002515 hid_set_drvdata(hdev, hidpp);
2516
2517 hidpp->quirks = id->driver_data;
2518
Benjamin Tissoires843c6242017-03-27 16:59:26 +02002519 if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE)
2520 hidpp->quirks |= HIDPP_QUIRK_UNIFYING;
2521
Benjamin Tissoires9188dba2015-03-26 12:41:57 -04002522 if (disable_raw_mode) {
2523 hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP;
Benjamin Tissoires580a7e82015-09-03 09:08:29 -04002524 hidpp->quirks &= ~HIDPP_QUIRK_NO_HIDINPUT;
Benjamin Tissoires9188dba2015-03-26 12:41:57 -04002525 }
2526
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002527 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
2528 ret = wtp_allocate(hdev, id);
2529 if (ret)
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02002530 goto allocate_fail;
2531 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) {
2532 ret = m560_allocate(hdev);
2533 if (ret)
2534 goto allocate_fail;
Benjamin Tissoires90cdd982015-09-03 09:08:30 -04002535 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) {
2536 ret = k400_allocate(hdev);
2537 if (ret)
2538 goto allocate_fail;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002539 }
2540
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002541 INIT_WORK(&hidpp->work, delayed_work_cb);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002542 mutex_init(&hidpp->send_mutex);
2543 init_waitqueue_head(&hidpp->wait);
2544
2545 ret = hid_parse(hdev);
2546 if (ret) {
2547 hid_err(hdev, "%s:parse failed\n", __func__);
2548 goto hid_parse_fail;
2549 }
2550
Simon Wood7bfd2922015-11-19 16:42:12 -07002551 if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
2552 connect_mask &= ~HID_CONNECT_HIDINPUT;
2553
2554 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
2555 ret = hid_hw_start(hdev, connect_mask);
2556 if (ret) {
2557 hid_err(hdev, "hw start failed\n");
2558 goto hid_hw_start_fail;
2559 }
2560 ret = hid_hw_open(hdev);
2561 if (ret < 0) {
2562 dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n",
2563 __func__, ret);
2564 hid_hw_stop(hdev);
2565 goto hid_hw_start_fail;
2566 }
2567 }
2568
2569
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002570 /* Allow incoming packets */
2571 hid_device_io_start(hdev);
2572
Benjamin Tissoires843c6242017-03-27 16:59:26 +02002573 if (hidpp->quirks & HIDPP_QUIRK_UNIFYING)
2574 hidpp_unifying_init(hidpp);
2575
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002576 connected = hidpp_is_connected(hidpp);
Benjamin Tissoires843c6242017-03-27 16:59:26 +02002577 atomic_set(&hidpp->connected, connected);
2578 if (!(hidpp->quirks & HIDPP_QUIRK_UNIFYING)) {
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04002579 if (!connected) {
Julia Lawallb832da52015-04-05 14:06:29 +02002580 ret = -ENODEV;
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04002581 hid_err(hdev, "Device not connected");
Simon Wood7bfd2922015-11-19 16:42:12 -07002582 goto hid_hw_open_failed;
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04002583 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002584
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04002585 hid_info(hdev, "HID++ %u.%u device connected.\n",
2586 hidpp->protocol_major, hidpp->protocol_minor);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002587
Benjamin Tissoires843c6242017-03-27 16:59:26 +02002588 hidpp_overwrite_name(hdev);
2589 }
Benjamin Tissoires33797822014-09-30 13:18:30 -04002590
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002591 if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002592 ret = wtp_get_config(hidpp);
2593 if (ret)
Simon Wood7bfd2922015-11-19 16:42:12 -07002594 goto hid_hw_open_failed;
Simon Wood7f4b49f2015-11-19 16:42:13 -07002595 } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
2596 ret = g920_get_config(hidpp);
2597 if (ret)
2598 goto hid_hw_open_failed;
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002599 }
2600
2601 /* Block incoming packets */
2602 hid_device_io_stop(hdev);
2603
Simon Wood7bfd2922015-11-19 16:42:12 -07002604 if (!(hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
2605 ret = hid_hw_start(hdev, connect_mask);
2606 if (ret) {
2607 hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
2608 goto hid_hw_start_fail;
2609 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002610 }
2611
Benjamin Tissoires6bd4e652016-06-29 19:28:02 +10002612 /* Allow incoming packets */
2613 hid_device_io_start(hdev);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002614
Benjamin Tissoires6bd4e652016-06-29 19:28:02 +10002615 hidpp_connect_event(hidpp);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002616
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002617 return ret;
2618
Simon Wood7bfd2922015-11-19 16:42:12 -07002619hid_hw_open_failed:
2620 hid_device_io_stop(hdev);
2621 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
2622 hid_hw_close(hdev);
2623 hid_hw_stop(hdev);
2624 }
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002625hid_hw_start_fail:
2626hid_parse_fail:
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002627 cancel_work_sync(&hidpp->work);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002628 mutex_destroy(&hidpp->send_mutex);
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02002629allocate_fail:
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002630 hid_set_drvdata(hdev, NULL);
2631 return ret;
2632}
2633
2634static void hidpp_remove(struct hid_device *hdev)
2635{
2636 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2637
Simon Wood7f4b49f2015-11-19 16:42:13 -07002638 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
Edwin Veldsff21a632016-01-11 00:25:15 +01002639 hidpp_ff_deinit(hdev);
Simon Wood7bfd2922015-11-19 16:42:12 -07002640 hid_hw_close(hdev);
Simon Wood7f4b49f2015-11-19 16:42:13 -07002641 }
Simon Wood7bfd2922015-11-19 16:42:12 -07002642 hid_hw_stop(hdev);
Benjamin Tissoiresc39e3d52014-09-30 13:18:32 -04002643 cancel_work_sync(&hidpp->work);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002644 mutex_destroy(&hidpp->send_mutex);
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002645}
2646
2647static const struct hid_device_id hidpp_devices[] = {
Benjamin Tissoires57ac86c2014-09-30 13:18:34 -04002648 { /* wireless touchpad */
2649 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
2650 USB_VENDOR_ID_LOGITECH, 0x4011),
2651 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
2652 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
Benjamin Tissoires586bdc42014-09-30 13:18:33 -04002653 { /* wireless touchpad T650 */
2654 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
2655 USB_VENDOR_ID_LOGITECH, 0x4101),
2656 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002657 { /* wireless touchpad T651 */
2658 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
2659 USB_DEVICE_ID_LOGITECH_T651),
2660 .driver_data = HIDPP_QUIRK_CLASS_WTP },
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02002661 { /* Mouse logitech M560 */
Benjamin Tissoires3a61e972014-09-30 13:18:35 -04002662 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
Goffredo Baroncelli8a09b4f2015-05-30 11:00:27 +02002663 USB_VENDOR_ID_LOGITECH, 0x402d),
2664 .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 },
Benjamin Tissoires90cdd982015-09-03 09:08:30 -04002665 { /* Keyboard logitech K400 */
2666 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
2667 USB_VENDOR_ID_LOGITECH, 0x4024),
Benjamin Tissoires6bd4e652016-06-29 19:28:02 +10002668 .driver_data = HIDPP_QUIRK_CLASS_K400 },
Benjamin Tissoiresab94e562014-09-30 13:18:28 -04002669
2670 { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
2671 USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
Simon Wood7bfd2922015-11-19 16:42:12 -07002672
2673 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
2674 .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002675 {}
2676};
2677
2678MODULE_DEVICE_TABLE(hid, hidpp_devices);
2679
2680static struct hid_driver hidpp_driver = {
2681 .name = "logitech-hidpp-device",
2682 .id_table = hidpp_devices,
2683 .probe = hidpp_probe,
2684 .remove = hidpp_remove,
2685 .raw_event = hidpp_raw_event,
2686 .input_configured = hidpp_input_configured,
2687 .input_mapping = hidpp_input_mapping,
Simon Wood0b1804e2015-11-19 16:42:15 -07002688 .input_mapped = hidpp_input_mapped,
Benjamin Tissoires2f31c522014-09-30 13:18:27 -04002689};
2690
2691module_hid_driver(hidpp_driver);