forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/drivers/platform/x86/surfacepro3_button.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * power/home/volume button support for
34 * Microsoft Surface Pro 3/4 tablet.
45 *
56 * Copyright (c) 2015 Intel Corporation.
67 * All rights reserved.
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; version 2
11
- * of the License.
128 */
139
1410 #include <linux/kernel.h>
....@@ -23,6 +19,12 @@
2319 #define SURFACE_PRO4_BUTTON_HID "MSHW0040"
2420 #define SURFACE_BUTTON_OBJ_NAME "VGBI"
2521 #define SURFACE_BUTTON_DEVICE_NAME "Surface Pro 3/4 Buttons"
22
+
23
+#define MSHW0040_DSM_REVISION 0x01
24
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
25
+static const guid_t MSHW0040_DSM_UUID =
26
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
27
+ 0x49, 0x80, 0x35);
2628
2729 #define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8
2830
....@@ -82,28 +84,28 @@
8284 /* Power button press,release handle */
8385 case SURFACE_BUTTON_NOTIFY_PRESS_POWER:
8486 pressed = true;
85
- /*fall through*/
87
+ fallthrough;
8688 case SURFACE_BUTTON_NOTIFY_RELEASE_POWER:
8789 key_code = KEY_POWER;
8890 break;
8991 /* Home button press,release handle */
9092 case SURFACE_BUTTON_NOTIFY_PRESS_HOME:
9193 pressed = true;
92
- /*fall through*/
94
+ fallthrough;
9395 case SURFACE_BUTTON_NOTIFY_RELEASE_HOME:
9496 key_code = KEY_LEFTMETA;
9597 break;
9698 /* Volume up button press,release handle */
9799 case SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_UP:
98100 pressed = true;
99
- /*fall through*/
101
+ fallthrough;
100102 case SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_UP:
101103 key_code = KEY_VOLUMEUP;
102104 break;
103105 /* Volume down button press,release handle */
104106 case SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_DOWN:
105107 pressed = true;
106
- /*fall through*/
108
+ fallthrough;
107109 case SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_DOWN:
108110 key_code = KEY_VOLUMEDOWN;
109111 break;
....@@ -146,6 +148,44 @@
146148 }
147149 #endif
148150
151
+/*
152
+ * Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device
153
+ * ID (MSHW0040) for the power/volume buttons. Make sure this is the right
154
+ * device by checking for the _DSM method and OEM Platform Revision.
155
+ *
156
+ * Returns true if the driver should bind to this device, i.e. the device is
157
+ * either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1.
158
+ */
159
+static bool surface_button_check_MSHW0040(struct acpi_device *dev)
160
+{
161
+ acpi_handle handle = dev->handle;
162
+ union acpi_object *result;
163
+ u64 oem_platform_rev = 0; // valid revisions are nonzero
164
+
165
+ // get OEM platform revision
166
+ result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
167
+ MSHW0040_DSM_REVISION,
168
+ MSHW0040_DSM_GET_OMPR,
169
+ NULL, ACPI_TYPE_INTEGER);
170
+
171
+ /*
172
+ * If evaluating the _DSM fails, the method is not present. This means
173
+ * that we have either MSHW0028 or MSHW0040 on Pro 4 or Book 1, so we
174
+ * should use this driver. We use revision 0 indicating it is
175
+ * unavailable.
176
+ */
177
+
178
+ if (result) {
179
+ oem_platform_rev = result->integer.value;
180
+ ACPI_FREE(result);
181
+ }
182
+
183
+ dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev);
184
+
185
+ return oem_platform_rev == 0;
186
+}
187
+
188
+
149189 static int surface_button_add(struct acpi_device *device)
150190 {
151191 struct surface_button *button;
....@@ -158,6 +198,9 @@
158198 strlen(SURFACE_BUTTON_OBJ_NAME)))
159199 return -ENODEV;
160200
201
+ if (!surface_button_check_MSHW0040(device))
202
+ return -ENODEV;
203
+
161204 button = kzalloc(sizeof(struct surface_button), GFP_KERNEL);
162205 if (!button)
163206 return -ENOMEM;