]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
HID: core: add helper for finding a field with a certain usage
authorKerem Karabay <kekrby@gmail.com>
Fri, 5 Jul 2024 11:17:42 +0000 (11:17 +0000)
committerJiri Kosina <jkosina@suse.com>
Fri, 2 Aug 2024 10:42:23 +0000 (12:42 +0200)
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.

Convert google-hammer driver to use it, and remove now superfluous
hammer_has_usage().

[jkosina@suse.com: expand changelog with the information about
 google-hammer being added as user of this API ]
Signed-off-by: Kerem Karabay <kekrby@gmail.com>
Signed-off-by: Aditya Garg <gargaditya08@live.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/hid-core.c
drivers/hid/hid-google-hammer.c
include/linux/hid.h

index 988d0acbdf04dd80385421a6b43e96153bce60d7..caeba5487b69bd2a11888d4ace601962126f54fd 100644 (file)
@@ -1912,6 +1912,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)
 {
index 6e4ebc349e4526c0c0e44ae277bb0ed74dcc2b93..4e79fafeeafa8966a67067c9c214fbee590b2b72 100644 (file)
@@ -418,38 +418,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);
 }
 
index 1533c9dcd3a67fa3523ef97d8d60880c70f338bf..2deff79f39a1506a145b0d064cad326f374de9a8 100644 (file)
@@ -940,6 +940,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);