diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c index 5fc4315f7382386974231d10a2aeae2c018b8acc..101c100a39290094ac63a616fcfc1171e726352a 100644 --- a/drivers/platform/x86/intel-vbtn.c +++ b/drivers/platform/x86/intel-vbtn.c @@ -26,6 +26,9 @@ #include #include +/* When NOT in tablet mode, VGBS returns with the flag 0x40 */ +#define TABLET_MODE_FLAG 0x40 + MODULE_LICENSE("GPL"); MODULE_AUTHOR("AceLan Kao"); @@ -108,6 +111,7 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) static int intel_vbtn_probe(struct platform_device *device) { + struct acpi_buffer vgbs_output = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_handle handle = ACPI_HANDLE(&device->dev); struct intel_vbtn_priv *priv; acpi_status status; @@ -130,6 +134,23 @@ static int intel_vbtn_probe(struct platform_device *device) return err; } + /* + * VGBS being present and returning something means we have + * a tablet mode switch. + */ + status = acpi_evaluate_object(handle, "VGBS", NULL, &vgbs_output); + if (ACPI_SUCCESS(status)) { + union acpi_object *obj = vgbs_output.pointer; + + if (obj && obj->type == ACPI_TYPE_INTEGER) { + int m = !(obj->integer.value & TABLET_MODE_FLAG); + + input_report_switch(priv->input_dev, SW_TABLET_MODE, m); + } + } + + kfree(vgbs_output.pointer); + status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler,