summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2018-04-24 04:04:33 -0400
committerJiri Kosina <jkosina@suse.cz>2018-04-26 08:17:31 -0400
commitf07b3c1da92db108662f99417a212fc1eddc44d1 (patch)
treed4ad0e580dfab744d34460c80a361e78c7ff47dd
parente1b63c0148a7f8edf1691770ec0527fe86fb6ab8 (diff)
HID: generic: create one input report per application type
It is not a good idea to try to fit all types of applications in the same input report. There are a lot of devices that are needing the quirk HID_MULTI_INPUT but this quirk doesn't match the actual HID description as it is based on the report ID. Given that most devices with MULTI_INPUT I can think of split nicely the devices inputs into application, it is a good thing to split the devices by default based on this assumption. Also make hid-multitouch following this rule, to not have to deal with too many input created. While we are at it, fix some checkpatch complaints about converting 'unsigned' to 'unsigned int'. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-core.c19
-rw-r--r--drivers/hid/hid-generic.c15
-rw-r--r--drivers/hid/hid-gfrm.c2
-rw-r--r--drivers/hid/hid-input.c17
-rw-r--r--drivers/hid/hid-magicmouse.c6
-rw-r--r--include/linux/hid.h10
6 files changed, 56 insertions, 13 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5d7cc6bbbac6..68819106f4fc 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -57,7 +57,9 @@ MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle
57 * Register a new report for a device. 57 * Register a new report for a device.
58 */ 58 */
59 59
60struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) 60struct hid_report *hid_register_report(struct hid_device *device,
61 unsigned int type, unsigned int id,
62 unsigned int application)
61{ 63{
62 struct hid_report_enum *report_enum = device->report_enum + type; 64 struct hid_report_enum *report_enum = device->report_enum + type;
63 struct hid_report *report; 65 struct hid_report *report;
@@ -78,6 +80,7 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type,
78 report->type = type; 80 report->type = type;
79 report->size = 0; 81 report->size = 0;
80 report->device = device; 82 report->device = device;
83 report->application = application;
81 report_enum->report_id_hash[id] = report; 84 report_enum->report_id_hash[id] = report;
82 85
83 list_add_tail(&report->list, &report_enum->report_list); 86 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
221{ 224{
222 struct hid_report *report; 225 struct hid_report *report;
223 struct hid_field *field; 226 struct hid_field *field;
224 unsigned usages; 227 unsigned int usages;
225 unsigned offset; 228 unsigned int offset;
226 unsigned i; 229 unsigned int i;
230 unsigned int application;
231
232 application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
227 233
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);
229 if (!report) { 236 if (!report) {
230 hid_err(parser->device, "hid_register_report failed\n"); 237 hid_err(parser->device, "hid_register_report failed\n");
231 return -1; 238 return -1;
@@ -259,7 +266,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
259 266
260 field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); 267 field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);
261 field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); 268 field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL);
262 field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); 269 field->application = application;
263 270
264 for (i = 0; i < usages; i++) { 271 for (i = 0; i < usages; i++) {
265 unsigned j = i; 272 unsigned j = i;
diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c
index c25b4718de44..3b6eccbc2519 100644
--- a/drivers/hid/hid-generic.c
+++ b/drivers/hid/hid-generic.c
@@ -56,6 +56,20 @@ static bool hid_generic_match(struct hid_device *hdev,
56 return true; 56 return true;
57} 57}
58 58
59static 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
59static const struct hid_device_id hid_table[] = { 73static const struct hid_device_id hid_table[] = {
60 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) }, 74 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) },
61 { } 75 { }
@@ -66,6 +80,7 @@ static struct hid_driver hid_generic = {
66 .name = "hid-generic", 80 .name = "hid-generic",
67 .id_table = hid_table, 81 .id_table = hid_table,
68 .match = hid_generic_match, 82 .match = hid_generic_match,
83 .probe = hid_generic_probe,
69}; 84};
70module_hid_driver(hid_generic); 85module_hid_driver(hid_generic);
71 86
diff --git a/drivers/hid/hid-gfrm.c b/drivers/hid/hid-gfrm.c
index 075b1c020846..cf477f8c8f4c 100644
--- a/drivers/hid/hid-gfrm.c
+++ b/drivers/hid/hid-gfrm.c
@@ -116,7 +116,7 @@ static int gfrm_probe(struct hid_device *hdev, const struct hid_device_id *id)
116 * those reports reach gfrm_raw_event() from hid_input_report(). 116 * those reports reach gfrm_raw_event() from hid_input_report().
117 */ 117 */
118 if (!hid_register_report(hdev, HID_INPUT_REPORT, 118 if (!hid_register_report(hdev, HID_INPUT_REPORT,
119 GFRM100_SEARCH_KEY_REPORT_ID)) { 119 GFRM100_SEARCH_KEY_REPORT_ID, 0)) {
120 ret = -ENOMEM; 120 ret = -ENOMEM;
121 goto done; 121 goto done;
122 } 122 }
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index fd1c4fe70327..7463ee2a1df2 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1610,6 +1610,20 @@ static struct hid_input *hidinput_match(struct hid_report *report)
1610 return NULL; 1610 return NULL;
1611} 1611}
1612 1612
1613static struct hid_input *hidinput_match_application(struct hid_report *report)
1614{
1615 struct hid_device *hid = report->device;
1616 struct hid_input *hidinput;
1617
1618 list_for_each_entry(hidinput, &hid->inputs, list) {
1619 if (hidinput->report &&
1620 hidinput->report->application == report->application)
1621 return hidinput;
1622 }
1623
1624 return NULL;
1625}
1626
1613static inline void hidinput_configure_usages(struct hid_input *hidinput, 1627static inline void hidinput_configure_usages(struct hid_input *hidinput,
1614 struct hid_report *report) 1628 struct hid_report *report)
1615{ 1629{
@@ -1670,6 +1684,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1670 */ 1684 */
1671 if (hid->quirks & HID_QUIRK_MULTI_INPUT) 1685 if (hid->quirks & HID_QUIRK_MULTI_INPUT)
1672 hidinput = hidinput_match(report); 1686 hidinput = hidinput_match(report);
1687 else if (hid->maxapplication > 1 &&
1688 (hid->quirks & HID_QUIRK_INPUT_PER_APP))
1689 hidinput = hidinput_match_application(report);
1673 1690
1674 if (!hidinput) { 1691 if (!hidinput) {
1675 hidinput = hidinput_allocate(hid); 1692 hidinput = hidinput_allocate(hid);
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 42ed887ba0be..b454c4386157 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -531,12 +531,12 @@ static int magicmouse_probe(struct hid_device *hdev,
531 531
532 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) 532 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
533 report = hid_register_report(hdev, HID_INPUT_REPORT, 533 report = hid_register_report(hdev, HID_INPUT_REPORT,
534 MOUSE_REPORT_ID); 534 MOUSE_REPORT_ID, 0);
535 else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 535 else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
536 report = hid_register_report(hdev, HID_INPUT_REPORT, 536 report = hid_register_report(hdev, HID_INPUT_REPORT,
537 TRACKPAD_REPORT_ID); 537 TRACKPAD_REPORT_ID, 0);
538 report = hid_register_report(hdev, HID_INPUT_REPORT, 538 report = hid_register_report(hdev, HID_INPUT_REPORT,
539 DOUBLE_REPORT_ID); 539 DOUBLE_REPORT_ID, 0);
540 } 540 }
541 541
542 if (!report) { 542 if (!report) {
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 396068ccc197..bcc91bfdd2cb 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -341,6 +341,7 @@ struct hid_item {
341/* BIT(8) reserved for backward compatibility, was HID_QUIRK_NO_EMPTY_INPUT */ 341/* BIT(8) reserved for backward compatibility, was HID_QUIRK_NO_EMPTY_INPUT */
342/* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */ 342/* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
343#define HID_QUIRK_ALWAYS_POLL BIT(10) 343#define HID_QUIRK_ALWAYS_POLL BIT(10)
344#define HID_QUIRK_INPUT_PER_APP BIT(11)
344#define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16) 345#define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16)
345#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17) 346#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17)
346#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18) 347#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
@@ -465,8 +466,9 @@ struct hid_field {
465struct hid_report { 466struct hid_report {
466 struct list_head list; 467 struct list_head list;
467 struct list_head hidinput_list; 468 struct list_head hidinput_list;
468 unsigned id; /* id of this report */ 469 unsigned int id; /* id of this report */
469 unsigned type; /* report type */ 470 unsigned int type; /* report type */
471 unsigned int application; /* application usage for this report */
470 struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */ 472 struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
471 unsigned maxfield; /* maximum valid field index */ 473 unsigned maxfield; /* maximum valid field index */
472 unsigned size; /* size of the report (bits) */ 474 unsigned size; /* size of the report (bits) */
@@ -861,7 +863,9 @@ void hid_output_report(struct hid_report *report, __u8 *data);
861void __hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype); 863void __hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype);
862u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags); 864u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
863struct hid_device *hid_allocate_device(void); 865struct hid_device *hid_allocate_device(void);
864struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); 866struct hid_report *hid_register_report(struct hid_device *device,
867 unsigned int type, unsigned int id,
868 unsigned int application);
865int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); 869int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
866struct hid_report *hid_validate_values(struct hid_device *hid, 870struct hid_report *hid_validate_values(struct hid_device *hid,
867 unsigned int type, unsigned int id, 871 unsigned int type, unsigned int id,