Merge branch 'for-4.19/multitouch-multiaxis' into for-linus

Multitouch updates:

- Dial support
- Palm rejection for touchscreens
- a few small assorted fixes
This commit is contained in:
Jiri Kosina 2018-08-20 18:09:06 +02:00
commit 16501e846d
7 changed files with 683 additions and 419 deletions

View File

@ -310,12 +310,12 @@ ABS_MT_TOOL_Y
ABS_MT_TOOL_TYPE
The type of approaching tool. A lot of kernel drivers cannot distinguish
between different tool types, such as a finger or a pen. In such cases, the
event should be omitted. The protocol currently supports MT_TOOL_FINGER,
MT_TOOL_PEN, and MT_TOOL_PALM [#f2]_. For type B devices, this event is
handled by input core; drivers should instead use
input_mt_report_slot_state(). A contact's ABS_MT_TOOL_TYPE may change over
time while still touching the device, because the firmware may not be able
to determine which tool is being used when it first appears.
event should be omitted. The protocol currently mainly supports
MT_TOOL_FINGER, MT_TOOL_PEN, and MT_TOOL_PALM [#f2]_.
For type B devices, this event is handled by input core; drivers should
instead use input_mt_report_slot_state(). A contact's ABS_MT_TOOL_TYPE may
change over time while still touching the device, because the firmware may
not be able to determine which tool is being used when it first appears.
ABS_MT_BLOB_ID
The BLOB_ID groups several packets together into one arbitrarily shaped

View File

@ -128,9 +128,19 @@ static int open_collection(struct hid_parser *parser, unsigned type)
usage = parser->local.usage[0];
if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
hid_err(parser->device, "collection stack overflow\n");
return -EINVAL;
if (parser->collection_stack_ptr == parser->collection_stack_size) {
unsigned int *collection_stack;
unsigned int new_size = parser->collection_stack_size +
HID_COLLECTION_STACK_SIZE;
collection_stack = krealloc(parser->collection_stack,
new_size * sizeof(unsigned int),
GFP_KERNEL);
if (!collection_stack)
return -ENOMEM;
parser->collection_stack = collection_stack;
parser->collection_stack_size = new_size;
}
if (parser->device->maxcollection == parser->device->collection_size) {
@ -840,6 +850,7 @@ static int hid_scan_report(struct hid_device *hid)
break;
}
kfree(parser->collection_stack);
vfree(parser);
return 0;
}

View File

@ -1550,6 +1550,9 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid,
case HID_GD_WIRELESS_RADIO_CTLS:
suffix = "Wireless Radio Control";
break;
case HID_GD_SYSTEM_MULTIAXIS:
suffix = "System Multi Axis";
break;
default:
break;
}

View File

@ -22,12 +22,13 @@
#include "hid-ids.h"
#define MS_HIDINPUT 0x01
#define MS_ERGONOMY 0x02
#define MS_PRESENTER 0x04
#define MS_RDESC 0x08
#define MS_NOGET 0x10
#define MS_DUPLICATE_USAGES 0x20
#define MS_HIDINPUT BIT(0)
#define MS_ERGONOMY BIT(1)
#define MS_PRESENTER BIT(2)
#define MS_RDESC BIT(3)
#define MS_NOGET BIT(4)
#define MS_DUPLICATE_USAGES BIT(5)
#define MS_SURFACE_DIAL BIT(6)
static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
@ -130,6 +131,30 @@ static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
return 1;
}
static int ms_surface_dial_quirk(struct hid_input *hi, struct hid_field *field,
struct hid_usage *usage, unsigned long **bit, int *max)
{
switch (usage->hid & HID_USAGE_PAGE) {
case 0xff070000:
/* fall-through */
case HID_UP_DIGITIZER:
/* ignore those axis */
return -1;
case HID_UP_GENDESK:
switch (usage->hid) {
case HID_GD_X:
/* fall-through */
case HID_GD_Y:
/* fall-through */
case HID_GD_RFKILL_BTN:
/* ignore those axis */
return -1;
}
}
return 0;
}
static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
@ -146,6 +171,13 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
ms_presenter_8k_quirk(hi, usage, bit, max))
return 1;
if (quirks & MS_SURFACE_DIAL) {
int ret = ms_surface_dial_quirk(hi, field, usage, bit, max);
if (ret)
return ret;
}
return 0;
}
@ -229,6 +261,9 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (quirks & MS_NOGET)
hdev->quirks |= HID_QUIRK_NOGET;
if (quirks & MS_SURFACE_DIAL)
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
ret = hid_parse(hdev);
if (ret) {
hid_err(hdev, "parse failed\n");
@ -281,6 +316,8 @@ static const struct hid_device_id ms_devices[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
.driver_data = MS_PRESENTER },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, 0x091B),
.driver_data = MS_SURFACE_DIAL },
{ }
};
MODULE_DEVICE_TABLE(hid, ms_devices);

File diff suppressed because it is too large Load Diff

View File

@ -190,6 +190,12 @@ struct hid_item {
* http://www.usb.org/developers/hidpage/HUTRR40RadioHIDUsagesFinal.pdf
*/
#define HID_GD_WIRELESS_RADIO_CTLS 0x0001000c
/*
* System Multi-Axis, see:
* http://www.usb.org/developers/hidpage/HUTRR62_-_Generic_Desktop_CA_for_System_Multi-Axis_Controllers.txt
*/
#define HID_GD_SYSTEM_MULTIAXIS 0x0001000e
#define HID_GD_X 0x00010030
#define HID_GD_Y 0x00010031
#define HID_GD_Z 0x00010032
@ -638,12 +644,13 @@ static inline void hid_set_drvdata(struct hid_device *hdev, void *data)
struct hid_parser {
struct hid_global global;
struct hid_global global_stack[HID_GLOBAL_STACK_SIZE];
unsigned global_stack_ptr;
unsigned int global_stack_ptr;
struct hid_local local;
unsigned collection_stack[HID_COLLECTION_STACK_SIZE];
unsigned collection_stack_ptr;
unsigned int *collection_stack;
unsigned int collection_stack_ptr;
unsigned int collection_stack_size;
struct hid_device *device;
unsigned scan_flags;
unsigned int scan_flags;
};
struct hid_class_descriptor {

View File

@ -270,10 +270,11 @@ struct input_mask {
/*
* MT_TOOL types
*/
#define MT_TOOL_FINGER 0
#define MT_TOOL_PEN 1
#define MT_TOOL_PALM 2
#define MT_TOOL_MAX 2
#define MT_TOOL_FINGER 0x00
#define MT_TOOL_PEN 0x01
#define MT_TOOL_PALM 0x02
#define MT_TOOL_DIAL 0x0a
#define MT_TOOL_MAX 0x0f
/*
* Values describing the status of a force-feedback effect