HID: Add input_register callback.
authorJaikumar Ganesh <jaikumarg@android.com>
Tue, 20 Sep 2011 23:40:43 +0000 (16:40 -0700)
committerArve Hjønnevåg <arve@android.com>
Mon, 1 Jul 2013 20:40:37 +0000 (13:40 -0700)
Add input_register callback which gets called after
hid_configure_usage is called for all the reports
and before the input device is registered. This allows
individual drivers to do extra work like input mapping just
before device registration.

Based on discussions with David Herrmann <dh.herrmann@googlemail.com>

Change-Id: Idab6fb4f7b1e5e569bd0410967288717e9d34c98
Signed-off-by: Jaikumar Ganesh <jaikumarg@android.com>
Changed to add return code to input_configured instead of
adding input_register

Signed-off-by: Arve Hjønnevåg <arve@android.com>
drivers/hid/hid-input.c
drivers/hid/hid-multitouch.c
include/linux/hid.h

index 945b8158ec4c7f556d6c9db8753762ac958276c1..4602d291c9bccfc4da523401b0a1f6aa28f73dd0 100644 (file)
@@ -1321,8 +1321,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
                                 * UGCI) cram a lot of unrelated inputs into the
                                 * same interface. */
                                hidinput->report = report;
-                               if (drv->input_configured)
-                                       drv->input_configured(hid, hidinput);
+                               if (drv->input_configured &&
+                                   drv->input_configured(hid, hidinput))
+                                       goto out_cleanup;
                                if (input_register_device(hidinput->input))
                                        goto out_cleanup;
                                hidinput = NULL;
@@ -1343,8 +1344,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
        }
 
        if (hidinput) {
-               if (drv->input_configured)
-                       drv->input_configured(hid, hidinput);
+               if (drv->input_configured &&
+                   drv->input_configured(hid, hidinput))
+                       goto out_cleanup;
                if (input_register_device(hidinput->input))
                        goto out_cleanup;
        }
index c92de0fb00928cef9b68a59c28437769f509b806..f4b77f4d5fb86c5595a32836431e3af45fcc15ce 100644 (file)
@@ -780,12 +780,13 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
                mt_sync_frame(td, report->field[0]->hidinput->input);
 }
 
-static void mt_touch_input_configured(struct hid_device *hdev,
+static int mt_touch_input_configured(struct hid_device *hdev,
                                        struct hid_input *hi)
 {
        struct mt_device *td = hid_get_drvdata(hdev);
        struct mt_class *cls = &td->mtclass;
        struct input_dev *input = hi->input;
+       int ret;
 
        if (!td->maxcontacts)
                td->maxcontacts = MT_DEFAULT_MAXCONTACT;
@@ -800,9 +801,12 @@ static void mt_touch_input_configured(struct hid_device *hdev,
        if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
                td->mt_flags |= INPUT_MT_DROP_UNUSED;
 
-       input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
+       ret = input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
+       if (ret)
+               return ret;
 
        td->mt_flags = 0;
+       return 0;
 }
 
 static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -935,19 +939,21 @@ static void mt_post_parse(struct mt_device *td)
                cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
 }
 
-static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
+static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
 {
        struct mt_device *td = hid_get_drvdata(hdev);
        char *name = kstrdup(hdev->name, GFP_KERNEL);
+       int ret = 0;
 
        if (name)
                hi->input->name = name;
 
        if (hi->report->id == td->mt_report_id)
-               mt_touch_input_configured(hdev, hi);
+               ret = mt_touch_input_configured(hdev, hi);
 
        if (hi->report->id == td->pen_report_id)
                mt_pen_input_configured(hdev, hi);
+       return ret;
 }
 
 static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
index 0c48991b0402d0d93110b8a4fa9cd42d615279c2..8136c6d99037aabcbc0bbedee22a23e9b557ce7d 100644 (file)
@@ -647,8 +647,8 @@ struct hid_driver {
        int (*input_mapped)(struct hid_device *hdev,
                        struct hid_input *hidinput, struct hid_field *field,
                        struct hid_usage *usage, unsigned long **bit, int *max);
-       void (*input_configured)(struct hid_device *hdev,
-                                struct hid_input *hidinput);
+       int (*input_configured)(struct hid_device *hdev,
+                               struct hid_input *hidinput);
        void (*feature_mapping)(struct hid_device *hdev,
                        struct hid_field *field,
                        struct hid_usage *usage);