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:
Jiri Kosina 2018-04-05 13:19:57 +02:00
commit af73686e7b
6 changed files with 65 additions and 77 deletions

View File

@ -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 * 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;
} }

View File

@ -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);

View File

@ -1657,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;

View File

@ -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 {
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);
#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[] = {
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[] = {
.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[] = {
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,7 +379,6 @@ 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;
u32 size = hid_report_len(report); u32 size = hid_report_len(report);
u8 *buf; 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 * 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);
@ -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 * 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--;
@ -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) 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);
@ -827,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;
@ -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 * 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;
@ -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 * 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;
@ -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) 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;
@ -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 * 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 */
@ -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) 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.
*/ */
@ -1464,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);
@ -1538,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;
} }
/* /*
@ -1794,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,

View File

@ -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);

View File

@ -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 {
* 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 {
*/ */
#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 {
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;