Skip to content

Commit f07b3c1

Browse files
bentissJiri Kosina
authored andcommitted
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 <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent e1b63c0 commit f07b3c1

File tree

6 files changed

+56
-13
lines changed

6 files changed

+56
-13
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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,6 +1610,20 @@ static struct hid_input *hidinput_match(struct hid_report *report)
16101610
return NULL;
16111611
}
16121612

1613+
static 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+
16131627
static inline void hidinput_configure_usages(struct hid_input *hidinput,
16141628
struct hid_report *report)
16151629
{
@@ -1670,6 +1684,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
16701684
*/
16711685
if (hid->quirks & HID_QUIRK_MULTI_INPUT)
16721686
hidinput = hidinput_match(report);
1687+
else if (hid->maxapplication > 1 &&
1688+
(hid->quirks & HID_QUIRK_INPUT_PER_APP))
1689+
hidinput = hidinput_match_application(report);
16731690

16741691
if (!hidinput) {
16751692
hidinput = hidinput_allocate(hid);

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) {

include/linux/hid.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ struct hid_item {
341341
/* BIT(8) reserved for backward compatibility, was HID_QUIRK_NO_EMPTY_INPUT */
342342
/* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
343343
#define HID_QUIRK_ALWAYS_POLL BIT(10)
344+
#define HID_QUIRK_INPUT_PER_APP BIT(11)
344345
#define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16)
345346
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17)
346347
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
@@ -465,8 +466,9 @@ struct hid_field {
465466
struct hid_report {
466467
struct list_head list;
467468
struct list_head hidinput_list;
468-
unsigned id; /* id of this report */
469-
unsigned type; /* report type */
469+
unsigned int id; /* id of this report */
470+
unsigned int type; /* report type */
471+
unsigned int application; /* application usage for this report */
470472
struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
471473
unsigned maxfield; /* maximum valid field index */
472474
unsigned size; /* size of the report (bits) */
@@ -861,7 +863,9 @@ void hid_output_report(struct hid_report *report, __u8 *data);
861863
void __hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype);
862864
u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
863865
struct hid_device *hid_allocate_device(void);
864-
struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
866+
struct hid_report *hid_register_report(struct hid_device *device,
867+
unsigned int type, unsigned int id,
868+
unsigned int application);
865869
int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
866870
struct hid_report *hid_validate_values(struct hid_device *hid,
867871
unsigned int type, unsigned int id,

0 commit comments

Comments
 (0)