diff --git a/patches/4.18/buttons.patch b/patches/4.18/buttons.patch index 98f6d036a..4877d305b 100644 --- a/patches/4.18/buttons.patch +++ b/patches/4.18/buttons.patch @@ -1,298 +1,156 @@ -diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig -index 2025f56446a0..97e612baa892 100644 ---- a/drivers/platform/x86/Kconfig -+++ b/drivers/platform/x86/Kconfig -@@ -1158,6 +1158,11 @@ config SURFACE_3_BUTTON - ---help--- - This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet. - -+config SURFACEBOOK2_BUTTON -+ tristate "Power/home/volume buttons driver for Microsoft Surface Book 2/ Surface Pro (2017) tablet" -+ ---help--- -+ This driver handles the power and volume buttons on the Microsoft Surface Book 2/ Surface Pro (2017) tablet. -+ - config ACPI_SURFACE - tristate "Microsoft Surface Extras" - depends on ACPI -diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile -index 8fd5b93bb20d..28c4cede2d91 100644 ---- a/drivers/platform/x86/Makefile -+++ b/drivers/platform/x86/Makefile -@@ -81,6 +81,7 @@ obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o - obj-$(CONFIG_SILEAD_DMI) += silead_dmi.o - obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o - obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o -+obj-$(CONFIG_SURFACEBOOK2_BUTTON) += surfacebook2_button.o - obj-$(CONFIG_ACPI_SURFACE) += surface_acpi.o - obj-$(CONFIG_ACPI_SURFACE) += surface_i2c.o - obj-$(CONFIG_ACPI_SURFACE) += surface_platform.o -diff --git a/drivers/platform/x86/surfacebook2_button.c b/drivers/platform/x86/surfacebook2_button.c -new file mode 100644 -index 000000000000..a6b7de595090 ---- /dev/null -+++ b/drivers/platform/x86/surfacebook2_button.c -@@ -0,0 +1,242 @@ -+/* -+ * Supports for Surface Book 2 and Surface Pro (2017) power and volume -+ * buttons. -+ * -+ * Based on soc_button_array.c: -+ * -+ * (C) Copyright 2014 Intel Corporation -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; version 2 -+ * of the License. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct soc_button_info { -+ const char *name; -+ int acpi_index; -+ unsigned int event_type; -+ unsigned int event_code; -+ bool autorepeat; -+ bool wakeup; -+}; -+ -+/* -+ * 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 -+ * buttons into them based on whether the key should be auto repeat. -+ */ -+#define BUTTON_TYPES 2 -+#define SURFACE_METHOD_DSM "_DSM" -+ -+struct soc_button_data { -+ struct platform_device *children[BUTTON_TYPES]; -+}; -+ -+/* -+ * Get the Nth GPIO number from the ACPI object. -+ */ -+static int soc_button_lookup_gpio(struct device *dev, int acpi_index) -+{ -+ struct gpio_desc *desc; -+ int gpio; -+ -+ desc = gpiod_get_index(dev, NULL, acpi_index, GPIOD_ASIS); -+ if (IS_ERR(desc)) -+ return PTR_ERR(desc); -+ -+ gpio = desc_to_gpio(desc); -+ -+ gpiod_put(desc); -+ -+ return gpio; -+} -+ -+static struct platform_device * -+soc_button_device_create(struct platform_device *pdev, -+ const struct soc_button_info *button_info, -+ bool autorepeat) -+{ -+ const struct soc_button_info *info; -+ struct platform_device *pd; -+ struct gpio_keys_button *gpio_keys; -+ struct gpio_keys_platform_data *gpio_keys_pdata; -+ int n_buttons = 0; -+ int gpio; -+ int error; -+ -+ for (info = button_info; info->name; info++) -+ if (info->autorepeat == autorepeat) -+ n_buttons++; -+ -+ gpio_keys_pdata = devm_kzalloc(&pdev->dev, -+ sizeof(*gpio_keys_pdata) + -+ sizeof(*gpio_keys) * n_buttons, -+ GFP_KERNEL); -+ if (!gpio_keys_pdata) -+ return ERR_PTR(-ENOMEM); -+ -+ gpio_keys = (void *)(gpio_keys_pdata + 1); -+ n_buttons = 0; -+ -+ for (info = button_info; info->name; info++) { -+ if (info->autorepeat != autorepeat) -+ continue; -+ -+ gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index); -+ if (!gpio_is_valid(gpio)) -+ continue; -+ -+ gpio_keys[n_buttons].type = info->event_type; -+ gpio_keys[n_buttons].code = info->event_code; -+ gpio_keys[n_buttons].gpio = gpio; -+ gpio_keys[n_buttons].active_low = 1; -+ gpio_keys[n_buttons].desc = info->name; -+ gpio_keys[n_buttons].wakeup = info->wakeup; -+ /* These devices often use cheap buttons, use 50 ms debounce */ -+ gpio_keys[n_buttons].debounce_interval = 50; -+ n_buttons++; -+ } -+ -+ if (n_buttons == 0) { -+ error = -ENODEV; -+ goto err_free_mem; -+ } -+ -+ gpio_keys_pdata->buttons = gpio_keys; -+ gpio_keys_pdata->nbuttons = n_buttons; -+ gpio_keys_pdata->rep = autorepeat; -+ -+ pd = platform_device_alloc("gpio-keys", PLATFORM_DEVID_AUTO); -+ if (!pd) { -+ error = -ENOMEM; -+ goto err_free_mem; -+ } -+ -+ error = platform_device_add_data(pd, gpio_keys_pdata, -+ sizeof(*gpio_keys_pdata)); -+ if (error) -+ goto err_free_pdev; -+ -+ error = platform_device_add(pd); -+ if (error) -+ goto err_free_pdev; -+ -+ return pd; -+ -+err_free_pdev: -+ platform_device_put(pd); -+err_free_mem: -+ devm_kfree(&pdev->dev, gpio_keys_pdata); -+ return ERR_PTR(error); -+} -+ -+static int soc_button_remove(struct platform_device *pdev) -+{ -+ struct soc_button_data *priv = platform_get_drvdata(pdev); -+ -+ int i; -+ -+ for (i = 0; i < BUTTON_TYPES; i++) -+ if (priv->children[i]) -+ platform_device_unregister(priv->children[i]); -+ -+ return 0; -+} -+ -+static int soc_button_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ const struct acpi_device_id *id; +From 9c4948b06b2e8d23bbb4d65c7453b6b847d3f237 Mon Sep 17 00:00:00 2001 +From: qzed +Date: Wed, 19 Sep 2018 19:21:14 +0200 +Subject: [PATCH] Surface Book 2 / Surface Pro 2017 button support + +--- + drivers/input/misc/soc_button_array.c | 67 +++++++++++++++++++++-- + drivers/platform/x86/surfacepro3_button.c | 9 +++ + 2 files changed, 70 insertions(+), 6 deletions(-) + +diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c +index 23520df7650f..d74f8c3dd54b 100644 +--- a/drivers/input/misc/soc_button_array.c ++++ b/drivers/input/misc/soc_button_array.c +@@ -29,12 +29,20 @@ struct soc_button_info { + bool wakeup; + }; + ++struct soc_device_data { ++ /* Button info, may be NULL. */ + struct soc_button_info *button_info; -+ struct soc_button_data *priv; -+ struct platform_device *pd; -+ int i; -+ int error; ++ /* Special device check function, may be NULL. */ ++ int (*check)(struct device *); ++}; + -+ id = acpi_match_device(dev->driver->acpi_match_table, dev); -+ if (!id) -+ return -ENODEV; + /* + * 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 + * buttons into them based on whether the key should be auto repeat. + */ +-#define BUTTON_TYPES 2 ++#define BUTTON_TYPES 2 ++#define SURFACE_METHOD_DSM "_DSM" + + struct soc_button_data { + struct platform_device *children[BUTTON_TYPES]; +@@ -310,6 +318,7 @@ static int soc_button_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + const struct acpi_device_id *id; ++ struct soc_device_data *device_data; + struct soc_button_info *button_info; + struct soc_button_data *priv; + struct platform_device *pd; +@@ -320,12 +329,20 @@ static int soc_button_probe(struct platform_device *pdev) + if (!id) + return -ENODEV; + +- if (!id->driver_data) { ++ device_data = (struct soc_device_data *)id->driver_data; ++ if (device_data && device_data->check) { ++ // device dependent check, required for MSHW0040 ++ error = device_data->check(dev); ++ if (error != 0) ++ return error; ++ } + ++ if (device_data && device_data->button_info) { ++ button_info = (struct soc_button_info *)device_data->button_info; ++ } else { + button_info = soc_button_get_button_info(dev); + if (IS_ERR(button_info)) + return PTR_ERR(button_info); +- } else { +- button_info = (struct soc_button_info *)id->driver_data; + } + + error = gpiod_count(dev, NULL); +@@ -357,7 +374,7 @@ static int soc_button_probe(struct platform_device *pdev) + if (!priv->children[0] && !priv->children[1]) + return -ENODEV; + +- if (!id->driver_data) ++ if (!device_data || !device_data->button_info) + devm_kfree(dev, button_info); + + return 0; +@@ -377,9 +394,47 @@ static struct soc_button_info soc_button_PNP0C40[] = { + { } + }; + ++static struct soc_device_data soc_device_PNP0C40 = { ++ .button_info = soc_button_PNP0C40, ++ .check = NULL, ++}; ++ ++/* ++ * Special device check for Surface Book 2 and Surface Pro (2017). ++ * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned ++ * devices use MSHW0040 for power and volume buttons, however the way they ++ * have to be addressed differs. Make sure that we only load this drivers ++ * for the correct devices by checking if the _DSM method exists. ++ */ ++static int soc_device_check_MSHW0040(struct device *dev) ++{ + if (!acpi_has_method(ACPI_HANDLE(dev), SURFACE_METHOD_DSM)) + return -ENODEV; + -+ 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; -+ } -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, priv); -+ -+ for (i = 0; i < BUTTON_TYPES; i++) { -+ pd = soc_button_device_create(pdev, button_info, i == 0); -+ if (IS_ERR(pd)) { -+ error = PTR_ERR(pd); -+ if (error != -ENODEV) { -+ soc_button_remove(pdev); -+ return error; -+ } -+ continue; -+ } -+ -+ priv->children[i] = pd; -+ } -+ -+ if (!priv->children[0] && !priv->children[1]) -+ return -ENODEV; -+ -+ if (!id->driver_data) -+ devm_kfree(dev, button_info); -+ + return 0; +} + +/* -+ * 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 -+ * Platforms" ++ * Button infos for Microsoft Surface Book 2 and Surface Pro (2017). ++ * Extracted from DSDT. + */ +static struct soc_button_info soc_button_MSHW0040[] = { -+ { "power", 0, EV_KEY, KEY_POWER, false, true }, -+ { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false }, -+ { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false }, ++ { "power", 0, EV_KEY, KEY_POWER, false, true }, ++ { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false }, ++ { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false }, + { } +}; + -+static const struct acpi_device_id soc_button_acpi_match[] = { -+ { "MSHW0040", (unsigned long)soc_button_MSHW0040 }, -+ { } ++static struct soc_device_data soc_device_MSHW0040 = { ++ .button_info = soc_button_MSHW0040, ++ .check = soc_device_check_MSHW0040, +}; + -+MODULE_DEVICE_TABLE(acpi, soc_button_acpi_match); -+ -+static struct platform_driver soc_button_driver_sb2 = { -+ .probe = soc_button_probe, -+ .remove = soc_button_remove, -+ .driver = { -+ .name = "surfacebook2_button", -+ .acpi_match_table = ACPI_PTR(soc_button_acpi_match), -+ }, -+}; -+module_platform_driver(soc_button_driver_sb2); -+ -+MODULE_AUTHOR("Maximilian Luz"); -+MODULE_DESCRIPTION("Surface Book 2/Surface Pro (2017) Button Driver"); -+MODULE_LICENSE("GPL v2"); + static const struct acpi_device_id soc_button_acpi_match[] = { +- { "PNP0C40", (unsigned long)soc_button_PNP0C40 }, ++ { "PNP0C40", (unsigned long)&soc_device_PNP0C40 }, + { "ACPI0011", 0 }, ++ /* Microsoft Surface Book 2 and Surface Pro (2017) */ ++ { "MSHW0040", (unsigned long)&soc_device_MSHW0040 }, + { } + }; + diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c -index 1b491690ce07..9385262b65be 100644 +index 1b491690ce07..006c94eda7be 100644 --- a/drivers/platform/x86/surfacepro3_button.c +++ b/drivers/platform/x86/surfacepro3_button.c @@ -22,6 +22,7 @@ #define SURFACE_PRO3_BUTTON_HID "MSHW0028" #define SURFACE_PRO4_BUTTON_HID "MSHW0040" #define SURFACE_BUTTON_OBJ_NAME "VGBI" -+#define SURFACE_METHOD_DSM "_DSM" ++#define SURFACE_METHOD_DSM "_DSM" #define SURFACE_BUTTON_DEVICE_NAME "Surface Pro 3/4 Buttons" - + #define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8 -@@ -158,6 +159,9 @@ static int surface_button_add(struct acpi_device *device) +@@ -158,6 +159,14 @@ static int surface_button_add(struct acpi_device *device) strlen(SURFACE_BUTTON_OBJ_NAME))) return -ENODEV; - + ++ /* ++ * Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device ++ * ID (MSHW0040) for the power/volume buttons. Make sure this is the right ++ * device by checking for the _DSM method. ++ */ + if (acpi_has_method(device->handle, SURFACE_METHOD_DSM)) + return -ENODEV; + button = kzalloc(sizeof(struct surface_button), GFP_KERNEL); if (!button) return -ENOMEM; +-- +2.19.0 +