#define ACER_WMID_GET_THREEG_METHODID          10
 #define ACER_WMID_SET_THREEG_METHODID          11
 
+#define ACER_WMID_SET_GAMING_LED_METHODID 2
+#define ACER_WMID_GET_GAMING_LED_METHODID 4
+#define ACER_WMID_SET_GAMING_FAN_BEHAVIOR 14
+#define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22
+
 /*
  * Acer ACPI method GUIDs
  */
 #define WMID_GUID1             "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
 #define WMID_GUID2             "95764E09-FB56-4E83-B31A-37761F60994A"
 #define WMID_GUID3             "61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
+#define WMID_GUID4             "7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
 
 /*
  * Acer ACPI event GUIDs
 enum acer_wmi_event_ids {
        WMID_HOTKEY_EVENT = 0x1,
        WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
+       WMID_GAMING_TURBO_KEY_EVENT = 0x7,
 };
 
 static const struct key_entry acer_wmi_keymap[] __initconst = {
 #define ACER_CAP_THREEG                        BIT(4)
 #define ACER_CAP_SET_FUNCTION_MODE     BIT(5)
 #define ACER_CAP_KBD_DOCK              BIT(6)
+#define ACER_CAP_TURBO_OC     BIT(7)
+#define ACER_CAP_TURBO_LED     BIT(8)
+#define ACER_CAP_TURBO_FAN     BIT(9)
 
 /*
  * Interface type flags
        u8 mailled;
        s8 brightness;
        u8 bluetooth;
+       u8 turbo;
+       u8 cpu_fans;
+       u8 gpu_fans;
 };
 
 static struct quirk_entry *quirks;
 
        if (quirks->brightness)
                interface->capability |= ACER_CAP_BRIGHTNESS;
+
+       if (quirks->turbo)
+               interface->capability |= ACER_CAP_TURBO_OC | ACER_CAP_TURBO_LED
+                                        | ACER_CAP_TURBO_FAN;
 }
 
 static int __init dmi_matched(const struct dmi_system_id *dmi)
        .mailled = 1,
 };
 
+static struct quirk_entry quirk_acer_predator_ph315_53 = {
+       .turbo = 1,
+       .cpu_fans = 1,
+       .gpu_fans = 1,
+};
+
 /* This AMW0 laptop has no bluetooth */
 static struct quirk_entry quirk_medion_md_98300 = {
        .wireless = 1,
                },
                .driver_data = &quirk_acer_travelmate_2490,
        },
+       {
+               .callback = dmi_matched,
+               .ident = "Acer Predator PH315-53",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH315-53"),
+               },
+               .driver_data = &quirk_acer_predator_ph315_53,
+       },
        {
                .callback = set_force_caps,
                .ident = "Acer Aspire Switch 10E SW3-016",
        .type = ACER_WMID_v2,
 };
 
+/*
+ * WMID Gaming interface
+ */
+
+static acpi_status
+WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out)
+{
+       struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) };
+       struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *obj;
+       u32 tmp = 0;
+       acpi_status status;
+
+       status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result);
+
+       if (ACPI_FAILURE(status))
+               return status;
+       obj = (union acpi_object *) result.pointer;
+
+       if (obj) {
+               if (obj->type == ACPI_TYPE_BUFFER) {
+                       if (obj->buffer.length == sizeof(u32))
+                               tmp = *((u32 *) obj->buffer.pointer);
+                       else if (obj->buffer.length == sizeof(u64))
+                               tmp = *((u64 *) obj->buffer.pointer);
+               } else if (obj->type == ACPI_TYPE_INTEGER) {
+                       tmp = (u64) obj->integer.value;
+               }
+       }
+
+       if (out)
+               *out = tmp;
+
+       kfree(result.pointer);
+
+       return status;
+}
+
+static acpi_status WMID_gaming_set_u64(u64 value, u32 cap)
+{
+       u32 method_id = 0;
+
+       if (!(interface->capability & cap))
+               return AE_BAD_PARAMETER;
+
+       switch (cap) {
+       case ACER_CAP_TURBO_LED:
+               method_id = ACER_WMID_SET_GAMING_LED_METHODID;
+               break;
+       case ACER_CAP_TURBO_FAN:
+               method_id = ACER_WMID_SET_GAMING_FAN_BEHAVIOR;
+               break;
+       case ACER_CAP_TURBO_OC:
+               method_id = ACER_WMID_SET_GAMING_MISC_SETTING_METHODID;
+               break;
+       default:
+               return AE_BAD_PARAMETER;
+       }
+
+       return WMI_gaming_execute_u64(method_id, value, NULL);
+}
+
+static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap)
+{
+       acpi_status status;
+       u64 result;
+       u64 input;
+       u32 method_id;
+
+       if (!(interface->capability & cap))
+               return AE_BAD_PARAMETER;
+
+       switch (cap) {
+       case ACER_CAP_TURBO_LED:
+               method_id = ACER_WMID_GET_GAMING_LED_METHODID;
+               input = 0x1;
+               break;
+       default:
+               return AE_BAD_PARAMETER;
+       }
+       status = WMI_gaming_execute_u64(method_id, input, &result);
+       if (ACPI_SUCCESS(status))
+               *value = (u64) result;
+
+       return status;
+}
+
+static void WMID_gaming_set_fan_mode(u8 fan_mode)
+{
+       /* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
+       u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
+       int i;
+
+       if (quirks->cpu_fans > 0)
+               gpu_fan_config2 |= 1;
+       for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
+               gpu_fan_config2 |= 1 << (i + 1);
+       for (i = 0; i < quirks->gpu_fans; ++i)
+               gpu_fan_config2 |= 1 << (i + 3);
+       if (quirks->cpu_fans > 0)
+               gpu_fan_config1 |= fan_mode;
+       for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
+               gpu_fan_config1 |= fan_mode << (2 * i + 2);
+       for (i = 0; i < quirks->gpu_fans; ++i)
+               gpu_fan_config1 |= fan_mode << (2 * i + 6);
+       WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
+}
+
 /*
  * Generic Device (interface-independent)
  */
        return 0;
 }
 
+/*
+ *  Predator series turbo button
+ */
+static int acer_toggle_turbo(void)
+{
+       u64 turbo_led_state;
+
+       /* Get current state from turbo button */
+       if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED)))
+               return -1;
+
+       if (turbo_led_state) {
+               /* Turn off turbo led */
+               WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED);
+
+               /* Set FAN mode to auto */
+               WMID_gaming_set_fan_mode(0x1);
+
+               /* Set OC to normal */
+               WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC);
+               WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC);
+       } else {
+               /* Turn on turbo led */
+               WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED);
+
+               /* Set FAN mode to turbo */
+               WMID_gaming_set_fan_mode(0x2);
+
+               /* Set OC to turbo mode */
+               WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC);
+               WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC);
+       }
+       return turbo_led_state;
+}
+
 /*
  * Switch series keyboard dock status
  */
                acer_gsensor_event();
                acer_kbd_dock_event(&return_value);
                break;
+       case WMID_GAMING_TURBO_KEY_EVENT:
+               if (return_value.key_num == 0x4)
+                       acer_toggle_turbo();
+               break;
        default:
                pr_warn("Unknown function number - %d - %d\n",
                        return_value.function, return_value.key_num);