diff options
author | Mario Limonciello <mario.limonciello@dell.com> | 2018-02-22 14:58:42 -0500 |
---|---|---|
committer | Darren Hart (VMware) <dvhart@infradead.org> | 2018-02-25 11:02:40 -0500 |
commit | de9647efeaa9f4e8b08c002e09757fd9c55ff901 (patch) | |
tree | 39e6b4ca8d8623231933fc65553e47357e51fb9b | |
parent | 91ab883eb21325ad80f3473633f794c78ac87f51 (diff) |
platform/x86: intel-vbtn: Only activate tablet mode switch on 2-in-1's
Some laptops such as the XPS 9360 support the intel-vbtn INT33D6
interface but don't initialize the bit that intel-vbtn uses to
represent switching tablet mode.
By running this only on real 2-in-1's it shouldn't cause false
positives.
Fixes: 30323fb6d5 ("Support tablet mode switch")
Reported-by: Jeremy Cline <jeremy@jcline.org>
Signed-off-by: Mario Limonciello <mario.limonciello@dell.com>
Tested-by: Jeremy Cline <jeremy@jcline.org>
Tested-by: Darren Hart (VMware) <dvhart@infradead.org>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
-rw-r--r-- | drivers/platform/x86/intel-vbtn.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c index b703d6f5b099..8173307d6bb1 100644 --- a/drivers/platform/x86/intel-vbtn.c +++ b/drivers/platform/x86/intel-vbtn.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/acpi.h> | 9 | #include <linux/acpi.h> |
10 | #include <linux/dmi.h> | ||
10 | #include <linux/input.h> | 11 | #include <linux/input.h> |
11 | #include <linux/input/sparse-keymap.h> | 12 | #include <linux/input/sparse-keymap.h> |
12 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
@@ -97,9 +98,35 @@ out_unknown: | |||
97 | dev_dbg(&device->dev, "unknown event index 0x%x\n", event); | 98 | dev_dbg(&device->dev, "unknown event index 0x%x\n", event); |
98 | } | 99 | } |
99 | 100 | ||
100 | static int intel_vbtn_probe(struct platform_device *device) | 101 | static void detect_tablet_mode(struct platform_device *device) |
101 | { | 102 | { |
103 | const char *chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); | ||
104 | struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev); | ||
105 | acpi_handle handle = ACPI_HANDLE(&device->dev); | ||
102 | struct acpi_buffer vgbs_output = { ACPI_ALLOCATE_BUFFER, NULL }; | 106 | struct acpi_buffer vgbs_output = { ACPI_ALLOCATE_BUFFER, NULL }; |
107 | union acpi_object *obj; | ||
108 | acpi_status status; | ||
109 | int m; | ||
110 | |||
111 | if (!(chassis_type && strcmp(chassis_type, "31") == 0)) | ||
112 | goto out; | ||
113 | |||
114 | status = acpi_evaluate_object(handle, "VGBS", NULL, &vgbs_output); | ||
115 | if (ACPI_FAILURE(status)) | ||
116 | goto out; | ||
117 | |||
118 | obj = vgbs_output.pointer; | ||
119 | if (!(obj && obj->type == ACPI_TYPE_INTEGER)) | ||
120 | goto out; | ||
121 | |||
122 | m = !(obj->integer.value & TABLET_MODE_FLAG); | ||
123 | input_report_switch(priv->input_dev, SW_TABLET_MODE, m); | ||
124 | out: | ||
125 | kfree(vgbs_output.pointer); | ||
126 | } | ||
127 | |||
128 | static int intel_vbtn_probe(struct platform_device *device) | ||
129 | { | ||
103 | acpi_handle handle = ACPI_HANDLE(&device->dev); | 130 | acpi_handle handle = ACPI_HANDLE(&device->dev); |
104 | struct intel_vbtn_priv *priv; | 131 | struct intel_vbtn_priv *priv; |
105 | acpi_status status; | 132 | acpi_status status; |
@@ -122,22 +149,7 @@ static int intel_vbtn_probe(struct platform_device *device) | |||
122 | return err; | 149 | return err; |
123 | } | 150 | } |
124 | 151 | ||
125 | /* | 152 | detect_tablet_mode(device); |
126 | * VGBS being present and returning something means we have | ||
127 | * a tablet mode switch. | ||
128 | */ | ||
129 | status = acpi_evaluate_object(handle, "VGBS", NULL, &vgbs_output); | ||
130 | if (ACPI_SUCCESS(status)) { | ||
131 | union acpi_object *obj = vgbs_output.pointer; | ||
132 | |||
133 | if (obj && obj->type == ACPI_TYPE_INTEGER) { | ||
134 | int m = !(obj->integer.value & TABLET_MODE_FLAG); | ||
135 | |||
136 | input_report_switch(priv->input_dev, SW_TABLET_MODE, m); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | kfree(vgbs_output.pointer); | ||
141 | 153 | ||
142 | status = acpi_install_notify_handler(handle, | 154 | status = acpi_install_notify_handler(handle, |
143 | ACPI_DEVICE_NOTIFY, | 155 | ACPI_DEVICE_NOTIFY, |