Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

platform/surface: Remove Surface 3 Button driver

The Surface 3 buttons are now handled by the generic soc_button_array
driver. As part of adding support to soc_button_array the ACPI code
now instantiates a platform_device rather then an i2c_client so there
no longer is an i2c_client for this driver to bind to.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Maximilian Luz <luzmaximilian@gmail.com
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20220224110241.9613-3-hdegoede@redhat.com

-255
-7
drivers/platform/surface/Kconfig
··· 28 28 To compile this driver as a module, choose M here: the module will 29 29 be called surface3-wmi. 30 30 31 - config SURFACE_3_BUTTON 32 - tristate "Power/home/volume buttons driver for Microsoft Surface 3 tablet" 33 - depends on ACPI 34 - depends on KEYBOARD_GPIO && I2C 35 - help 36 - This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet. 37 - 38 31 config SURFACE_3_POWER_OPREGION 39 32 tristate "Surface 3 battery platform operation region support" 40 33 depends on ACPI
-1
drivers/platform/surface/Makefile
··· 5 5 # 6 6 7 7 obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o 8 - obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o 9 8 obj-$(CONFIG_SURFACE_3_POWER_OPREGION) += surface3_power.o 10 9 obj-$(CONFIG_SURFACE_ACPI_NOTIFY) += surface_acpi_notify.o 11 10 obj-$(CONFIG_SURFACE_AGGREGATOR) += aggregator/
-247
drivers/platform/surface/surface3_button.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Supports for the button array on the Surface tablets. 4 - * 5 - * (C) Copyright 2016 Red Hat, Inc 6 - * 7 - * Based on soc_button_array.c: 8 - * 9 - * {C} Copyright 2014 Intel Corporation 10 - */ 11 - 12 - #include <linux/module.h> 13 - #include <linux/input.h> 14 - #include <linux/init.h> 15 - #include <linux/kernel.h> 16 - #include <linux/i2c.h> 17 - #include <linux/slab.h> 18 - #include <linux/acpi.h> 19 - #include <linux/gpio/consumer.h> 20 - #include <linux/gpio_keys.h> 21 - #include <linux/gpio.h> 22 - #include <linux/platform_device.h> 23 - 24 - 25 - #define SURFACE_BUTTON_OBJ_NAME "TEV2" 26 - #define MAX_NBUTTONS 4 27 - 28 - /* 29 - * Some of the buttons like volume up/down are auto repeat, while others 30 - * are not. To support both, we register two platform devices, and put 31 - * buttons into them based on whether the key should be auto repeat. 32 - */ 33 - #define BUTTON_TYPES 2 34 - 35 - /* 36 - * Power button, Home button, Volume buttons support is supposed to 37 - * be covered by drivers/input/misc/soc_button_array.c, which is implemented 38 - * according to "Windows ACPI Design Guide for SoC Platforms". 39 - * However surface 3 seems not to obey the specs, instead it uses 40 - * device TEV2(MSHW0028) for declaring the GPIOs. The gpios are also slightly 41 - * different in which the Home button is active high. 42 - * Compared to surfacepro3_button.c which also handles MSHW0028, the Surface 3 43 - * is a reduce platform and thus uses GPIOs, not ACPI events. 44 - * We choose an I2C driver here because we need to access the resources 45 - * declared under the device node, while surfacepro3_button.c only needs 46 - * the ACPI companion node. 47 - */ 48 - static const struct acpi_device_id surface3_acpi_match[] = { 49 - { "MSHW0028", 0 }, 50 - { } 51 - }; 52 - MODULE_DEVICE_TABLE(acpi, surface3_acpi_match); 53 - 54 - struct surface3_button_info { 55 - const char *name; 56 - int acpi_index; 57 - unsigned int event_type; 58 - unsigned int event_code; 59 - bool autorepeat; 60 - bool wakeup; 61 - bool active_low; 62 - }; 63 - 64 - struct surface3_button_data { 65 - struct platform_device *children[BUTTON_TYPES]; 66 - }; 67 - 68 - /* 69 - * Get the Nth GPIO number from the ACPI object. 70 - */ 71 - static int surface3_button_lookup_gpio(struct device *dev, int acpi_index) 72 - { 73 - struct gpio_desc *desc; 74 - int gpio; 75 - 76 - desc = gpiod_get_index(dev, NULL, acpi_index, GPIOD_ASIS); 77 - if (IS_ERR(desc)) 78 - return PTR_ERR(desc); 79 - 80 - gpio = desc_to_gpio(desc); 81 - 82 - gpiod_put(desc); 83 - 84 - return gpio; 85 - } 86 - 87 - static struct platform_device * 88 - surface3_button_device_create(struct i2c_client *client, 89 - const struct surface3_button_info *button_info, 90 - bool autorepeat) 91 - { 92 - const struct surface3_button_info *info; 93 - struct platform_device *pd; 94 - struct gpio_keys_button *gpio_keys; 95 - struct gpio_keys_platform_data *gpio_keys_pdata; 96 - int n_buttons = 0; 97 - int gpio; 98 - int error; 99 - 100 - gpio_keys_pdata = devm_kzalloc(&client->dev, 101 - sizeof(*gpio_keys_pdata) + 102 - sizeof(*gpio_keys) * MAX_NBUTTONS, 103 - GFP_KERNEL); 104 - if (!gpio_keys_pdata) 105 - return ERR_PTR(-ENOMEM); 106 - 107 - gpio_keys = (void *)(gpio_keys_pdata + 1); 108 - 109 - for (info = button_info; info->name; info++) { 110 - if (info->autorepeat != autorepeat) 111 - continue; 112 - 113 - gpio = surface3_button_lookup_gpio(&client->dev, 114 - info->acpi_index); 115 - if (!gpio_is_valid(gpio)) 116 - continue; 117 - 118 - gpio_keys[n_buttons].type = info->event_type; 119 - gpio_keys[n_buttons].code = info->event_code; 120 - gpio_keys[n_buttons].gpio = gpio; 121 - gpio_keys[n_buttons].active_low = info->active_low; 122 - gpio_keys[n_buttons].desc = info->name; 123 - gpio_keys[n_buttons].wakeup = info->wakeup; 124 - n_buttons++; 125 - } 126 - 127 - if (n_buttons == 0) { 128 - error = -ENODEV; 129 - goto err_free_mem; 130 - } 131 - 132 - gpio_keys_pdata->buttons = gpio_keys; 133 - gpio_keys_pdata->nbuttons = n_buttons; 134 - gpio_keys_pdata->rep = autorepeat; 135 - 136 - pd = platform_device_alloc("gpio-keys", PLATFORM_DEVID_AUTO); 137 - if (!pd) { 138 - error = -ENOMEM; 139 - goto err_free_mem; 140 - } 141 - 142 - error = platform_device_add_data(pd, gpio_keys_pdata, 143 - sizeof(*gpio_keys_pdata)); 144 - if (error) 145 - goto err_free_pdev; 146 - 147 - error = platform_device_add(pd); 148 - if (error) 149 - goto err_free_pdev; 150 - 151 - return pd; 152 - 153 - err_free_pdev: 154 - platform_device_put(pd); 155 - err_free_mem: 156 - devm_kfree(&client->dev, gpio_keys_pdata); 157 - return ERR_PTR(error); 158 - } 159 - 160 - static int surface3_button_remove(struct i2c_client *client) 161 - { 162 - struct surface3_button_data *priv = i2c_get_clientdata(client); 163 - 164 - int i; 165 - 166 - for (i = 0; i < BUTTON_TYPES; i++) 167 - if (priv->children[i]) 168 - platform_device_unregister(priv->children[i]); 169 - 170 - return 0; 171 - } 172 - 173 - static struct surface3_button_info surface3_button_surface3[] = { 174 - { "power", 0, EV_KEY, KEY_POWER, false, true, true }, 175 - { "home", 1, EV_KEY, KEY_LEFTMETA, false, true, false }, 176 - { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false, true }, 177 - { "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false, true }, 178 - { } 179 - }; 180 - 181 - static int surface3_button_probe(struct i2c_client *client, 182 - const struct i2c_device_id *id) 183 - { 184 - struct device *dev = &client->dev; 185 - struct surface3_button_data *priv; 186 - struct platform_device *pd; 187 - int i; 188 - int error; 189 - 190 - if (strncmp(acpi_device_bid(ACPI_COMPANION(&client->dev)), 191 - SURFACE_BUTTON_OBJ_NAME, 192 - strlen(SURFACE_BUTTON_OBJ_NAME))) 193 - return -ENODEV; 194 - 195 - error = gpiod_count(dev, NULL); 196 - if (error < 0) { 197 - dev_dbg(dev, "no GPIO attached, ignoring...\n"); 198 - return error; 199 - } 200 - 201 - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 202 - if (!priv) 203 - return -ENOMEM; 204 - 205 - i2c_set_clientdata(client, priv); 206 - 207 - for (i = 0; i < BUTTON_TYPES; i++) { 208 - pd = surface3_button_device_create(client, 209 - surface3_button_surface3, 210 - i == 0); 211 - if (IS_ERR(pd)) { 212 - error = PTR_ERR(pd); 213 - if (error != -ENODEV) { 214 - surface3_button_remove(client); 215 - return error; 216 - } 217 - continue; 218 - } 219 - 220 - priv->children[i] = pd; 221 - } 222 - 223 - if (!priv->children[0] && !priv->children[1]) 224 - return -ENODEV; 225 - 226 - return 0; 227 - } 228 - 229 - static const struct i2c_device_id surface3_id[] = { 230 - { } 231 - }; 232 - MODULE_DEVICE_TABLE(i2c, surface3_id); 233 - 234 - static struct i2c_driver surface3_driver = { 235 - .probe = surface3_button_probe, 236 - .remove = surface3_button_remove, 237 - .id_table = surface3_id, 238 - .driver = { 239 - .name = "surface3", 240 - .acpi_match_table = ACPI_PTR(surface3_acpi_match), 241 - }, 242 - }; 243 - module_i2c_driver(surface3_driver); 244 - 245 - MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); 246 - MODULE_DESCRIPTION("surface3 button array driver"); 247 - MODULE_LICENSE("GPL v2");