Commit e8403b49 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID updates from Jiri Kosina:

 - 3rd generation Wacom Intuos BT device support from Aaron Armstrong
   Skomra

 - support for NSG-MR5U and NSG-MR7U devices from Todd Kelner

 - multitouch Razer Blade Stealth support from Benjamin Tissoires

 - Elantech touchpad support from Alexandrov Stansilav

 - a few other scattered-around fixes and cleanups to drivers and
   generic code

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (31 commits)
  HID: google: Enable PM Full On mode when adjusting backlight
  HID: google: add google hammer HID driver
  HID: core: reset the quirks before calling probe again
  HID: multitouch: do not set HID_QUIRK_NO_INIT_REPORTS
  HID: core: remove the need for HID_QUIRK_NO_EMPTY_INPUT
  HID: use BIT() macro for quirks too
  HID: use BIT macro instead of plain integers for flags
  HID: multitouch: remove dead zones of Razer Blade Stealth
  HID: multitouch: export a quirk for the button handling of touchpads
  HID: usbhid: extend the polling interval configuration to keyboards
  HID: ntrig: document sysfs interface
  HID: wacom: wacom_wac_collection() is local to wacom_wac.c
  HID: wacom: generic: add the "Report Valid" usage
  HID: wacom: generic: Support multiple tools per report
  HID: wacom: Add support for 3rd generation Intuos BT
  HID: core: rewrite the hid-generic automatic unbind
  HID: sony: Add touchpad support for NSG-MR5U and NSG-MR7U remotes
  HID: hid-multitouch: Use true and false for boolean values
  HID: hid-ntrig: use true and false for boolean values
  HID: logitech-hidpp: document sysfs interface
  ...
