Skip to content

Commit 25721ae

Browse files
author
Jiri Kosina
committed
Merge branch 'for-4.18/multitouch' into for-linus
- improvement of duplicate usage handling in hid-input from Benjamin Tissoires - Win 8.1 precisioun touchpad spec implementation from Benjamin Tissoires
2 parents 72d0beb + abb36fe commit 25721ae

File tree

7 files changed

+281
-134
lines changed

7 files changed

+281
-134
lines changed

drivers/hid/hid-core.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle
5757
* Register a new report for a device.
5858
*/
5959

60-
struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id)
60+
struct hid_report *hid_register_report(struct hid_device *device,
61+
unsigned int type, unsigned int id,
62+
unsigned int application)
6163
{
6264
struct hid_report_enum *report_enum = device->report_enum + type;
6365
struct hid_report *report;
@@ -78,6 +80,7 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type,
7880
report->type = type;
7981
report->size = 0;
8082
report->device = device;
83+
report->application = application;
8184
report_enum->report_id_hash[id] = report;
8285

8386
list_add_tail(&report->list, &report_enum->report_list);
@@ -221,11 +224,15 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
221224
{
222225
struct hid_report *report;
223226
struct hid_field *field;
224-
unsigned usages;
225-
unsigned offset;
226-
unsigned i;
227+
unsigned int usages;
228+
unsigned int offset;
229+
unsigned int i;
230+
unsigned int application;
231+
232+
application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
227233

228-
report = hid_register_report(parser->device, report_type, parser->global.report_id);
234+
report = hid_register_report(parser->device, report_type,
235+
parser->global.report_id, application);
229236
if (!report) {
230237
hid_err(parser->device, "hid_register_report failed\n");
231238
return -1;
@@ -259,7 +266,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
259266

260267
field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);
261268
field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL);
262-
field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
269+
field->application = application;
263270

264271
for (i = 0; i < usages; i++) {
265272
unsigned j = i;

drivers/hid/hid-generic.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,20 @@ static bool hid_generic_match(struct hid_device *hdev,
5656
return true;
5757
}
5858

59+
static int hid_generic_probe(struct hid_device *hdev,
60+
const struct hid_device_id *id)
61+
{
62+
int ret;
63+
64+
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
65+
66+
ret = hid_parse(hdev);
67+
if (ret)
68+
return ret;
69+
70+
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
71+
}
72+
5973
static const struct hid_device_id hid_table[] = {
6074
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) },
6175
{ }
@@ -66,6 +80,7 @@ static struct hid_driver hid_generic = {
6680
.name = "hid-generic",
6781
.id_table = hid_table,
6882
.match = hid_generic_match,
83+
.probe = hid_generic_probe,
6984
};
7085
module_hid_driver(hid_generic);
7186

drivers/hid/hid-gfrm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ static int gfrm_probe(struct hid_device *hdev, const struct hid_device_id *id)
116116
* those reports reach gfrm_raw_event() from hid_input_report().
117117
*/
118118
if (!hid_register_report(hdev, HID_INPUT_REPORT,
119-
GFRM100_SEARCH_KEY_REPORT_ID)) {
119+
GFRM100_SEARCH_KEY_REPORT_ID, 0)) {
120120
ret = -ENOMEM;
121121
goto done;
122122
}

drivers/hid/hid-input.c

Lines changed: 113 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,8 +1110,31 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
11101110

11111111
set_bit(usage->type, input->evbit);
11121112

1113-
while (usage->code <= max && test_and_set_bit(usage->code, bit))
1114-
usage->code = find_next_zero_bit(bit, max + 1, usage->code);
1113+
/*
1114+
* This part is *really* controversial:
1115+
* - HID aims at being generic so we should do our best to export
1116+
* all incoming events
1117+
* - HID describes what events are, so there is no reason for ABS_X
1118+
* to be mapped to ABS_Y
1119+
* - HID is using *_MISC+N as a default value, but nothing prevents
1120+
* *_MISC+N to overwrite a legitimate even, which confuses userspace
1121+
* (for instance ABS_MISC + 7 is ABS_MT_SLOT, which has a different
1122+
* processing)
1123+
*
1124+
* If devices still want to use this (at their own risk), they will
1125+
* have to use the quirk HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE, but
1126+
* the default should be a reliable mapping.
1127+
*/
1128+
while (usage->code <= max && test_and_set_bit(usage->code, bit)) {
1129+
if (device->quirks & HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE) {
1130+
usage->code = find_next_zero_bit(bit,
1131+
max + 1,
1132+
usage->code);
1133+
} else {
1134+
device->status |= HID_STAT_DUP_DETECTED;
1135+
goto ignore;
1136+
}
1137+
}
11151138

