Merge pull request #478 from qzed/master

Ensure GPIOs are available in button driver
This commit is contained in:
Jake Day 2019-04-30 20:29:34 -04:00 committed by GitHub
commit 46b3dbff4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 194 additions and 94 deletions

View file

@ -1,44 +1,36 @@
From 72113fc16eb482e9ee1a5bf31e829128de2e4a65 Mon Sep 17 00:00:00 2001 From 3421b5f76fef2381ed85bd9a74b66a99719ecaa8 Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com> From: qzed <qzed@users.noreply.github.com>
Date: Thu, 7 Mar 2019 11:55:17 -0500 Date: Wed, 24 Apr 2019 20:34:29 +0200
Subject: [PATCH 03/11] buttons Subject: [PATCH 03/11] buttons
--- ---
drivers/input/misc/soc_button_array.c | 84 +++++++++++++++++++++-- drivers/input/misc/soc_button_array.c | 133 ++++++++++++++++++++--
drivers/platform/x86/surfacepro3_button.c | 36 ++++++++++ drivers/platform/x86/surfacepro3_button.c | 38 +++++++
2 files changed, 114 insertions(+), 6 deletions(-) 2 files changed, 159 insertions(+), 12 deletions(-)
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index 23520df7650f..1ea239ff426d 100644 index 55cd6e0b409c..ad4d591cf179 100644
--- a/drivers/input/misc/soc_button_array.c --- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c
@@ -29,12 +29,24 @@ struct soc_button_info { @@ -29,6 +29,17 @@ struct soc_button_info {
bool wakeup; bool wakeup;
}; };
+/**
+ * struct soc_device_data - driver data for different device types
+ * @button_info: specifications of buttons, if NULL specification is assumed to
+ * be present in _DSD
+ * @check: device-specific check (NULL means all will be accepted)
+ */
+struct soc_device_data { +struct soc_device_data {
+ /* Button info, may be NULL. */
+ struct soc_button_info *button_info; + struct soc_button_info *button_info;
+ /* Special device check function, may be NULL. */ + int (*check)(struct device *dev);
+ int (*check)(struct device *);
+}; +};
+ +
/* /*
* Some of the buttons like volume up/down are auto repeat, while others * Some of the buttons like volume up/down are auto repeat, while others
* are not. To support both, we register two platform devices, and put * are not. To support both, we register two platform devices, and put
* buttons into them based on whether the key should be auto repeat. @@ -310,6 +321,7 @@ static int soc_button_probe(struct platform_device *pdev)
*/
-#define BUTTON_TYPES 2
+#define BUTTON_TYPES 2
+
+#define MSHW0040_DSM_REVISION 0x01
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
+static const guid_t MSHW0040_DSM_UUID =
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65, 0x49, 0x80, 0x35);
struct soc_button_data {
struct platform_device *children[BUTTON_TYPES];
@@ -310,6 +322,7 @@ static int soc_button_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct acpi_device_id *id; const struct acpi_device_id *id;
@ -46,16 +38,15 @@ index 23520df7650f..1ea239ff426d 100644
struct soc_button_info *button_info; struct soc_button_info *button_info;
struct soc_button_data *priv; struct soc_button_data *priv;
struct platform_device *pd; struct platform_device *pd;
@@ -320,12 +333,20 @@ static int soc_button_probe(struct platform_device *pdev) @@ -320,18 +332,19 @@ static int soc_button_probe(struct platform_device *pdev)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
- if (!id->driver_data) { - if (!id->driver_data) {
+ device_data = (struct soc_device_data *)id->driver_data; + device_data = (struct soc_device_data *)id->driver_data;
+ if (device_data && device_data->check) { + if (device_data && device_data->check) {
+ // device dependent check, required for MSHW0040
+ error = device_data->check(dev); + error = device_data->check(dev);
+ if (error != 0) + if (error)
+ return error; + return error;
+ } + }
+ +
@ -67,10 +58,16 @@ index 23520df7650f..1ea239ff426d 100644
return PTR_ERR(button_info); return PTR_ERR(button_info);
- } else { - } else {
- button_info = (struct soc_button_info *)id->driver_data; - button_info = (struct soc_button_info *)id->driver_data;
- }
-
- error = gpiod_count(dev, NULL);
- if (error < 0) {
- dev_dbg(dev, "no GPIO attached, ignoring...\n");
- return -ENODEV;
} }
error = gpiod_count(dev, NULL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -357,7 +378,7 @@ static int soc_button_probe(struct platform_device *pdev) @@ -357,12 +370,32 @@ static int soc_button_probe(struct platform_device *pdev)
if (!priv->children[0] && !priv->children[1]) if (!priv->children[0] && !priv->children[1])
return -ENODEV; return -ENODEV;
@ -79,15 +76,41 @@ index 23520df7650f..1ea239ff426d 100644
devm_kfree(dev, button_info); devm_kfree(dev, button_info);
return 0; return 0;
@@ -377,9 +398,60 @@ static struct soc_button_info soc_button_PNP0C40[] = { }
+
+static int soc_device_check_generic(struct device *dev)
+{
+ int gpios;
+
+ gpios = gpiod_count(dev, NULL);
+ if (gpios < 0) {
+ dev_dbg(dev, "no GPIO attached, ignoring...\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static struct soc_device_data soc_device_ACPI0011 = {
+ .button_info = NULL,
+ .check = soc_device_check_generic,
+};
+
+
/*
* Definition of buttons on the tablet. The ACPI index of each button
* is defined in section 2.8.7.2 of "Windows ACPI Design Guide for SoC
@@ -377,9 +410,85 @@ static struct soc_button_info soc_button_PNP0C40[] = {
{ } { }
}; };
+static struct soc_device_data soc_device_PNP0C40 = { +static struct soc_device_data soc_device_PNP0C40 = {
+ .button_info = soc_button_PNP0C40, + .button_info = soc_button_PNP0C40,
+ .check = NULL, + .check = soc_device_check_generic,
+}; +};
+ +
+
+/* +/*
+ * Special device check for Surface Book 2 and Surface Pro (2017). + * Special device check for Surface Book 2 and Surface Pro (2017).
+ * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned + * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned
@ -96,29 +119,50 @@ index 23520df7650f..1ea239ff426d 100644
+ * for the correct devices by checking the OEM Platform Revision provided by + * for the correct devices by checking the OEM Platform Revision provided by
+ * the _DSM method. + * the _DSM method.
+ */ + */
+#define MSHW0040_DSM_REVISION 0x01
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
+static const guid_t MSHW0040_DSM_UUID =
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
+ 0x49, 0x80, 0x35);
+
+static int soc_device_check_MSHW0040(struct device *dev) +static int soc_device_check_MSHW0040(struct device *dev)
+{ +{
+ acpi_handle handle = ACPI_HANDLE(dev); + acpi_handle handle = ACPI_HANDLE(dev);
+ union acpi_object *result; + union acpi_object *result;
+ u64 oem_platform_rev = 0; + u64 oem_platform_rev = 0;
+ int gpios;
+ +
+ // get OEM board revision + // get OEM platform revision
+ result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, MSHW0040_DSM_REVISION, + result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
+ MSHW0040_DSM_GET_OMPR, NULL, ACPI_TYPE_INTEGER); + MSHW0040_DSM_REVISION,
+ MSHW0040_DSM_GET_OMPR, NULL,
+ ACPI_TYPE_INTEGER);
+ +
+ if (result) { + if (result) {
+ oem_platform_rev = result->integer.value; + oem_platform_rev = result->integer.value;
+ ACPI_FREE(result); + ACPI_FREE(result);
+ } + }
+ +
+ if (oem_platform_rev == 0)
+ return -ENODEV;
+
+ dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev); + dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
+ +
+ return oem_platform_rev > 0 ? 0 : -ENODEV; + /*
+ * We are _really_ expecting GPIOs here. If we do not get any, this
+ * means the GPIO driver has not been loaded yet (which can happen).
+ * Try again later.
+ */
+ gpios = gpiod_count(dev, NULL);
+ if (gpios < 0)
+ return -EAGAIN;
+
+ return 0;
+} +}
+ +
+/* +/*
+ * Button infos for Microsoft Surface Book 2 and Surface Pro (2017). + * Button infos for Microsoft Surface Book 2 and Surface Pro (2017).
+ * Extracted from DSDT. + * Obtained from DSDT/testing.
+ */ + */
+static struct soc_button_info soc_button_MSHW0040[] = { +static struct soc_button_info soc_button_MSHW0040[] = {
+ { "power", 0, EV_KEY, KEY_POWER, false, true }, + { "power", 0, EV_KEY, KEY_POWER, false, true },
@ -131,18 +175,22 @@ index 23520df7650f..1ea239ff426d 100644
+ .button_info = soc_button_MSHW0040, + .button_info = soc_button_MSHW0040,
+ .check = soc_device_check_MSHW0040, + .check = soc_device_check_MSHW0040,
+}; +};
+
+ +
static const struct acpi_device_id soc_button_acpi_match[] = { static const struct acpi_device_id soc_button_acpi_match[] = {
- { "PNP0C40", (unsigned long)soc_button_PNP0C40 }, - { "PNP0C40", (unsigned long)soc_button_PNP0C40 },
- { "ACPI0011", 0 },
+ { "PNP0C40", (unsigned long)&soc_device_PNP0C40 }, + { "PNP0C40", (unsigned long)&soc_device_PNP0C40 },
{ "ACPI0011", 0 }, + { "ACPI0011", (unsigned long)&soc_device_ACPI0011 },
+ /* Microsoft Surface Book 2 and Surface Pro (2017) */ +
+ /* Microsoft Surface Devices (5th and 6th generation) */
+ { "MSHW0040", (unsigned long)&soc_device_MSHW0040 }, + { "MSHW0040", (unsigned long)&soc_device_MSHW0040 },
+
{ } { }
}; };
diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c
index 1b491690ce07..b67f559ee209 100644 index 1b491690ce07..eaec30380b11 100644
--- a/drivers/platform/x86/surfacepro3_button.c --- a/drivers/platform/x86/surfacepro3_button.c
+++ b/drivers/platform/x86/surfacepro3_button.c +++ b/drivers/platform/x86/surfacepro3_button.c
@@ -24,6 +24,12 @@ @@ -24,6 +24,12 @@
@ -152,13 +200,13 @@ index 1b491690ce07..b67f559ee209 100644
+#define MSHW0040_DSM_REVISION 0x01 +#define MSHW0040_DSM_REVISION 0x01
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision +#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
+static const guid_t MSHW0040_DSM_UUID = +static const guid_t MSHW0040_DSM_UUID =
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65, 0x49, 0x80, 0x35); + GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
+ + 0x49, 0x80, 0x35);
+ +
#define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8 #define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8
#define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6 #define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6
@@ -146,6 +152,32 @@ static int surface_button_resume(struct device *dev) @@ -146,6 +152,34 @@ static int surface_button_resume(struct device *dev)
} }
#endif #endif
@ -173,9 +221,11 @@ index 1b491690ce07..b67f559ee209 100644
+ union acpi_object *result; + union acpi_object *result;
+ u64 oem_platform_rev = 0; + u64 oem_platform_rev = 0;
+ +
+ // get OEM board revision + // get OEM platform revision
+ result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, MSHW0040_DSM_REVISION, + result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
+ MSHW0040_DSM_GET_OMPR, NULL, ACPI_TYPE_INTEGER); + MSHW0040_DSM_REVISION,
+ MSHW0040_DSM_GET_OMPR,
+ NULL, ACPI_TYPE_INTEGER);
+ +
+ if (result) { + if (result) {
+ oem_platform_rev = result->integer.value; + oem_platform_rev = result->integer.value;
@ -191,7 +241,7 @@ index 1b491690ce07..b67f559ee209 100644
static int surface_button_add(struct acpi_device *device) static int surface_button_add(struct acpi_device *device)
{ {
struct surface_button *button; struct surface_button *button;
@@ -158,6 +190,10 @@ static int surface_button_add(struct acpi_device *device) @@ -158,6 +192,10 @@ static int surface_button_add(struct acpi_device *device)
strlen(SURFACE_BUTTON_OBJ_NAME))) strlen(SURFACE_BUTTON_OBJ_NAME)))
return -ENODEV; return -ENODEV;
@ -203,5 +253,5 @@ index 1b491690ce07..b67f559ee209 100644
if (!button) if (!button)
return -ENOMEM; return -ENOMEM;
-- --
2.19.1 2.21.0