parents e02d37bf 9931753b
What: /sys/bus/hid/drivers/logitech-hidpp-device/<dev>/range
Date: Jan, 2016
KernelVersion: 4.6
Contact: linux-input@vger.kernel.org
Description:
(RW) This attribute controls the amount of 'turn' permitted in
Logitech G920 wheel. Reading from the file shows the current
range of the steering wheel. Writing a value within the min and
max boundary sets the range of the wheel.
What: /sys/bus/hid/drivers/logitech-hidpp-device/<dev>/builtin_power_supply
Date: Apr, 2017
KernelVersion: 4.12
Contact: linux-input@vger.kernel.org
Description:
Presence of this file indicates that HID++ driver is capable of
handling battery properties in the kernel. This way, upower can
add a udev rule to decide whether or not it should use the
internal unifying support or the generic kernel one.
What: /sys/bus/hid/drivers/ntrig/<dev>/activate_slack
Date: May, 2010
KernelVersion: 2.6.35
Contact: linux-input@vger.kernel.org
Description:
(RW) Number of contact frames ignored before acknowledging the
start of activity (activating touch).
What: /sys/bus/hid/drivers/ntrig/<dev>/decativate_slack
Date: May, 2010
KernelVersion: 2.6.35
Contact: linux-input@vger.kernel.org
Description:
(RW) Number of empty (no contact) frames ignored before
acknowledging the end of activity (deactivating touch).
When the last finger is removed from the device, it sends a
number of empty frames. By holding off on deactivation for a few
frames false erroneous disconnects can be tolerated, where the
sensor may mistakenly not detect a finger that is still present.
What: /sys/bus/hid/drivers/ntrig/<dev>/activation_width
What: /sys/bus/hid/drivers/ntrig/<dev>/activation_height
Date: May, 2010
KernelVersion: 2.6.35
Contact: linux-input@vger.kernel.org
Description:
Threholds to override activation slack.
activation_width: (RW) Width threshold to immediately
start processing touch events.
activation_height: (RW) Height threshold to immediately
start processing touch events.
What: /sys/bus/hid/drivers/ntrig/<dev>/min_width
What: /sys/bus/hid/drivers/ntrig/<dev>/min_height
Date: May, 2010
KernelVersion: 2.6.35
Contact: linux-input@vger.kernel.org
Description:
Minimum size contact accepted.
min_width: (RW) Minimum touch contact width to decide
activation and activity.
min_height: (RW) Minimum touch contact height to decide
activation and activity.
What: /sys/bus/hid/drivers/ntrig/<dev>/sensor_physical_width
What: /sys/bus/hid/drivers/ntrig/<dev>/sensor_physical_height
Date: May, 2010
KernelVersion: 2.6.35
Contact: linux-input@vger.kernel.org
Description:
(RO) These are internal ranges not used for normal events but
useful for tuning.
What: /sys/bus/hid/drivers/ntrig/<dev>/sensor_logical_width
What: /sys/bus/hid/drivers/ntrig/<dev>/sensor_logical_height
Date: May, 2010
KernelVersion: 2.6.35
Contact: linux-input@vger.kernel.org
Description:
(RO) The range for positions reported during activity.
...@@ -4456,6 +4456,9 @@ ...@@ -4456,6 +4456,9 @@
usbhid.jspoll= usbhid.jspoll=
[USBHID] The interval which joysticks are to be polled at. [USBHID] The interval which joysticks are to be polled at.
usbhid.kbpoll=
[USBHID] The interval which keyboards are to be polled at.
usb-storage.delay_use= usb-storage.delay_use=
[UMS] The delay in seconds before a new device is [UMS] The delay in seconds before a new device is
scanned for Logical Units (default 1). scanned for Logical Units (default 1).
......
...@@ -274,15 +274,23 @@ config HID_EMS_FF ...@@ -274,15 +274,23 @@ config HID_EMS_FF
Currently the following devices are known to be supported: Currently the following devices are known to be supported:
- Trio Linker Plus II - Trio Linker Plus II
config HID_ELAN
tristate "ELAN USB Touchpad Support"
depends on LEDS_CLASS && USB_HID
---help---
Say Y to enable support for the USB ELAN touchpad
Currently the following devices are known to be supported:
- HP Pavilion X2 10-p0XX.
config HID_ELECOM config HID_ELECOM
tristate "ELECOM HID devices" tristate "ELECOM HID devices"
depends on HID depends on HID
---help--- ---help---
Support for ELECOM devices: Support for ELECOM devices:
- BM084 Bluetooth Mouse - BM084 Bluetooth Mouse
- EX-G Trackball (Wired and wireless) - EX-G Trackballs (M-XT3DRBK, M-XT3URBK)
- DEFT Trackball (Wired and wireless) - DEFT Trackballs (M-DT1DRBK, M-DT1URBK, M-DT2DRBK, M-DT2URBK)
- HUGE Trackball (Wired and wireless) - HUGE Trackballs (M-HT1DRBK, M-HT1URBK)
config HID_ELO config HID_ELO
tristate "ELO USB 4000/4500 touchscreen" tristate "ELO USB 4000/4500 touchscreen"
...@@ -331,6 +339,12 @@ config HOLTEK_FF ...@@ -331,6 +339,12 @@ config HOLTEK_FF
Say Y here if you have a Holtek On Line Grip based game controller Say Y here if you have a Holtek On Line Grip based game controller
and want to have force feedback support for it. and want to have force feedback support for it.
config HID_GOOGLE_HAMMER
tristate "Google Hammer Keyboard"
depends on USB_HID && LEDS_CLASS
---help---
Say Y here if you have a Google Hammer device.
config HID_GT683R config HID_GT683R
tristate "MSI GT68xR LED support" tristate "MSI GT68xR LED support"
depends on LEDS_CLASS && USB_HID depends on LEDS_CLASS && USB_HID
......
...@@ -39,11 +39,13 @@ obj-$(CONFIG_HID_CP2112) += hid-cp2112.o ...@@ -39,11 +39,13 @@ obj-$(CONFIG_HID_CP2112) += hid-cp2112.o
obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o
obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
obj-$(CONFIG_HID_ELAN) += hid-elan.o
obj-$(CONFIG_HID_ELECOM) += hid-elecom.o obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
obj-$(CONFIG_HID_ELO) += hid-elo.o obj-$(CONFIG_HID_ELO) += hid-elo.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o
obj-$(CONFIG_HID_GFRM) += hid-gfrm.o obj-$(CONFIG_HID_GFRM) += hid-gfrm.o
obj-$(CONFIG_HID_GOOGLE_HAMMER) += hid-google-hammer.o
obj-$(CONFIG_HID_GT683R) += hid-gt683r.o obj-$(CONFIG_HID_GT683R) += hid-gt683r.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
......
...@@ -570,7 +570,9 @@ static int asus_input_mapping(struct hid_device *hdev, ...@@ -570,7 +570,9 @@ static int asus_input_mapping(struct hid_device *hdev,
static int asus_start_multitouch(struct hid_device *hdev) static int asus_start_multitouch(struct hid_device *hdev)
{ {
int ret; int ret;
const unsigned char buf[] = { FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00 }; static const unsigned char buf[] = {
FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00
};
unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL); unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
if (!dmabuf) { if (!dmabuf) {
...@@ -644,8 +646,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -644,8 +646,7 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
* All functionality is on a single HID interface and for * All functionality is on a single HID interface and for
* userspace the touchpad must be a separate input_dev. * userspace the touchpad must be a separate input_dev.
*/ */
hdev->quirks |= HID_QUIRK_MULTI_INPUT | hdev->quirks |= HID_QUIRK_MULTI_INPUT;
HID_QUIRK_NO_EMPTY_INPUT;
drvdata->tp = &asus_t100chi_tp; drvdata->tp = &asus_t100chi_tp;
} }
......
...@@ -1365,7 +1365,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) ...@@ -1365,7 +1365,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
* of implement() working on 8 byte chunks * of implement() working on 8 byte chunks
*/ */
int len = hid_report_len(report) + 7; u32 len = hid_report_len(report) + 7;
return kmalloc(len, flags); return kmalloc(len, flags);
} }
...@@ -1430,7 +1430,7 @@ void __hid_request(struct hid_device *hid, struct hid_report *report, ...@@ -1430,7 +1430,7 @@ void __hid_request(struct hid_device *hid, struct hid_report *report,
{ {
char *buf; char *buf;
int ret; int ret;
int len; u32 len;
buf = hid_alloc_report_buf(report, GFP_KERNEL); buf = hid_alloc_report_buf(report, GFP_KERNEL);
if (!buf) if (!buf)
...@@ -1456,14 +1456,14 @@ void __hid_request(struct hid_device *hid, struct hid_report *report, ...@@ -1456,14 +1456,14 @@ void __hid_request(struct hid_device *hid, struct hid_report *report,
} }
EXPORT_SYMBOL_GPL(__hid_request); EXPORT_SYMBOL_GPL(__hid_request);
int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
int interrupt) int interrupt)
{ {
struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report_enum *report_enum = hid->report_enum + type;
struct hid_report *report; struct hid_report *report;
struct hid_driver *hdrv; struct hid_driver *hdrv;
unsigned int a; unsigned int a;
int rsize, csize = size; u32 rsize, csize = size;
u8 *cdata = data; u8 *cdata = data;
int ret = 0; int ret = 0;
...@@ -1521,7 +1521,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event); ...@@ -1521,7 +1521,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event);
* *
* This is data entry for lower layers. * This is data entry for lower layers.
*/ */
int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt)
{ {
struct hid_report_enum *report_enum; struct hid_report_enum *report_enum;
struct hid_driver *hdrv; struct hid_driver *hdrv;
...@@ -1966,6 +1966,8 @@ static int hid_device_probe(struct device *dev) ...@@ -1966,6 +1966,8 @@ static int hid_device_probe(struct device *dev)
} }
} }
/* reset the quirks that has been previously set */
hdev->quirks = hid_lookup_quirk(hdev);
hdev->driver = hdrv; hdev->driver = hdrv;
if (hdrv->probe) { if (hdrv->probe) {
ret = hdrv->probe(hdev, id); ret = hdrv->probe(hdev, id);
...@@ -2197,31 +2199,40 @@ void hid_destroy_device(struct hid_device *hdev) ...@@ -2197,31 +2199,40 @@ void hid_destroy_device(struct hid_device *hdev)
EXPORT_SYMBOL_GPL(hid_destroy_device); EXPORT_SYMBOL_GPL(hid_destroy_device);
static int __bus_add_driver(struct device_driver *drv, void *data) static int __hid_bus_reprobe_drivers(struct device *dev, void *data)
{ {
struct hid_driver *added_hdrv = data; struct hid_driver *hdrv = data;
struct hid_driver *hdrv = to_hid_driver(drv); struct hid_device *hdev = to_hid_device(dev);
if (hdrv->bus_add_driver) if (hdev->driver == hdrv &&
hdrv->bus_add_driver(added_hdrv); !hdrv->match(hdev, hid_ignore_special_drivers))
return device_reprobe(dev);
return 0; return 0;
} }
static int __bus_removed_driver(struct device_driver *drv, void *data) static int __hid_bus_driver_added(struct device_driver *drv, void *data)
{ {
struct hid_driver *removed_hdrv = data;
struct hid_driver *hdrv = to_hid_driver(drv); struct hid_driver *hdrv = to_hid_driver(drv);
if (hdrv->bus_removed_driver) if (hdrv->match) {
hdrv->bus_removed_driver(removed_hdrv); bus_for_each_dev(&hid_bus_type, NULL, hdrv,
__hid_bus_reprobe_drivers);
}
return 0; return 0;
} }
static int __bus_removed_driver(struct device_driver *drv, void *data)
{
return bus_rescan_devices(&hid_bus_type);
}
int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
const char *mod_name) const char *mod_name)
{ {
int ret;
hdrv->driver.name = hdrv->name; hdrv->driver.name = hdrv->name;
hdrv->driver.bus = &hid_bus_type; hdrv->driver.bus = &hid_bus_type;
hdrv->driver.owner = owner; hdrv->driver.owner = owner;
...@@ -2230,9 +2241,13 @@ int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, ...@@ -2230,9 +2241,13 @@ int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
INIT_LIST_HEAD(&hdrv->dyn_list); INIT_LIST_HEAD(&hdrv->dyn_list);
spin_lock_init(&hdrv->dyn_lock); spin_lock_init(&hdrv->dyn_lock);
bus_for_each_drv(&hid_bus_type, NULL, hdrv, __bus_add_driver); ret = driver_register(&hdrv->driver);
if (ret == 0)
bus_for_each_drv(&hid_bus_type, NULL, NULL,
__hid_bus_driver_added);
return driver_register(&hdrv->driver); return ret;
} }
EXPORT_SYMBOL_GPL(__hid_register_driver); EXPORT_SYMBOL_GPL(__hid_register_driver);
......
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
* HID driver for Corsair devices * HID driver for Corsair devices
* *
* Supported devices: * Supported devices:
* - Vengeance K70 Keyboard
* - K70 RAPIDFIRE Keyboard
* - Vengeance K90 Keyboard * - Vengeance K90 Keyboard
* - Scimitar PRO RGB Gaming Mouse * - Scimitar PRO RGB Gaming Mouse
* *
* Copyright (c) 2015 Clement Vuchener * Copyright (c) 2015 Clement Vuchener
* Copyright (c) 2017 Oscar Campos * Copyright (c) 2017 Oscar Campos
* Copyright (c) 2017 Aaron Bottegal
*/ */
/* /*
...@@ -673,7 +676,7 @@ static int corsair_input_mapping(struct hid_device *dev, ...@@ -673,7 +676,7 @@ static int corsair_input_mapping(struct hid_device *dev,
} }
/* /*
* The report descriptor of Corsair Scimitar RGB Pro gaming mouse is * The report descriptor of some of the Corsair gaming mice is
* non parseable as they define two consecutive Logical Minimum for * non parseable as they define two consecutive Logical Minimum for
* the Usage Page (Consumer) in rdescs bytes 75 and 77 being 77 0x16 * the Usage Page (Consumer) in rdescs bytes 75 and 77 being 77 0x16
* that should be obviousy 0x26 for Logical Magimum of 16 bits. This * that should be obviousy 0x26 for Logical Magimum of 16 bits. This
...@@ -681,7 +684,8 @@ static int corsair_input_mapping(struct hid_device *dev, ...@@ -681,7 +684,8 @@ static int corsair_input_mapping(struct hid_device *dev,
* Minimum being larger than Logical Maximum. * Minimum being larger than Logical Maximum.
* *
* This driver fixes the report descriptor for: * This driver fixes the report descriptor for:
* - USB ID b1c:1b3e, sold as Scimitar RGB Pro Gaming mouse * - USB ID 1b1c:1b34, sold as GLAIVE RGB Gaming mouse
* - USB ID 1b1c:1b3e, sold as Scimitar RGB Pro Gaming mouse
*/ */
static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
...@@ -691,13 +695,14 @@ static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, ...@@ -691,13 +695,14 @@ static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
/* /*
* Corsair Scimitar RGB Pro report descriptor is broken and * Corsair GLAIVE RGB and Scimitar RGB Pro report descriptor is
* defines two different Logical Minimum for the Consumer * broken and defines two different Logical Minimum for the
* Application. The byte 77 should be a 0x26 defining a 16 * Consumer Application. The byte 77 should be a 0x26 defining
* bits integer for the Logical Maximum but it is a 0x16 * a 16 bits integer for the Logical Maximum but it is a 0x16
* instead (Logical Minimum) * instead (Logical Minimum)
*/ */
switch (hdev->product) { switch (hdev->product) {
case USB_DEVICE_ID_CORSAIR_GLAIVE_RGB:
case USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB: case USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB:
if (*rsize >= 172 && rdesc[75] == 0x15 && rdesc[77] == 0x16 if (*rsize >= 172 && rdesc[75] == 0x15 && rdesc[77] == 0x16
&& rdesc[78] == 0xff && rdesc[79] == 0x0f) { && rdesc[78] == 0xff && rdesc[79] == 0x0f) {
...@@ -715,8 +720,15 @@ static const struct hid_device_id corsair_devices[] = { ...@@ -715,8 +720,15 @@ static const struct hid_device_id corsair_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90), { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90),
.driver_data = CORSAIR_USE_K90_MACRO | .driver_data = CORSAIR_USE_K90_MACRO |
CORSAIR_USE_K90_BACKLIGHT }, CORSAIR_USE_K90_BACKLIGHT },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
USB_DEVICE_ID_CORSAIR_GLAIVE_RGB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) }, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
/*
* Vengeance K70 and K70 RAPIDFIRE share product IDs.
*/
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
USB_DEVICE_ID_CORSAIR_K70R) },
{} {}
}; };
......
This diff is collapsed.
/* /*
* HID driver for ELECOM devices: * HID driver for ELECOM devices:
* - BM084 Bluetooth Mouse * - BM084 Bluetooth Mouse
* - EX-G Trackball (Wired and wireless) * - EX-G Trackballs (M-XT3DRBK, M-XT3URBK, M-XT4DRBK)
* - DEFT Trackball (Wired and wireless) * - DEFT Trackballs (M-DT1DRBK, M-DT1URBK, M-DT2DRBK, M-DT2URBK)
* - HUGE Trackball (Wired and wireless) * - HUGE Trackballs (M-HT1DRBK, M-HT1URBK)
* *
* Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com> * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
* Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com> * Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
...@@ -65,14 +65,15 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, ...@@ -65,14 +65,15 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[47] = 0x00; rdesc[47] = 0x00;
} }
break; break;
case USB_DEVICE_ID_ELECOM_EX_G_WIRED: case USB_DEVICE_ID_ELECOM_M_XT3URBK:
case USB_DEVICE_ID_ELECOM_EX_G_WIRELESS: case USB_DEVICE_ID_ELECOM_M_XT3DRBK:
case USB_DEVICE_ID_ELECOM_M_XT4DRBK:
mouse_button_fixup(hdev, rdesc, *rsize, 6); mouse_button_fixup(hdev, rdesc, *rsize, 6);
break; break;
case USB_DEVICE_ID_ELECOM_DEFT_WIRED: case USB_DEVICE_ID_ELECOM_M_DT1URBK:
case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS: case USB_DEVICE_ID_ELECOM_M_DT1DRBK:
case USB_DEVICE_ID_ELECOM_HUGE_WIRED: case USB_DEVICE_ID_ELECOM_M_HT1URBK:
case USB_DEVICE_ID_ELECOM_HUGE_WIRELESS: case USB_DEVICE_ID_ELECOM_M_HT1DRBK:
mouse_button_fixup(hdev, rdesc, *rsize, 8); mouse_button_fixup(hdev, rdesc, *rsize, 8);
break; break;
} }
...@@ -81,12 +82,13 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, ...@@ -81,12 +82,13 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static const struct hid_device_id elecom_devices[] = { static const struct hid_device_id elecom_devices[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_EX_G_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_EX_G_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK) },
{ } { }
}; };
MODULE_DEVICE_TABLE(hid, elecom_devices); MODULE_DEVICE_TABLE(hid, elecom_devices);
......
...@@ -26,37 +26,6 @@ ...@@ -26,37 +26,6 @@
static struct hid_driver hid_generic; static struct hid_driver hid_generic;
static int __unmap_hid_generic(struct device *dev, void *data)
{
struct hid_driver *hdrv = data;
struct hid_device *hdev = to_hid_device(dev);
/* only unbind matching devices already bound to hid-generic */
if (hdev->driver != &hid_generic ||
hid_match_device(hdev, hdrv) == NULL)
return 0;
if (dev->parent) /* Needed for USB */
device_lock(dev->parent);
device_release_driver(dev);
if (dev->parent)
device_unlock(dev->parent);
return 0;
}
static void hid_generic_add_driver(struct hid_driver *hdrv)
{
bus_for_each_dev(&hid_bus_type, NULL, hdrv, __unmap_hid_generic);
}
static void hid_generic_removed_driver(struct hid_driver *hdrv)
{
int ret;
ret = driver_attach(&hid_generic.driver);
}
static int __check_hid_generic(struct device_driver *drv, void *data) static int __check_hid_generic(struct device_driver *drv, void *data)
{ {
struct hid_driver *hdrv = to_hid_driver(drv); struct hid_driver *hdrv = to_hid_driver(drv);
...@@ -97,8 +66,6 @@ static struct hid_driver hid_generic = { ...@@ -97,8 +66,6 @@ static struct hid_driver hid_generic = {
.name = "hid-generic", .name = "hid-generic",
.id_table = hid_table, .id_table = hid_table,
.match = hid_generic_match, .match = hid_generic_match,
.bus_add_driver = hid_generic_add_driver,
.bus_removed_driver = hid_generic_removed_driver,
}; };
module_hid_driver(hid_generic); module_hid_driver(hid_generic);
......
// SPDX-License-Identifier: GPL-2.0+
/*
* HID driver for Google Hammer device.
*
* Copyright (c) 2017 Google Inc.
* Author: Wei-Ning Huang <wnhuang@google.com>
*/
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*/
#include <linux/hid.h>
#include <linux/leds.h>
#include <linux/module.h>
#include "hid-ids.h"
#define MAX_BRIGHTNESS 100
/* HID usage for keyboard backlight (Alphanumeric display brightness) */
#define HID_AD_BRIGHTNESS 0x00140046
struct hammer_kbd_leds {
struct led_classdev cdev;
struct hid_device *hdev;
u8 buf[2] ____cacheline_aligned;
};
static int hammer_kbd_brightness_set_blocking(struct led_classdev *cdev,
enum led_brightness br)
{
struct hammer_kbd_leds *led = container_of(cdev,
struct hammer_kbd_leds,
cdev);
int ret;
led->buf[0] = 0;
led->buf[1] = br;
/*
* Request USB HID device to be in Full On mode, so that sending
* hardware output report and hardware raw request won't fail.
*/
ret = hid_hw_power(led->hdev, PM_HINT_FULLON);
if (ret < 0) {
hid_err(led->hdev, "failed: device not resumed %d\n", ret);
return ret;
}
ret = hid_hw_output_report(led->hdev, led->buf, sizeof(led->buf));
if (ret == -ENOSYS)
ret = hid_hw_raw_request(led->hdev, 0, led->buf,
sizeof(led->buf),
HID_OUTPUT_REPORT,
HID_REQ_SET_REPORT);
if (ret < 0)
hid_err(led->hdev, "failed to set keyboard backlight: %d\n",
ret);
/* Request USB HID device back to Normal Mode. */
hid_hw_power(led->hdev, PM_HINT_NORMAL);
return ret;
}
static int hammer_register_leds(struct hid_device *hdev)
{
struct hammer_kbd_leds *kbd_backlight;
kbd_backlight = devm_kzalloc(&hdev->dev,
sizeof(*kbd_backlight),
GFP_KERNEL);
if (!kbd_backlight)
return -ENOMEM;
kbd_backlight->hdev = hdev;
kbd_backlight->cdev.name = "hammer::kbd_backlight";
kbd_backlight->cdev.max_brightness = MAX_BRIGHTNESS;
kbd_backlight->cdev.brightness_set_blocking =
hammer_kbd_brightness_set_blocking;
kbd_backlight->cdev.flags = LED_HW_PLUGGABLE;
/* Set backlight to 0% initially. */
hammer_kbd_brightness_set_blocking(&kbd_backlight->cdev, 0);
return devm_led_classdev_register(&hdev->dev, &kbd_backlight->cdev);
}
static int hammer_input_configured(struct hid_device *hdev,
struct hid_input *hi)
{
struct list_head *report_list =
&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report;
if (list_empty(report_list))
return 0;
report = list_first_entry(report_list, struct hid_report, list);
if (report->maxfield == 1 &&
report->field[0]->application == HID_GD_KEYBOARD &&
report->field[0]->maxusage == 1 &&
report->field[0]->usage[0].hid == HID_AD_BRIGHTNESS) {
int err = hammer_register_leds(hdev);
if (err)
hid_warn(hdev,
"Failed to register keyboard backlight: %d\n",
err);
}
return 0;
}
static const struct hid_device_id hammer_devices[] = {
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) },
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) },
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) },
{ }
};
MODULE_DEVICE_TABLE(hid, hammer_devices);
static struct hid_driver hammer_driver = {
.name = "hammer",
.id_table = hammer_devices,
.input_configured = hammer_input_configured,
};
module_hid_driver(hammer_driver);
MODULE_LICENSE("GPL");
...@@ -291,6 +291,7 @@ ...@@ -291,6 +291,7 @@
#define USB_DEVICE_ID_CORSAIR_K70RGB 0x1b13 #define USB_DEVICE_ID_CORSAIR_K70RGB 0x1b13
#define USB_DEVICE_ID_CORSAIR_STRAFE 0x1b15 #define USB_DEVICE_ID_CORSAIR_STRAFE 0x1b15
#define USB_DEVICE_ID_CORSAIR_K65RGB 0x1b17 #define USB_DEVICE_ID_CORSAIR_K65RGB 0x1b17
#define USB_DEVICE_ID_CORSAIR_GLAIVE_RGB 0x1b34
#define USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE 0x1b38 #define USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE 0x1b38
#define USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE 0x1b39 #define USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE 0x1b39
#define USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB 0x1b3e #define USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB 0x1b3e
...@@ -368,15 +369,17 @@ ...@@ -368,15 +369,17 @@
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001
#define USB_VENDOR_ID_ELAN 0x04f3 #define USB_VENDOR_ID_ELAN 0x04f3
#define USB_DEVICE_ID_HP_X2_10_COVER 0x0755
#define USB_VENDOR_ID_ELECOM 0x056e #define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061 #define USB_DEVICE_ID_ELECOM_BM084 0x0061
#define USB_DEVICE_ID_ELECOM_EX_G_WIRED 0x00fb #define USB_DEVICE_ID_ELECOM_M_XT3URBK 0x00fb
#define USB_DEVICE_ID_ELECOM_EX_G_WIRELESS 0x00fc #define USB_DEVICE_ID_ELECOM_M_XT3DRBK 0x00fc
#define USB_DEVICE_ID_ELECOM_DEFT_WIRED 0x00fe #define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd
#define USB_DEVICE_ID_ELECOM_DEFT_WIRELESS 0x00ff #define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe
#define USB_DEVICE_ID_ELECOM_HUGE_WIRED 0x010c #define USB_DEVICE_ID_ELECOM_M_DT1DRBK 0x00ff
#define USB_DEVICE_ID_ELECOM_HUGE_WIRELESS 0x010d #define USB_DEVICE_ID_ELECOM_M_HT1URBK 0x010c
#define USB_DEVICE_ID_ELECOM_M_HT1DRBK 0x010d
#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34
#define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004 #define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004
...@@ -445,7 +448,10 @@ ...@@ -445,7 +448,10 @@
#define USB_DEVICE_ID_GOODTOUCH_000f 0x000f #define USB_DEVICE_ID_GOODTOUCH_000f 0x000f
#define USB_VENDOR_ID_GOOGLE 0x18d1 #define USB_VENDOR_ID_GOOGLE 0x18d1
#define USB_DEVICE_ID_GOOGLE_HAMMER 0x5022
#define USB_DEVICE_ID_GOOGLE_TOUCH_ROSE 0x5028 #define USB_DEVICE_ID_GOOGLE_TOUCH_ROSE 0x5028
#define USB_DEVICE_ID_GOOGLE_STAFF 0x502b
#define USB_DEVICE_ID_GOOGLE_WAND 0x502d
#define USB_VENDOR_ID_GOTOP 0x08f2 #define USB_VENDOR_ID_GOTOP 0x08f2
#define USB_DEVICE_ID_SUPER_Q2 0x007f #define USB_DEVICE_ID_SUPER_Q2 0x007f
...@@ -961,6 +967,9 @@ ...@@ -961,6 +967,9 @@
#define USB_VENDOR_ID_SMK 0x0609 #define USB_VENDOR_ID_SMK 0x0609
#define USB_DEVICE_ID_SMK_PS3_BDREMOTE 0x0306 #define USB_DEVICE_ID_SMK_PS3_BDREMOTE 0x0306
#define USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE 0x0368
#define USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE 0x0369
#define USB_VENDOR_ID_SONY 0x054c #define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
......
...@@ -1368,7 +1368,8 @@ static void hidinput_led_worker(struct work_struct *work) ...@@ -1368,7 +1368,8 @@ static void hidinput_led_worker(struct work_struct *work)
led_work); led_work);
struct hid_field *field; struct hid_field *field;
struct hid_report *report; struct hid_report *report;
int len, ret; int ret;
u32 len;
__u8 *buf; __u8 *buf;
field = hidinput_get_led_field(hid); field = hidinput_get_led_field(hid);
...@@ -1656,16 +1657,16 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) ...@@ -1656,16 +1657,16 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
} }
list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
if ((hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) && if (drv->input_configured &&
!hidinput_has_been_populated(hidinput)) { drv->input_configured(hid, hidinput))
goto out_unwind;
if (!hidinput_has_been_populated(hidinput)) {
/* no need to register an input device not populated */ /* no need to register an input device not populated */
hidinput_cleanup_hidinput(hid, hidinput); hidinput_cleanup_hidinput(hid, hidinput);
continue; continue;
} }
if (drv->input_configured &&
drv->input_configured(hid, hidinput))
goto out_unwind;
if (input_register_device(hidinput->input)) if (input_register_device(hidinput->input))
goto out_unwind; goto out_unwind;
hidinput->registered = true; hidinput->registered = true;
......
...@@ -74,6 +74,7 @@ MODULE_LICENSE("GPL"); ...@@ -74,6 +74,7 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_TOUCH_SIZE_SCALING BIT(15) #define MT_QUIRK_TOUCH_SIZE_SCALING BIT(15)
#define MT_QUIRK_STICKY_FINGERS BIT(16) #define MT_QUIRK_STICKY_FINGERS BIT(16)
#define MT_QUIRK_ASUS_CUSTOM_UP BIT(17) #define MT_QUIRK_ASUS_CUSTOM_UP BIT(17)
#define MT_QUIRK_WIN8_PTP_BUTTONS BIT(18)
#define MT_INPUTMODE_TOUCHSCREEN 0x02 #define MT_INPUTMODE_TOUCHSCREEN 0x02
#define MT_INPUTMODE_TOUCHPAD 0x03 #define MT_INPUTMODE_TOUCHPAD 0x03
...@@ -126,7 +127,6 @@ struct mt_device { ...@@ -126,7 +127,6 @@ struct mt_device {
int left_button_state; /* left button state */ int left_button_state; /* left button state */
unsigned last_slot_field; /* the last field of a slot */ unsigned last_slot_field; /* the last field of a slot */
unsigned mt_report_id; /* the report ID of the multitouch device */ unsigned mt_report_id; /* the report ID of the multitouch device */
unsigned long initial_quirks; /* initial quirks state */
__s16 inputmode; /* InputMode HID feature, -1 if non-existent */ __s16 inputmode; /* InputMode HID feature, -1 if non-existent */
__s16 inputmode_index; /* InputMode HID feature index in the report */ __s16 inputmode_index; /* InputMode HID feature index in the report */
__s16 maxcontact_report_id; /* Maximum Contact Number HID feature, __s16 maxcontact_report_id; /* Maximum Contact Number HID feature,
...@@ -183,6 +183,7 @@ static void mt_post_parse(struct mt_device *td); ...@@ -183,6 +183,7 @@ static void mt_post_parse(struct mt_device *td);
#define MT_CLS_ASUS 0x010b #define MT_CLS_ASUS 0x010b
#define MT_CLS_VTL 0x0110 #define MT_CLS_VTL 0x0110
#define MT_CLS_GOOGLE 0x0111 #define MT_CLS_GOOGLE 0x0111
#define MT_CLS_RAZER_BLADE_STEALTH 0x0112
#define MT_DEFAULT_MAXCONTACT 10 #define MT_DEFAULT_MAXCONTACT 10
#define MT_MAX_MAXCONTACT 250 #define MT_MAX_MAXCONTACT 250
...@@ -241,7 +242,8 @@ static struct mt_class mt_classes[] = { ...@@ -241,7 +242,8 @@ static struct mt_class mt_classes[] = {
MT_QUIRK_IGNORE_DUPLICATES | MT_QUIRK_IGNORE_DUPLICATES |
MT_QUIRK_HOVERING | MT_QUIRK_HOVERING |
MT_QUIRK_CONTACT_CNT_ACCURATE | MT_QUIRK_CONTACT_CNT_ACCURATE |
MT_QUIRK_STICKY_FINGERS }, MT_QUIRK_STICKY_FINGERS |
MT_QUIRK_WIN8_PTP_BUTTONS },
{ .name = MT_CLS_EXPORT_ALL_INPUTS, { .name = MT_CLS_EXPORT_ALL_INPUTS,
.quirks = MT_QUIRK_ALWAYS_VALID | .quirks = MT_QUIRK_ALWAYS_VALID |
MT_QUIRK_CONTACT_CNT_ACCURATE, MT_QUIRK_CONTACT_CNT_ACCURATE,
...@@ -250,7 +252,8 @@ static struct mt_class mt_classes[] = { ...@@ -250,7 +252,8 @@ static struct mt_class mt_classes[] = {
.quirks = MT_QUIRK_ALWAYS_VALID | .quirks = MT_QUIRK_ALWAYS_VALID |
MT_QUIRK_IGNORE_DUPLICATES | MT_QUIRK_IGNORE_DUPLICATES |
MT_QUIRK_HOVERING | MT_QUIRK_HOVERING |
MT_QUIRK_CONTACT_CNT_ACCURATE, MT_QUIRK_CONTACT_CNT_ACCURATE |
MT_QUIRK_WIN8_PTP_BUTTONS,
.export_all_inputs = true }, .export_all_inputs = true },
/* /*
...@@ -323,6 +326,13 @@ static struct mt_class mt_classes[] = { ...@@ -323,6 +326,13 @@ static struct mt_class mt_classes[] = {
MT_QUIRK_SLOT_IS_CONTACTID | MT_QUIRK_SLOT_IS_CONTACTID |
MT_QUIRK_HOVERING MT_QUIRK_HOVERING
}, },
{ .name = MT_CLS_RAZER_BLADE_STEALTH,
.quirks = MT_QUIRK_ALWAYS_VALID |
MT_QUIRK_IGNORE_DUPLICATES |
MT_QUIRK_HOVERING |
MT_QUIRK_CONTACT_CNT_ACCURATE |
MT_QUIRK_WIN8_PTP_BUTTONS,
},
{ } { }
}; };
...@@ -369,15 +379,15 @@ static const struct attribute_group mt_attribute_group = { ...@@ -369,15 +379,15 @@ static const struct attribute_group mt_attribute_group = {
static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
{ {
struct mt_device *td = hid_get_drvdata(hdev); int ret;
int ret, size = hid_report_len(report); u32 size = hid_report_len(report);
u8 *buf; u8 *buf;
/* /*
* Do not fetch the feature report if the device has been explicitly * Do not fetch the feature report if the device has been explicitly
* marked as non-capable. * marked as non-capable.
*/ */
if (td->initial_quirks & HID_QUIRK_NO_INIT_REPORTS) if (hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)
return; return;
buf = hid_alloc_report_buf(report, GFP_KERNEL); buf = hid_alloc_report_buf(report, GFP_KERNEL);
...@@ -659,8 +669,7 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, ...@@ -659,8 +669,7 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
* MS PTP spec says that external buttons left and right have * MS PTP spec says that external buttons left and right have
* usages 2 and 3. * usages 2 and 3.
*/ */
if ((cls->name == MT_CLS_WIN_8 || if ((cls->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
cls->name == MT_CLS_WIN_8_DUAL) &&
field->application == HID_DG_TOUCHPAD && field->application == HID_DG_TOUCHPAD &&
(usage->hid & HID_USAGE) > 1) (usage->hid & HID_USAGE) > 1)
code--; code--;
...@@ -722,7 +731,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) ...@@ -722,7 +731,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
} }
if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE)) if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE))
s->confidence_state = 1; s->confidence_state = true;
active = (s->touch_state || s->inrange_state) && active = (s->touch_state || s->inrange_state) &&
s->confidence_state; s->confidence_state;
...@@ -772,9 +781,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) ...@@ -772,9 +781,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
*/ */
static void mt_sync_frame(struct mt_device *td, struct input_dev *input) static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
{ {
__s32 cls = td->mtclass.name; if (td->mtclass.quirks & MT_QUIRK_WIN8_PTP_BUTTONS)
if (cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL)
input_event(input, EV_KEY, BTN_LEFT, td->left_button_state); input_event(input, EV_KEY, BTN_LEFT, td->left_button_state);
input_mt_sync_frame(input); input_mt_sync_frame(input);
...@@ -826,7 +833,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, ...@@ -826,7 +833,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
bool first_packet) bool first_packet)
{ {
struct mt_device *td = hid_get_drvdata(hid); struct mt_device *td = hid_get_drvdata(hid);
__s32 cls = td->mtclass.name;
__s32 quirks = td->mtclass.quirks; __s32 quirks = td->mtclass.quirks;
struct input_dev *input = field->hidinput->input; struct input_dev *input = field->hidinput->input;
...@@ -904,7 +910,7 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, ...@@ -904,7 +910,7 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
* non finger/touch events in the first_packet of * non finger/touch events in the first_packet of
* a (possible) multi-packet frame. * a (possible) multi-packet frame.
*/ */
if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) && if ((quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
!first_packet) !first_packet)
return; return;
...@@ -915,7 +921,7 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, ...@@ -915,7 +921,7 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
* BTN_LEFT if either is pressed, so we or all values * BTN_LEFT if either is pressed, so we or all values
* together and report the result in mt_sync_frame(). * together and report the result in mt_sync_frame().
*/ */
if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) && if ((quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
usage->type == EV_KEY && usage->code == BTN_LEFT) { usage->type == EV_KEY && usage->code == BTN_LEFT) {
td->left_button_state |= value; td->left_button_state |= value;
return; return;
...@@ -939,7 +945,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, ...@@ -939,7 +945,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
static void mt_touch_report(struct hid_device *hid, struct hid_report *report) static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
{ {
struct mt_device *td = hid_get_drvdata(hid); struct mt_device *td = hid_get_drvdata(hid);
__s32 cls = td->mtclass.name;
struct hid_field *field; struct hid_field *field;
bool first_packet; bool first_packet;
unsigned count; unsigned count;
...@@ -968,7 +973,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report) ...@@ -968,7 +973,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
* of a possible multi-packet frame be checking that the * of a possible multi-packet frame be checking that the
* timestamp has changed. * timestamp has changed.
*/ */
if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) && if ((td->mtclass.quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
td->num_received == 0 && td->prev_scantime != scantime) td->num_received == 0 && td->prev_scantime != scantime)
td->num_expected = value; td->num_expected = value;
/* A non 0 contact count always indicates a first packet */ /* A non 0 contact count always indicates a first packet */
...@@ -1183,7 +1188,7 @@ static void mt_set_input_mode(struct hid_device *hdev) ...@@ -1183,7 +1188,7 @@ static void mt_set_input_mode(struct hid_device *hdev)
struct hid_report_enum *re; struct hid_report_enum *re;
struct mt_class *cls = &td->mtclass; struct mt_class *cls = &td->mtclass;
char *buf; char *buf;
int report_len; u32 report_len;
if (td->inputmode < 0) if (td->inputmode < 0)
return; return;
...@@ -1447,11 +1452,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1447,11 +1452,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
td->serial_maybe = true; td->serial_maybe = true;
/*
* Store the initial quirk state
*/
td->initial_quirks = hdev->quirks;
/* This allows the driver to correctly support devices /* This allows the driver to correctly support devices
* that emit events over several HID messages. * that emit events over several HID messages.
*/ */
...@@ -1463,22 +1463,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1463,22 +1463,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
* device. * device.
*/ */
hdev->quirks |= HID_QUIRK_MULTI_INPUT; hdev->quirks |= HID_QUIRK_MULTI_INPUT;
hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
/*
* Some multitouch screens do not like to be polled for input
* reports. Fortunately, the Win8 spec says that all touches
* should be sent during each report, making the initialization
* of input reports unnecessary. For Win7 devices, well, let's hope
* they will still be happy (this is only be a problem if a touch
* was already there while probing the device).
*
* In addition some touchpads do not behave well if we read
* all feature reports from them. Instead we prevent
* initial report fetching and then selectively fetch each
* report we are interested in.
*/
hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
timer_setup(&td->release_timer, mt_expired_timeout, 0); timer_setup(&td->release_timer, mt_expired_timeout, 0);
...@@ -1537,7 +1521,6 @@ static void mt_remove(struct hid_device *hdev) ...@@ -1537,7 +1521,6 @@ static void mt_remove(struct hid_device *hdev)
sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
hid_hw_stop(hdev); hid_hw_stop(hdev);
hdev->quirks = td->initial_quirks;
} }
/* /*
...@@ -1793,6 +1776,11 @@ static const struct hid_device_id mt_devices[] = { ...@@ -1793,6 +1776,11 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE(USB_VENDOR_ID_QUANTA, MT_USB_DEVICE(USB_VENDOR_ID_QUANTA,
USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) }, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) },
/* Razer touchpads */
{ .driver_data = MT_CLS_RAZER_BLADE_STEALTH,
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
USB_VENDOR_ID_SYNAPTICS, 0x8323) },
/* Stantum panels */ /* Stantum panels */
{ .driver_data = MT_CLS_CONFIDENCE, { .driver_data = MT_CLS_CONFIDENCE,
MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
......
...@@ -591,8 +591,8 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, ...@@ -591,8 +591,8 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
switch (usage->hid) { switch (usage->hid) {
case 0xff000001: case 0xff000001:
/* Tag indicating the start of a multitouch group */ /* Tag indicating the start of a multitouch group */
nd->reading_mt = 1; nd->reading_mt = true;
nd->first_contact_touch = 0; nd->first_contact_touch = false;
break; break;
case HID_DG_TIPSWITCH: case HID_DG_TIPSWITCH:
nd->tipswitch = value; nd->tipswitch = value;
...@@ -663,7 +663,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, ...@@ -663,7 +663,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
* even if deactivation slack is turned off. * even if deactivation slack is turned off.
*/ */
nd->act_state = deactivate_slack - 1; nd->act_state = deactivate_slack - 1;
nd->confidence = 0; nd->confidence = false;
break; break;
} }
...@@ -679,7 +679,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, ...@@ -679,7 +679,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
*/ */
if (nd->w < nd->min_width || if (nd->w < nd->min_width ||
nd->h < nd->min_height) nd->h < nd->min_height)
nd->confidence = 0; nd->confidence = false;
} else } else
break; break;
...@@ -758,7 +758,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, ...@@ -758,7 +758,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
if (!nd->reading_mt) /* Just to be sure */ if (!nd->reading_mt) /* Just to be sure */
break; break;
nd->reading_mt = 0; nd->reading_mt = false;
/* /*
...@@ -910,7 +910,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -910,7 +910,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
return -ENOMEM; return -ENOMEM;
} }
nd->reading_mt = 0; nd->reading_mt = false;
nd->min_width = 0; nd->min_width = 0;
nd->min_height = 0; nd->min_height = 0;
nd->activate_slack = activate_slack; nd->activate_slack = activate_slack;
......
...@@ -62,6 +62,7 @@ static const struct hid_device_id hid_quirks[] = { ...@@ -62,6 +62,7 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET },
...@@ -317,6 +318,7 @@ static const struct hid_device_id hid_have_special_driver[] = { ...@@ -317,6 +318,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
#endif #endif
#if IS_ENABLED(CONFIG_HID_CORSAIR) #if IS_ENABLED(CONFIG_HID_CORSAIR)
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_GLAIVE_RGB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
#endif #endif
#if IS_ENABLED(CONFIG_HID_CP2112) #if IS_ENABLED(CONFIG_HID_CP2112)
...@@ -333,14 +335,18 @@ static const struct hid_device_id hid_have_special_driver[] = { ...@@ -333,14 +335,18 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
#endif #endif
#if IS_ENABLED(CONFIG_HID_ELAN)
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2_10_COVER) },
#endif
#if IS_ENABLED(CONFIG_HID_ELECOM) #if IS_ENABLED(CONFIG_HID_ELECOM)
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_EX_G_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_EX_G_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK) },
#endif #endif
#if IS_ENABLED(CONFIG_HID_ELO) #if IS_ENABLED(CONFIG_HID_ELO)
{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
...@@ -608,6 +614,8 @@ static const struct hid_device_id hid_have_special_driver[] = { ...@@ -608,6 +614,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
#if IS_ENABLED(CONFIG_HID_SONY) #if IS_ENABLED(CONFIG_HID_SONY)
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) },
......
...@@ -89,8 +89,8 @@ struct rmi_data { ...@@ -89,8 +89,8 @@ struct rmi_data {
u8 *writeReport; u8 *writeReport;
u8 *readReport; u8 *readReport;
int input_report_size; u32 input_report_size;
int output_report_size; u32 output_report_size;
unsigned long flags; unsigned long flags;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* Copyright (c) 2006-2013 Jiri Kosina * Copyright (c) 2006-2013 Jiri Kosina
* Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
* Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com> * Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com>
* Copyright (c) 2018 Todd Kelner
*/ */
/* /*
...@@ -55,6 +56,8 @@ ...@@ -55,6 +56,8 @@
#define NAVIGATION_CONTROLLER_BT BIT(11) #define NAVIGATION_CONTROLLER_BT BIT(11)
#define SINO_LITE_CONTROLLER BIT(12) #define SINO_LITE_CONTROLLER BIT(12)
#define FUTUREMAX_DANCE_MAT BIT(13) #define FUTUREMAX_DANCE_MAT BIT(13)
#define NSG_MR5U_REMOTE_BT BIT(14)
#define NSG_MR7U_REMOTE_BT BIT(15)
#define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
#define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
...@@ -72,8 +75,11 @@ ...@@ -72,8 +75,11 @@
MOTION_CONTROLLER) MOTION_CONTROLLER)
#define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\ #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\
MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT) MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT)
#define NSG_MRXU_REMOTE (NSG_MR5U_REMOTE_BT | NSG_MR7U_REMOTE_BT)
#define MAX_LEDS 4 #define MAX_LEDS 4
#define NSG_MRXU_MAX_X 1667
#define NSG_MRXU_MAX_Y 1868
/* PS/3 Motion controller */ /* PS/3 Motion controller */
...@@ -1098,6 +1104,80 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) ...@@ -1098,6 +1104,80 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
} }
} }
static void nsg_mrxu_parse_report(struct sony_sc *sc, u8 *rd, int size)
{
int n, offset, relx, rely;
u8 active;
/*
* The NSG-MRxU multi-touch trackpad data starts at offset 1 and
* the touch-related data starts at offset 2.
* For the first byte, bit 0 is set when touchpad button is pressed.
* Bit 2 is set when a touch is active and the drag (Fn) key is pressed.
* This drag key is mapped to BTN_LEFT. It is operational only when a
* touch point is active.
* Bit 4 is set when only the first touch point is active.
* Bit 6 is set when only the second touch point is active.
* Bits 5 and 7 are set when both touch points are active.
* The next 3 bytes are two 12 bit X/Y coordinates for the first touch.
* The following byte, offset 5, has the touch width and length.
* Bits 0-4=X (width), bits 5-7=Y (length).
* A signed relative X coordinate is at offset 6.
* The bytes at offset 7-9 are the second touch X/Y coordinates.
* Offset 10 has the second touch width and length.
* Offset 11 has the relative Y coordinate.
*/
offset = 1;
input_report_key(sc->touchpad, BTN_LEFT, rd[offset] & 0x0F);
active = (rd[offset] >> 4);
relx = (s8) rd[offset+5];
rely = ((s8) rd[offset+10]) * -1;
offset++;
for (n = 0; n < 2; n++) {
u16 x, y;
u8 contactx, contacty;
x = rd[offset] | ((rd[offset+1] & 0x0F) << 8);
y = ((rd[offset+1] & 0xF0) >> 4) | (rd[offset+2] << 4);
input_mt_slot(sc->touchpad, n);
input_mt_report_slot_state(sc->touchpad, MT_TOOL_FINGER, active & 0x03);
if (active & 0x03) {
contactx = rd[offset+3] & 0x0F;
contacty = rd[offset+3] >> 4;
input_report_abs(sc->touchpad, ABS_MT_TOUCH_MAJOR,
max(contactx, contacty));
input_report_abs(sc->touchpad, ABS_MT_TOUCH_MINOR,
min(contactx, contacty));
input_report_abs(sc->touchpad, ABS_MT_ORIENTATION,
(bool) (contactx > contacty));
input_report_abs(sc->touchpad, ABS_MT_POSITION_X, x);
input_report_abs(sc->touchpad, ABS_MT_POSITION_Y,
NSG_MRXU_MAX_Y - y);
/*
* The relative coordinates belong to the first touch
* point, when present, or to the second touch point
* when the first is not active.
*/
if ((n == 0) || ((n == 1) && (active & 0x01))) {
input_report_rel(sc->touchpad, REL_X, relx);
input_report_rel(sc->touchpad, REL_Y, rely);
}
}
offset += 5;
active >>= 2;
}
input_mt_sync_frame(sc->touchpad);
input_sync(sc->touchpad);
}
static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
u8 *rd, int size) u8 *rd, int size)
{ {
...@@ -1206,6 +1286,10 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, ...@@ -1206,6 +1286,10 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
} }
dualshock4_parse_report(sc, rd, size); dualshock4_parse_report(sc, rd, size);
} else if ((sc->quirks & NSG_MRXU_REMOTE) && rd[0] == 0x02) {
nsg_mrxu_parse_report(sc, rd, size);
return 1;
} }
if (sc->defer_initialization) { if (sc->defer_initialization) {
...@@ -1263,7 +1347,7 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, ...@@ -1263,7 +1347,7 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
} }
static int sony_register_touchpad(struct sony_sc *sc, int touch_count, static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
int w, int h) int w, int h, int touch_major, int touch_minor, int orientation)
{ {
size_t name_sz; size_t name_sz;
char *name; char *name;
...@@ -1294,10 +1378,6 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count, ...@@ -1294,10 +1378,6 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name); snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name);
sc->touchpad->name = name; sc->touchpad->name = name;
ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER);
if (ret < 0)
goto err;
/* We map the button underneath the touchpad to BTN_LEFT. */ /* We map the button underneath the touchpad to BTN_LEFT. */
__set_bit(EV_KEY, sc->touchpad->evbit); __set_bit(EV_KEY, sc->touchpad->evbit);
__set_bit(BTN_LEFT, sc->touchpad->keybit); __set_bit(BTN_LEFT, sc->touchpad->keybit);
...@@ -1306,6 +1386,25 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count, ...@@ -1306,6 +1386,25 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0); input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0);
input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0); input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0);
if (touch_major > 0) {
input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR,
0, touch_major, 0, 0);
if (touch_minor > 0)
input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR,
0, touch_minor, 0, 0);
if (orientation > 0)
input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION,
0, orientation, 0, 0);
}
if (sc->quirks & NSG_MRXU_REMOTE) {
__set_bit(EV_REL, sc->touchpad->evbit);
}
ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER);
if (ret < 0)
goto err;
ret = input_register_device(sc->touchpad); ret = input_register_device(sc->touchpad);
if (ret < 0) if (ret < 0)
goto err; goto err;
...@@ -2690,7 +2789,7 @@ static int sony_input_configured(struct hid_device *hdev, ...@@ -2690,7 +2789,7 @@ static int sony_input_configured(struct hid_device *hdev,
* The Dualshock 4 touchpad supports 2 touches and has a * The Dualshock 4 touchpad supports 2 touches and has a
* resolution of 1920x942 (44.86 dots/mm). * resolution of 1920x942 (44.86 dots/mm).
*/ */
ret = sony_register_touchpad(sc, 2, 1920, 942); ret = sony_register_touchpad(sc, 2, 1920, 942, 0, 0, 0);
if (ret) { if (ret) {
hid_err(sc->hdev, hid_err(sc->hdev,
"Unable to initialize multi-touch slots: %d\n", "Unable to initialize multi-touch slots: %d\n",
...@@ -2721,6 +2820,20 @@ static int sony_input_configured(struct hid_device *hdev, ...@@ -2721,6 +2820,20 @@ static int sony_input_configured(struct hid_device *hdev,
} }
sony_init_output_report(sc, dualshock4_send_output_report); sony_init_output_report(sc, dualshock4_send_output_report);
} else if (sc->quirks & NSG_MRXU_REMOTE) {
/*
* The NSG-MRxU touchpad supports 2 touches and has a
* resolution of 1667x1868
*/
ret = sony_register_touchpad(sc, 2,
NSG_MRXU_MAX_X, NSG_MRXU_MAX_Y, 15, 15, 1);
if (ret) {
hid_err(sc->hdev,
"Unable to initialize multi-touch slots: %d\n",
ret);
goto err_stop;
}
} else if (sc->quirks & MOTION_CONTROLLER) { } else if (sc->quirks & MOTION_CONTROLLER) {
sony_init_output_report(sc, motion_send_output_report); sony_init_output_report(sc, motion_send_output_report);
} else { } else {
...@@ -2969,6 +3082,12 @@ static const struct hid_device_id sony_devices[] = { ...@@ -2969,6 +3082,12 @@ static const struct hid_device_id sony_devices[] = {
/* Nyko Core Controller for PS3 */ /* Nyko Core Controller for PS3 */
{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER), { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER),
.driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER }, .driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER },
/* SMK-Link NSG-MR5U Remote Control */
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE),
.driver_data = NSG_MR5U_REMOTE_BT },
/* SMK-Link NSG-MR7U Remote Control */
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE),
.driver_data = NSG_MR7U_REMOTE_BT },
{ } { }
}; };
MODULE_DEVICE_TABLE(hid, sony_devices); MODULE_DEVICE_TABLE(hid, sony_devices);
......
...@@ -946,7 +946,6 @@ static int uclogic_probe(struct hid_device *hdev, ...@@ -946,7 +946,6 @@ static int uclogic_probe(struct hid_device *hdev,
* than the pen, so use QUIRK_MULTI_INPUT for all tablets. * than the pen, so use QUIRK_MULTI_INPUT for all tablets.
*/ */
hdev->quirks |= HID_QUIRK_MULTI_INPUT; hdev->quirks |= HID_QUIRK_MULTI_INPUT;
hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
/* Allocate and assign driver data */ /* Allocate and assign driver data */
drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
......
...@@ -144,10 +144,10 @@ struct i2c_hid { ...@@ -144,10 +144,10 @@ struct i2c_hid {
* register of the HID * register of the HID
* descriptor. */ * descriptor. */
unsigned int bufsize; /* i2c buffer size */ unsigned int bufsize; /* i2c buffer size */
char *inbuf; /* Input buffer */ u8 *inbuf; /* Input buffer */
char *rawbuf; /* Raw Input buffer */ u8 *rawbuf; /* Raw Input buffer */
char *cmdbuf; /* Command buffer */ u8 *cmdbuf; /* Command buffer */
char *argsbuf; /* Command arguments buffer */ u8 *argsbuf; /* Command arguments buffer */
unsigned long flags; /* device flags */ unsigned long flags; /* device flags */
unsigned long quirks; /* Various quirks */ unsigned long quirks; /* Various quirks */
...@@ -455,7 +455,8 @@ static int i2c_hid_hwreset(struct i2c_client *client) ...@@ -455,7 +455,8 @@ static int i2c_hid_hwreset(struct i2c_client *client)
static void i2c_hid_get_input(struct i2c_hid *ihid) static void i2c_hid_get_input(struct i2c_hid *ihid)
{ {
int ret, ret_size; int ret;
u32 ret_size;
int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
if (size > ihid->bufsize) if (size > ihid->bufsize)
...@@ -480,7 +481,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) ...@@ -480,7 +481,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
return; return;
} }
if (ret_size > size) { if ((ret_size > size) || (ret_size <= 2)) {
dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
__func__, size, ret_size); __func__, size, ret_size);
return; return;
...@@ -891,10 +892,10 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client, ...@@ -891,10 +892,10 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
static void i2c_hid_acpi_fix_up_power(struct device *dev) static void i2c_hid_acpi_fix_up_power(struct device *dev)
{ {
acpi_handle handle = ACPI_HANDLE(dev);
struct acpi_device *adev; struct acpi_device *adev;
if (handle && acpi_bus_get_device(handle, &adev) == 0) adev = ACPI_COMPANION(dev);
if (adev)
acpi_device_fix_up_power(adev); acpi_device_fix_up_power(adev);
} }
......
...@@ -496,12 +496,12 @@ static int uhid_dev_create2(struct uhid_device *uhid, ...@@ -496,12 +496,12 @@ static int uhid_dev_create2(struct uhid_device *uhid,
goto err_free; goto err_free;
} }
len = min(sizeof(hid->name), sizeof(ev->u.create2.name)) - 1; len = min(sizeof(hid->name), sizeof(ev->u.create2.name));
strncpy(hid->name, ev->u.create2.name, len); strlcpy(hid->name, ev->u.create2.name, len);
len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys)) - 1; len = min(sizeof(hid->phys), sizeof(ev->u.create2.phys));
strncpy(hid->phys, ev->u.create2.phys, len); strlcpy(hid->phys, ev->u.create2.phys, len);
len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq)) - 1; len = min(sizeof(hid->uniq), sizeof(ev->u.create2.uniq));
strncpy(hid->uniq, ev->u.create2.uniq, len); strlcpy(hid->uniq, ev->u.create2.uniq, len);
hid->ll_driver = &uhid_hid_driver; hid->ll_driver = &uhid_hid_driver;
hid->bus = ev->u.create2.bus; hid->bus = ev->u.create2.bus;
......
...@@ -56,6 +56,10 @@ static unsigned int hid_jspoll_interval; ...@@ -56,6 +56,10 @@ static unsigned int hid_jspoll_interval;
module_param_named(jspoll, hid_jspoll_interval, uint, 0644); module_param_named(jspoll, hid_jspoll_interval, uint, 0644);
MODULE_PARM_DESC(jspoll, "Polling interval of joysticks"); MODULE_PARM_DESC(jspoll, "Polling interval of joysticks");
static unsigned int hid_kbpoll_interval;
module_param_named(kbpoll, hid_kbpoll_interval, uint, 0644);
MODULE_PARM_DESC(kbpoll, "Polling interval of keyboards");
static unsigned int ignoreled; static unsigned int ignoreled;
module_param_named(ignoreled, ignoreled, uint, 0644); module_param_named(ignoreled, ignoreled, uint, 0644);
MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds"); MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
...@@ -1094,7 +1098,9 @@ static int usbhid_start(struct hid_device *hid) ...@@ -1094,7 +1098,9 @@ static int usbhid_start(struct hid_device *hid)
hid->name, endpoint->bInterval, interval); hid->name, endpoint->bInterval, interval);
} }
/* Change the polling interval of mice and joysticks. */ /* Change the polling interval of mice, joysticks
* and keyboards.
*/
switch (hid->collection->usage) { switch (hid->collection->usage) {
case HID_GD_MOUSE: case HID_GD_MOUSE:
if (hid_mousepoll_interval > 0) if (hid_mousepoll_interval > 0)
...@@ -1104,6 +1110,10 @@ static int usbhid_start(struct hid_device *hid) ...@@ -1104,6 +1110,10 @@ static int usbhid_start(struct hid_device *hid)
if (hid_jspoll_interval > 0) if (hid_jspoll_interval > 0)
interval = hid_jspoll_interval; interval = hid_jspoll_interval;
break; break;
case HID_GD_KEYBOARD:
if (hid_kbpoll_interval > 0)
interval = hid_kbpoll_interval;
break;
} }
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -219,7 +219,7 @@ static void wacom_feature_mapping(struct hid_device *hdev, ...@@ -219,7 +219,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
u8 *data; u8 *data;
int ret; int ret;
int n; u32 n;
switch (equivalent_usage) { switch (equivalent_usage) {
case HID_DG_CONTACTMAX: case HID_DG_CONTACTMAX:
...@@ -519,7 +519,7 @@ static int wacom_set_device_mode(struct hid_device *hdev, ...@@ -519,7 +519,7 @@ static int wacom_set_device_mode(struct hid_device *hdev,
u8 *rep_data; u8 *rep_data;
struct hid_report *r; struct hid_report *r;
struct hid_report_enum *re; struct hid_report_enum *re;
int length; u32 length;
int error = -ENOMEM, limit = 0; int error = -ENOMEM, limit = 0;
if (wacom_wac->mode_report < 0) if (wacom_wac->mode_report < 0)
......
This diff is collapsed.
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
#define WACOM_HID_WD_TOUCHSTRIP2 (WACOM_HID_UP_WACOMDIGITIZER | 0x0137) #define WACOM_HID_WD_TOUCHSTRIP2 (WACOM_HID_UP_WACOMDIGITIZER | 0x0137)
#define WACOM_HID_WD_TOUCHRING (WACOM_HID_UP_WACOMDIGITIZER | 0x0138) #define WACOM_HID_WD_TOUCHRING (WACOM_HID_UP_WACOMDIGITIZER | 0x0138)
#define WACOM_HID_WD_TOUCHRINGSTATUS (WACOM_HID_UP_WACOMDIGITIZER | 0x0139) #define WACOM_HID_WD_TOUCHRINGSTATUS (WACOM_HID_UP_WACOMDIGITIZER | 0x0139)
#define WACOM_HID_WD_REPORT_VALID (WACOM_HID_UP_WACOMDIGITIZER | 0x01d0)
#define WACOM_HID_WD_ACCELEROMETER_X (WACOM_HID_UP_WACOMDIGITIZER | 0x0401) #define WACOM_HID_WD_ACCELEROMETER_X (WACOM_HID_UP_WACOMDIGITIZER | 0x0401)
#define WACOM_HID_WD_ACCELEROMETER_Y (WACOM_HID_UP_WACOMDIGITIZER | 0x0402) #define WACOM_HID_WD_ACCELEROMETER_Y (WACOM_HID_UP_WACOMDIGITIZER | 0x0402)
#define WACOM_HID_WD_ACCELEROMETER_Z (WACOM_HID_UP_WACOMDIGITIZER | 0x0403) #define WACOM_HID_WD_ACCELEROMETER_Z (WACOM_HID_UP_WACOMDIGITIZER | 0x0403)
...@@ -213,6 +214,7 @@ enum { ...@@ -213,6 +214,7 @@ enum {
INTUOSPM, INTUOSPM,
INTUOSPL, INTUOSPL,
INTUOSP2_BT, INTUOSP2_BT,
INTUOSHT3_BT,
WACOM_21UX2, WACOM_21UX2,
WACOM_22HD, WACOM_22HD,
DTK, DTK,
...@@ -352,7 +354,7 @@ struct wacom_wac { ...@@ -352,7 +354,7 @@ struct wacom_wac {
bool has_mute_touch_switch; bool has_mute_touch_switch;
bool has_mode_change; bool has_mode_change;
bool is_direct_mode; bool is_direct_mode;
bool is_invalid_bt_frame;
}; };
#endif #endif
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define __HID_H #define __HID_H
#include <linux/bitops.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/list.h> #include <linux/list.h>
...@@ -310,13 +311,13 @@ struct hid_item { ...@@ -310,13 +311,13 @@ struct hid_item {
* HID connect requests * HID connect requests
*/ */
#define HID_CONNECT_HIDINPUT 0x01 #define HID_CONNECT_HIDINPUT BIT(0)
#define HID_CONNECT_HIDINPUT_FORCE 0x02 #define HID_CONNECT_HIDINPUT_FORCE BIT(1)
#define HID_CONNECT_HIDRAW 0x04 #define HID_CONNECT_HIDRAW BIT(2)
#define HID_CONNECT_HIDDEV 0x08 #define HID_CONNECT_HIDDEV BIT(3)
#define HID_CONNECT_HIDDEV_FORCE 0x10 #define HID_CONNECT_HIDDEV_FORCE BIT(4)
#define HID_CONNECT_FF 0x20 #define HID_CONNECT_FF BIT(5)
#define HID_CONNECT_DRIVER 0x40 #define HID_CONNECT_DRIVER BIT(6)
#define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \
HID_CONNECT_HIDDEV|HID_CONNECT_FF) HID_CONNECT_HIDDEV|HID_CONNECT_FF)
...@@ -329,25 +330,25 @@ struct hid_item { ...@@ -329,25 +330,25 @@ struct hid_item {
*/ */
#define MAX_USBHID_BOOT_QUIRKS 4 #define MAX_USBHID_BOOT_QUIRKS 4
#define HID_QUIRK_INVERT 0x00000001 #define HID_QUIRK_INVERT BIT(0)
#define HID_QUIRK_NOTOUCH 0x00000002 #define HID_QUIRK_NOTOUCH BIT(1)
#define HID_QUIRK_IGNORE 0x00000004 #define HID_QUIRK_IGNORE BIT(2)
#define HID_QUIRK_NOGET 0x00000008 #define HID_QUIRK_NOGET BIT(3)
#define HID_QUIRK_HIDDEV_FORCE 0x00000010 #define HID_QUIRK_HIDDEV_FORCE BIT(4)
#define HID_QUIRK_BADPAD 0x00000020 #define HID_QUIRK_BADPAD BIT(5)
#define HID_QUIRK_MULTI_INPUT 0x00000040 #define HID_QUIRK_MULTI_INPUT BIT(6)
#define HID_QUIRK_HIDINPUT_FORCE 0x00000080 #define HID_QUIRK_HIDINPUT_FORCE BIT(7)
#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 /* BIT(8) reserved for backward compatibility, was HID_QUIRK_NO_EMPTY_INPUT */
/* 0x00000200 reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */ /* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
#define HID_QUIRK_ALWAYS_POLL 0x00000400 #define HID_QUIRK_ALWAYS_POLL BIT(10)
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 #define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16)
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000 #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17)
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000 #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
#define HID_QUIRK_HAVE_SPECIAL_DRIVER 0x00080000 #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19)
#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28)
#define HID_QUIRK_NO_INIT_REPORTS 0x20000000 #define HID_QUIRK_NO_INIT_REPORTS BIT(29)
#define HID_QUIRK_NO_IGNORE 0x40000000 #define HID_QUIRK_NO_IGNORE BIT(30)
#define HID_QUIRK_NO_INPUT_SYNC 0x80000000 #define HID_QUIRK_NO_INPUT_SYNC BIT(31)
/* /*
* HID device groups * HID device groups
...@@ -494,13 +495,13 @@ struct hid_output_fifo { ...@@ -494,13 +495,13 @@ struct hid_output_fifo {
char *raw_report; char *raw_report;
}; };
#define HID_CLAIMED_INPUT 1 #define HID_CLAIMED_INPUT BIT(0)
#define HID_CLAIMED_HIDDEV 2 #define HID_CLAIMED_HIDDEV BIT(1)
#define HID_CLAIMED_HIDRAW 4 #define HID_CLAIMED_HIDRAW BIT(2)
#define HID_CLAIMED_DRIVER 8 #define HID_CLAIMED_DRIVER BIT(3)
#define HID_STAT_ADDED 1 #define HID_STAT_ADDED BIT(0)
#define HID_STAT_PARSED 2 #define HID_STAT_PARSED BIT(1)
struct hid_input { struct hid_input {
struct list_head list; struct list_head list;
...@@ -686,8 +687,6 @@ struct hid_usage_id { ...@@ -686,8 +687,6 @@ struct hid_usage_id {
* @input_mapped: invoked on input registering after mapping an usage * @input_mapped: invoked on input registering after mapping an usage
* @input_configured: invoked just before the device is registered * @input_configured: invoked just before the device is registered
* @feature_mapping: invoked on feature registering * @feature_mapping: invoked on feature registering
* @bus_add_driver: invoked when a HID driver is about to be added
* @bus_removed_driver: invoked when a HID driver has been removed
* @suspend: invoked on suspend (NULL means nop) * @suspend: invoked on suspend (NULL means nop)
* @resume: invoked on resume if device was not reset (NULL means nop) * @resume: invoked on resume if device was not reset (NULL means nop)
* @reset_resume: invoked on resume if device was reset (NULL means nop) * @reset_resume: invoked on resume if device was reset (NULL means nop)
...@@ -742,8 +741,6 @@ struct hid_driver { ...@@ -742,8 +741,6 @@ struct hid_driver {
void (*feature_mapping)(struct hid_device *hdev, void (*feature_mapping)(struct hid_device *hdev,
struct hid_field *field, struct hid_field *field,
struct hid_usage *usage); struct hid_usage *usage);
void (*bus_add_driver)(struct hid_driver *driver);
void (*bus_removed_driver)(struct hid_driver *driver);
#ifdef CONFIG_PM #ifdef CONFIG_PM
int (*suspend)(struct hid_device *hdev, pm_message_t message); int (*suspend)(struct hid_device *hdev, pm_message_t message);
int (*resume)(struct hid_device *hdev); int (*resume)(struct hid_device *hdev);
...@@ -851,7 +848,7 @@ extern int hidinput_connect(struct hid_device *hid, unsigned int force); ...@@ -851,7 +848,7 @@ extern int hidinput_connect(struct hid_device *hid, unsigned int force);
extern void hidinput_disconnect(struct hid_device *); extern void hidinput_disconnect(struct hid_device *);
int hid_set_field(struct hid_field *, unsigned, __s32); int hid_set_field(struct hid_field *, unsigned, __s32);
int hid_input_report(struct hid_device *, int type, u8 *, int, int); int hid_input_report(struct hid_device *, int type, u8 *, u32, int);
int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
struct hid_field *hidinput_get_led_field(struct hid_device *hid); struct hid_field *hidinput_get_led_field(struct hid_device *hid);
unsigned int hidinput_count_leds(struct hid_device *hid); unsigned int hidinput_count_leds(struct hid_device *hid);
...@@ -1102,13 +1099,13 @@ static inline void hid_hw_wait(struct hid_device *hdev) ...@@ -1102,13 +1099,13 @@ static inline void hid_hw_wait(struct hid_device *hdev)
* *
* @report: the report we want to know the length * @report: the report we want to know the length
*/ */
static inline int hid_report_len(struct hid_report *report) static inline u32 hid_report_len(struct hid_report *report)
{ {
/* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
return ((report->size - 1) >> 3) + 1 + (report->id > 0); return ((report->size - 1) >> 3) + 1 + (report->id > 0);
} }
int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
int interrupt); int interrupt);
/* HID quirks API */ /* HID quirks API */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment