You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina: - remove hid_have_special_driver[] entry hard requirement for any newly supported VID/PID by a specific non-core hid driver, and general related cleanup of HID matching core, from Benjamin Tissoires - support for new Wacom devices and a few small fixups for already supported ones in Wacom driver, from Aaron Armstrong Skomra and Jason Gerecke - sysfs interface fix for roccat driver from Dan Carpenter - support for new Asus HW (T100TAF, T100HA, T200TA) from Hans de Goede - improved support for Jabra devices, from Niels Skou Olsen - other assorted small fixes and new device IDs * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (30 commits) HID: quirks: Fix keyboard + touchpad on Toshiba Click Mini not working HID: roccat: prevent an out of bounds read in kovaplus_profile_activated() HID: asus: Fix special function keys on T200TA HID: asus: Add touchpad max x/y and resolution info for the T200TA HID: wacom: Add support for One by Wacom (CTL-472 / CTL-672) HID: wacom: Fix reporting of touch toggle (WACOM_HID_WD_MUTE_DEVICE) events HID: intel-ish-hid: Enable Cannon Lake and Coffee Lake laptop/desktop HID: elecom: rewrite report fixup for EX-G and future mice HID: sony: Report DS4 version info through sysfs HID: sony: Print reversed MAC address via %pMR HID: wacom: EKR: ensure devres groups at higher indexes are released HID: rmi: Support the Fujitsu R726 Pad dock using hid-rmi HID: add quirk for another PIXART OEM mouse used by HP HID: quirks: make array hid_quirks static HID: hid-multitouch: support fine-grain orientation reporting HID: asus: Add product-id for the T100TAF and T100HA keyboard docks HID: elo: clear BTN_LEFT mapping HID: multitouch: Combine all left-button events in a frame HID: multitouch: Only look at non touch fields in first packet of a frame HID: multitouch: Properly deal with Win8 PTP reports with 0 touches ...
This commit is contained in:
@@ -31,7 +31,7 @@ device-specific compatible properties, which should be used in addition to the
|
||||
|
||||
- vdd-supply: phandle of the regulator that provides the supply voltage.
|
||||
- post-power-on-delay-ms: time required by the device after enabling its regulators
|
||||
before it is ready for communication. Must be used with 'vdd-supply'.
|
||||
or powering it on, before it is ready for communication.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -269,10 +269,11 @@ ABS_MT_ORIENTATION
|
||||
The orientation of the touching ellipse. The value should describe a signed
|
||||
quarter of a revolution clockwise around the touch center. The signed value
|
||||
range is arbitrary, but zero should be returned for an ellipse aligned with
|
||||
the Y axis of the surface, a negative value when the ellipse is turned to
|
||||
the left, and a positive value when the ellipse is turned to the
|
||||
right. When completely aligned with the X axis, the range max should be
|
||||
returned.
|
||||
the Y axis (north) of the surface, a negative value when the ellipse is
|
||||
turned to the left, and a positive value when the ellipse is turned to the
|
||||
right. When aligned with the X axis in the positive direction, the range
|
||||
max should be returned; when aligned with the X axis in the negative
|
||||
direction, the range -max should be returned.
|
||||
|
||||
Touch ellipsis are symmetrical by default. For devices capable of true 360
|
||||
degree orientation, the reported orientation must exceed the range max to
|
||||
|
||||
@@ -280,6 +280,7 @@ config HID_ELECOM
|
||||
---help---
|
||||
Support for ELECOM devices:
|
||||
- BM084 Bluetooth Mouse
|
||||
- EX-G Trackball (Wired and wireless)
|
||||
- DEFT Trackball (Wired and wireless)
|
||||
- HUGE Trackball (Wired and wireless)
|
||||
|
||||
@@ -396,6 +397,17 @@ config HID_ITE
|
||||
---help---
|
||||
Support for ITE devices not fully compliant with HID standard.
|
||||
|
||||
config HID_JABRA
|
||||
tristate "Jabra USB HID Driver"
|
||||
depends on HID
|
||||
---help---
|
||||
Support for Jabra USB HID devices.
|
||||
|
||||
Prevents mapping of vendor defined HID usages to input events. Without
|
||||
this driver HID reports from Jabra devices may incorrectly be seen as
|
||||
mouse button events.
|
||||
Say M here if you may ever plug in a Jabra USB device.
|
||||
|
||||
config HID_TWINHAN
|
||||
tristate "Twinhan IR remote control"
|
||||
depends on HID
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Makefile for the HID driver
|
||||
#
|
||||
hid-y := hid-core.o hid-input.o
|
||||
hid-y := hid-core.o hid-input.o hid-quirks.o
|
||||
hid-$(CONFIG_DEBUG_FS) += hid-debug.o
|
||||
|
||||
obj-$(CONFIG_HID) += hid.o
|
||||
@@ -52,6 +52,7 @@ obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
|
||||
obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
|
||||
obj-$(CONFIG_HID_ICADE) += hid-icade.o
|
||||
obj-$(CONFIG_HID_ITE) += hid-ite.o
|
||||
obj-$(CONFIG_HID_JABRA) += hid-jabra.o
|
||||
obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
|
||||
obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
|
||||
obj-$(CONFIG_HID_KYE) += hid-kye.o
|
||||
|
||||
+37
-4
@@ -26,6 +26,7 @@
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input/mt.h>
|
||||
@@ -119,6 +120,24 @@ static const struct asus_touchpad_info asus_t100ta_tp = {
|
||||
.max_contacts = 5,
|
||||
};
|
||||
|
||||
static const struct asus_touchpad_info asus_t100ha_tp = {
|
||||
.max_x = 2640,
|
||||
.max_y = 1320,
|
||||
.res_x = 30, /* units/mm */
|
||||
.res_y = 29, /* units/mm */
|
||||
.contact_size = 5,
|
||||
.max_contacts = 5,
|
||||
};
|
||||
|
||||
static const struct asus_touchpad_info asus_t200ta_tp = {
|
||||
.max_x = 3120,
|
||||
.max_y = 1716,
|
||||
.res_x = 30, /* units/mm */
|
||||
.res_y = 28, /* units/mm */
|
||||
.contact_size = 5,
|
||||
.max_contacts = 5,
|
||||
};
|
||||
|
||||
static const struct asus_touchpad_info asus_t100chi_tp = {
|
||||
.max_x = 2640,
|
||||
.max_y = 1320,
|
||||
@@ -606,7 +625,17 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
|
||||
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
|
||||
drvdata->quirks = QUIRK_SKIP_INPUT_MAPPING;
|
||||
drvdata->tp = &asus_t100ta_tp;
|
||||
/*
|
||||
* The T100HA uses the same USB-ids as the T100TAF and
|
||||
* the T200TA uses the same USB-ids as the T100TA, while
|
||||
* both have different max x/y values as the T100TA[F].
|
||||
*/
|
||||
if (dmi_match(DMI_PRODUCT_NAME, "T100HAN"))
|
||||
drvdata->tp = &asus_t100ha_tp;
|
||||
else if (dmi_match(DMI_PRODUCT_NAME, "T200TA"))
|
||||
drvdata->tp = &asus_t200ta_tp;
|
||||
else
|
||||
drvdata->tp = &asus_t100ta_tp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,9 +715,10 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
hid_info(hdev, "Fixing up Asus notebook report descriptor\n");
|
||||
rdesc[55] = 0xdd;
|
||||
}
|
||||
/* For the T100TA keyboard dock */
|
||||
/* For the T100TA/T200TA keyboard dock */
|
||||
if (drvdata->quirks & QUIRK_T100_KEYBOARD &&
|
||||
*rsize == 76 && rdesc[73] == 0x81 && rdesc[74] == 0x01) {
|
||||
(*rsize == 76 || *rsize == 101) &&
|
||||
rdesc[73] == 0x81 && rdesc[74] == 0x01) {
|
||||
hid_info(hdev, "Fixing up Asus T100 keyb report descriptor\n");
|
||||
rdesc[74] &= ~HID_MAIN_ITEM_CONSTANT;
|
||||
}
|
||||
@@ -751,7 +781,10 @@ static const struct hid_device_id asus_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3), QUIRK_G752_KEYBOARD },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD),
|
||||
USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD),
|
||||
QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD),
|
||||
QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) },
|
||||
|
||||
+56
-876
File diff suppressed because it is too large
Load Diff
+42
-36
@@ -1,9 +1,15 @@
|
||||
/*
|
||||
* HID driver for ELECOM devices.
|
||||
* HID driver for ELECOM devices:
|
||||
* - BM084 Bluetooth Mouse
|
||||
* - EX-G Trackball (Wired and wireless)
|
||||
* - DEFT Trackball (Wired and wireless)
|
||||
* - HUGE Trackball (Wired and wireless)
|
||||
*
|
||||
* Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
|
||||
* Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
|
||||
* Copyright (c) 2017 Diego Elio Pettenò <flameeyes@flameeyes.eu>
|
||||
* Copyright (c) 2017 Alex Manoussakis <amanou@gnu.org>
|
||||
* Copyright (c) 2017 Tomasz Kramkowski <tk@the-tk.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -19,6 +25,34 @@
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
/*
|
||||
* Certain ELECOM mice misreport their button count meaning that they only work
|
||||
* correctly with the ELECOM mouse assistant software which is unavailable for
|
||||
* Linux. A four extra INPUT reports and a FEATURE report are described by the
|
||||
* report descriptor but it does not appear that these enable software to
|
||||
* control what the extra buttons map to. The only simple and straightforward
|
||||
* solution seems to involve fixing up the report descriptor.
|
||||
*
|
||||
* Report descriptor format:
|
||||
* Positions 13, 15, 21 and 31 store the button bit count, button usage minimum,
|
||||
* button usage maximum and padding bit count respectively.
|
||||
*/
|
||||
#define MOUSE_BUTTONS_MAX 8
|
||||
static void mouse_button_fixup(struct hid_device *hdev,
|
||||
__u8 *rdesc, unsigned int rsize,
|
||||
int nbuttons)
|
||||
{
|
||||
if (rsize < 32 || rdesc[12] != 0x95 ||
|
||||
rdesc[14] != 0x75 || rdesc[15] != 0x01 ||
|
||||
rdesc[20] != 0x29 || rdesc[30] != 0x75)
|
||||
return;
|
||||
hid_info(hdev, "Fixing up Elecom mouse button count\n");
|
||||
nbuttons = clamp(nbuttons, 0, MOUSE_BUTTONS_MAX);
|
||||
rdesc[13] = nbuttons;
|
||||
rdesc[21] = nbuttons;
|
||||
rdesc[31] = MOUSE_BUTTONS_MAX - nbuttons;
|
||||
}
|
||||
|
||||
static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
@@ -31,45 +65,15 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
rdesc[47] = 0x00;
|
||||
}
|
||||
break;
|
||||
case USB_DEVICE_ID_ELECOM_EX_G_WIRED:
|
||||
case USB_DEVICE_ID_ELECOM_EX_G_WIRELESS:
|
||||
mouse_button_fixup(hdev, rdesc, *rsize, 6);
|
||||
break;
|
||||
case USB_DEVICE_ID_ELECOM_DEFT_WIRED:
|
||||
case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS:
|
||||
case USB_DEVICE_ID_ELECOM_HUGE_WIRED:
|
||||
case USB_DEVICE_ID_ELECOM_HUGE_WIRELESS:
|
||||
/* The DEFT/HUGE trackball has eight buttons, but its descriptor
|
||||
* only reports five, disabling the three Fn buttons on the top
|
||||
* of the mouse.
|
||||
*
|
||||
* Apply the following diff to the descriptor:
|
||||
*
|
||||
* Collection (Physical), Collection (Physical),
|
||||
* Report ID (1), Report ID (1),
|
||||
* Report Count (5), -> Report Count (8),
|
||||
* Report Size (1), Report Size (1),
|
||||
* Usage Page (Button), Usage Page (Button),
|
||||
* Usage Minimum (01h), Usage Minimum (01h),
|
||||
* Usage Maximum (05h), -> Usage Maximum (08h),
|
||||
* Logical Minimum (0), Logical Minimum (0),
|
||||
* Logical Maximum (1), Logical Maximum (1),
|
||||
* Input (Variable), Input (Variable),
|
||||
* Report Count (1), -> Report Count (0),
|
||||
* Report Size (3), Report Size (3),
|
||||
* Input (Constant), Input (Constant),
|
||||
* Report Size (16), Report Size (16),
|
||||
* Report Count (2), Report Count (2),
|
||||
* Usage Page (Desktop), Usage Page (Desktop),
|
||||
* Usage (X), Usage (X),
|
||||
* Usage (Y), Usage (Y),
|
||||
* Logical Minimum (-32768), Logical Minimum (-32768),
|
||||
* Logical Maximum (32767), Logical Maximum (32767),
|
||||
* Input (Variable, Relative), Input (Variable, Relative),
|
||||
* End Collection, End Collection,
|
||||
*/
|
||||
if (*rsize == 213 && rdesc[13] == 5 && rdesc[21] == 5) {
|
||||
hid_info(hdev, "Fixing up Elecom DEFT/HUGE Fn buttons\n");
|
||||
rdesc[13] = 8; /* Button/Variable Report Count */
|
||||
rdesc[21] = 8; /* Button/Variable Usage Maximum */
|
||||
rdesc[29] = 0; /* Button/Constant Report Count */
|
||||
}
|
||||
mouse_button_fixup(hdev, rdesc, *rsize, 8);
|
||||
break;
|
||||
}
|
||||
return rdesc;
|
||||
@@ -77,6 +81,8 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
|
||||
static const struct hid_device_id elecom_devices[] = {
|
||||
{ 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_EX_G_WIRELESS) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) },
|
||||
|
||||
@@ -42,6 +42,12 @@ static int elo_input_configured(struct hid_device *hdev,
|
||||
{
|
||||
struct input_dev *input = hidinput->input;
|
||||
|
||||
/*
|
||||
* ELO devices have one Button usage in GenDesk field, which makes
|
||||
* hid-input map it to BTN_LEFT; that confuses userspace, which then
|
||||
* considers the device to be a mouse/touchpad instead of touchscreen.
|
||||
*/
|
||||
clear_bit(BTN_LEFT, input->keybit);
|
||||
set_bit(BTN_TOUCH, input->keybit);
|
||||
set_bit(ABS_PRESSURE, input->absbit);
|
||||
input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0);
|
||||
|
||||
@@ -24,8 +24,71 @@
|
||||
|
||||
#include <linux/hid.h>
|
||||
|
||||
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)
|
||||
{
|
||||
struct hid_driver *hdrv = to_hid_driver(drv);
|
||||
struct hid_device *hdev = data;
|
||||
|
||||
if (hdrv == &hid_generic)
|
||||
return 0;
|
||||
|
||||
return hid_match_device(hdev, hdrv) != NULL;
|
||||
}
|
||||
|
||||
static bool hid_generic_match(struct hid_device *hdev,
|
||||
bool ignore_special_driver)
|
||||
{
|
||||
if (ignore_special_driver)
|
||||
return true;
|
||||
|
||||
if (hdev->quirks & HID_QUIRK_HAVE_SPECIAL_DRIVER)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If any other driver wants the device, leave the device to this other
|
||||
* driver.
|
||||
*/
|
||||
if (bus_for_each_drv(&hid_bus_type, NULL, hdev, __check_hid_generic))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct hid_device_id hid_table[] = {
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_GENERIC, HID_ANY_ID, HID_ANY_ID) },
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, hid_table);
|
||||
@@ -33,6 +96,9 @@ MODULE_DEVICE_TABLE(hid, hid_table);
|
||||
static struct hid_driver hid_generic = {
|
||||
.name = "hid-generic",
|
||||
.id_table = hid_table,
|
||||
.match = hid_generic_match,
|
||||
.bus_add_driver = hid_generic_add_driver,
|
||||
.bus_removed_driver = hid_generic_removed_driver,
|
||||
};
|
||||
module_hid_driver(hid_generic);
|
||||
|
||||
|
||||
@@ -178,7 +178,8 @@
|
||||
#define USB_VENDOR_ID_ASUSTEK 0x0b05
|
||||
#define USB_DEVICE_ID_ASUSTEK_LCM 0x1726
|
||||
#define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b
|
||||
#define USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD 0x17e0
|
||||
#define USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD 0x17e0
|
||||
#define USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD 0x1807
|
||||
#define USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD 0x8502
|
||||
#define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD 0x184a
|
||||
#define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585
|
||||
@@ -370,6 +371,8 @@
|
||||
|
||||
#define USB_VENDOR_ID_ELECOM 0x056e
|
||||
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
|
||||
#define USB_DEVICE_ID_ELECOM_EX_G_WIRED 0x00fb
|
||||
#define USB_DEVICE_ID_ELECOM_EX_G_WIRELESS 0x00fc
|
||||
#define USB_DEVICE_ID_ELECOM_DEFT_WIRED 0x00fe
|
||||
#define USB_DEVICE_ID_ELECOM_DEFT_WIRELESS 0x00ff
|
||||
#define USB_DEVICE_ID_ELECOM_HUGE_WIRED 0x010c
|
||||
@@ -535,6 +538,7 @@
|
||||
#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a
|
||||
#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
|
||||
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a
|
||||
#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A 0x094a
|
||||
|
||||
#define USB_VENDOR_ID_HUION 0x256c
|
||||
#define USB_DEVICE_ID_HUION_TABLET 0x006e
|
||||
@@ -1156,6 +1160,7 @@
|
||||
#define USB_VENDOR_ID_PRIMAX 0x0461
|
||||
#define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22
|
||||
#define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05
|
||||
#define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72
|
||||
|
||||
|
||||
#define USB_VENDOR_ID_RISO_KAGAKU 0x1294 /* Riso Kagaku Corp. */
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Jabra USB HID Driver
|
||||
*
|
||||
* Copyright (c) 2017 Niels Skou Olsen <nolsen@jabra.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/module.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define HID_UP_VENDOR_DEFINED_MIN 0xff000000
|
||||
#define HID_UP_VENDOR_DEFINED_MAX 0xffff0000
|
||||
|
||||
static int jabra_input_mapping(struct hid_device *hdev,
|
||||
struct hid_input *hi,
|
||||
struct hid_field *field,
|
||||
struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
int is_vendor_defined =
|
||||
((usage->hid & HID_USAGE_PAGE) >= HID_UP_VENDOR_DEFINED_MIN &&
|
||||
(usage->hid & HID_USAGE_PAGE) <= HID_UP_VENDOR_DEFINED_MAX);
|
||||
|
||||
dbg_hid("hid=0x%08x appl=0x%08x coll_idx=0x%02x usage_idx=0x%02x: %s\n",
|
||||
usage->hid,
|
||||
field->application,
|
||||
usage->collection_index,
|
||||
usage->usage_index,
|
||||
is_vendor_defined ? "ignored" : "defaulted");
|
||||
|
||||
/* Ignore vendor defined usages, default map standard usages */
|
||||
return is_vendor_defined ? -1 : 0;
|
||||
}
|
||||
|
||||
static const struct hid_device_id jabra_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, HID_ANY_ID) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, jabra_devices);
|
||||
|
||||
static struct hid_driver jabra_driver = {
|
||||
.name = "jabra",
|
||||
.id_table = jabra_devices,
|
||||
.input_mapping = jabra_input_mapping,
|
||||
};
|
||||
module_hid_driver(jabra_driver);
|
||||
|
||||
MODULE_AUTHOR("Niels Skou Olsen <nolsen@jabra.com>");
|
||||
MODULE_DESCRIPTION("Jabra USB HID Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
+121
-16
@@ -85,11 +85,12 @@ MODULE_LICENSE("GPL");
|
||||
#define MT_IO_FLAGS_PENDING_SLOTS 2
|
||||
|
||||
struct mt_slot {
|
||||
__s32 x, y, cx, cy, p, w, h;
|
||||
__s32 x, y, cx, cy, p, w, h, a;
|
||||
__s32 contactid; /* the device ContactID assigned to this slot */
|
||||
bool touch_state; /* is the touch valid? */
|
||||
bool inrange_state; /* is the finger in proximity of the sensor? */
|
||||
bool confidence_state; /* is the touch made by a finger? */
|
||||
bool has_azimuth; /* the contact reports azimuth */
|
||||
};
|
||||
|
||||
struct mt_class {
|
||||
@@ -119,6 +120,10 @@ struct mt_device {
|
||||
unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */
|
||||
int cc_index; /* contact count field index in the report */
|
||||
int cc_value_index; /* contact count value index in the field */
|
||||
int scantime_index; /* scantime field index in the report */
|
||||
int scantime_val_index; /* scantime value index in the field */
|
||||
int prev_scantime; /* scantime reported in the previous packet */
|
||||
int left_button_state; /* left button state */
|
||||
unsigned last_slot_field; /* the last field of a slot */
|
||||
unsigned mt_report_id; /* the report ID of the multitouch device */
|
||||
unsigned long initial_quirks; /* initial quirks state */
|
||||
@@ -582,8 +587,15 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
if (!(cls->quirks & MT_QUIRK_NO_AREA)) {
|
||||
set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
|
||||
cls->sn_height);
|
||||
input_set_abs_params(hi->input,
|
||||
ABS_MT_ORIENTATION, 0, 1, 0, 0);
|
||||
|
||||
/*
|
||||
* Only set ABS_MT_ORIENTATION if it is not
|
||||
* already set by the HID_DG_AZIMUTH usage.
|
||||
*/
|
||||
if (!test_bit(ABS_MT_ORIENTATION,
|
||||
hi->input->absbit))
|
||||
input_set_abs_params(hi->input,
|
||||
ABS_MT_ORIENTATION, 0, 1, 0, 0);
|
||||
}
|
||||
mt_store_field(usage, td, hi);
|
||||
return 1;
|
||||
@@ -599,6 +611,12 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
EV_MSC, MSC_TIMESTAMP);
|
||||
input_set_capability(hi->input, EV_MSC, MSC_TIMESTAMP);
|
||||
mt_store_field(usage, td, hi);
|
||||
/* Ignore if indexes are out of bounds. */
|
||||
if (field->index >= field->report->maxfield ||
|
||||
usage->usage_index >= field->report_count)
|
||||
return 1;
|
||||
td->scantime_index = field->index;
|
||||
td->scantime_val_index = usage->usage_index;
|
||||
return 1;
|
||||
case HID_DG_CONTACTCOUNT:
|
||||
/* Ignore if indexes are out of bounds. */
|
||||
@@ -608,6 +626,21 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
td->cc_index = field->index;
|
||||
td->cc_value_index = usage->usage_index;
|
||||
return 1;
|
||||
case HID_DG_AZIMUTH:
|
||||
hid_map_usage(hi, usage, bit, max,
|
||||
EV_ABS, ABS_MT_ORIENTATION);
|
||||
/*
|
||||
* Azimuth has the range of [0, MAX) representing a full
|
||||
* revolution. Set ABS_MT_ORIENTATION to a quarter of
|
||||
* MAX according the definition of ABS_MT_ORIENTATION
|
||||
*/
|
||||
input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
|
||||
-field->logical_maximum / 4,
|
||||
field->logical_maximum / 4,
|
||||
cls->sn_move ?
|
||||
field->logical_maximum / cls->sn_move : 0, 0);
|
||||
mt_store_field(usage, td, hi);
|
||||
return 1;
|
||||
case HID_DG_CONTACTMAX:
|
||||
/* we don't set td->last_slot_field as contactcount and
|
||||
* contact max are global to the report */
|
||||
@@ -700,6 +733,10 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
|
||||
int wide = (s->w > s->h);
|
||||
int major = max(s->w, s->h);
|
||||
int minor = min(s->w, s->h);
|
||||
int orientation = wide;
|
||||
|
||||
if (s->has_azimuth)
|
||||
orientation = s->a;
|
||||
|
||||
/*
|
||||
* divided by two to match visual scale of touch
|
||||
@@ -716,7 +753,8 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
|
||||
input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
|
||||
input_event(input, EV_ABS, ABS_MT_DISTANCE,
|
||||
!s->touch_state);
|
||||
input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
|
||||
input_event(input, EV_ABS, ABS_MT_ORIENTATION,
|
||||
orientation);
|
||||
input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
|
||||
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
|
||||
input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
|
||||
@@ -734,10 +772,16 @@ 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)
|
||||
{
|
||||
__s32 cls = td->mtclass.name;
|
||||
|
||||
if (cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL)
|
||||
input_event(input, EV_KEY, BTN_LEFT, td->left_button_state);
|
||||
|
||||
input_mt_sync_frame(input);
|
||||
input_event(input, EV_MSC, MSC_TIMESTAMP, td->timestamp);
|
||||
input_sync(input);
|
||||
td->num_received = 0;
|
||||
td->left_button_state = 0;
|
||||
if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags))
|
||||
set_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags);
|
||||
else
|
||||
@@ -778,9 +822,11 @@ static int mt_touch_event(struct hid_device *hid, struct hid_field *field,
|
||||
}
|
||||
|
||||
static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
struct hid_usage *usage, __s32 value,
|
||||
bool first_packet)
|
||||
{
|
||||
struct mt_device *td = hid_get_drvdata(hid);
|
||||
__s32 cls = td->mtclass.name;
|
||||
__s32 quirks = td->mtclass.quirks;
|
||||
struct input_dev *input = field->hidinput->input;
|
||||
|
||||
@@ -832,11 +878,49 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
|
||||
break;
|
||||
case HID_DG_CONTACTCOUNT:
|
||||
break;
|
||||
case HID_DG_AZIMUTH:
|
||||
/*
|
||||
* Azimuth is counter-clockwise and ranges from [0, MAX)
|
||||
* (a full revolution). Convert it to clockwise ranging
|
||||
* [-MAX/2, MAX/2].
|
||||
*
|
||||
* Note that ABS_MT_ORIENTATION require us to report
|
||||
* the limit of [-MAX/4, MAX/4], but the value can go
|
||||
* out of range to [-MAX/2, MAX/2] to report an upside
|
||||
* down ellipsis.
|
||||
*/
|
||||
if (value > field->logical_maximum / 2)
|
||||
value -= field->logical_maximum;
|
||||
td->curdata.a = -value;
|
||||
td->curdata.has_azimuth = true;
|
||||
break;
|
||||
case HID_DG_TOUCH:
|
||||
/* do nothing */
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* For Win8 PTP touchpads we should only look at
|
||||
* non finger/touch events in the first_packet of
|
||||
* a (possible) multi-packet frame.
|
||||
*/
|
||||
if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
|
||||
!first_packet)
|
||||
return;
|
||||
|
||||
/*
|
||||
* For Win8 PTP touchpads we map both the clickpad click
|
||||
* and any "external" left buttons to BTN_LEFT if a
|
||||
* device claims to have both we need to report 1 for
|
||||
* BTN_LEFT if either is pressed, so we or all values
|
||||
* together and report the result in mt_sync_frame().
|
||||
*/
|
||||
if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
|
||||
usage->type == EV_KEY && usage->code == BTN_LEFT) {
|
||||
td->left_button_state |= value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (usage->type)
|
||||
input_event(input, usage->type, usage->code,
|
||||
value);
|
||||
@@ -855,9 +939,11 @@ 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)
|
||||
{
|
||||
struct mt_device *td = hid_get_drvdata(hid);
|
||||
__s32 cls = td->mtclass.name;
|
||||
struct hid_field *field;
|
||||
bool first_packet;
|
||||
unsigned count;
|
||||
int r, n;
|
||||
int r, n, scantime = 0;
|
||||
|
||||
/* sticky fingers release in progress, abort */
|
||||
if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
|
||||
@@ -867,13 +953,31 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
|
||||
* Includes multi-packet support where subsequent
|
||||
* packets are sent with zero contactcount.
|
||||
*/
|
||||
if (td->scantime_index >= 0) {
|
||||
field = report->field[td->scantime_index];
|
||||
scantime = field->value[td->scantime_val_index];
|
||||
}
|
||||
if (td->cc_index >= 0) {
|
||||
struct hid_field *field = report->field[td->cc_index];
|
||||
int value = field->value[td->cc_value_index];
|
||||
if (value)
|
||||
|
||||
/*
|
||||
* For Win8 PTPs the first packet (td->num_received == 0) may
|
||||
* have a contactcount of 0 if there only is a button event.
|
||||
* We double check that this is not a continuation packet
|
||||
* of a possible multi-packet frame be checking that the
|
||||
* timestamp has changed.
|
||||
*/
|
||||
if ((cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL) &&
|
||||
td->num_received == 0 && td->prev_scantime != scantime)
|
||||
td->num_expected = value;
|
||||
/* A non 0 contact count always indicates a first packet */
|
||||
else if (value)
|
||||
td->num_expected = value;
|
||||
}
|
||||
td->prev_scantime = scantime;
|
||||
|
||||
first_packet = td->num_received == 0;
|
||||
for (r = 0; r < report->maxfield; r++) {
|
||||
field = report->field[r];
|
||||
count = field->report_count;
|
||||
@@ -883,7 +987,7 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
mt_process_mt_event(hid, field, &field->usage[n],
|
||||
field->value[n]);
|
||||
field->value[n], first_packet);
|
||||
}
|
||||
|
||||
if (td->num_received >= td->num_expected)
|
||||
@@ -1329,6 +1433,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
td->maxcontact_report_id = -1;
|
||||
td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
|
||||
td->cc_index = -1;
|
||||
td->scantime_index = -1;
|
||||
td->mt_report_id = -1;
|
||||
hid_set_drvdata(hdev, td);
|
||||
|
||||
@@ -1649,14 +1754,6 @@ static const struct hid_device_id mt_devices[] = {
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_TURBOX,
|
||||
USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
|
||||
|
||||
/* Panasonic panels */
|
||||
{ .driver_data = MT_CLS_PANASONIC,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
|
||||
USB_DEVICE_ID_PANABOARD_UBT780) },
|
||||
{ .driver_data = MT_CLS_PANASONIC,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
|
||||
USB_DEVICE_ID_PANABOARD_UBT880) },
|
||||
|
||||
/* Novatek Panel */
|
||||
{ .driver_data = MT_CLS_NSMU,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_NOVATEK,
|
||||
@@ -1667,6 +1764,14 @@ static const struct hid_device_id mt_devices[] = {
|
||||
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_NTRIG, 0x1b05) },
|
||||
|
||||
/* Panasonic panels */
|
||||
{ .driver_data = MT_CLS_PANASONIC,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
|
||||
USB_DEVICE_ID_PANABOARD_UBT780) },
|
||||
{ .driver_data = MT_CLS_PANASONIC,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
|
||||
USB_DEVICE_ID_PANABOARD_UBT880) },
|
||||
|
||||
/* PixArt optical touch screen */
|
||||
{ .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_PIXART,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -731,6 +731,7 @@ static const struct hid_device_id rmi_id[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER, USB_DEVICE_ID_RAZER_BLADE_14),
|
||||
.driver_data = RMI_DEVICE_HAS_PHYS_BUTTONS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_REZEL) },
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -37,6 +37,8 @@ static uint kovaplus_convert_event_cpi(uint value)
|
||||
static void kovaplus_profile_activated(struct kovaplus_device *kovaplus,
|
||||
uint new_profile_index)
|
||||
{
|
||||
if (new_profile_index >= ARRAY_SIZE(kovaplus->profile_settings))
|
||||
return;
|
||||
kovaplus->actual_profile = new_profile_index;
|
||||
kovaplus->actual_cpi = kovaplus->profile_settings[new_profile_index].cpi_startup_level;
|
||||
kovaplus->actual_x_sensitivity = kovaplus->profile_settings[new_profile_index].sensitivity_x;
|
||||
|
||||
+85
-8
@@ -473,6 +473,7 @@ struct motion_output_report_02 {
|
||||
#define DS4_FEATURE_REPORT_0x02_SIZE 37
|
||||
#define DS4_FEATURE_REPORT_0x05_SIZE 41
|
||||
#define DS4_FEATURE_REPORT_0x81_SIZE 7
|
||||
#define DS4_FEATURE_REPORT_0xA3_SIZE 49
|
||||
#define DS4_INPUT_REPORT_0x11_SIZE 78
|
||||
#define DS4_OUTPUT_REPORT_0x05_SIZE 32
|
||||
#define DS4_OUTPUT_REPORT_0x11_SIZE 78
|
||||
@@ -544,6 +545,8 @@ struct sony_sc {
|
||||
struct power_supply *battery;
|
||||
struct power_supply_desc battery_desc;
|
||||
int device_id;
|
||||
unsigned fw_version;
|
||||
unsigned hw_version;
|
||||
u8 *output_report_dmabuf;
|
||||
|
||||
#ifdef CONFIG_SONY_FF
|
||||
@@ -627,6 +630,29 @@ static ssize_t ds4_store_poll_interval(struct device *dev,
|
||||
static DEVICE_ATTR(bt_poll_interval, 0644, ds4_show_poll_interval,
|
||||
ds4_store_poll_interval);
|
||||
|
||||
static ssize_t sony_show_firmware_version(struct device *dev,
|
||||
struct device_attribute
|
||||
*attr, char *buf)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct sony_sc *sc = hid_get_drvdata(hdev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "0x%04x\n", sc->fw_version);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(firmware_version, 0444, sony_show_firmware_version, NULL);
|
||||
|
||||
static ssize_t sony_show_hardware_version(struct device *dev,
|
||||
struct device_attribute
|
||||
*attr, char *buf)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct sony_sc *sc = hid_get_drvdata(hdev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "0x%04x\n", sc->hw_version);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(hardware_version, 0444, sony_show_hardware_version, NULL);
|
||||
|
||||
static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
@@ -1646,6 +1672,31 @@ static void dualshock4_calibration_work(struct work_struct *work)
|
||||
spin_unlock_irqrestore(&sc->lock, flags);
|
||||
}
|
||||
|
||||
static int dualshock4_get_version_info(struct sony_sc *sc)
|
||||
{
|
||||
u8 *buf;
|
||||
int ret;
|
||||
|
||||
buf = kmalloc(DS4_FEATURE_REPORT_0xA3_SIZE, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = hid_hw_raw_request(sc->hdev, 0xA3, buf,
|
||||
DS4_FEATURE_REPORT_0xA3_SIZE,
|
||||
HID_FEATURE_REPORT,
|
||||
HID_REQ_GET_REPORT);
|
||||
if (ret < 0) {
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sc->hw_version = get_unaligned_le16(&buf[35]);
|
||||
sc->fw_version = get_unaligned_le16(&buf[41]);
|
||||
|
||||
kfree(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sixaxis_set_leds_from_id(struct sony_sc *sc)
|
||||
{
|
||||
static const u8 sixaxis_leds[10][4] = {
|
||||
@@ -2399,10 +2450,7 @@ static int sony_check_add(struct sony_sc *sc)
|
||||
memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
|
||||
|
||||
snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
|
||||
"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
|
||||
sc->mac_address[5], sc->mac_address[4],
|
||||
sc->mac_address[3], sc->mac_address[2],
|
||||
sc->mac_address[1], sc->mac_address[0]);
|
||||
"%pMR", sc->mac_address);
|
||||
} else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
|
||||
(sc->quirks & NAVIGATION_CONTROLLER_USB)) {
|
||||
buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL);
|
||||
@@ -2432,10 +2480,7 @@ static int sony_check_add(struct sony_sc *sc)
|
||||
sc->mac_address[5-n] = buf[4+n];
|
||||
|
||||
snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
|
||||
"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
|
||||
sc->mac_address[5], sc->mac_address[4],
|
||||
sc->mac_address[3], sc->mac_address[2],
|
||||
sc->mac_address[1], sc->mac_address[0]);
|
||||
"%pMR", sc->mac_address);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -2619,6 +2664,28 @@ static int sony_input_configured(struct hid_device *hdev,
|
||||
goto err_stop;
|
||||
}
|
||||
|
||||
ret = dualshock4_get_version_info(sc);
|
||||
if (ret < 0) {
|
||||
hid_err(sc->hdev, "Failed to get version data from Dualshock 4\n");
|
||||
goto err_stop;
|
||||
}
|
||||
|
||||
ret = device_create_file(&sc->hdev->dev, &dev_attr_firmware_version);
|
||||
if (ret) {
|
||||
/* Make zero for cleanup reasons of sysfs entries. */
|
||||
sc->fw_version = 0;
|
||||
sc->hw_version = 0;
|
||||
hid_err(sc->hdev, "can't create sysfs firmware_version attribute err: %d\n", ret);
|
||||
goto err_stop;
|
||||
}
|
||||
|
||||
ret = device_create_file(&sc->hdev->dev, &dev_attr_hardware_version);
|
||||
if (ret) {
|
||||
sc->hw_version = 0;
|
||||
hid_err(sc->hdev, "can't create sysfs hardware_version attribute err: %d\n", ret);
|
||||
goto err_stop;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Dualshock 4 touchpad supports 2 touches and has a
|
||||
* resolution of 1920x942 (44.86 dots/mm).
|
||||
@@ -2695,6 +2762,10 @@ err_stop:
|
||||
*/
|
||||
if (sc->ds4_bt_poll_interval)
|
||||
device_remove_file(&sc->hdev->dev, &dev_attr_bt_poll_interval);
|
||||
if (sc->fw_version)
|
||||
device_remove_file(&sc->hdev->dev, &dev_attr_firmware_version);
|
||||
if (sc->hw_version)
|
||||
device_remove_file(&sc->hdev->dev, &dev_attr_hardware_version);
|
||||
if (sc->quirks & SONY_LED_SUPPORT)
|
||||
sony_leds_remove(sc);
|
||||
if (sc->quirks & SONY_BATTERY_SUPPORT)
|
||||
@@ -2796,6 +2867,12 @@ static void sony_remove(struct hid_device *hdev)
|
||||
if (sc->quirks & DUALSHOCK4_CONTROLLER_BT)
|
||||
device_remove_file(&sc->hdev->dev, &dev_attr_bt_poll_interval);
|
||||
|
||||
if (sc->fw_version)
|
||||
device_remove_file(&sc->hdev->dev, &dev_attr_firmware_version);
|
||||
|
||||
if (sc->hw_version)
|
||||
device_remove_file(&sc->hdev->dev, &dev_attr_hardware_version);
|
||||
|
||||
sony_cancel_work_sync(sc);
|
||||
|
||||
kfree(sc->output_report_dmabuf);
|
||||
|
||||
@@ -934,11 +934,6 @@ static int i2c_hid_of_probe(struct i2c_client *client,
|
||||
}
|
||||
pdata->hid_descriptor_address = val;
|
||||
|
||||
ret = of_property_read_u32(dev->of_node, "post-power-on-delay-ms",
|
||||
&val);
|
||||
if (!ret)
|
||||
pdata->post_power_delay_ms = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -955,6 +950,16 @@ static inline int i2c_hid_of_probe(struct i2c_client *client,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void i2c_hid_fwnode_probe(struct i2c_client *client,
|
||||
struct i2c_hid_platform_data *pdata)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (!device_property_read_u32(&client->dev, "post-power-on-delay-ms",
|
||||
&val))
|
||||
pdata->post_power_delay_ms = val;
|
||||
}
|
||||
|
||||
static int i2c_hid_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *dev_id)
|
||||
{
|
||||
@@ -998,6 +1003,9 @@ static int i2c_hid_probe(struct i2c_client *client,
|
||||
ihid->pdata = *platform_data;
|
||||
}
|
||||
|
||||
/* Parse platform agnostic common properties from ACPI / device tree */
|
||||
i2c_hid_fwnode_probe(client, &ihid->pdata);
|
||||
|
||||
ihid->pdata.supply = devm_regulator_get(&client->dev, "vdd");
|
||||
if (IS_ERR(ihid->pdata.supply)) {
|
||||
ret = PTR_ERR(ihid->pdata.supply);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define SPT_Ax_DEVICE_ID 0x9D35
|
||||
#define CNL_Ax_DEVICE_ID 0x9DFC
|
||||
#define GLK_Ax_DEVICE_ID 0x31A2
|
||||
#define CNL_H_DEVICE_ID 0xA37C
|
||||
|
||||
#define REVISION_ID_CHT_A0 0x6
|
||||
#define REVISION_ID_CHT_Ax_SI 0x0
|
||||
|
||||
@@ -37,6 +37,7 @@ static const struct pci_device_id ish_pci_tbl[] = {
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_Ax_DEVICE_ID)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_Ax_DEVICE_ID)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, GLK_Ax_DEVICE_ID)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_H_DEVICE_ID)},
|
||||
{0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Makefile for the USB input drivers
|
||||
#
|
||||
|
||||
usbhid-y := hid-core.o hid-quirks.o
|
||||
usbhid-y := hid-core.o
|
||||
usbhid-$(CONFIG_USB_HIDDEV) += hiddev.o
|
||||
usbhid-$(CONFIG_HID_PID) += hid-pidff.o
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user