aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 23:56:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 23:56:28 -0400
commit172bfe09dc52aef29f9c5c0bd9f77a558120faf4 (patch)
treeffbcbb384ef1a46c469d484d0e6ede828099da1e /drivers
parenta1b0a006ea7eb0c272cef33740a9563cd5190974 (diff)
parentcf6f3976045468049038cfc45586b8b16c33dd05 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina: "Some highlights: - hid-sony improvements of Sixaxis device support by Antonio Ospite - hid-hyperv driven devices can now be used as wakeup source, by Dexuan Cui - hid-lenovo driver is now more generic and supports more devices, by Jamie Lentin - hid-huion now supports wider range of tablets, by Nikolai Kondrashov - other various unsorted fixes and device ID additions" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (30 commits) HID: hyperv: register as a wakeup source HID: sony: Default initialize all elements of the LED max_brightness array to 1 HID: huion: Fix sparse warnings HID: usbhid: Use flag HID_DISCONNECTED when a usb device is removed HID: ignore jabra gn9350e HID: cp2112: add I2C mode HID: use multi input quirk for 22b9:2968 HID: rmi: only bind the hid-rmi driver to the mouse interface of composite USB devices HID: rmi: check that report ids exist in the report_id_hash before accessing their size HID: lenovo: Add support for Compact (BT|USB) keyboard HID: lenovo: Don't call function in condition, show error codes HID: lenovo: Prepare support for adding other devices HID: lenovo: Rename hid-lenovo-tpkbd to hid-lenovo HID: huion: Handle tablets with UC-Logic vendor ID HID: huion: Switch to generating report descriptor HID: huion: Don't ignore other interfaces HID: huion: Use "tablet" instead of specific model HID: add quirk for 0x04d9:0xa096 device HID: i2c-hid: call the hid driver's suspend and resume callbacks HID: rmi: change logging level of log messages related to unexpected reports ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/Kconfig18
-rw-r--r--drivers/hid/Makefile2
-rw-r--r--drivers/hid/hid-core.c11
-rw-r--r--drivers/hid/hid-cp2112.c111
-rw-r--r--drivers/hid/hid-huion.c265
-rw-r--r--drivers/hid/hid-hyperv.c6
-rw-r--r--drivers/hid/hid-ids.h6
-rw-r--r--drivers/hid/hid-lenovo-tpkbd.c462
-rw-r--r--drivers/hid/hid-lenovo.c708
-rw-r--r--drivers/hid/hid-picolcd_debugfs.c9
-rw-r--r--drivers/hid/hid-rmi.c67
-rw-r--r--drivers/hid/hid-roccat-lua.c2
-rw-r--r--drivers/hid/hid-sony.c132
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c15
-rw-r--r--drivers/hid/usbhid/hid-core.c8
-rw-r--r--drivers/hid/usbhid/hid-quirks.c1
16 files changed, 1181 insertions, 642 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 5e79c6ad914f..e02cf59b048d 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -331,18 +331,20 @@ config HID_LCPOWER
331 ---help--- 331 ---help---
332 Support for LC-Power RC1000MCE RF remote control. 332 Support for LC-Power RC1000MCE RF remote control.
333 333
334config HID_LENOVO_TPKBD 334config HID_LENOVO
335 tristate "Lenovo ThinkPad USB Keyboard with TrackPoint" 335 tristate "Lenovo / Thinkpad devices"
336 depends on HID 336 depends on HID
337 select NEW_LEDS 337 select NEW_LEDS
338 select LEDS_CLASS 338 select LEDS_CLASS
339 ---help--- 339 ---help---
340 Support for the Lenovo ThinkPad USB Keyboard with TrackPoint. 340 Support for Lenovo devices that are not fully compliant with HID standard.
341 341
342 Say Y here if you have a Lenovo ThinkPad USB Keyboard with TrackPoint 342 Say Y if you want support for the non-compliant features of the Lenovo
343 and would like to use device-specific features like changing the 343 Thinkpad standalone keyboards, e.g:
344 sensitivity of the trackpoint, using the microphone mute button or 344 - ThinkPad USB Keyboard with TrackPoint (supports extra LEDs and trackpoint
345 controlling the mute and microphone mute LEDs. 345 configuration)
346 - ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys)
347 - ThinkPad Compact USB Keyboard with TrackPoint (supports Fn keys)
346 348
347config HID_LOGITECH 349config HID_LOGITECH
348 tristate "Logitech devices" if EXPERT 350 tristate "Logitech devices" if EXPERT
@@ -785,7 +787,7 @@ config HID_XINMO
785 depends on HID 787 depends on HID
786 ---help--- 788 ---help---
787 Support for Xin-Mo devices that are not fully compliant with the HID 789 Support for Xin-Mo devices that are not fully compliant with the HID
788 standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here 790 standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
789 if you have a Xin-Mo Dual Arcade controller. 791 if you have a Xin-Mo Dual Arcade controller.
790 792
791config HID_ZEROPLUS 793config HID_ZEROPLUS
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index a6fa6baf368e..5e96be3ab280 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -59,7 +59,7 @@ obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
59obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o 59obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
60obj-$(CONFIG_HID_KYE) += hid-kye.o 60obj-$(CONFIG_HID_KYE) += hid-kye.o
61obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o 61obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
62obj-$(CONFIG_HID_LENOVO_TPKBD) += hid-lenovo-tpkbd.o 62obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o
63obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 63obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
64obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o 64obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
65obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o 65obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8ed66fd1ea87..6c813c6092f8 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -783,7 +783,9 @@ static int hid_scan_report(struct hid_device *hid)
783 * Vendor specific handlings 783 * Vendor specific handlings
784 */ 784 */
785 if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) && 785 if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) &&
786 (hid->group == HID_GROUP_GENERIC)) 786 (hid->group == HID_GROUP_GENERIC) &&
787 /* only bind to the mouse interface of composite USB devices */
788 (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE))
787 /* hid-rmi should take care of them, not hid-generic */ 789 /* hid-rmi should take care of them, not hid-generic */
788 hid->group = HID_GROUP_RMI; 790 hid->group = HID_GROUP_RMI;
789 791
@@ -1782,7 +1784,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1782 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) }, 1784 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) },
1783 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) }, 1785 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
1784 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, 1786 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
1785 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) }, 1787 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
1786 { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, 1788 { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
1787 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, 1789 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
1788 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, 1790 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
@@ -1796,8 +1798,10 @@ static const struct hid_device_id hid_have_special_driver[] = {
1796 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, 1798 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
1797 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, 1799 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
1798 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, 1800 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
1799#if IS_ENABLED(CONFIG_HID_LENOVO_TPKBD) 1801#if IS_ENABLED(CONFIG_HID_LENOVO)
1800 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, 1802 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
1803 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
1804 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
1801#endif 1805#endif
1802 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, 1806 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
1803 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, 1807 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
@@ -2266,6 +2270,7 @@ static const struct hid_device_id hid_ignore_list[] = {
2266 { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, 2270 { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
2267 { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) }, 2271 { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) },
2268 { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) }, 2272 { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) },
2273 { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_GN9350E) },
2269 { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, 2274 { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
2270 { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, 2275 { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
2271 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, 2276 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
index 56be85a9a77c..a822db5a8338 100644
--- a/drivers/hid/hid-cp2112.c
+++ b/drivers/hid/hid-cp2112.c
@@ -240,8 +240,6 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
240 u8 buf[5]; 240 u8 buf[5];
241 int ret; 241 int ret;
242 242
243 cp2112_gpio_set(chip, offset, value);
244
245 ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf, 243 ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
246 sizeof(buf), HID_FEATURE_REPORT, 244 sizeof(buf), HID_FEATURE_REPORT,
247 HID_REQ_GET_REPORT); 245 HID_REQ_GET_REPORT);
@@ -260,6 +258,12 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
260 return ret; 258 return ret;
261 } 259 }
262 260
261 /*
262 * Set gpio value when output direction is already set,
263 * as specified in AN495, Rev. 0.2, cpt. 4.4
264 */
265 cp2112_gpio_set(chip, offset, value);
266
263 return 0; 267 return 0;
264} 268}
265 269
@@ -425,6 +429,105 @@ static int cp2112_write_req(void *buf, u8 slave_address, u8 command, u8 *data,
425 return data_length + 4; 429 return data_length + 4;
426} 430}
427 431
432static int cp2112_i2c_write_req(void *buf, u8 slave_address, u8 *data,
433 u8 data_length)
434{
435 struct cp2112_write_req_report *report = buf;
436
437 if (data_length > sizeof(report->data))
438 return -EINVAL;
439
440 report->report = CP2112_DATA_WRITE_REQUEST;
441 report->slave_address = slave_address << 1;
442 report->length = data_length;
443 memcpy(report->data, data, data_length);
444 return data_length + 3;
445}
446
447static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
448 int num)
449{
450 struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data;
451 struct hid_device *hdev = dev->hdev;
452 u8 buf[64];
453 ssize_t count;
454 unsigned int retries;
455 int ret;
456
457 hid_dbg(hdev, "I2C %d messages\n", num);
458
459 if (num != 1) {
460 hid_err(hdev,
461 "Multi-message I2C transactions not supported\n");
462 return -EOPNOTSUPP;
463 }
464
465 if (msgs->flags & I2C_M_RD)
466 count = cp2112_read_req(buf, msgs->addr, msgs->len);
467 else
468 count = cp2112_i2c_write_req(buf, msgs->addr, msgs->buf,
469 msgs->len);
470
471 if (count < 0)
472 return count;
473
474 ret = hid_hw_power(hdev, PM_HINT_FULLON);
475 if (ret < 0) {
476 hid_err(hdev, "power management error: %d\n", ret);
477 return ret;
478 }
479
480 ret = cp2112_hid_output(hdev, buf, count, HID_OUTPUT_REPORT);
481 if (ret < 0) {
482 hid_warn(hdev, "Error starting transaction: %d\n", ret);
483 goto power_normal;
484 }
485
486 for (retries = 0; retries < XFER_STATUS_RETRIES; ++retries) {
487 ret = cp2112_xfer_status(dev);
488 if (-EBUSY == ret)
489 continue;
490 if (ret < 0)
491 goto power_normal;
492 break;
493 }
494
495 if (XFER_STATUS_RETRIES <= retries) {
496 hid_warn(hdev, "Transfer timed out, cancelling.\n");
497 buf[0] = CP2112_CANCEL_TRANSFER;
498 buf[1] = 0x01;
499
500 ret = cp2112_hid_output(hdev, buf, 2, HID_OUTPUT_REPORT);
501 if (ret < 0)
502 hid_warn(hdev, "Error cancelling transaction: %d\n",
503 ret);
504
505 ret = -ETIMEDOUT;
506 goto power_normal;
507 }
508
509 if (!(msgs->flags & I2C_M_RD))
510 goto finish;
511
512 ret = cp2112_read(dev, msgs->buf, msgs->len);
513 if (ret < 0)
514 goto power_normal;
515 if (ret != msgs->len) {
516 hid_warn(hdev, "short read: %d < %d\n", ret, msgs->len);
517 ret = -EIO;
518 goto power_normal;
519 }
520
521finish:
522 /* return the number of transferred messages */
523 ret = 1;
524
525power_normal:
526 hid_hw_power(hdev, PM_HINT_NORMAL);
527 hid_dbg(hdev, "I2C transfer finished: %d\n", ret);
528 return ret;
529}
530
428static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, 531static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
429 unsigned short flags, char read_write, u8 command, 532 unsigned short flags, char read_write, u8 command,
430 int size, union i2c_smbus_data *data) 533 int size, union i2c_smbus_data *data)
@@ -591,7 +694,8 @@ power_normal:
591 694
592static u32 cp2112_functionality(struct i2c_adapter *adap) 695static u32 cp2112_functionality(struct i2c_adapter *adap)
593{ 696{
594 return I2C_FUNC_SMBUS_BYTE | 697 return I2C_FUNC_I2C |
698 I2C_FUNC_SMBUS_BYTE |
595 I2C_FUNC_SMBUS_BYTE_DATA | 699 I2C_FUNC_SMBUS_BYTE_DATA |
596 I2C_FUNC_SMBUS_WORD_DATA | 700 I2C_FUNC_SMBUS_WORD_DATA |
597 I2C_FUNC_SMBUS_BLOCK_DATA | 701 I2C_FUNC_SMBUS_BLOCK_DATA |
@@ -601,6 +705,7 @@ static u32 cp2112_functionality(struct i2c_adapter *adap)
601} 705}
602 706
603static const struct i2c_algorithm smbus_algorithm = { 707static const struct i2c_algorithm smbus_algorithm = {
708 .master_xfer = cp2112_i2c_xfer,
604 .smbus_xfer = cp2112_xfer, 709 .smbus_xfer = cp2112_xfer,
605 .functionality = cp2112_functionality, 710 .functionality = cp2112_functionality,
606}; 711};
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
index cbf4da4689ba..60f44cd1b0ed 100644
--- a/drivers/hid/hid-huion.c
+++ b/drivers/hid/hid-huion.c
@@ -2,6 +2,7 @@
2 * HID driver for Huion devices not fully compliant with HID standard 2 * HID driver for Huion devices not fully compliant with HID standard
3 * 3 *
4 * Copyright (c) 2013 Martin Rusko 4 * Copyright (c) 2013 Martin Rusko
5 * Copyright (c) 2014 Nikolai Kondrashov
5 */ 6 */
6 7
7/* 8/*
@@ -15,67 +16,89 @@
15#include <linux/hid.h> 16#include <linux/hid.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/usb.h> 18#include <linux/usb.h>
19#include <asm/unaligned.h>
18#include "usbhid/usbhid.h" 20#include "usbhid/usbhid.h"
19 21
20#include "hid-ids.h" 22#include "hid-ids.h"
21 23
22/* Original Huion 580 report descriptor size */ 24/* Report descriptor template placeholder head */
23#define HUION_580_RDESC_ORIG_SIZE 177 25#define HUION_PH_HEAD 0xFE, 0xED, 0x1D
24 26
25/* Fixed Huion 580 report descriptor */ 27/* Report descriptor template placeholder IDs */
26static __u8 huion_580_rdesc_fixed[] = { 28enum huion_ph_id {
27 0x05, 0x0D, /* Usage Page (Digitizer), */ 29 HUION_PH_ID_X_LM,
28 0x09, 0x02, /* Usage (Pen), */ 30 HUION_PH_ID_X_PM,
29 0xA1, 0x01, /* Collection (Application), */ 31 HUION_PH_ID_Y_LM,
30 0x85, 0x07, /* Report ID (7), */ 32 HUION_PH_ID_Y_PM,
31 0x09, 0x20, /* Usage (Stylus), */ 33 HUION_PH_ID_PRESSURE_LM,
32 0xA0, /* Collection (Physical), */ 34 HUION_PH_ID_NUM
33 0x14, /* Logical Minimum (0), */ 35};
34 0x25, 0x01, /* Logical Maximum (1), */ 36
35 0x75, 0x01, /* Report Size (1), */ 37/* Report descriptor template placeholder */
36 0x09, 0x42, /* Usage (Tip Switch), */ 38#define HUION_PH(_ID) HUION_PH_HEAD, HUION_PH_ID_##_ID
37 0x09, 0x44, /* Usage (Barrel Switch), */ 39
38 0x09, 0x46, /* Usage (Tablet Pick), */ 40/* Fixed report descriptor template */
39 0x95, 0x03, /* Report Count (3), */ 41static const __u8 huion_tablet_rdesc_template[] = {
40 0x81, 0x02, /* Input (Variable), */ 42 0x05, 0x0D, /* Usage Page (Digitizer), */
41 0x95, 0x03, /* Report Count (3), */ 43 0x09, 0x02, /* Usage (Pen), */
42 0x81, 0x03, /* Input (Constant, Variable), */ 44 0xA1, 0x01, /* Collection (Application), */
43 0x09, 0x32, /* Usage (In Range), */ 45 0x85, 0x07, /* Report ID (7), */
44 0x95, 0x01, /* Report Count (1), */ 46 0x09, 0x20, /* Usage (Stylus), */
45 0x81, 0x02, /* Input (Variable), */ 47 0xA0, /* Collection (Physical), */
46 0x95, 0x01, /* Report Count (1), */ 48 0x14, /* Logical Minimum (0), */
47 0x81, 0x03, /* Input (Constant, Variable), */ 49 0x25, 0x01, /* Logical Maximum (1), */
48 0x75, 0x10, /* Report Size (16), */ 50 0x75, 0x01, /* Report Size (1), */
49 0x95, 0x01, /* Report Count (1), */ 51 0x09, 0x42, /* Usage (Tip Switch), */
50 0xA4, /* Push, */ 52 0x09, 0x44, /* Usage (Barrel Switch), */
51 0x05, 0x01, /* Usage Page (Desktop), */ 53 0x09, 0x46, /* Usage (Tablet Pick), */
52 0x65, 0x13, /* Unit (Inch), */ 54 0x95, 0x03, /* Report Count (3), */
53 0x55, 0xFD, /* Unit Exponent (-3), */ 55 0x81, 0x02, /* Input (Variable), */
54 0x34, /* Physical Minimum (0), */ 56 0x95, 0x03, /* Report Count (3), */
55 0x09, 0x30, /* Usage (X), */ 57 0x81, 0x03, /* Input (Constant, Variable), */
56 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ 58 0x09, 0x32, /* Usage (In Range), */
57 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */ 59 0x95, 0x01, /* Report Count (1), */
58 0x81, 0x02, /* Input (Variable), */ 60 0x81, 0x02, /* Input (Variable), */
59 0x09, 0x31, /* Usage (Y), */ 61 0x95, 0x01, /* Report Count (1), */
60 0x46, 0x88, 0x13, /* Physical Maximum (5000), */ 62 0x81, 0x03, /* Input (Constant, Variable), */
61 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ 63 0x75, 0x10, /* Report Size (16), */
62 0x81, 0x02, /* Input (Variable), */ 64 0x95, 0x01, /* Report Count (1), */
63 0xB4, /* Pop, */ 65 0xA4, /* Push, */
64 0x09, 0x30, /* Usage (Tip Pressure), */ 66 0x05, 0x01, /* Usage Page (Desktop), */
65 0x26, 0xFF, 0x07, /* Logical Maximum (2047), */ 67 0x65, 0x13, /* Unit (Inch), */
66 0x81, 0x02, /* Input (Variable), */ 68 0x55, 0xFD, /* Unit Exponent (-3), */
67 0xC0, /* End Collection, */ 69 0x34, /* Physical Minimum (0), */
68 0xC0 /* End Collection */ 70 0x09, 0x30, /* Usage (X), */
71 0x27, HUION_PH(X_LM), /* Logical Maximum (PLACEHOLDER), */
72 0x47, HUION_PH(X_PM), /* Physical Maximum (PLACEHOLDER), */
73 0x81, 0x02, /* Input (Variable), */
74 0x09, 0x31, /* Usage (Y), */
75 0x27, HUION_PH(Y_LM), /* Logical Maximum (PLACEHOLDER), */
76 0x47, HUION_PH(Y_PM), /* Physical Maximum (PLACEHOLDER), */
77 0x81, 0x02, /* Input (Variable), */
78 0xB4, /* Pop, */
79 0x09, 0x30, /* Usage (Tip Pressure), */
80 0x27,
81 HUION_PH(PRESSURE_LM), /* Logical Maximum (PLACEHOLDER), */
82 0x81, 0x02, /* Input (Variable), */
83 0xC0, /* End Collection, */
84 0xC0 /* End Collection */
85};
86
87/* Driver data */
88struct huion_drvdata {
89 __u8 *rdesc;
90 unsigned int rsize;
69}; 91};
70 92
71static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc, 93static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
72 unsigned int *rsize) 94 unsigned int *rsize)
73{ 95{
96 struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
74 switch (hdev->product) { 97 switch (hdev->product) {
75 case USB_DEVICE_ID_HUION_580: 98 case USB_DEVICE_ID_HUION_TABLET:
76 if (*rsize == HUION_580_RDESC_ORIG_SIZE) { 99 if (drvdata->rdesc != NULL) {
77 rdesc = huion_580_rdesc_fixed; 100 rdesc = drvdata->rdesc;
78 *rsize = sizeof(huion_580_rdesc_fixed); 101 *rsize = drvdata->rsize;
79 } 102 }
80 break; 103 break;
81 } 104 }
@@ -83,82 +106,144 @@ static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
83} 106}
84 107
85/** 108/**
86 * Enable fully-functional tablet mode by reading special string 109 * Enable fully-functional tablet mode and determine device parameters.
87 * descriptor.
88 * 110 *
89 * @hdev: HID device 111 * @hdev: HID device
90 *
91 * The specific string descriptor and data were discovered by sniffing
92 * the Windows driver traffic.
93 */ 112 */
94static int huion_tablet_enable(struct hid_device *hdev) 113static int huion_tablet_enable(struct hid_device *hdev)
95{ 114{
96 int rc; 115 int rc;
97 char buf[22]; 116 struct usb_device *usb_dev = hid_to_usb_dev(hdev);
117 struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
118 __le16 buf[6];
98 119
99 rc = usb_string(hid_to_usb_dev(hdev), 0x64, buf, sizeof(buf)); 120 /*
100 if (rc < 0) 121 * Read string descriptor containing tablet parameters. The specific
101 return rc; 122 * string descriptor and data were discovered by sniffing the Windows
123 * driver traffic.
124 * NOTE: This enables fully-functional tablet mode.
125 */
126 rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
127 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
128 (USB_DT_STRING << 8) + 0x64,
129 0x0409, buf, sizeof(buf),
130 USB_CTRL_GET_TIMEOUT);
131 if (rc == -EPIPE)
132 hid_warn(hdev, "device parameters not found\n");
133 else if (rc < 0)
134 hid_warn(hdev, "failed to get device parameters: %d\n", rc);
135 else if (rc != sizeof(buf))
136 hid_warn(hdev, "invalid device parameters\n");
137 else {
138 s32 params[HUION_PH_ID_NUM];
139 s32 resolution;
140 __u8 *p;
141 s32 v;
142
143 /* Extract device parameters */
144 params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]);
145 params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]);
146 params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]);
147 resolution = le16_to_cpu(buf[5]);
148 if (resolution == 0) {
149 params[HUION_PH_ID_X_PM] = 0;
150 params[HUION_PH_ID_Y_PM] = 0;
151 } else {
152 params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] *
153 1000 / resolution;
154 params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] *
155 1000 / resolution;
156 }
157
158 /* Allocate fixed report descriptor */
159 drvdata->rdesc = devm_kmalloc(&hdev->dev,
160 sizeof(huion_tablet_rdesc_template),
161 GFP_KERNEL);
162 if (drvdata->rdesc == NULL) {
163 hid_err(hdev, "failed to allocate fixed rdesc\n");
164 return -ENOMEM;
165 }
166 drvdata->rsize = sizeof(huion_tablet_rdesc_template);
167
168 /* Format fixed report descriptor */
169 memcpy(drvdata->rdesc, huion_tablet_rdesc_template,
170 drvdata->rsize);
171 for (p = drvdata->rdesc;
172 p <= drvdata->rdesc + drvdata->rsize - 4;) {
173 if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D &&
174 p[3] < sizeof(params)) {
175 v = params[p[3]];
176 put_unaligned(cpu_to_le32(v), (s32 *)p);
177 p += 4;
178 } else {
179 p++;
180 }
181 }
182 }
102 183
103 return 0; 184 return 0;
104} 185}
105 186
106static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) 187static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
107{ 188{
108 int ret; 189 int rc;
109 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 190 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
191 struct huion_drvdata *drvdata;
192
193 /* Allocate and assign driver data */
194 drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
195 if (drvdata == NULL) {
196 hid_err(hdev, "failed to allocate driver data\n");
197 return -ENOMEM;
198 }
199 hid_set_drvdata(hdev, drvdata);
110 200
111 /* Ignore interfaces 1 (mouse) and 2 (keyboard) for Huion 580 tablet,
112 * as they are not used
113 */
114 switch (id->product) { 201 switch (id->product) {
115 case USB_DEVICE_ID_HUION_580: 202 case USB_DEVICE_ID_HUION_TABLET:
116 if (intf->cur_altsetting->desc.bInterfaceNumber != 0x00) 203 /* If this is the pen interface */
117 return -ENODEV; 204 if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
205 rc = huion_tablet_enable(hdev);
206 if (rc) {
207 hid_err(hdev, "tablet enabling failed\n");
208 return rc;
209 }
210 }
118 break; 211 break;
119 } 212 }
120 213
121 ret = hid_parse(hdev); 214 rc = hid_parse(hdev);
122 if (ret) { 215 if (rc) {
123 hid_err(hdev, "parse failed\n"); 216 hid_err(hdev, "parse failed\n");
124 goto err; 217 return rc;
125 } 218 }
126 219
127 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 220 rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
128 if (ret) { 221 if (rc) {
129 hid_err(hdev, "hw start failed\n"); 222 hid_err(hdev, "hw start failed\n");
130 goto err; 223 return rc;
131 }
132
133 switch (id->product) {
134 case USB_DEVICE_ID_HUION_580:
135 ret = huion_tablet_enable(hdev);
136 if (ret) {
137 hid_err(hdev, "tablet enabling failed\n");
138 goto enabling_err;
139 }
140 break;
141 } 224 }
142 225
143 return 0; 226 return 0;
144enabling_err:
145 hid_hw_stop(hdev);
146err:
147 return ret;
148} 227}
149 228
150static int huion_raw_event(struct hid_device *hdev, struct hid_report *report, 229static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
151 u8 *data, int size) 230 u8 *data, int size)
152{ 231{
153 /* If this is a pen input report then invert the in-range bit */ 232 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
154 if (report->type == HID_INPUT_REPORT && report->id == 0x07 && size >= 2) 233
234 /* If this is a pen input report */
235 if (intf->cur_altsetting->desc.bInterfaceNumber == 0 &&
236 report->type == HID_INPUT_REPORT &&
237 report->id == 0x07 && size >= 2)
238 /* Invert the in-range bit */
155 data[1] ^= 0x40; 239 data[1] ^= 0x40;
156 240
157 return 0; 241 return 0;
158} 242}
159 243
160static const struct hid_device_id huion_devices[] = { 244static const struct hid_device_id huion_devices[] = {
161 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) }, 245 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
246 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_HUION_TABLET) },
162 { } 247 { }
163}; 248};
164MODULE_DEVICE_TABLE(hid, huion_devices); 249MODULE_DEVICE_TABLE(hid, huion_devices);
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
index f52dbcb7133b..31fad641b744 100644
--- a/drivers/hid/hid-hyperv.c
+++ b/drivers/hid/hid-hyperv.c
@@ -308,6 +308,9 @@ static void mousevsc_on_receive(struct hv_device *device,
308 memcpy(input_dev->input_buf, input_report->buffer, len); 308 memcpy(input_dev->input_buf, input_report->buffer, len);
309 hid_input_report(input_dev->hid_device, HID_INPUT_REPORT, 309 hid_input_report(input_dev->hid_device, HID_INPUT_REPORT,
310 input_dev->input_buf, len, 1); 310 input_dev->input_buf, len, 1);
311
312 pm_wakeup_event(&input_dev->device->device, 0);
313
311 break; 314 break;
312 default: 315 default:
313 pr_err("unsupported hid msg type - type %d len %d", 316 pr_err("unsupported hid msg type - type %d len %d",
@@ -549,6 +552,8 @@ static int mousevsc_probe(struct hv_device *device,
549 goto probe_err2; 552 goto probe_err2;
550 } 553 }
551 554
555 device_init_wakeup(&device->device, true);
556
552 input_dev->connected = true; 557 input_dev->connected = true;
553 input_dev->init_complete = true; 558 input_dev->init_complete = true;
554 559
@@ -571,6 +576,7 @@ static int mousevsc_remove(struct hv_device *dev)
571{ 576{
572 struct mousevsc_dev *input_dev = hv_get_drvdata(dev); 577 struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
573 578
579 device_init_wakeup(&dev->device, false);
574 vmbus_close(dev->channel); 580 vmbus_close(dev->channel);
575 hid_hw_stop(input_dev->hid_device); 581 hid_hw_stop(input_dev->hid_device);
576 hid_destroy_device(input_dev->hid_device); 582 hid_destroy_device(input_dev->hid_device);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 48b66bbffc94..d53bdda26207 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -448,7 +448,7 @@
448#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 448#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
449 449
450#define USB_VENDOR_ID_HUION 0x256c 450#define USB_VENDOR_ID_HUION 0x256c
451#define USB_DEVICE_ID_HUION_580 0x006e 451#define USB_DEVICE_ID_HUION_TABLET 0x006e
452 452
453#define USB_VENDOR_ID_IDEACOM 0x1cb6 453#define USB_VENDOR_ID_IDEACOM 0x1cb6
454#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 454#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
@@ -479,6 +479,7 @@
479#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 0xa070 479#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 0xa070
480#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 0xa072 480#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 0xa072
481#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081 481#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081
482#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096
482 483
483#define USB_VENDOR_ID_IMATION 0x0718 484#define USB_VENDOR_ID_IMATION 0x0718
484#define USB_DEVICE_ID_DISC_STAKKA 0xd000 485#define USB_DEVICE_ID_DISC_STAKKA 0xd000
@@ -489,6 +490,7 @@
489#define USB_VENDOR_ID_JABRA 0x0b0e 490#define USB_VENDOR_ID_JABRA 0x0b0e
490#define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 491#define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412
491#define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420 492#define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420
493#define USB_DEVICE_ID_JABRA_GN9350E 0x9350
492 494
493#define USB_VENDOR_ID_JESS 0x0c45 495#define USB_VENDOR_ID_JESS 0x0c45
494#define USB_DEVICE_ID_JESS_YUREX 0x1010 496#define USB_DEVICE_ID_JESS_YUREX 0x1010
@@ -561,6 +563,8 @@
561 563
562#define USB_VENDOR_ID_LENOVO 0x17ef 564#define USB_VENDOR_ID_LENOVO 0x17ef
563#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009 565#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
566#define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
567#define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048
564 568
565#define USB_VENDOR_ID_LG 0x1fd2 569#define USB_VENDOR_ID_LG 0x1fd2
566#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 570#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c
deleted file mode 100644
index 2d25b6cbbc05..000000000000
--- a/drivers/hid/hid-lenovo-tpkbd.c
+++ /dev/null
@@ -1,462 +0,0 @@
1/*
2 * HID driver for Lenovo ThinkPad USB Keyboard with TrackPoint
3 *
4 * Copyright (c) 2012 Bernhard Seibold
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/sysfs.h>
16#include <linux/device.h>
17#include <linux/hid.h>
18#include <linux/input.h>
19#include <linux/leds.h>
20
21#include "hid-ids.h"
22
23/* This is only used for the trackpoint part of the driver, hence _tp */
24struct tpkbd_data_pointer {
25 int led_state;
26 struct led_classdev led_mute;
27 struct led_classdev led_micmute;
28 int press_to_select;
29 int dragging;
30 int release_to_select;
31 int select_right;
32 int sensitivity;
33 int press_speed;
34};
35
36#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
37
38static int tpkbd_input_mapping(struct hid_device *hdev,
39 struct hid_input *hi, struct hid_field *field,
40 struct hid_usage *usage, unsigned long **bit, int *max)
41{
42 if (usage->hid == (HID_UP_BUTTON | 0x0010)) {
43 /* mark the device as pointer */
44 hid_set_drvdata(hdev, (void *)1);
45 map_key_clear(KEY_MICMUTE);
46 return 1;
47 }
48 return 0;
49}
50
51#undef map_key_clear
52
53static int tpkbd_features_set(struct hid_device *hdev)
54{
55 struct hid_report *report;
56 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
57
58 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4];
59
60 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02;
61 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08;
62 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20;
63 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40;
64 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver
65 report->field[2]->value[0] = data_pointer->sensitivity;
66 report->field[3]->value[0] = data_pointer->press_speed;
67
68 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
69 return 0;
70}
71
72static ssize_t pointer_press_to_select_show(struct device *dev,
73 struct device_attribute *attr,
74 char *buf)
75{
76 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
77 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
78
79 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select);
80}
81
82static ssize_t pointer_press_to_select_store(struct device *dev,
83 struct device_attribute *attr,
84 const char *buf,
85 size_t count)
86{
87 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
88 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
89 int value;
90
91 if (kstrtoint(buf, 10, &value))
92 return -EINVAL;
93 if (value < 0 || value > 1)
94 return -EINVAL;
95
96 data_pointer->press_to_select = value;
97 tpkbd_features_set(hdev);
98
99 return count;
100}
101
102static ssize_t pointer_dragging_show(struct device *dev,
103 struct device_attribute *attr,
104 char *buf)
105{
106 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
107 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
108
109 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging);
110}
111
112static ssize_t pointer_dragging_store(struct device *dev,
113 struct device_attribute *attr,
114 const char *buf,
115 size_t count)
116{
117 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
118 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
119 int value;
120
121 if (kstrtoint(buf, 10, &value))
122 return -EINVAL;
123 if (value < 0 || value > 1)
124 return -EINVAL;
125
126 data_pointer->dragging = value;
127 tpkbd_features_set(hdev);
128
129 return count;
130}
131
132static ssize_t pointer_release_to_select_show(struct device *dev,
133 struct device_attribute *attr,
134 char *buf)
135{
136 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
137 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
138
139 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select);
140}
141
142static ssize_t pointer_release_to_select_store(struct device *dev,
143 struct device_attribute *attr,
144 const char *buf,
145 size_t count)
146{
147 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
148 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
149 int value;
150
151 if (kstrtoint(buf, 10, &value))
152 return -EINVAL;
153 if (value < 0 || value > 1)
154 return -EINVAL;
155
156 data_pointer->release_to_select = value;
157 tpkbd_features_set(hdev);
158
159 return count;
160}
161
162static ssize_t pointer_select_right_show(struct device *dev,
163 struct device_attribute *attr,
164 char *buf)
165{
166 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
167 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
168
169 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right);
170}
171
172static ssize_t pointer_select_right_store(struct device *dev,
173 struct device_attribute *attr,
174 const char *buf,
175 size_t count)
176{
177 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
178 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
179 int value;
180
181 if (kstrtoint(buf, 10, &value))
182 return -EINVAL;
183 if (value < 0 || value > 1)
184 return -EINVAL;
185
186 data_pointer->select_right = value;
187 tpkbd_features_set(hdev);
188
189 return count;
190}
191
192static ssize_t pointer_sensitivity_show(struct device *dev,
193 struct device_attribute *attr,
194 char *buf)
195{
196 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
197 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
198
199 return snprintf(buf, PAGE_SIZE, "%u\n",
200 data_pointer->sensitivity);
201}
202
203static ssize_t pointer_sensitivity_store(struct device *dev,
204 struct device_attribute *attr,
205 const char *buf,
206 size_t count)
207{
208 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
209 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
210 int value;
211
212 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
213 return -EINVAL;
214
215 data_pointer->sensitivity = value;
216 tpkbd_features_set(hdev);
217
218 return count;
219}
220
221static ssize_t pointer_press_speed_show(struct device *dev,
222 struct device_attribute *attr,
223 char *buf)
224{
225 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
226 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
227
228 return snprintf(buf, PAGE_SIZE, "%u\n",
229 data_pointer->press_speed);
230}
231
232static ssize_t pointer_press_speed_store(struct device *dev,
233 struct device_attribute *attr,
234 const char *buf,
235 size_t count)
236{
237 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
238 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
239 int value;
240
241 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
242 return -EINVAL;
243
244 data_pointer->press_speed = value;
245 tpkbd_features_set(hdev);
246
247 return count;
248}
249
250static struct device_attribute dev_attr_pointer_press_to_select =
251 __ATTR(press_to_select, S_IWUSR | S_IRUGO,
252 pointer_press_to_select_show,
253 pointer_press_to_select_store);
254
255static struct device_attribute dev_attr_pointer_dragging =
256 __ATTR(dragging, S_IWUSR | S_IRUGO,
257 pointer_dragging_show,
258 pointer_dragging_store);
259
260static struct device_attribute dev_attr_pointer_release_to_select =
261 __ATTR(release_to_select, S_IWUSR | S_IRUGO,
262 pointer_release_to_select_show,
263 pointer_release_to_select_store);
264
265static struct device_attribute dev_attr_pointer_select_right =
266 __ATTR(select_right, S_IWUSR | S_IRUGO,
267 pointer_select_right_show,
268 pointer_select_right_store);
269
270static struct device_attribute dev_attr_pointer_sensitivity =
271 __ATTR(sensitivity, S_IWUSR | S_IRUGO,
272 pointer_sensitivity_show,
273 pointer_sensitivity_store);
274
275static struct device_attribute dev_attr_pointer_press_speed =
276 __ATTR(press_speed, S_IWUSR | S_IRUGO,
277 pointer_press_speed_show,
278 pointer_press_speed_store);
279
280static struct attribute *tpkbd_attributes_pointer[] = {
281 &dev_attr_pointer_press_to_select.attr,
282 &dev_attr_pointer_dragging.attr,
283 &dev_attr_pointer_release_to_select.attr,
284 &dev_attr_pointer_select_right.attr,
285 &dev_attr_pointer_sensitivity.attr,
286 &dev_attr_pointer_press_speed.attr,
287 NULL
288};
289
290static const struct attribute_group tpkbd_attr_group_pointer = {
291 .attrs = tpkbd_attributes_pointer,
292};
293
294static enum led_brightness tpkbd_led_brightness_get(
295 struct led_classdev *led_cdev)
296{
297 struct device *dev = led_cdev->dev->parent;
298 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
299 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
300 int led_nr = 0;
301
302 if (led_cdev == &data_pointer->led_micmute)
303 led_nr = 1;
304
305 return data_pointer->led_state & (1 << led_nr)
306 ? LED_FULL
307 : LED_OFF;
308}
309
310static void tpkbd_led_brightness_set(struct led_classdev *led_cdev,
311 enum led_brightness value)
312{
313 struct device *dev = led_cdev->dev->parent;
314 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
315 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
316 struct hid_report *report;
317 int led_nr = 0;
318
319 if (led_cdev == &data_pointer->led_micmute)
320 led_nr = 1;
321
322 if (value == LED_OFF)
323 data_pointer->led_state &= ~(1 << led_nr);
324 else
325 data_pointer->led_state |= 1 << led_nr;
326
327 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
328 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
329 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
330 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
331}
332
333static int tpkbd_probe_tp(struct hid_device *hdev)
334{
335 struct device *dev = &hdev->dev;
336 struct tpkbd_data_pointer *data_pointer;
337 size_t name_sz = strlen(dev_name(dev)) + 16;
338 char *name_mute, *name_micmute;
339 int i;
340
341 /* Validate required reports. */
342 for (i = 0; i < 4; i++) {
343 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
344 return -ENODEV;
345 }
346 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2))
347 return -ENODEV;
348
349 if (sysfs_create_group(&hdev->dev.kobj,
350 &tpkbd_attr_group_pointer)) {
351 hid_warn(hdev, "Could not create sysfs group\n");
352 }
353
354 data_pointer = devm_kzalloc(&hdev->dev,
355 sizeof(struct tpkbd_data_pointer),
356 GFP_KERNEL);
357 if (data_pointer == NULL) {
358 hid_err(hdev, "Could not allocate memory for driver data\n");
359 return -ENOMEM;
360 }
361
362 // set same default values as windows driver
363 data_pointer->sensitivity = 0xa0;
364 data_pointer->press_speed = 0x38;
365
366 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
367 name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
368 if (name_mute == NULL || name_micmute == NULL) {
369 hid_err(hdev, "Could not allocate memory for led data\n");
370 return -ENOMEM;
371 }
372 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
373 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
374
375 hid_set_drvdata(hdev, data_pointer);
376
377 data_pointer->led_mute.name = name_mute;
378 data_pointer->led_mute.brightness_get = tpkbd_led_brightness_get;
379 data_pointer->led_mute.brightness_set = tpkbd_led_brightness_set;
380 data_pointer->led_mute.dev = dev;
381 led_classdev_register(dev, &data_pointer->led_mute);
382
383 data_pointer->led_micmute.name = name_micmute;
384 data_pointer->led_micmute.brightness_get = tpkbd_led_brightness_get;
385 data_pointer->led_micmute.brightness_set = tpkbd_led_brightness_set;
386 data_pointer->led_micmute.dev = dev;
387 led_classdev_register(dev, &data_pointer->led_micmute);
388
389 tpkbd_features_set(hdev);
390
391 return 0;
392}
393
394static int tpkbd_probe(struct hid_device *hdev,
395 const struct hid_device_id *id)
396{
397 int ret;
398
399 ret = hid_parse(hdev);
400 if (ret) {
401 hid_err(hdev, "hid_parse failed\n");
402 goto err;
403 }
404
405 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
406 if (ret) {
407 hid_err(hdev, "hid_hw_start failed\n");
408 goto err;
409 }
410
411 if (hid_get_drvdata(hdev)) {
412 hid_set_drvdata(hdev, NULL);
413 ret = tpkbd_probe_tp(hdev);
414 if (ret)
415 goto err_hid;
416 }
417
418 return 0;
419err_hid:
420 hid_hw_stop(hdev);
421err:
422 return ret;
423}
424
425static void tpkbd_remove_tp(struct hid_device *hdev)
426{
427 struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
428
429 sysfs_remove_group(&hdev->dev.kobj,
430 &tpkbd_attr_group_pointer);
431
432 led_classdev_unregister(&data_pointer->led_micmute);
433 led_classdev_unregister(&data_pointer->led_mute);
434
435 hid_set_drvdata(hdev, NULL);
436}
437
438static void tpkbd_remove(struct hid_device *hdev)
439{
440 if (hid_get_drvdata(hdev))
441 tpkbd_remove_tp(hdev);
442
443 hid_hw_stop(hdev);
444}
445
446static const struct hid_device_id tpkbd_devices[] = {
447 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
448 { }
449};
450
451MODULE_DEVICE_TABLE(hid, tpkbd_devices);
452
453static struct hid_driver tpkbd_driver = {
454 .name = "lenovo_tpkbd",
455 .id_table = tpkbd_devices,
456 .input_mapping = tpkbd_input_mapping,
457 .probe = tpkbd_probe,
458 .remove = tpkbd_remove,
459};
460module_hid_driver(tpkbd_driver);
461
462MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
new file mode 100644
index 000000000000..bf227f7679af
--- /dev/null
+++ b/drivers/hid/hid-lenovo.c
@@ -0,0 +1,708 @@
1/*
2 * HID driver for Lenovo:
3 * - ThinkPad USB Keyboard with TrackPoint (tpkbd)
4 * - ThinkPad Compact Bluetooth Keyboard with TrackPoint (cptkbd)
5 * - ThinkPad Compact USB Keyboard with TrackPoint (cptkbd)
6 *
7 * Copyright (c) 2012 Bernhard Seibold
8 * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk>
9 */
10
11/*
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or (at your option)
15 * any later version.
16 */
17
18#include <linux/module.h>
19#include <linux/sysfs.h>
20#include <linux/device.h>
21#include <linux/hid.h>
22#include <linux/input.h>
23#include <linux/leds.h>
24
25#include "hid-ids.h"
26
27struct lenovo_drvdata_tpkbd {
28 int led_state;
29 struct led_classdev led_mute;
30 struct led_classdev led_micmute;
31 int press_to_select;
32 int dragging;
33 int release_to_select;
34 int select_right;
35 int sensitivity;
36 int press_speed;
37};
38
39struct lenovo_drvdata_cptkbd {
40 bool fn_lock;
41};
42
43#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
44
45static int lenovo_input_mapping_tpkbd(struct hid_device *hdev,
46 struct hid_input *hi, struct hid_field *field,
47 struct hid_usage *usage, unsigned long **bit, int *max)
48{
49 if (usage->hid == (HID_UP_BUTTON | 0x0010)) {
50 /* This sub-device contains trackpoint, mark it */
51 hid_set_drvdata(hdev, (void *)1);
52 map_key_clear(KEY_MICMUTE);
53 return 1;
54 }
55 return 0;
56}
57
58static int lenovo_input_mapping_cptkbd(struct hid_device *hdev,
59 struct hid_input *hi, struct hid_field *field,
60 struct hid_usage *usage, unsigned long **bit, int *max)
61{
62 /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */
63 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR ||
64 (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) {
65 set_bit(EV_REP, hi->input->evbit);
66 switch (usage->hid & HID_USAGE) {
67 case 0x00f1: /* Fn-F4: Mic mute */
68 map_key_clear(KEY_MICMUTE);
69 return 1;
70 case 0x00f2: /* Fn-F5: Brightness down */
71 map_key_clear(KEY_BRIGHTNESSDOWN);
72 return 1;
73 case 0x00f3: /* Fn-F6: Brightness up */
74 map_key_clear(KEY_BRIGHTNESSUP);
75 return 1;
76 case 0x00f4: /* Fn-F7: External display (projector) */
77 map_key_clear(KEY_SWITCHVIDEOMODE);
78 return 1;
79 case 0x00f5: /* Fn-F8: Wireless */
80 map_key_clear(KEY_WLAN);
81 return 1;
82 case 0x00f6: /* Fn-F9: Control panel */
83 map_key_clear(KEY_CONFIG);
84 return 1;
85 case 0x00f8: /* Fn-F11: View open applications (3 boxes) */
86 map_key_clear(KEY_SCALE);
87 return 1;
88 case 0x00fa: /* Fn-Esc: Fn-lock toggle */
89 map_key_clear(KEY_FN_ESC);
90 return 1;
91 case 0x00fb: /* Fn-F12: Open My computer (6 boxes) USB-only */
92 /* NB: This mapping is invented in raw_event below */
93 map_key_clear(KEY_FILE);
94 return 1;
95 }
96 }
97
98 return 0;
99}
100
101static int lenovo_input_mapping(struct hid_device *hdev,
102 struct hid_input *hi, struct hid_field *field,
103 struct hid_usage *usage, unsigned long **bit, int *max)
104{
105 switch (hdev->product) {
106 case USB_DEVICE_ID_LENOVO_TPKBD:
107 return lenovo_input_mapping_tpkbd(hdev, hi, field,
108 usage, bit, max);
109 case USB_DEVICE_ID_LENOVO_CUSBKBD:
110 case USB_DEVICE_ID_LENOVO_CBTKBD:
111 return lenovo_input_mapping_cptkbd(hdev, hi, field,
112 usage, bit, max);
113 default:
114 return 0;
115 }
116}
117
118#undef map_key_clear
119
120/* Send a config command to the keyboard */
121static int lenovo_send_cmd_cptkbd(struct hid_device *hdev,
122 unsigned char byte2, unsigned char byte3)
123{
124 int ret;
125 unsigned char buf[] = {0x18, byte2, byte3};
126
127 switch (hdev->product) {
128 case USB_DEVICE_ID_LENOVO_CUSBKBD:
129 ret = hid_hw_raw_request(hdev, 0x13, buf, sizeof(buf),
130 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
131 break;
132 case USB_DEVICE_ID_LENOVO_CBTKBD:
133 ret = hid_hw_output_report(hdev, buf, sizeof(buf));
134 break;
135 default:
136 ret = -EINVAL;
137 break;
138 }
139
140 return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */
141}
142
143static void lenovo_features_set_cptkbd(struct hid_device *hdev)
144{
145 int ret;
146 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
147
148 ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock);
149 if (ret)
150 hid_err(hdev, "Fn-lock setting failed: %d\n", ret);
151}
152
153static ssize_t attr_fn_lock_show_cptkbd(struct device *dev,
154 struct device_attribute *attr,
155 char *buf)
156{
157 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
158 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
159
160 return snprintf(buf, PAGE_SIZE, "%u\n", cptkbd_data->fn_lock);
161}
162
163static ssize_t attr_fn_lock_store_cptkbd(struct device *dev,
164 struct device_attribute *attr,
165 const char *buf,
166 size_t count)
167{
168 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
169 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
170 int value;
171
172 if (kstrtoint(buf, 10, &value))
173 return -EINVAL;
174 if (value < 0 || value > 1)
175 return -EINVAL;
176
177 cptkbd_data->fn_lock = !!value;
178 lenovo_features_set_cptkbd(hdev);
179
180 return count;
181}
182
183static struct device_attribute dev_attr_fn_lock_cptkbd =
184 __ATTR(fn_lock, S_IWUSR | S_IRUGO,
185 attr_fn_lock_show_cptkbd,
186 attr_fn_lock_store_cptkbd);
187
188static struct attribute *lenovo_attributes_cptkbd[] = {
189 &dev_attr_fn_lock_cptkbd.attr,
190 NULL
191};
192
193static const struct attribute_group lenovo_attr_group_cptkbd = {
194 .attrs = lenovo_attributes_cptkbd,
195};
196
197static int lenovo_raw_event(struct hid_device *hdev,
198 struct hid_report *report, u8 *data, int size)
199{
200 /*
201 * Compact USB keyboard's Fn-F12 report holds down many other keys, and
202 * its own key is outside the usage page range. Remove extra
203 * keypresses and remap to inside usage page.
204 */
205 if (unlikely(hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
206 && size == 3
207 && data[0] == 0x15
208 && data[1] == 0x94
209 && data[2] == 0x01)) {
210 data[1] = 0x0;
211 data[2] = 0x4;
212 }
213
214 return 0;
215}
216
217static int lenovo_features_set_tpkbd(struct hid_device *hdev)
218{
219 struct hid_report *report;
220 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
221
222 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4];
223
224 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02;
225 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08;
226 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20;
227 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40;
228 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver
229 report->field[2]->value[0] = data_pointer->sensitivity;
230 report->field[3]->value[0] = data_pointer->press_speed;
231
232 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
233 return 0;
234}
235
236static ssize_t attr_press_to_select_show_tpkbd(struct device *dev,
237 struct device_attribute *attr,
238 char *buf)
239{
240 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
241 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
242
243 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select);
244}
245
246static ssize_t attr_press_to_select_store_tpkbd(struct device *dev,
247 struct device_attribute *attr,
248 const char *buf,
249 size_t count)
250{
251 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
252 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
253 int value;
254
255 if (kstrtoint(buf, 10, &value))
256 return -EINVAL;
257 if (value < 0 || value > 1)
258 return -EINVAL;
259
260 data_pointer->press_to_select = value;
261 lenovo_features_set_tpkbd(hdev);
262
263 return count;
264}
265
266static ssize_t attr_dragging_show_tpkbd(struct device *dev,
267 struct device_attribute *attr,
268 char *buf)
269{
270 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
271 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
272
273 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging);
274}
275
276static ssize_t attr_dragging_store_tpkbd(struct device *dev,
277 struct device_attribute *attr,
278 const char *buf,
279 size_t count)
280{
281 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
282 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
283 int value;
284
285 if (kstrtoint(buf, 10, &value))
286 return -EINVAL;
287 if (value < 0 || value > 1)
288 return -EINVAL;
289
290 data_pointer->dragging = value;
291 lenovo_features_set_tpkbd(hdev);
292
293 return count;
294}
295
296static ssize_t attr_release_to_select_show_tpkbd(struct device *dev,
297 struct device_attribute *attr,
298 char *buf)
299{
300 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
301 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
302
303 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select);
304}
305
306static ssize_t attr_release_to_select_store_tpkbd(struct device *dev,
307 struct device_attribute *attr,
308 const char *buf,
309 size_t count)
310{
311 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
312 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
313 int value;
314
315 if (kstrtoint(buf, 10, &value))
316 return -EINVAL;
317 if (value < 0 || value > 1)
318 return -EINVAL;
319
320 data_pointer->release_to_select = value;
321 lenovo_features_set_tpkbd(hdev);
322
323 return count;
324}
325
326static ssize_t attr_select_right_show_tpkbd(struct device *dev,
327 struct device_attribute *attr,
328 char *buf)
329{
330 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
331 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
332
333 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right);
334}
335
336static ssize_t attr_select_right_store_tpkbd(struct device *dev,
337 struct device_attribute *attr,
338 const char *buf,
339 size_t count)
340{
341 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
342 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
343 int value;
344
345 if (kstrtoint(buf, 10, &value))
346 return -EINVAL;
347 if (value < 0 || value > 1)
348 return -EINVAL;
349
350 data_pointer->select_right = value;
351 lenovo_features_set_tpkbd(hdev);
352
353 return count;
354}
355
356static ssize_t attr_sensitivity_show_tpkbd(struct device *dev,
357 struct device_attribute *attr,
358 char *buf)
359{
360 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
361 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
362
363 return snprintf(buf, PAGE_SIZE, "%u\n",
364 data_pointer->sensitivity);
365}
366
367static ssize_t attr_sensitivity_store_tpkbd(struct device *dev,
368 struct device_attribute *attr,
369 const char *buf,
370 size_t count)
371{
372 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
373 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
374 int value;
375
376 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
377 return -EINVAL;
378
379 data_pointer->sensitivity = value;
380 lenovo_features_set_tpkbd(hdev);
381
382 return count;
383}
384
385static ssize_t attr_press_speed_show_tpkbd(struct device *dev,
386 struct device_attribute *attr,
387 char *buf)
388{
389 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
390 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
391
392 return snprintf(buf, PAGE_SIZE, "%u\n",
393 data_pointer->press_speed);
394}
395
396static ssize_t attr_press_speed_store_tpkbd(struct device *dev,
397 struct device_attribute *attr,
398 const char *buf,
399 size_t count)
400{
401 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
402 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
403 int value;
404
405 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
406 return -EINVAL;
407
408 data_pointer->press_speed = value;
409 lenovo_features_set_tpkbd(hdev);
410
411 return count;
412}
413
414static struct device_attribute dev_attr_press_to_select_tpkbd =
415 __ATTR(press_to_select, S_IWUSR | S_IRUGO,
416 attr_press_to_select_show_tpkbd,
417 attr_press_to_select_store_tpkbd);
418
419static struct device_attribute dev_attr_dragging_tpkbd =
420 __ATTR(dragging, S_IWUSR | S_IRUGO,
421 attr_dragging_show_tpkbd,
422 attr_dragging_store_tpkbd);
423
424static struct device_attribute dev_attr_release_to_select_tpkbd =
425 __ATTR(release_to_select, S_IWUSR | S_IRUGO,
426 attr_release_to_select_show_tpkbd,
427 attr_release_to_select_store_tpkbd);
428
429static struct device_attribute dev_attr_select_right_tpkbd =
430 __ATTR(select_right, S_IWUSR | S_IRUGO,
431 attr_select_right_show_tpkbd,
432 attr_select_right_store_tpkbd);
433
434static struct device_attribute dev_attr_sensitivity_tpkbd =
435 __ATTR(sensitivity, S_IWUSR | S_IRUGO,
436 attr_sensitivity_show_tpkbd,
437 attr_sensitivity_store_tpkbd);
438
439static struct device_attribute dev_attr_press_speed_tpkbd =
440 __ATTR(press_speed, S_IWUSR | S_IRUGO,
441 attr_press_speed_show_tpkbd,
442 attr_press_speed_store_tpkbd);
443
444static struct attribute *lenovo_attributes_tpkbd[] = {
445 &dev_attr_press_to_select_tpkbd.attr,
446 &dev_attr_dragging_tpkbd.attr,
447 &dev_attr_release_to_select_tpkbd.attr,
448 &dev_attr_select_right_tpkbd.attr,
449 &dev_attr_sensitivity_tpkbd.attr,
450 &dev_attr_press_speed_tpkbd.attr,
451 NULL
452};
453
454static const struct attribute_group lenovo_attr_group_tpkbd = {
455 .attrs = lenovo_attributes_tpkbd,
456};
457
458static enum led_brightness lenovo_led_brightness_get_tpkbd(
459 struct led_classdev *led_cdev)
460{
461 struct device *dev = led_cdev->dev->parent;
462 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
463 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
464 int led_nr = 0;
465
466 if (led_cdev == &data_pointer->led_micmute)
467 led_nr = 1;
468
469 return data_pointer->led_state & (1 << led_nr)
470 ? LED_FULL
471 : LED_OFF;
472}
473
474static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev,
475 enum led_brightness value)
476{
477 struct device *dev = led_cdev->dev->parent;
478 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
479 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
480 struct hid_report *report;
481 int led_nr = 0;
482
483 if (led_cdev == &data_pointer->led_micmute)
484 led_nr = 1;
485
486 if (value == LED_OFF)
487 data_pointer->led_state &= ~(1 << led_nr);
488 else
489 data_pointer->led_state |= 1 << led_nr;
490
491 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
492 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
493 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
494 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
495}
496
497static int lenovo_probe_tpkbd(struct hid_device *hdev)
498{
499 struct device *dev = &hdev->dev;
500 struct lenovo_drvdata_tpkbd *data_pointer;
501 size_t name_sz = strlen(dev_name(dev)) + 16;
502 char *name_mute, *name_micmute;
503 int i;
504 int ret;
505
506 /*
507 * Only register extra settings against subdevice where input_mapping
508 * set drvdata to 1, i.e. the trackpoint.
509 */
510 if (!hid_get_drvdata(hdev))
511 return 0;
512
513 hid_set_drvdata(hdev, NULL);
514
515 /* Validate required reports. */
516 for (i = 0; i < 4; i++) {
517 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
518 return -ENODEV;
519 }
520 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2))
521 return -ENODEV;
522
523 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd);
524 if (ret)
525 hid_warn(hdev, "Could not create sysfs group: %d\n", ret);
526
527 data_pointer = devm_kzalloc(&hdev->dev,
528 sizeof(struct lenovo_drvdata_tpkbd),
529 GFP_KERNEL);
530 if (data_pointer == NULL) {
531 hid_err(hdev, "Could not allocate memory for driver data\n");
532 return -ENOMEM;
533 }
534
535 // set same default values as windows driver
536 data_pointer->sensitivity = 0xa0;
537 data_pointer->press_speed = 0x38;
538
539 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
540 name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
541 if (name_mute == NULL || name_micmute == NULL) {
542 hid_err(hdev, "Could not allocate memory for led data\n");
543 return -ENOMEM;
544 }
545 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
546 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
547
548 hid_set_drvdata(hdev, data_pointer);
549
550 data_pointer->led_mute.name = name_mute;
551 data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd;
552 data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd;
553 data_pointer->led_mute.dev = dev;
554 led_classdev_register(dev, &data_pointer->led_mute);
555
556 data_pointer->led_micmute.name = name_micmute;
557 data_pointer->led_micmute.brightness_get =
558 lenovo_led_brightness_get_tpkbd;
559 data_pointer->led_micmute.brightness_set =
560 lenovo_led_brightness_set_tpkbd;
561 data_pointer->led_micmute.dev = dev;
562 led_classdev_register(dev, &data_pointer->led_micmute);
563
564 lenovo_features_set_tpkbd(hdev);
565
566 return 0;
567}
568
569static int lenovo_probe_cptkbd(struct hid_device *hdev)
570{
571 int ret;
572 struct lenovo_drvdata_cptkbd *cptkbd_data;
573
574 /* All the custom action happens on the USBMOUSE device for USB */
575 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
576 && hdev->type != HID_TYPE_USBMOUSE) {
577 hid_dbg(hdev, "Ignoring keyboard half of device\n");
578 return 0;
579 }
580
581 cptkbd_data = devm_kzalloc(&hdev->dev,
582 sizeof(*cptkbd_data),
583 GFP_KERNEL);
584 if (cptkbd_data == NULL) {
585 hid_err(hdev, "can't alloc keyboard descriptor\n");
586 return -ENOMEM;
587 }
588 hid_set_drvdata(hdev, cptkbd_data);
589
590 /*
591 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into
592 * regular keys
593 */
594 ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03);
595 if (ret)
596 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
597
598 /* Turn Fn-Lock on by default */
599 cptkbd_data->fn_lock = true;
600 lenovo_features_set_cptkbd(hdev);
601
602 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
603 if (ret)
604 hid_warn(hdev, "Could not create sysfs group: %d\n", ret);
605
606 return 0;
607}
608
609static int lenovo_probe(struct hid_device *hdev,
610 const struct hid_device_id *id)
611{
612 int ret;
613
614 ret = hid_parse(hdev);
615 if (ret) {
616 hid_err(hdev, "hid_parse failed\n");
617 goto err;
618 }
619
620 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
621 if (ret) {
622 hid_err(hdev, "hid_hw_start failed\n");
623 goto err;
624 }
625
626 switch (hdev->product) {
627 case USB_DEVICE_ID_LENOVO_TPKBD:
628 ret = lenovo_probe_tpkbd(hdev);
629 break;
630 case USB_DEVICE_ID_LENOVO_CUSBKBD:
631 case USB_DEVICE_ID_LENOVO_CBTKBD:
632 ret = lenovo_probe_cptkbd(hdev);
633 break;
634 default:
635 ret = 0;
636 break;
637 }
638 if (ret)
639 goto err_hid;
640
641 return 0;
642err_hid:
643 hid_hw_stop(hdev);
644err:
645 return ret;
646}
647
648static void lenovo_remove_tpkbd(struct hid_device *hdev)
649{
650 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
651
652 /*
653 * Only the trackpoint half of the keyboard has drvdata and stuff that
654 * needs unregistering.
655 */
656 if (data_pointer == NULL)
657 return;
658
659 sysfs_remove_group(&hdev->dev.kobj,
660 &lenovo_attr_group_tpkbd);
661
662 led_classdev_unregister(&data_pointer->led_micmute);
663 led_classdev_unregister(&data_pointer->led_mute);
664
665 hid_set_drvdata(hdev, NULL);
666}
667
668static void lenovo_remove_cptkbd(struct hid_device *hdev)
669{
670 sysfs_remove_group(&hdev->dev.kobj,
671 &lenovo_attr_group_cptkbd);
672}
673
674static void lenovo_remove(struct hid_device *hdev)
675{
676 switch (hdev->product) {
677 case USB_DEVICE_ID_LENOVO_TPKBD:
678 lenovo_remove_tpkbd(hdev);
679 break;
680 case USB_DEVICE_ID_LENOVO_CUSBKBD:
681 case USB_DEVICE_ID_LENOVO_CBTKBD:
682 lenovo_remove_cptkbd(hdev);
683 break;
684 }
685
686 hid_hw_stop(hdev);
687}
688
689static const struct hid_device_id lenovo_devices[] = {
690 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
691 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
692 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
693 { }
694};
695
696MODULE_DEVICE_TABLE(hid, lenovo_devices);
697
698static struct hid_driver lenovo_driver = {
699 .name = "lenovo",
700 .id_table = lenovo_devices,
701 .input_mapping = lenovo_input_mapping,
702 .probe = lenovo_probe,
703 .remove = lenovo_remove,
704 .raw_event = lenovo_raw_event,
705};
706module_hid_driver(lenovo_driver);
707
708MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-picolcd_debugfs.c b/drivers/hid/hid-picolcd_debugfs.c
index 024cdf3c2297..3c13af684410 100644
--- a/drivers/hid/hid-picolcd_debugfs.c
+++ b/drivers/hid/hid-picolcd_debugfs.c
@@ -883,16 +883,13 @@ void picolcd_exit_devfs(struct picolcd_data *data)
883 883
884 dent = data->debug_reset; 884 dent = data->debug_reset;
885 data->debug_reset = NULL; 885 data->debug_reset = NULL;
886 if (dent) 886 debugfs_remove(dent);
887 debugfs_remove(dent);
888 dent = data->debug_eeprom; 887 dent = data->debug_eeprom;
889 data->debug_eeprom = NULL; 888 data->debug_eeprom = NULL;
890 if (dent) 889 debugfs_remove(dent);
891 debugfs_remove(dent);
892 dent = data->debug_flash; 890 dent = data->debug_flash;
893 data->debug_flash = NULL; 891 data->debug_flash = NULL;
894 if (dent) 892 debugfs_remove(dent);
895 debugfs_remove(dent);
896 mutex_destroy(&data->mutex_flash); 893 mutex_destroy(&data->mutex_flash);
897} 894}
898 895
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index 578bbe65902b..0dc25142f451 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -377,7 +377,7 @@ static int rmi_input_event(struct hid_device *hdev, u8 *data, int size)
377 irq_mask |= hdata->f30.irq_mask; 377 irq_mask |= hdata->f30.irq_mask;
378 378
379 if (data[1] & ~irq_mask) 379 if (data[1] & ~irq_mask)
380 hid_warn(hdev, "unknown intr source:%02lx %s:%d\n", 380 hid_dbg(hdev, "unknown intr source:%02lx %s:%d\n",
381 data[1] & ~irq_mask, __FILE__, __LINE__); 381 data[1] & ~irq_mask, __FILE__, __LINE__);
382 382
383 if (hdata->f11.interrupt_base < hdata->f30.interrupt_base) { 383 if (hdata->f11.interrupt_base < hdata->f30.interrupt_base) {
@@ -400,7 +400,7 @@ static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size)
400 struct rmi_data *hdata = hid_get_drvdata(hdev); 400 struct rmi_data *hdata = hid_get_drvdata(hdev);
401 401
402 if (!test_bit(RMI_READ_REQUEST_PENDING, &hdata->flags)) { 402 if (!test_bit(RMI_READ_REQUEST_PENDING, &hdata->flags)) {
403 hid_err(hdev, "no read request pending\n"); 403 hid_dbg(hdev, "no read request pending\n");
404 return 0; 404 return 0;
405 } 405 }
406 406
@@ -549,10 +549,12 @@ static int rmi_populate_f11(struct hid_device *hdev)
549 u8 buf[20]; 549 u8 buf[20];
550 int ret; 550 int ret;
551 bool has_query9; 551 bool has_query9;
552 bool has_query10; 552 bool has_query10 = false;
553 bool has_query11; 553 bool has_query11;
554 bool has_query12; 554 bool has_query12;
555 bool has_physical_props; 555 bool has_physical_props;
556 bool has_gestures;
557 bool has_rel;
556 unsigned x_size, y_size; 558 unsigned x_size, y_size;
557 u16 query12_offset; 559 u16 query12_offset;
558 560
@@ -589,19 +591,32 @@ static int rmi_populate_f11(struct hid_device *hdev)
589 return -ENODEV; 591 return -ENODEV;
590 } 592 }
591 593
592 /* query 8 to find out if query 10 exists */ 594 has_rel = !!(buf[0] & BIT(3));
593 ret = rmi_read(hdev, data->f11.query_base_addr + 8, buf); 595 has_gestures = !!(buf[0] & BIT(5));
594 if (ret) { 596
595 hid_err(hdev, "can not read gesture information: %d.\n", ret); 597 if (has_gestures) {
596 return ret; 598 /* query 8 to find out if query 10 exists */
599 ret = rmi_read(hdev, data->f11.query_base_addr + 8, buf);
600 if (ret) {
601 hid_err(hdev, "can not read gesture information: %d.\n",
602 ret);
603 return ret;
604 }
605 has_query10 = !!(buf[0] & BIT(2));
597 } 606 }
598 has_query10 = !!(buf[0] & BIT(2));
599 607
600 /* 608 /*
601 * At least 8 queries are guaranteed to be present in F11 609 * At least 4 queries are guaranteed to be present in F11
602 * +1 for query12. 610 * +1 for query 5 which is present since absolute events are
611 * reported and +1 for query 12.
603 */ 612 */
604 query12_offset = 9; 613 query12_offset = 6;
614
615 if (has_rel)
616 ++query12_offset; /* query 6 is present */
617
618 if (has_gestures)
619 query12_offset += 2; /* query 7 and 8 are present */
605 620
606 if (has_query9) 621 if (has_query9)
607 ++query12_offset; 622 ++query12_offset;
@@ -833,6 +848,8 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
833 struct rmi_data *data = NULL; 848 struct rmi_data *data = NULL;
834 int ret; 849 int ret;
835 size_t alloc_size; 850 size_t alloc_size;
851 struct hid_report *input_report;
852 struct hid_report *output_report;
836 853
837 data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL); 854 data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL);
838 if (!data) 855 if (!data)
@@ -851,12 +868,26 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
851 return ret; 868 return ret;
852 } 869 }
853 870
854 data->input_report_size = (hdev->report_enum[HID_INPUT_REPORT] 871 input_report = hdev->report_enum[HID_INPUT_REPORT]
855 .report_id_hash[RMI_ATTN_REPORT_ID]->size >> 3) 872 .report_id_hash[RMI_ATTN_REPORT_ID];
856 + 1 /* report id */; 873 if (!input_report) {
857 data->output_report_size = (hdev->report_enum[HID_OUTPUT_REPORT] 874 hid_err(hdev, "device does not have expected input report\n");
858 .report_id_hash[RMI_WRITE_REPORT_ID]->size >> 3) 875 ret = -ENODEV;
859 + 1 /* report id */; 876 return ret;
877 }
878
879 data->input_report_size = (input_report->size >> 3) + 1 /* report id */;
880
881 output_report = hdev->report_enum[HID_OUTPUT_REPORT]
882 .report_id_hash[RMI_WRITE_REPORT_ID];
883 if (!output_report) {
884 hid_err(hdev, "device does not have expected output report\n");
885 ret = -ENODEV;
886 return ret;
887 }
888
889 data->output_report_size = (output_report->size >> 3)
890 + 1 /* report id */;
860 891
861 alloc_size = data->output_report_size + data->input_report_size; 892 alloc_size = data->output_report_size + data->input_report_size;
862 893
diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c
index 6adc0fa08d96..65e2e76bf2fe 100644
--- a/drivers/hid/hid-roccat-lua.c
+++ b/drivers/hid/hid-roccat-lua.c
@@ -61,7 +61,7 @@ static ssize_t lua_sysfs_write(struct file *fp, struct kobject *kobj,
61 return -EINVAL; 61 return -EINVAL;
62 62
63 mutex_lock(&lua->lua_lock); 63 mutex_lock(&lua->lua_lock);
64 retval = roccat_common2_send(usb_dev, command, (void *)buf, real_size); 64 retval = roccat_common2_send(usb_dev, command, buf, real_size);
65 mutex_unlock(&lua->lua_lock); 65 mutex_unlock(&lua->lua_lock);
66 66
67 return retval ? retval : real_size; 67 return retval ? retval : real_size;
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 2259eaa8b988..c372368e438c 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -56,32 +56,81 @@
56 56
57#define MAX_LEDS 4 57#define MAX_LEDS 4
58 58
59static const u8 sixaxis_rdesc_fixup[] = { 59static __u8 sixaxis_rdesc[] = {
60 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, 60 0x05, 0x01, /* Usage Page (Desktop), */
61 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF, 61 0x09, 0x04, /* Usage (Joystik), */
62 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 62 0xA1, 0x01, /* Collection (Application), */
63}; 63 0xA1, 0x02, /* Collection (Logical), */
64 64 0x85, 0x01, /* Report ID (1), */
65static const u8 sixaxis_rdesc_fixup2[] = { 65 0x75, 0x08, /* Report Size (8), */
66 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 66 0x95, 0x01, /* Report Count (1), */
67 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 67 0x15, 0x00, /* Logical Minimum (0), */
68 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, 68 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
69 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45, 69 0x81, 0x03, /* Input (Constant, Variable), */
70 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, 70 0x75, 0x01, /* Report Size (1), */
71 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, 71 0x95, 0x13, /* Report Count (19), */
72 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 72 0x15, 0x00, /* Logical Minimum (0), */
73 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95, 73 0x25, 0x01, /* Logical Maximum (1), */
74 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, 74 0x35, 0x00, /* Physical Minimum (0), */
75 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02, 75 0x45, 0x01, /* Physical Maximum (1), */
76 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81, 76 0x05, 0x09, /* Usage Page (Button), */
77 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95, 77 0x19, 0x01, /* Usage Minimum (01h), */
78 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09, 78 0x29, 0x13, /* Usage Maximum (13h), */
79 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02, 79 0x81, 0x02, /* Input (Variable), */
80 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 80 0x75, 0x01, /* Report Size (1), */
81 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, 81 0x95, 0x0D, /* Report Count (13), */
82 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 82 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
83 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 83 0x81, 0x03, /* Input (Constant, Variable), */
84 0xb1, 0x02, 0xc0, 0xc0, 84 0x15, 0x00, /* Logical Minimum (0), */
85 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
86 0x05, 0x01, /* Usage Page (Desktop), */
87 0x09, 0x01, /* Usage (Pointer), */
88 0xA1, 0x00, /* Collection (Physical), */
89 0x75, 0x08, /* Report Size (8), */
90 0x95, 0x04, /* Report Count (4), */
91 0x35, 0x00, /* Physical Minimum (0), */
92 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
93 0x09, 0x30, /* Usage (X), */
94 0x09, 0x31, /* Usage (Y), */
95 0x09, 0x32, /* Usage (Z), */
96 0x09, 0x35, /* Usage (Rz), */
97 0x81, 0x02, /* Input (Variable), */
98 0xC0, /* End Collection, */
99 0x05, 0x01, /* Usage Page (Desktop), */
100 0x95, 0x13, /* Report Count (19), */
101 0x09, 0x01, /* Usage (Pointer), */
102 0x81, 0x02, /* Input (Variable), */
103 0x95, 0x0C, /* Report Count (12), */
104 0x81, 0x01, /* Input (Constant), */
105 0x75, 0x10, /* Report Size (16), */
106 0x95, 0x04, /* Report Count (4), */
107 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
108 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */
109 0x09, 0x01, /* Usage (Pointer), */
110 0x81, 0x02, /* Input (Variable), */
111 0xC0, /* End Collection, */
112 0xA1, 0x02, /* Collection (Logical), */
113 0x85, 0x02, /* Report ID (2), */
114 0x75, 0x08, /* Report Size (8), */
115 0x95, 0x30, /* Report Count (48), */
116 0x09, 0x01, /* Usage (Pointer), */
117 0xB1, 0x02, /* Feature (Variable), */
118 0xC0, /* End Collection, */
119 0xA1, 0x02, /* Collection (Logical), */
120 0x85, 0xEE, /* Report ID (238), */
121 0x75, 0x08, /* Report Size (8), */
122 0x95, 0x30, /* Report Count (48), */
123 0x09, 0x01, /* Usage (Pointer), */
124 0xB1, 0x02, /* Feature (Variable), */
125 0xC0, /* End Collection, */
126 0xA1, 0x02, /* Collection (Logical), */
127 0x85, 0xEF, /* Report ID (239), */
128 0x75, 0x08, /* Report Size (8), */
129 0x95, 0x30, /* Report Count (48), */
130 0x09, 0x01, /* Usage (Pointer), */
131 0xB1, 0x02, /* Feature (Variable), */
132 0xC0, /* End Collection, */
133 0xC0 /* End Collection */
85}; 134};
86 135
87/* 136/*
@@ -778,6 +827,13 @@ struct sony_sc {
778 __u8 led_count; 827 __u8 led_count;
779}; 828};
780 829
830static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc,
831 unsigned int *rsize)
832{
833 *rsize = sizeof(sixaxis_rdesc);
834 return sixaxis_rdesc;
835}
836
781static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 837static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
782 unsigned int *rsize) 838 unsigned int *rsize)
783{ 839{
@@ -819,8 +875,6 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
819 return 1; 875 return 1;
820} 876}
821 877
822
823/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
824static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 878static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
825 unsigned int *rsize) 879 unsigned int *rsize)
826{ 880{
@@ -857,20 +911,8 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
857 *rsize = sizeof(dualshock4_bt_rdesc); 911 *rsize = sizeof(dualshock4_bt_rdesc);
858 } 912 }
859 913
860 /* The HID descriptor exposed over BT has a trailing zero byte */ 914 if (sc->quirks & SIXAXIS_CONTROLLER)
861 if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 915 return sixaxis_fixup(hdev, rdesc, rsize);
862 ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
863 rdesc[83] == 0x75) {
864 hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
865 memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
866 sizeof(sixaxis_rdesc_fixup));
867 } else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
868 *rsize > sizeof(sixaxis_rdesc_fixup2)) {
869 hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
870 *rsize, (int)sizeof(sixaxis_rdesc_fixup2));
871 *rsize = sizeof(sixaxis_rdesc_fixup2);
872 memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
873 }
874 916
875 if (sc->quirks & PS3REMOTE) 917 if (sc->quirks & PS3REMOTE)
876 return ps3remote_fixup(hdev, rdesc, rsize); 918 return ps3remote_fixup(hdev, rdesc, rsize);
@@ -1307,7 +1349,7 @@ static int sony_leds_init(struct sony_sc *sc)
1307 static const char * const ds4_name_str[] = { "red", "green", "blue", 1349 static const char * const ds4_name_str[] = { "red", "green", "blue",
1308 "global" }; 1350 "global" };
1309 __u8 initial_values[MAX_LEDS] = { 0 }; 1351 __u8 initial_values[MAX_LEDS] = { 0 };
1310 __u8 max_brightness[MAX_LEDS] = { 1 }; 1352 __u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 };
1311 __u8 use_hw_blink[MAX_LEDS] = { 0 }; 1353 __u8 use_hw_blink[MAX_LEDS] = { 0 };
1312 1354
1313 BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 1355 BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
@@ -1830,9 +1872,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1830 1872
1831 if (sc->quirks & VAIO_RDESC_CONSTANT) 1873 if (sc->quirks & VAIO_RDESC_CONSTANT)
1832 connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1874 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1833 else if (sc->quirks & SIXAXIS_CONTROLLER_USB) 1875 else if (sc->quirks & SIXAXIS_CONTROLLER)
1834 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1835 else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
1836 connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1876 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1837 1877
1838 ret = hid_hw_start(hdev, connect_mask); 1878 ret = hid_hw_start(hdev, connect_mask);
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 21aafc8f48c8..747d54421e73 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -1054,21 +1054,29 @@ static int i2c_hid_remove(struct i2c_client *client)
1054static int i2c_hid_suspend(struct device *dev) 1054static int i2c_hid_suspend(struct device *dev)
1055{ 1055{
1056 struct i2c_client *client = to_i2c_client(dev); 1056 struct i2c_client *client = to_i2c_client(dev);
1057 struct i2c_hid *ihid = i2c_get_clientdata(client);
1058 struct hid_device *hid = ihid->hid;
1059 int ret = 0;
1057 1060
1058 disable_irq(client->irq); 1061 disable_irq(client->irq);
1059 if (device_may_wakeup(&client->dev)) 1062 if (device_may_wakeup(&client->dev))
1060 enable_irq_wake(client->irq); 1063 enable_irq_wake(client->irq);
1061 1064
1065 if (hid->driver && hid->driver->suspend)
1066 ret = hid->driver->suspend(hid, PMSG_SUSPEND);
1067
1062 /* Save some power */ 1068 /* Save some power */
1063 i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); 1069 i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
1064 1070
1065 return 0; 1071 return ret;
1066} 1072}
1067 1073
1068static int i2c_hid_resume(struct device *dev) 1074static int i2c_hid_resume(struct device *dev)
1069{ 1075{
1070 int ret; 1076 int ret;
1071 struct i2c_client *client = to_i2c_client(dev); 1077 struct i2c_client *client = to_i2c_client(dev);
1078 struct i2c_hid *ihid = i2c_get_clientdata(client);
1079 struct hid_device *hid = ihid->hid;
1072 1080
1073 enable_irq(client->irq); 1081 enable_irq(client->irq);
1074 ret = i2c_hid_hwreset(client); 1082 ret = i2c_hid_hwreset(client);
@@ -1078,6 +1086,11 @@ static int i2c_hid_resume(struct device *dev)
1078 if (device_may_wakeup(&client->dev)) 1086 if (device_may_wakeup(&client->dev))
1079 disable_irq_wake(client->irq); 1087 disable_irq_wake(client->irq);
1080 1088
1089 if (hid->driver && hid->driver->reset_resume) {
1090 ret = hid->driver->reset_resume(hid);
1091 return ret;
1092 }
1093
1081 return 0; 1094 return 0;
1082} 1095}
1083#endif 1096#endif
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 7b88f4cb9902..79cf503e37bf 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -58,7 +58,7 @@ module_param_named(ignoreled, ignoreled, uint, 0644);
58MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds"); 58MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
59 59
60/* Quirks specified at module load time */ 60/* Quirks specified at module load time */
61static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL }; 61static char *quirks_param[MAX_USBHID_BOOT_QUIRKS];
62module_param_array_named(quirks, quirks_param, charp, NULL, 0444); 62module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
63MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " 63MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
64 " quirks=vendorID:productID:quirks" 64 " quirks=vendorID:productID:quirks"
@@ -536,7 +536,8 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
536 int head; 536 int head;
537 struct usbhid_device *usbhid = hid->driver_data; 537 struct usbhid_device *usbhid = hid->driver_data;
538 538
539 if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) 539 if (((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) ||
540 test_bit(HID_DISCONNECTED, &usbhid->iofl))
540 return; 541 return;
541 542
542 if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { 543 if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
@@ -1366,6 +1367,9 @@ static void usbhid_disconnect(struct usb_interface *intf)
1366 return; 1367 return;
1367 1368
1368 usbhid = hid->driver_data; 1369 usbhid = hid->driver_data;
1370 spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
1371 set_bit(HID_DISCONNECTED, &usbhid->iofl);
1372 spin_unlock_irq(&usbhid->lock);
1369 hid_destroy_device(hid); 1373 hid_destroy_device(hid);
1370 kfree(usbhid); 1374 kfree(usbhid);
1371} 1375}
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 31e6727cd009..0dd568170d6e 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -124,6 +124,7 @@ static const struct hid_blacklist {
124 { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS }, 124 { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS },
125 { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS }, 125 { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS },
126 { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS }, 126 { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS },
127 { USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096, HID_QUIRK_NO_INIT_INPUT_REPORTS },
127 128
128 { 0, 0 } 129 { 0, 0 }
129}; 130};