-
Notifications
You must be signed in to change notification settings - Fork 11
/
1004-HID-core-add-helper-for-finding-a-field-with-a-certa.patch
115 lines (106 loc) · 3.71 KB
/
1004-HID-core-add-helper-for-finding-a-field-with-a-certa.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
From 75ca57b64ce6846622d8aefac5a76fc638a2123d Mon Sep 17 00:00:00 2001
From: Kerem Karabay <[email protected]>
Date: Sun, 5 Mar 2023 19:12:53 +0300
Subject: [PATCH 01/12] HID: core: add helper for finding a field with a
certain usage
This helper will allow HID drivers to easily determine if they should
bind to a hid_device by checking for the prescence of a certain field
when its ID is not enough, which can be the case on USB devices with
multiple interfaces and/or configurations.
Signed-off-by: Kerem Karabay <[email protected]>
---
drivers/hid/hid-core.c | 25 +++++++++++++++++++++++++
drivers/hid/hid-google-hammer.c | 27 ++-------------------------
include/linux/hid.h | 2 ++
3 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8992e3c1e..6395bdc2e 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1906,6 +1906,31 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
}
EXPORT_SYMBOL_GPL(hid_set_field);
+struct hid_field *hid_find_field(struct hid_device *hdev, unsigned int report_type,
+ unsigned int application, unsigned int usage)
+{
+ struct list_head *report_list = &hdev->report_enum[report_type].report_list;
+ struct hid_report *report;
+ int i, j;
+
+ list_for_each_entry(report, report_list, list) {
+ if (report->application != application)
+ continue;
+
+ for (i = 0; i < report->maxfield; i++) {
+ struct hid_field *field = report->field[i];
+
+ for (j = 0; j < field->maxusage; j++) {
+ if (field->usage[j].hid == usage)
+ return field;
+ }
+ }
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(hid_find_field);
+
static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
const u8 *data)
{
diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c
index c6bdb9c4e..fba3652aa 100644
--- a/drivers/hid/hid-google-hammer.c
+++ b/drivers/hid/hid-google-hammer.c
@@ -419,38 +419,15 @@ static int hammer_event(struct hid_device *hid, struct hid_field *field,
return 0;
}
-static bool hammer_has_usage(struct hid_device *hdev, unsigned int report_type,
- unsigned application, unsigned usage)
-{
- struct hid_report_enum *re = &hdev->report_enum[report_type];
- struct hid_report *report;
- int i, j;
-
- list_for_each_entry(report, &re->report_list, list) {
- if (report->application != application)
- continue;
-
- for (i = 0; i < report->maxfield; i++) {
- struct hid_field *field = report->field[i];
-
- for (j = 0; j < field->maxusage; j++)
- if (field->usage[j].hid == usage)
- return true;
- }
- }
-
- return false;
-}
-
static bool hammer_has_folded_event(struct hid_device *hdev)
{
- return hammer_has_usage(hdev, HID_INPUT_REPORT,
+ return !!hid_find_field(hdev, HID_INPUT_REPORT,
HID_GD_KEYBOARD, HID_USAGE_KBD_FOLDED);
}
static bool hammer_has_backlight_control(struct hid_device *hdev)
{
- return hammer_has_usage(hdev, HID_OUTPUT_REPORT,
+ return !!hid_find_field(hdev, HID_OUTPUT_REPORT,
HID_GD_KEYBOARD, HID_AD_BRIGHTNESS);
}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 39e21e381..9520fdfdd 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -913,6 +913,8 @@ extern void hidinput_report_event(struct hid_device *hid, struct hid_report *rep
extern int hidinput_connect(struct hid_device *hid, unsigned int force);
extern void hidinput_disconnect(struct hid_device *);
+struct hid_field *hid_find_field(struct hid_device *hdev, unsigned int report_type,
+ unsigned int application, unsigned int usage);
int hid_set_field(struct hid_field *, unsigned, __s32);
int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
int interrupt);
--
2.42.0