| .. | .. | 
|---|
|  | 1 | +// SPDX-License-Identifier: GPL-2.0-only | 
|---|
| 1 | 2 | /* | 
|---|
| 2 | 3 | *  Driver for buttons on GPIO lines not capable of generating interrupts | 
|---|
| 3 | 4 | * | 
|---|
| .. | .. | 
|---|
| 9 | 10 | * | 
|---|
| 10 | 11 | *  also was based on: /drivers/input/keyboard/gpio_keys.c | 
|---|
| 11 | 12 | *	Copyright 2005 Phil Blundell | 
|---|
| 12 |  | - * | 
|---|
| 13 |  | - *  This program is free software; you can redistribute it and/or modify | 
|---|
| 14 |  | - *  it under the terms of the GNU General Public License version 2 as | 
|---|
| 15 |  | - *  published by the Free Software Foundation. | 
|---|
| 16 | 13 | */ | 
|---|
| 17 | 14 |  | 
|---|
| 18 | 15 | #include <linux/kernel.h> | 
|---|
| 19 | 16 | #include <linux/module.h> | 
|---|
| 20 | 17 | #include <linux/slab.h> | 
|---|
| 21 | 18 | #include <linux/input.h> | 
|---|
| 22 |  | -#include <linux/input-polldev.h> | 
|---|
| 23 | 19 | #include <linux/ioport.h> | 
|---|
| 24 | 20 | #include <linux/platform_device.h> | 
|---|
| 25 | 21 | #include <linux/gpio.h> | 
|---|
| .. | .. | 
|---|
| 37 | 33 | }; | 
|---|
| 38 | 34 |  | 
|---|
| 39 | 35 | struct gpio_keys_polled_dev { | 
|---|
| 40 |  | -	struct input_polled_dev *poll_dev; | 
|---|
|  | 36 | +	struct input_dev *input; | 
|---|
| 41 | 37 | struct device *dev; | 
|---|
| 42 | 38 | const struct gpio_keys_platform_data *pdata; | 
|---|
| 43 | 39 | unsigned long rel_axis_seen[BITS_TO_LONGS(REL_CNT)]; | 
|---|
| 44 | 40 | unsigned long abs_axis_seen[BITS_TO_LONGS(ABS_CNT)]; | 
|---|
| 45 |  | -	struct gpio_keys_button_data data[0]; | 
|---|
|  | 41 | +	struct gpio_keys_button_data data[]; | 
|---|
| 46 | 42 | }; | 
|---|
| 47 | 43 |  | 
|---|
| 48 |  | -static void gpio_keys_button_event(struct input_polled_dev *dev, | 
|---|
|  | 44 | +static void gpio_keys_button_event(struct input_dev *input, | 
|---|
| 49 | 45 | const struct gpio_keys_button *button, | 
|---|
| 50 | 46 | int state) | 
|---|
| 51 | 47 | { | 
|---|
| 52 |  | -	struct gpio_keys_polled_dev *bdev = dev->private; | 
|---|
| 53 |  | -	struct input_dev *input = dev->input; | 
|---|
|  | 48 | +	struct gpio_keys_polled_dev *bdev = input_get_drvdata(input); | 
|---|
| 54 | 49 | unsigned int type = button->type ?: EV_KEY; | 
|---|
| 55 | 50 |  | 
|---|
| 56 | 51 | if (type == EV_REL) { | 
|---|
| .. | .. | 
|---|
| 69 | 64 | } | 
|---|
| 70 | 65 | } | 
|---|
| 71 | 66 |  | 
|---|
| 72 |  | -static void gpio_keys_polled_check_state(struct input_polled_dev *dev, | 
|---|
|  | 67 | +static void gpio_keys_polled_check_state(struct input_dev *input, | 
|---|
| 73 | 68 | const struct gpio_keys_button *button, | 
|---|
| 74 | 69 | struct gpio_keys_button_data *bdata) | 
|---|
| 75 | 70 | { | 
|---|
| .. | .. | 
|---|
| 77 | 72 |  | 
|---|
| 78 | 73 | state = gpiod_get_value_cansleep(bdata->gpiod); | 
|---|
| 79 | 74 | if (state < 0) { | 
|---|
| 80 |  | -		dev_err(dev->input->dev.parent, | 
|---|
|  | 75 | +		dev_err(input->dev.parent, | 
|---|
| 81 | 76 | "failed to get gpio state: %d\n", state); | 
|---|
| 82 | 77 | } else { | 
|---|
| 83 |  | -		gpio_keys_button_event(dev, button, state); | 
|---|
|  | 78 | +		gpio_keys_button_event(input, button, state); | 
|---|
| 84 | 79 |  | 
|---|
| 85 | 80 | if (state != bdata->last_state) { | 
|---|
| 86 | 81 | bdata->count = 0; | 
|---|
| .. | .. | 
|---|
| 89 | 84 | } | 
|---|
| 90 | 85 | } | 
|---|
| 91 | 86 |  | 
|---|
| 92 |  | -static void gpio_keys_polled_poll(struct input_polled_dev *dev) | 
|---|
|  | 87 | +static void gpio_keys_polled_poll(struct input_dev *input) | 
|---|
| 93 | 88 | { | 
|---|
| 94 |  | -	struct gpio_keys_polled_dev *bdev = dev->private; | 
|---|
|  | 89 | +	struct gpio_keys_polled_dev *bdev = input_get_drvdata(input); | 
|---|
| 95 | 90 | const struct gpio_keys_platform_data *pdata = bdev->pdata; | 
|---|
| 96 |  | -	struct input_dev *input = dev->input; | 
|---|
| 97 | 91 | int i; | 
|---|
| 98 | 92 |  | 
|---|
| 99 | 93 | memset(bdev->rel_axis_seen, 0, sizeof(bdev->rel_axis_seen)); | 
|---|
| .. | .. | 
|---|
| 104 | 98 |  | 
|---|
| 105 | 99 | if (bdata->count < bdata->threshold) { | 
|---|
| 106 | 100 | bdata->count++; | 
|---|
| 107 |  | -			gpio_keys_button_event(dev, &pdata->buttons[i], | 
|---|
|  | 101 | +			gpio_keys_button_event(input, &pdata->buttons[i], | 
|---|
| 108 | 102 | bdata->last_state); | 
|---|
| 109 | 103 | } else { | 
|---|
| 110 |  | -			gpio_keys_polled_check_state(dev, &pdata->buttons[i], | 
|---|
|  | 104 | +			gpio_keys_polled_check_state(input, &pdata->buttons[i], | 
|---|
| 111 | 105 | bdata); | 
|---|
| 112 | 106 | } | 
|---|
| 113 | 107 | } | 
|---|
| .. | .. | 
|---|
| 125 | 119 | input_sync(input); | 
|---|
| 126 | 120 | } | 
|---|
| 127 | 121 |  | 
|---|
| 128 |  | -static void gpio_keys_polled_open(struct input_polled_dev *dev) | 
|---|
|  | 122 | +static int gpio_keys_polled_open(struct input_dev *input) | 
|---|
| 129 | 123 | { | 
|---|
| 130 |  | -	struct gpio_keys_polled_dev *bdev = dev->private; | 
|---|
|  | 124 | +	struct gpio_keys_polled_dev *bdev = input_get_drvdata(input); | 
|---|
| 131 | 125 | const struct gpio_keys_platform_data *pdata = bdev->pdata; | 
|---|
| 132 | 126 |  | 
|---|
| 133 | 127 | if (pdata->enable) | 
|---|
| 134 | 128 | pdata->enable(bdev->dev); | 
|---|
|  | 129 | + | 
|---|
|  | 130 | +	return 0; | 
|---|
| 135 | 131 | } | 
|---|
| 136 | 132 |  | 
|---|
| 137 |  | -static void gpio_keys_polled_close(struct input_polled_dev *dev) | 
|---|
|  | 133 | +static void gpio_keys_polled_close(struct input_dev *input) | 
|---|
| 138 | 134 | { | 
|---|
| 139 |  | -	struct gpio_keys_polled_dev *bdev = dev->private; | 
|---|
|  | 135 | +	struct gpio_keys_polled_dev *bdev = input_get_drvdata(input); | 
|---|
| 140 | 136 | const struct gpio_keys_platform_data *pdata = bdev->pdata; | 
|---|
| 141 | 137 |  | 
|---|
| 142 | 138 | if (pdata->disable) | 
|---|
| .. | .. | 
|---|
| 167 | 163 |  | 
|---|
| 168 | 164 | pdata->rep = device_property_present(dev, "autorepeat"); | 
|---|
| 169 | 165 | device_property_read_u32(dev, "poll-interval", &pdata->poll_interval); | 
|---|
|  | 166 | + | 
|---|
|  | 167 | +	device_property_read_string(dev, "label", &pdata->name); | 
|---|
| 170 | 168 |  | 
|---|
| 171 | 169 | device_for_each_child_node(dev, child) { | 
|---|
| 172 | 170 | if (fwnode_property_read_u32(child, "linux,code", | 
|---|
| .. | .. | 
|---|
| 233 | 231 | struct fwnode_handle *child = NULL; | 
|---|
| 234 | 232 | const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); | 
|---|
| 235 | 233 | struct gpio_keys_polled_dev *bdev; | 
|---|
| 236 |  | -	struct input_polled_dev *poll_dev; | 
|---|
| 237 | 234 | struct input_dev *input; | 
|---|
| 238 |  | -	size_t size; | 
|---|
| 239 | 235 | int error; | 
|---|
| 240 | 236 | int i; | 
|---|
| 241 | 237 |  | 
|---|
| .. | .. | 
|---|
| 250 | 246 | return -EINVAL; | 
|---|
| 251 | 247 | } | 
|---|
| 252 | 248 |  | 
|---|
| 253 |  | -	size = sizeof(struct gpio_keys_polled_dev) + | 
|---|
| 254 |  | -			pdata->nbuttons * sizeof(struct gpio_keys_button_data); | 
|---|
| 255 |  | -	bdev = devm_kzalloc(dev, size, GFP_KERNEL); | 
|---|
|  | 249 | +	bdev = devm_kzalloc(dev, struct_size(bdev, data, pdata->nbuttons), | 
|---|
|  | 250 | +			    GFP_KERNEL); | 
|---|
| 256 | 251 | if (!bdev) { | 
|---|
| 257 | 252 | dev_err(dev, "no memory for private data\n"); | 
|---|
| 258 | 253 | return -ENOMEM; | 
|---|
| 259 | 254 | } | 
|---|
| 260 | 255 |  | 
|---|
| 261 |  | -	poll_dev = devm_input_allocate_polled_device(dev); | 
|---|
| 262 |  | -	if (!poll_dev) { | 
|---|
| 263 |  | -		dev_err(dev, "no memory for polled device\n"); | 
|---|
|  | 256 | +	input = devm_input_allocate_device(dev); | 
|---|
|  | 257 | +	if (!input) { | 
|---|
|  | 258 | +		dev_err(dev, "no memory for input device\n"); | 
|---|
| 264 | 259 | return -ENOMEM; | 
|---|
| 265 | 260 | } | 
|---|
| 266 | 261 |  | 
|---|
| 267 |  | -	poll_dev->private = bdev; | 
|---|
| 268 |  | -	poll_dev->poll = gpio_keys_polled_poll; | 
|---|
| 269 |  | -	poll_dev->poll_interval = pdata->poll_interval; | 
|---|
| 270 |  | -	poll_dev->open = gpio_keys_polled_open; | 
|---|
| 271 |  | -	poll_dev->close = gpio_keys_polled_close; | 
|---|
|  | 262 | +	input_set_drvdata(input, bdev); | 
|---|
| 272 | 263 |  | 
|---|
| 273 |  | -	input = poll_dev->input; | 
|---|
| 274 |  | - | 
|---|
| 275 |  | -	input->name = pdev->name; | 
|---|
|  | 264 | +	input->name = pdata->name ?: pdev->name; | 
|---|
| 276 | 265 | input->phys = DRV_NAME"/input0"; | 
|---|
| 277 | 266 |  | 
|---|
| 278 | 267 | input->id.bustype = BUS_HOST; | 
|---|
| 279 | 268 | input->id.vendor = 0x0001; | 
|---|
| 280 | 269 | input->id.product = 0x0001; | 
|---|
| 281 | 270 | input->id.version = 0x0100; | 
|---|
|  | 271 | + | 
|---|
|  | 272 | +	input->open = gpio_keys_polled_open; | 
|---|
|  | 273 | +	input->close = gpio_keys_polled_close; | 
|---|
| 282 | 274 |  | 
|---|
| 283 | 275 | __set_bit(EV_KEY, input->evbit); | 
|---|
| 284 | 276 | if (pdata->rep) | 
|---|
| .. | .. | 
|---|
| 303 | 295 | return -EINVAL; | 
|---|
| 304 | 296 | } | 
|---|
| 305 | 297 |  | 
|---|
| 306 |  | -			bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, | 
|---|
| 307 |  | -								NULL, child, | 
|---|
| 308 |  | -								GPIOD_IN, | 
|---|
| 309 |  | -								button->desc); | 
|---|
|  | 298 | +			bdata->gpiod = devm_fwnode_gpiod_get(dev, child, | 
|---|
|  | 299 | +							     NULL, GPIOD_IN, | 
|---|
|  | 300 | +							     button->desc); | 
|---|
| 310 | 301 | if (IS_ERR(bdata->gpiod)) { | 
|---|
| 311 | 302 | error = PTR_ERR(bdata->gpiod); | 
|---|
| 312 | 303 | if (error != -EPROBE_DEFER) | 
|---|
| .. | .. | 
|---|
| 356 | 347 |  | 
|---|
| 357 | 348 | fwnode_handle_put(child); | 
|---|
| 358 | 349 |  | 
|---|
| 359 |  | -	bdev->poll_dev = poll_dev; | 
|---|
|  | 350 | +	bdev->input = input; | 
|---|
| 360 | 351 | bdev->dev = dev; | 
|---|
| 361 | 352 | bdev->pdata = pdata; | 
|---|
| 362 | 353 |  | 
|---|
| 363 |  | -	error = input_register_polled_device(poll_dev); | 
|---|
|  | 354 | +	error = input_setup_polling(input, gpio_keys_polled_poll); | 
|---|
|  | 355 | +	if (error) { | 
|---|
|  | 356 | +		dev_err(dev, "unable to set up polling, err=%d\n", error); | 
|---|
|  | 357 | +		return error; | 
|---|
|  | 358 | +	} | 
|---|
|  | 359 | + | 
|---|
|  | 360 | +	input_set_poll_interval(input, pdata->poll_interval); | 
|---|
|  | 361 | + | 
|---|
|  | 362 | +	error = input_register_device(input); | 
|---|
| 364 | 363 | if (error) { | 
|---|
| 365 | 364 | dev_err(dev, "unable to register polled device, err=%d\n", | 
|---|
| 366 | 365 | error); | 
|---|
| .. | .. | 
|---|
| 369 | 368 |  | 
|---|
| 370 | 369 | /* report initial state of the buttons */ | 
|---|
| 371 | 370 | for (i = 0; i < pdata->nbuttons; i++) | 
|---|
| 372 |  | -		gpio_keys_polled_check_state(poll_dev, &pdata->buttons[i], | 
|---|
|  | 371 | +		gpio_keys_polled_check_state(input, &pdata->buttons[i], | 
|---|
| 373 | 372 | &bdev->data[i]); | 
|---|
| 374 | 373 |  | 
|---|
| 375 | 374 | input_sync(input); | 
|---|