int left_button_state;  /* left button state */
        unsigned last_slot_field;       /* the last field of a slot */
        unsigned mt_report_id;  /* the report ID of the multitouch device */
-       __s16 inputmode;        /* InputMode HID feature, -1 if non-existent */
-       __s16 inputmode_index;  /* InputMode HID feature index in the report */
-       __s16 maxcontact_report_id;     /* Maximum Contact Number HID feature,
-                                  -1 if non-existent */
-       __u8 inputmode_value;  /* InputMode HID feature value */
+       __u8 inputmode_value;   /* InputMode HID feature value */
        __u8 num_received;      /* how many contacts we received */
        __u8 num_expected;      /* expected last contact index */
        __u8 maxcontacts;
        struct mt_device *td = hid_get_drvdata(hdev);
 
        switch (usage->hid) {
-       case HID_DG_INPUTMODE:
-               /* Ignore if value index is out of bounds. */
-               if (usage->usage_index >= field->report_count) {
-                       dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n");
-                       break;
-               }
-
-               if (td->inputmode < 0) {
-                       td->inputmode = field->report->id;
-                       td->inputmode_index = usage->usage_index;
-               } else {
-                       /*
-                        * Some elan panels wrongly declare 2 input mode
-                        * features, and silently ignore when we set the
-                        * value in the second field. Skip the second feature
-                        * and hope for the best.
-                        */
-                       dev_info(&hdev->dev,
-                                "Ignoring the extra HID_DG_INPUTMODE\n");
-               }
-
-               break;
        case HID_DG_CONTACTMAX:
                mt_get_feature(hdev, field->report);
 
-               td->maxcontact_report_id = field->report->id;
                td->maxcontacts = field->value[0];
                if (!td->maxcontacts &&
                    field->logical_maximum <= MT_MAX_MAXCONTACT)
                input_sync(field->hidinput->input);
 }
 
-static void mt_set_input_mode(struct hid_device *hdev)
+static bool mt_need_to_apply_feature(struct hid_device *hdev,
+                                    struct hid_field *field,
+                                    struct hid_usage *usage)
 {
        struct mt_device *td = hid_get_drvdata(hdev);
-       struct hid_report *r;
-       struct hid_report_enum *re;
        struct mt_class *cls = &td->mtclass;
+       struct hid_report *report = field->report;
+       unsigned int index = usage->usage_index;
        char *buf;
        u32 report_len;
+       int max;
 
-       if (td->inputmode < 0)
-               return;
-
-       re = &(hdev->report_enum[HID_FEATURE_REPORT]);
-       r = re->report_id_hash[td->inputmode];
-       if (r) {
+       switch (usage->hid) {
+       case HID_DG_INPUTMODE:
                if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
-                       report_len = hid_report_len(r);
-                       buf = hid_alloc_report_buf(r, GFP_KERNEL);
+                       report_len = hid_report_len(report);
+                       buf = hid_alloc_report_buf(report, GFP_KERNEL);
                        if (!buf) {
-                               hid_err(hdev, "failed to allocate buffer for report\n");
-                               return;
+                               hid_err(hdev,
+                                       "failed to allocate buffer for report\n");
+                               return false;
                        }
-                       hid_hw_raw_request(hdev, r->id, buf, report_len,
+                       hid_hw_raw_request(hdev, report->id, buf, report_len,
                                           HID_FEATURE_REPORT,
                                           HID_REQ_GET_REPORT);
                        kfree(buf);
                }
-               r->field[0]->value[td->inputmode_index] = td->inputmode_value;
-               hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
-       }
-}
 
-static void mt_set_maxcontacts(struct hid_device *hdev)
-{
-       struct mt_device *td = hid_get_drvdata(hdev);
-       struct hid_report *r;
-       struct hid_report_enum *re;
-       int fieldmax, max;
+               field->value[index] = td->inputmode_value;
+               return true;
 
-       if (td->maxcontact_report_id < 0)
-               return;
+       case HID_DG_CONTACTMAX:
+               if (td->mtclass.maxcontacts) {
+                       max = min_t(int, field->logical_maximum,
+                                   td->mtclass.maxcontacts);
+                       if (field->value[index] != max) {
+                               field->value[index] = max;
+                               return true;
+                       }
+               }
+               break;
+       }
 
-       if (!td->mtclass.maxcontacts)
-               return;
+       return false; /* no need to update the report */
+}
 
-       re = &hdev->report_enum[HID_FEATURE_REPORT];
-       r = re->report_id_hash[td->maxcontact_report_id];
-       if (r) {
-               max = td->mtclass.maxcontacts;
-               fieldmax = r->field[0]->logical_maximum;
-               max = min(fieldmax, max);
-               if (r->field[0]->value[0] != max) {
-                       r->field[0]->value[0] = max;
-                       hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
+static void mt_set_modes(struct hid_device *hdev)
+{
+       struct hid_report_enum *rep_enum;
+       struct hid_report *rep;
+       struct hid_usage *usage;
+       int i, j;
+       bool update_report;
+
+       rep_enum = &hdev->report_enum[HID_FEATURE_REPORT];
+       list_for_each_entry(rep, &rep_enum->report_list, list) {
+               update_report = false;
+
+               for (i = 0; i < rep->maxfield; i++) {
+                       /* Ignore if report count is out of bounds. */
+                       if (rep->field[i]->report_count < 1)
+                               continue;
+
+                       for (j = 0; j < rep->field[i]->maxusage; j++) {
+                               usage = &rep->field[i]->usage[j];
+
+                               if (mt_need_to_apply_feature(hdev,
+                                                            rep->field[i],
+                                                            usage))
+                                       update_report = true;
+                       }
                }
+
+               if (update_report)
+                       hid_hw_request(hdev, rep, HID_REQ_SET_REPORT);
        }
 }
 
        }
        td->hdev = hdev;
        td->mtclass = *mtclass;
-       td->inputmode = -1;
-       td->maxcontact_report_id = -1;
        td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
        td->cc_index = -1;
        td->scantime_index = -1;
                dev_warn(&hdev->dev, "Cannot allocate sysfs group for %s\n",
                                hdev->name);
 
-       mt_set_maxcontacts(hdev);
-       mt_set_input_mode(hdev);
+       mt_set_modes(hdev);
 
        /* release .fields memory as it is not used anymore */
        devm_kfree(&hdev->dev, td->fields);
 static int mt_reset_resume(struct hid_device *hdev)
 {
        mt_release_contacts(hdev);
-       mt_set_maxcontacts(hdev);
-       mt_set_input_mode(hdev);
+       mt_set_modes(hdev);
        return 0;
 }