View file

@ -1,44 +1,36 @@
From 5351e555fb2119dcf04c436b3828e1e99fcdba34 Mon Sep 17 00:00:00 2001 From 3e59ef509f37b135fb12556180463af0b16c9f2f Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com> From: qzed <qzed@users.noreply.github.com>
Date: Wed, 13 Mar 2019 15:15:47 -0400 Date: Wed, 24 Apr 2019 20:29:20 +0200
Subject: [PATCH 03/11] buttons Subject: [PATCH 03/11] buttons
--- ---
drivers/input/misc/soc_button_array.c | 84 +++++++++++++++++++++-- drivers/input/misc/soc_button_array.c | 133 ++++++++++++++++++++--
drivers/platform/x86/surfacepro3_button.c | 36 ++++++++++ drivers/platform/x86/surfacepro3_button.c | 38 +++++++
2 files changed, 114 insertions(+), 6 deletions(-) 2 files changed, 159 insertions(+), 12 deletions(-)
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index 23520df7650f..1ea239ff426d 100644 index 55cd6e0b409c..ad4d591cf179 100644
--- a/drivers/input/misc/soc_button_array.c --- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c
@@ -29,12 +29,24 @@ struct soc_button_info { @@ -29,6 +29,17 @@ struct soc_button_info {
bool wakeup; bool wakeup;
}; };
+/**
+ * struct soc_device_data - driver data for different device types
+ * @button_info: specifications of buttons, if NULL specification is assumed to
+ * be present in _DSD
+ * @check: device-specific check (NULL means all will be accepted)
+ */
+struct soc_device_data { +struct soc_device_data {
+ /* Button info, may be NULL. */
+ struct soc_button_info *button_info; + struct soc_button_info *button_info;
+ /* Special device check function, may be NULL. */ + int (*check)(struct device *dev);
+ int (*check)(struct device *);
+}; +};
+ +
/* /*
* Some of the buttons like volume up/down are auto repeat, while others * Some of the buttons like volume up/down are auto repeat, while others
* are not. To support both, we register two platform devices, and put * are not. To support both, we register two platform devices, and put
* buttons into them based on whether the key should be auto repeat. @@ -310,6 +321,7 @@ static int soc_button_probe(struct platform_device *pdev)
*/
-#define BUTTON_TYPES 2
+#define BUTTON_TYPES 2
+
+#define MSHW0040_DSM_REVISION 0x01
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
+static const guid_t MSHW0040_DSM_UUID =
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65, 0x49, 0x80, 0x35);
struct soc_button_data {
struct platform_device *children[BUTTON_TYPES];
@@ -310,6 +322,7 @@ static int soc_button_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct acpi_device_id *id; const struct acpi_device_id *id;
@ -46,16 +38,15 @@ index 23520df7650f..1ea239ff426d 100644
struct soc_button_info *button_info; struct soc_button_info *button_info;
struct soc_button_data *priv; struct soc_button_data *priv;
struct platform_device *pd; struct platform_device *pd;
@@ -320,12 +333,20 @@ static int soc_button_probe(struct platform_device *pdev) @@ -320,18 +332,19 @@ static int soc_button_probe(struct platform_device *pdev)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
- if (!id->driver_data) { - if (!id->driver_data) {
+ device_data = (struct soc_device_data *)id->driver_data; + device_data = (struct soc_device_data *)id->driver_data;
+ if (device_data && device_data->check) { + if (device_data && device_data->check) {
+ // device dependent check, required for MSHW0040
+ error = device_data->check(dev); + error = device_data->check(dev);
+ if (error != 0) + if (error)
+ return error; + return error;
+ } + }
+ +
@ -67,10 +58,16 @@ index 23520df7650f..1ea239ff426d 100644
return PTR_ERR(button_info); return PTR_ERR(button_info);
- } else { - } else {
- button_info = (struct soc_button_info *)id->driver_data; - button_info = (struct soc_button_info *)id->driver_data;
- }
-
- error = gpiod_count(dev, NULL);
- if (error < 0) {
- dev_dbg(dev, "no GPIO attached, ignoring...\n");
- return -ENODEV;
} }
error = gpiod_count(dev, NULL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -357,7 +378,7 @@ static int soc_button_probe(struct platform_device *pdev) @@ -357,12 +370,32 @@ static int soc_button_probe(struct platform_device *pdev)
if (!priv->children[0] && !priv->children[1]) if (!priv->children[0] && !priv->children[1])
return -ENODEV; return -ENODEV;
@ -79,15 +76,41 @@ index 23520df7650f..1ea239ff426d 100644
devm_kfree(dev, button_info); devm_kfree(dev, button_info);
return 0; return 0;
@@ -377,9 +398,60 @@ static struct soc_button_info soc_button_PNP0C40[] = { }
+
+static int soc_device_check_generic(struct device *dev)
+{
+ int gpios;
+
+ gpios = gpiod_count(dev, NULL);
+ if (gpios < 0) {
+ dev_dbg(dev, "no GPIO attached, ignoring...\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static struct soc_device_data soc_device_ACPI0011 = {
+ .button_info = NULL,
+ .check = soc_device_check_generic,
+};
+
+
/*
* Definition of buttons on the tablet. The ACPI index of each button
* is defined in section 2.8.7.2 of "Windows ACPI Design Guide for SoC
@@ -377,9 +410,85 @@ static struct soc_button_info soc_button_PNP0C40[] = {
{ } { }
}; };
+static struct soc_device_data soc_device_PNP0C40 = { +static struct soc_device_data soc_device_PNP0C40 = {
+ .button_info = soc_button_PNP0C40, + .button_info = soc_button_PNP0C40,
+ .check = NULL, + .check = soc_device_check_generic,
+}; +};
+ +
+
+/* +/*
+ * Special device check for Surface Book 2 and Surface Pro (2017). + * Special device check for Surface Book 2 and Surface Pro (2017).
+ * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned + * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned
@ -96,29 +119,50 @@ index 23520df7650f..1ea239ff426d 100644
+ * for the correct devices by checking the OEM Platform Revision provided by + * for the correct devices by checking the OEM Platform Revision provided by
+ * the _DSM method. + * the _DSM method.
+ */ + */
+#define MSHW0040_DSM_REVISION 0x01
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
+static const guid_t MSHW0040_DSM_UUID =
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
+ 0x49, 0x80, 0x35);
+
+static int soc_device_check_MSHW0040(struct device *dev) +static int soc_device_check_MSHW0040(struct device *dev)
+{ +{
+ acpi_handle handle = ACPI_HANDLE(dev); + acpi_handle handle = ACPI_HANDLE(dev);
+ union acpi_object *result; + union acpi_object *result;
+ u64 oem_platform_rev = 0; + u64 oem_platform_rev = 0;
+ int gpios;
+ +
+ // get OEM board revision + // get OEM platform revision
+ result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, MSHW0040_DSM_REVISION, + result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
+ MSHW0040_DSM_GET_OMPR, NULL, ACPI_TYPE_INTEGER); + MSHW0040_DSM_REVISION,
+ MSHW0040_DSM_GET_OMPR, NULL,
+ ACPI_TYPE_INTEGER);
+ +
+ if (result) { + if (result) {
+ oem_platform_rev = result->integer.value; + oem_platform_rev = result->integer.value;
+ ACPI_FREE(result); + ACPI_FREE(result);
+ } + }
+ +
+ if (oem_platform_rev == 0)
+ return -ENODEV;
+
+ dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev); + dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
+ +
+ return oem_platform_rev > 0 ? 0 : -ENODEV; + /*
+ * We are _really_ expecting GPIOs here. If we do not get any, this
+ * means the GPIO driver has not been loaded yet (which can happen).
+ * Try again later.
+ */
+ gpios = gpiod_count(dev, NULL);
+ if (gpios < 0)
+ return -EAGAIN;
+
+ return 0;
+} +}
+ +
+/* +/*
+ * Button infos for Microsoft Surface Book 2 and Surface Pro (2017). + * Button infos for Microsoft Surface Book 2 and Surface Pro (2017).
+ * Extracted from DSDT. + * Obtained from DSDT/testing.
+ */ + */
+static struct soc_button_info soc_button_MSHW0040[] = { +static struct soc_button_info soc_button_MSHW0040[] = {
+ { "power", 0, EV_KEY, KEY_POWER, false, true }, + { "power", 0, EV_KEY, KEY_POWER, false, true },
@ -131,18 +175,22 @@ index 23520df7650f..1ea239ff426d 100644
+ .button_info = soc_button_MSHW0040, + .button_info = soc_button_MSHW0040,
+ .check = soc_device_check_MSHW0040, + .check = soc_device_check_MSHW0040,
+}; +};
+
+ +
static const struct acpi_device_id soc_button_acpi_match[] = { static const struct acpi_device_id soc_button_acpi_match[] = {
- { "PNP0C40", (unsigned long)soc_button_PNP0C40 }, - { "PNP0C40", (unsigned long)soc_button_PNP0C40 },
- { "ACPI0011", 0 },
+ { "PNP0C40", (unsigned long)&soc_device_PNP0C40 }, + { "PNP0C40", (unsigned long)&soc_device_PNP0C40 },
{ "ACPI0011", 0 }, + { "ACPI0011", (unsigned long)&soc_device_ACPI0011 },
+ /* Microsoft Surface Book 2 and Surface Pro (2017) */ +
+ /* Microsoft Surface Devices (5th and 6th generation) */
+ { "MSHW0040", (unsigned long)&soc_device_MSHW0040 }, + { "MSHW0040", (unsigned long)&soc_device_MSHW0040 },
+
{ } { }
}; };
diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c
index 1b491690ce07..b67f559ee209 100644 index 1b491690ce07..eaec30380b11 100644
--- a/drivers/platform/x86/surfacepro3_button.c --- a/drivers/platform/x86/surfacepro3_button.c
+++ b/drivers/platform/x86/surfacepro3_button.c +++ b/drivers/platform/x86/surfacepro3_button.c
@@ -24,6 +24,12 @@ @@ -24,6 +24,12 @@
@ -152,13 +200,13 @@ index 1b491690ce07..b67f559ee209 100644
+#define MSHW0040_DSM_REVISION 0x01 +#define MSHW0040_DSM_REVISION 0x01
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision +#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
+static const guid_t MSHW0040_DSM_UUID = +static const guid_t MSHW0040_DSM_UUID =
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65, 0x49, 0x80, 0x35); + GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
+ + 0x49, 0x80, 0x35);
+ +
#define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8 #define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8
#define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6 #define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6
@@ -146,6 +152,32 @@ static int surface_button_resume(struct device *dev) @@ -146,6 +152,34 @@ static int surface_button_resume(struct device *dev)
} }
#endif #endif
@ -173,9 +221,11 @@ index 1b491690ce07..b67f559ee209 100644
+ union acpi_object *result; + union acpi_object *result;
+ u64 oem_platform_rev = 0; + u64 oem_platform_rev = 0;
+ +
+ // get OEM board revision + // get OEM platform revision
+ result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, MSHW0040_DSM_REVISION, + result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
+ MSHW0040_DSM_GET_OMPR, NULL, ACPI_TYPE_INTEGER); + MSHW0040_DSM_REVISION,
+ MSHW0040_DSM_GET_OMPR,
+ NULL, ACPI_TYPE_INTEGER);
+ +
+ if (result) { + if (result) {
+ oem_platform_rev = result->integer.value; + oem_platform_rev = result->integer.value;
@ -191,7 +241,7 @@ index 1b491690ce07..b67f559ee209 100644
static int surface_button_add(struct acpi_device *device) static int surface_button_add(struct acpi_device *device)
{ {
struct surface_button *button; struct surface_button *button;
@@ -158,6 +190,10 @@ static int surface_button_add(struct acpi_device *device) @@ -158,6 +192,10 @@ static int surface_button_add(struct acpi_device *device)
strlen(SURFACE_BUTTON_OBJ_NAME))) strlen(SURFACE_BUTTON_OBJ_NAME)))
return -ENODEV; return -ENODEV;
@ -203,5 +253,5 @@ index 1b491690ce07..b67f559ee209 100644
if (!button) if (!button)
return -ENOMEM; return -ENOMEM;
-- --
2.19.1 2.21.0