HID: Do not create input devices for feature reports
authorHenrik Rydberg <rydberg@euromail.se>
Thu, 24 Feb 2011 18:30:59 +0000 (19:30 +0100)
committerJiri Kosina <jkosina@suse.cz>
Tue, 1 Mar 2011 16:25:39 +0000 (17:25 +0100)
When the multi input quirk is set, there is a new input device
created for every feature report. Since the idea is to present
features per hid device, not per input device, revert back to
the original report loop and change the feature_mapping() callback
to not take the input device as argument.

Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Tested-by: Benjamin Tissoires <benjmain.tissoires@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/hid-input.c
drivers/hid/hid-multitouch.c
include/linux/hid.h

index 7f552bfad32c01a26bb52a239175a801754103bd..ebcc02a1c1c94c8b80bbcc4608a249e8da855d1d 100644 (file)
@@ -290,14 +290,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                goto ignore;
        }
 
-       if (field->report_type == HID_FEATURE_REPORT) {
-               if (device->driver->feature_mapping) {
-                       device->driver->feature_mapping(device, hidinput, field,
-                               usage);
-               }
-               goto ignore;
-       }
-
        if (device->driver->input_mapping) {
                int ret = device->driver->input_mapping(device, hidinput, field,
                                usage, &bit, &max);
@@ -835,6 +827,24 @@ static void hidinput_close(struct input_dev *dev)
        hid_hw_close(hid);
 }
 
+static void report_features(struct hid_device *hid)
+{
+       struct hid_driver *drv = hid->driver;
+       struct hid_report_enum *rep_enum;
+       struct hid_report *rep;
+       int i, j;
+
+       if (!drv->feature_mapping)
+               return;
+
+       rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
+       list_for_each_entry(rep, &rep_enum->report_list, list)
+               for (i = 0; i < rep->maxfield; i++)
+                       for (j = 0; j < rep->field[i]->maxusage; j++)
+                               drv->feature_mapping(hid, rep->field[i],
+                                                    rep->field[i]->usage + j);
+}
+
 /*
  * Register the input device; print a message.
  * Configure the input layer interface
@@ -863,7 +873,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
                        return -1;
        }
 
-       for (k = HID_INPUT_REPORT; k <= HID_FEATURE_REPORT; k++) {
+       report_features(hid);
+
+       for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
                if (k == HID_OUTPUT_REPORT &&
                        hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
                        continue;
index 07d3183fdde50ca4fd3a57807e727b73094b3e6b..2bbc9545f5ccd9f331026f827906efcf021515bd 100644 (file)
@@ -122,7 +122,7 @@ struct mt_class mt_classes[] = {
        { }
 };
 
-static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi,
+static void mt_feature_mapping(struct hid_device *hdev,
                struct hid_field *field, struct hid_usage *usage)
 {
        if (usage->hid == HID_DG_INPUTMODE) {
index d91c25e253c87e8f940e34d31d1eee854e7ce4bb..fc5faf60f6df45213f41b4a6d2039274e6a9bb0f 100644 (file)
@@ -638,7 +638,7 @@ struct hid_driver {
                        struct hid_input *hidinput, struct hid_field *field,
                        struct hid_usage *usage, unsigned long **bit, int *max);
        void (*feature_mapping)(struct hid_device *hdev,
-                       struct hid_input *hidinput, struct hid_field *field,
+                       struct hid_field *field,
                        struct hid_usage *usage);
 #ifdef CONFIG_PM
        int (*suspend)(struct hid_device *hdev, pm_message_t message);