11161139
if (usage->code > max)
11171140
goto ignore;
@@ -1487,15 +1510,56 @@ static void report_features(struct hid_device *hid)
14871510
}
14881511
}
14891512

1490-
static struct hid_input *hidinput_allocate(struct hid_device *hid)
1513+
static struct hid_input *hidinput_allocate(struct hid_device *hid,
1514+
unsigned int application)
14911515
{
14921516
struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
14931517
struct input_dev *input_dev = input_allocate_device();
1494-
if (!hidinput || !input_dev) {
1495-
kfree(hidinput);
1496-
input_free_device(input_dev);
1497-
hid_err(hid, "Out of memory during hid input probe\n");
1498-
return NULL;
1518+
const char *suffix = NULL;
1519+
1520+
if (!hidinput || !input_dev)
1521+
goto fail;
1522+
1523+
if ((hid->quirks & HID_QUIRK_INPUT_PER_APP) &&
1524+
hid->maxapplication > 1) {
1525+
switch (application) {
1526+
case HID_GD_KEYBOARD:
1527+
suffix = "Keyboard";
1528+
break;
1529+
case HID_GD_KEYPAD:
1530+
suffix = "Keypad";
1531+
break;
1532+
case HID_GD_MOUSE:
1533+
suffix = "Mouse";
1534+
break;
1535+
case HID_DG_STYLUS:
1536+
suffix = "Pen";
1537+
break;
1538+
case HID_DG_TOUCHSCREEN:
1539+
suffix = "Touchscreen";
1540+
break;
1541+
case HID_DG_TOUCHPAD:
1542+
suffix = "Touchpad";
1543+
break;
1544+
case HID_GD_SYSTEM_CONTROL:
1545+
suffix = "System Control";
1546+
break;
1547+
case HID_CP_CONSUMER_CONTROL:
1548+
suffix = "Consumer Control";
1549+
break;
1550+
case HID_GD_WIRELESS_RADIO_CTLS:
1551+
suffix = "Wireless Radio Control";
1552+
break;
1553+
default:
1554+
break;
1555+
}
1556+
}
1557+
1558+
if (suffix) {
1559+
hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
1560+
hid->name, suffix);
1561+
if (!hidinput->name)
1562+
goto fail;
14991563
}
15001564

15011565
input_set_drvdata(input_dev, hid);
@@ -1505,18 +1569,27 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
15051569
input_dev->setkeycode = hidinput_setkeycode;
15061570
input_dev->getkeycode = hidinput_getkeycode;
15071571

1508-
input_dev->name = hid->name;
1572+
input_dev->name = hidinput->name ? hidinput->name : hid->name;
15091573
input_dev->phys = hid->phys;
15101574
input_dev->uniq = hid->uniq;
15111575
input_dev->id.bustype = hid->bus;
15121576
input_dev->id.vendor = hid->vendor;
15131577
input_dev->id.product = hid->product;
15141578
input_dev->id.version = hid->version;
15151579
input_dev->dev.parent = &hid->dev;
1580+
15161581
hidinput->input = input_dev;
15171582
list_add_tail(&hidinput->list, &hid->inputs);
15181583

1584+
INIT_LIST_HEAD(&hidinput->reports);
1585+
15191586
return hidinput;
1587+
1588+
fail:
1589+
kfree(hidinput);
1590+
input_free_device(input_dev);
1591+
hid_err(hid, "Out of memory during hid input probe\n");
1592+
return NULL;
15201593
}
15211594

