forked from Minki/linux
Merge branch 'for-4.17/multitouch' into for-linus
Pull Razer Blade Stealth support improvement and a few generic cleanups
This commit is contained in:
commit
af73686e7b
@ -644,8 +644,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
|
||||
* userspace the touchpad must be a separate input_dev.
|
||||
*/
|
||||
hdev->quirks |= HID_QUIRK_MULTI_INPUT |
|
||||
HID_QUIRK_NO_EMPTY_INPUT;
|
||||
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
|
||||
drvdata->tp = &asus_t100chi_tp;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
if (hdrv->probe) {
|
||||
ret = hdrv->probe(hdev, id);
|
||||
|
@ -1657,16 +1657,16 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
|
||||
if ((hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
|
||||
!hidinput_has_been_populated(hidinput)) {
|
||||
if (drv->input_configured &&
|
||||
drv->input_configured(hid, hidinput))
|
||||
goto out_unwind;
|
||||
|
||||
if (!hidinput_has_been_populated(hidinput)) {
|
||||
/* no need to register an input device not populated */
|
||||
hidinput_cleanup_hidinput(hid, hidinput);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (drv->input_configured &&
|
||||
drv->input_configured(hid, hidinput))
|
||||
goto out_unwind;
|
||||
if (input_register_device(hidinput->input))
|
||||
goto out_unwind;
|
||||
hidinput->registered = true;
|
||||
|
@ -74,6 +74,7 @@ MODULE_LICENSE("GPL");
|
||||
#define MT_QUIRK_TOUCH_SIZE_SCALING BIT(15)
|
||||
#define MT_QUIRK_STICKY_FINGERS BIT(16)
|
||||
#define MT_QUIRK_ASUS_CUSTOM_UP BIT(17)
|
||||
#define MT_QUIRK_WIN8_PTP_BUTTONS BIT(18)
|
||||
|
||||
#define MT_INPUTMODE_TOUCHSCREEN 0x02
|
||||
#define MT_INPUTMODE_TOUCHPAD 0x03
|
||||
@ -126,7 +127,6 @@ struct mt_device {
|
||||
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 */
|
||||
__s16 inputmode; /* InputMode HID feature, -1 if non-existent */
|
||||
__s16 inputmode_index; /* InputMode HID feature index in the report */
|
||||
__s16 maxcontact_report_id; /* Maximum Contact Number HID feature,
|
||||
@ -183,6 +183,7 @@ static void mt_post_parse(struct mt_device *td);
|
||||
#define MT_CLS_ASUS 0x010b
|
||||
#define MT_CLS_VTL 0x0110
|
||||
#define MT_CLS_GOOGLE 0x0111
|
||||
#define MT_CLS_RAZER_BLADE_STEALTH 0x0112
|
||||
|
||||
#define MT_DEFAULT_MAXCONTACT 10
|
||||
#define MT_MAX_MAXCONTACT 250
|
||||
@ -241,7 +242,8 @@ static struct mt_class mt_classes[] = {
|
||||
MT_QUIRK_IGNORE_DUPLICATES |
|
||||
MT_QUIRK_HOVERING |
|
||||
MT_QUIRK_CONTACT_CNT_ACCURATE |
|
||||
MT_QUIRK_STICKY_FINGERS },
|
||||
MT_QUIRK_STICKY_FINGERS |
|
||||
MT_QUIRK_WIN8_PTP_BUTTONS },
|
||||
{ .name = MT_CLS_EXPORT_ALL_INPUTS,
|
||||
.quirks = MT_QUIRK_ALWAYS_VALID |
|
||||
MT_QUIRK_CONTACT_CNT_ACCURATE,
|
||||
@ -250,7 +252,8 @@ static struct mt_class mt_classes[] = {
|
||||
.quirks = MT_QUIRK_ALWAYS_VALID |
|
||||
MT_QUIRK_IGNORE_DUPLICATES |
|
||||
MT_QUIRK_HOVERING |
|
||||
MT_QUIRK_CONTACT_CNT_ACCURATE,
|
||||
MT_QUIRK_CONTACT_CNT_ACCURATE |
|
||||
MT_QUIRK_WIN8_PTP_BUTTONS,
|
||||
.export_all_inputs = true },
|
||||
|
||||
/*
|
||||
@ -323,6 +326,13 @@ static struct mt_class mt_classes[] = {
|
||||
MT_QUIRK_SLOT_IS_CONTACTID |
|
||||
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,7 +379,6 @@ static const struct attribute_group mt_attribute_group = {
|
||||
|
||||
static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
|
||||
{
|
||||
struct mt_device *td = hid_get_drvdata(hdev);
|
||||
int ret;
|
||||
u32 size = hid_report_len(report);
|
||||
u8 *buf;
|
||||
@ -378,7 +387,7 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
|
||||
* Do not fetch the feature report if the device has been explicitly
|
||||
* marked as non-capable.
|
||||
*/
|
||||
if (td->initial_quirks & HID_QUIRK_NO_INIT_REPORTS)
|
||||
if (hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)
|
||||
return;
|
||||
|
||||
buf = hid_alloc_report_buf(report, GFP_KERNEL);
|
||||
@ -660,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
|
||||
* usages 2 and 3.
|
||||
*/
|
||||
if ((cls->name == MT_CLS_WIN_8 ||
|
||||
cls->name == MT_CLS_WIN_8_DUAL) &&
|
||||
if ((cls->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
|
||||
field->application == HID_DG_TOUCHPAD &&
|
||||
(usage->hid & HID_USAGE) > 1)
|
||||
code--;
|
||||
@ -773,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)
|
||||
{
|
||||
__s32 cls = td->mtclass.name;
|
||||
|
||||
if (cls == MT_CLS_WIN_8 || cls == MT_CLS_WIN_8_DUAL)
|
||||
if (td->mtclass.quirks & MT_QUIRK_WIN8_PTP_BUTTONS)
|
||||
input_event(input, EV_KEY, BTN_LEFT, td->left_button_state);
|
||||
|
||||
input_mt_sync_frame(input);
|
||||
@ -827,7 +833,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
|
||||
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;
|
||||
|
||||
@ -905,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
|
||||
* 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)
|
||||
return;
|
||||
|
||||
@ -916,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
|
||||
* 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) {
|
||||
td->left_button_state |= value;
|
||||
return;
|
||||
@ -940,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)
|
||||
{
|
||||
struct mt_device *td = hid_get_drvdata(hid);
|
||||
__s32 cls = td->mtclass.name;
|
||||
struct hid_field *field;
|
||||
bool first_packet;
|
||||
unsigned count;
|
||||
@ -969,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
|
||||
* 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_expected = value;
|
||||
/* A non 0 contact count always indicates a first packet */
|
||||
@ -1448,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)
|
||||
td->serial_maybe = true;
|
||||
|
||||
/*
|
||||
* Store the initial quirk state
|
||||
*/
|
||||
td->initial_quirks = hdev->quirks;
|
||||
|
||||
/* This allows the driver to correctly support devices
|
||||
* that emit events over several HID messages.
|
||||
*/
|
||||
@ -1464,22 +1463,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
* device.
|
||||
*/
|
||||
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);
|
||||
|
||||
@ -1538,7 +1521,6 @@ static void mt_remove(struct hid_device *hdev)
|
||||
|
||||
sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
|
||||
hid_hw_stop(hdev);
|
||||
hdev->quirks = td->initial_quirks;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1794,6 +1776,11 @@ static const struct hid_device_id mt_devices[] = {
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_QUANTA,
|
||||
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 */
|
||||
{ .driver_data = MT_CLS_CONFIDENCE,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
|
||||
|
@ -946,7 +946,6 @@ static int uclogic_probe(struct hid_device *hdev,
|
||||
* than the pen, so use QUIRK_MULTI_INPUT for all tablets.
|
||||
*/
|
||||
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
|
||||
hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
|
||||
|
||||
/* Allocate and assign driver data */
|
||||
drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define __HID_H
|
||||
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
@ -310,13 +311,13 @@ struct hid_item {
|
||||
* HID connect requests
|
||||
*/
|
||||
|
||||
#define HID_CONNECT_HIDINPUT 0x01
|
||||
#define HID_CONNECT_HIDINPUT_FORCE 0x02
|
||||
#define HID_CONNECT_HIDRAW 0x04
|
||||
#define HID_CONNECT_HIDDEV 0x08
|
||||
#define HID_CONNECT_HIDDEV_FORCE 0x10
|
||||
#define HID_CONNECT_FF 0x20
|
||||
#define HID_CONNECT_DRIVER 0x40
|
||||
#define HID_CONNECT_HIDINPUT BIT(0)
|
||||
#define HID_CONNECT_HIDINPUT_FORCE BIT(1)
|
||||
#define HID_CONNECT_HIDRAW BIT(2)
|
||||
#define HID_CONNECT_HIDDEV BIT(3)
|
||||
#define HID_CONNECT_HIDDEV_FORCE BIT(4)
|
||||
#define HID_CONNECT_FF BIT(5)
|
||||
#define HID_CONNECT_DRIVER BIT(6)
|
||||
#define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \
|
||||
HID_CONNECT_HIDDEV|HID_CONNECT_FF)
|
||||
|
||||
@ -329,25 +330,25 @@ struct hid_item {
|
||||
*/
|
||||
#define MAX_USBHID_BOOT_QUIRKS 4
|
||||
|
||||
#define HID_QUIRK_INVERT 0x00000001
|
||||
#define HID_QUIRK_NOTOUCH 0x00000002
|
||||
#define HID_QUIRK_IGNORE 0x00000004
|
||||
#define HID_QUIRK_NOGET 0x00000008
|
||||
#define HID_QUIRK_HIDDEV_FORCE 0x00000010
|
||||
#define HID_QUIRK_BADPAD 0x00000020
|
||||
#define HID_QUIRK_MULTI_INPUT 0x00000040
|
||||
#define HID_QUIRK_HIDINPUT_FORCE 0x00000080
|
||||
#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100
|
||||
/* 0x00000200 reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
|
||||
#define HID_QUIRK_ALWAYS_POLL 0x00000400
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000
|
||||
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000
|
||||
#define HID_QUIRK_HAVE_SPECIAL_DRIVER 0x00080000
|
||||
#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
|
||||
#define HID_QUIRK_NO_INIT_REPORTS 0x20000000
|
||||
#define HID_QUIRK_NO_IGNORE 0x40000000
|
||||
#define HID_QUIRK_NO_INPUT_SYNC 0x80000000
|
||||
#define HID_QUIRK_INVERT BIT(0)
|
||||
#define HID_QUIRK_NOTOUCH BIT(1)
|
||||
#define HID_QUIRK_IGNORE BIT(2)
|
||||
#define HID_QUIRK_NOGET BIT(3)
|
||||
#define HID_QUIRK_HIDDEV_FORCE BIT(4)
|
||||
#define HID_QUIRK_BADPAD BIT(5)
|
||||
#define HID_QUIRK_MULTI_INPUT BIT(6)
|
||||
#define HID_QUIRK_HIDINPUT_FORCE BIT(7)
|
||||
/* BIT(8) reserved for backward compatibility, was HID_QUIRK_NO_EMPTY_INPUT */
|
||||
/* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
|
||||
#define HID_QUIRK_ALWAYS_POLL BIT(10)
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16)
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17)
|
||||
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
|
||||
#define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19)
|
||||
#define HID_QUIRK_FULLSPEED_INTERVAL BIT(28)
|
||||
#define HID_QUIRK_NO_INIT_REPORTS BIT(29)
|
||||
#define HID_QUIRK_NO_IGNORE BIT(30)
|
||||
#define HID_QUIRK_NO_INPUT_SYNC BIT(31)
|
||||
|
||||
/*
|
||||
* HID device groups
|
||||
@ -494,13 +495,13 @@ struct hid_output_fifo {
|
||||
char *raw_report;
|
||||
};
|
||||
|
||||
#define HID_CLAIMED_INPUT 1
|
||||
#define HID_CLAIMED_HIDDEV 2
|
||||
#define HID_CLAIMED_HIDRAW 4
|
||||
#define HID_CLAIMED_DRIVER 8
|
||||
#define HID_CLAIMED_INPUT BIT(0)
|
||||
#define HID_CLAIMED_HIDDEV BIT(1)
|
||||
#define HID_CLAIMED_HIDRAW BIT(2)
|
||||
#define HID_CLAIMED_DRIVER BIT(3)
|
||||
|
||||
#define HID_STAT_ADDED 1
|
||||
#define HID_STAT_PARSED 2
|
||||
#define HID_STAT_ADDED BIT(0)
|
||||
#define HID_STAT_PARSED BIT(1)
|
||||
|
||||
struct hid_input {
|
||||
struct list_head list;
|
||||
|
Loading…
Reference in New Issue
Block a user