15221595
static bool hidinput_has_been_populated(struct hid_input *hidinput)
@@ -1562,6 +1635,7 @@ static void hidinput_cleanup_hidinput(struct hid_device *hid,
15621635

15631636
list_del(&hidinput->list);
15641637
input_free_device(hidinput->input);
1638+
kfree(hidinput->name);
15651639

15661640
for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
15671641
if (k == HID_OUTPUT_REPORT &&
@@ -1594,6 +1668,20 @@ static struct hid_input *hidinput_match(struct hid_report *report)
15941668
return NULL;
15951669
}
15961670

1671+
static struct hid_input *hidinput_match_application(struct hid_report *report)
1672+
{
1673+
struct hid_device *hid = report->device;
1674+
struct hid_input *hidinput;
1675+
1676+
list_for_each_entry(hidinput, &hid->inputs, list) {
1677+
if (hidinput->report &&
1678+
hidinput->report->application == report->application)
1679+
return hidinput;
1680+
}
1681+
1682+
return NULL;
1683+
}
1684+
15971685
static inline void hidinput_configure_usages(struct hid_input *hidinput,
15981686
struct hid_report *report)
15991687
{
@@ -1616,11 +1704,14 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
16161704
struct hid_driver *drv = hid->driver;
16171705
struct hid_report *report;
16181706
struct hid_input *next, *hidinput = NULL;
1707+
unsigned int application;
16191708
int i, k;
16201709

16211710
INIT_LIST_HEAD(&hid->inputs);
16221711
INIT_WORK(&hid->led_work, hidinput_led_worker);
16231712

1713+
hid->status &= ~HID_STAT_DUP_DETECTED;
1714+
16241715
if (!force) {
16251716
for (i = 0; i < hid->maxcollection; i++) {
16261717
struct hid_collection *col = &hid->collection[i];
@@ -1646,15 +1737,20 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
16461737
if (!report->maxfield)
16471738
continue;
16481739

1740+
application = report->application;
1741+
16491742
/*
16501743
* Find the previous hidinput report attached
16511744
* to this report id.
16521745
*/
16531746
if (hid->quirks & HID_QUIRK_MULTI_INPUT)
16541747
hidinput = hidinput_match(report);
1748+
else if (hid->maxapplication > 1 &&
1749+
(hid->quirks & HID_QUIRK_INPUT_PER_APP))
1750+
hidinput = hidinput_match_application(report);
16551751

16561752
if (!hidinput) {
1657-
hidinput = hidinput_allocate(hid);
1753+
hidinput = hidinput_allocate(hid, application);
16581754
if (!hidinput)
16591755
goto out_unwind;
16601756
}
@@ -1663,6 +1759,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
16631759

16641760
if (hid->quirks & HID_QUIRK_MULTI_INPUT)
16651761
hidinput->report = report;
1762+
1763+
list_add_tail(&report->hidinput_list,
1764+
&hidinput->reports);
16661765
}
16671766
}
16681767

@@ -1687,6 +1786,10 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
16871786
goto out_unwind;
16881787
}
16891788

1789+
if (hid->status & HID_STAT_DUP_DETECTED)
1790+
hid_dbg(hid,
1791+
"Some usages could not be mapped, please use HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE if this is legitimate.\n");
1792+
16901793
return 0;
16911794

16921795
out_unwind:

drivers/hid/hid-magicmouse.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,12 +531,12 @@ static int magicmouse_probe(struct hid_device *hdev,
531531

532532
if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
533533
report = hid_register_report(hdev, HID_INPUT_REPORT,
534-
MOUSE_REPORT_ID);
534+
MOUSE_REPORT_ID, 0);
535535
else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
536536
report = hid_register_report(hdev, HID_INPUT_REPORT,
537-
TRACKPAD_REPORT_ID);
537+
TRACKPAD_REPORT_ID, 0);
538538
report = hid_register_report(hdev, HID_INPUT_REPORT,
539-
DOUBLE_REPORT_ID);
539+
DOUBLE_REPORT_ID, 0);
540540
}
541541

542542
if (!report) {

0 commit comments

Comments
 (0)