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

Input: gpio_keys - add support for GPIO descriptors

GPIO descriptors are the preferred way over legacy GPIO numbers
nowadays. Convert the driver to use GPIO descriptors internally but
still allow passing legacy GPIO numbers from platform data to support
existing platforms.

Based on commits 633a21d80b4a2cd6 ("input: gpio_keys_polled: Add support
for GPIO descriptors") and 1ae5ddb6f8837558 ("Input: gpio_keys_polled -
request GPIO pin as input.").

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Geert Uytterhoeven and committed by
Dmitry Torokhov
5feeca3c 0860913b

+26 -11
+26 -11
drivers/input/keyboard/gpio_keys.c
··· 26 26 #include <linux/gpio_keys.h> 27 27 #include <linux/workqueue.h> 28 28 #include <linux/gpio.h> 29 + #include <linux/gpio/consumer.h> 29 30 #include <linux/of.h> 30 31 #include <linux/of_platform.h> 31 32 #include <linux/of_gpio.h> ··· 36 35 struct gpio_button_data { 37 36 const struct gpio_keys_button *button; 38 37 struct input_dev *input; 38 + struct gpio_desc *gpiod; 39 39 40 40 struct timer_list release_timer; 41 41 unsigned int release_delay; /* in msecs, for IRQ-only buttons */ ··· 142 140 */ 143 141 disable_irq(bdata->irq); 144 142 145 - if (gpio_is_valid(bdata->button->gpio)) 143 + if (bdata->gpiod) 146 144 cancel_delayed_work_sync(&bdata->work); 147 145 else 148 146 del_timer_sync(&bdata->release_timer); ··· 360 358 const struct gpio_keys_button *button = bdata->button; 361 359 struct input_dev *input = bdata->input; 362 360 unsigned int type = button->type ?: EV_KEY; 363 - int state = gpio_get_value_cansleep(button->gpio); 361 + int state; 364 362 363 + state = gpiod_get_value_cansleep(bdata->gpiod); 365 364 if (state < 0) { 366 - dev_err(input->dev.parent, "failed to get gpio state\n"); 365 + dev_err(input->dev.parent, 366 + "failed to get gpio state: %d\n", state); 367 367 return; 368 368 } 369 369 370 - state = (state ? 1 : 0) ^ button->active_low; 371 370 if (type == EV_ABS) { 372 371 if (state) 373 372 input_event(input, type, button->code, button->value); 374 373 } else { 375 - input_event(input, type, button->code, !!state); 374 + input_event(input, type, button->code, state); 376 375 } 377 376 input_sync(input); 378 377 } ··· 459 456 { 460 457 struct gpio_button_data *bdata = data; 461 458 462 - if (gpio_is_valid(bdata->button->gpio)) 459 + if (bdata->gpiod) 463 460 cancel_delayed_work_sync(&bdata->work); 464 461 else 465 462 del_timer_sync(&bdata->release_timer); ··· 481 478 bdata->button = button; 482 479 spin_lock_init(&bdata->lock); 483 480 481 + /* 482 + * Legacy GPIO number, so request the GPIO here and 483 + * convert it to descriptor. 484 + */ 484 485 if (gpio_is_valid(button->gpio)) { 486 + unsigned flags = GPIOF_IN; 485 487 486 - error = devm_gpio_request_one(&pdev->dev, button->gpio, 487 - GPIOF_IN, desc); 488 + if (button->active_low) 489 + flags |= GPIOF_ACTIVE_LOW; 490 + 491 + error = devm_gpio_request_one(&pdev->dev, button->gpio, flags, 492 + desc); 488 493 if (error < 0) { 489 494 dev_err(dev, "Failed to request GPIO %d, error %d\n", 490 495 button->gpio, error); 491 496 return error; 492 497 } 493 498 499 + bdata->gpiod = gpio_to_desc(button->gpio); 500 + if (!bdata->gpiod) 501 + return -EINVAL; 502 + 494 503 if (button->debounce_interval) { 495 - error = gpio_set_debounce(button->gpio, 504 + error = gpiod_set_debounce(bdata->gpiod, 496 505 button->debounce_interval * 1000); 497 506 /* use timer if gpiolib doesn't provide debounce */ 498 507 if (error < 0) ··· 515 500 if (button->irq) { 516 501 bdata->irq = button->irq; 517 502 } else { 518 - irq = gpio_to_irq(button->gpio); 503 + irq = gpiod_to_irq(bdata->gpiod); 519 504 if (irq < 0) { 520 505 error = irq; 521 506 dev_err(dev, ··· 590 575 591 576 for (i = 0; i < ddata->pdata->nbuttons; i++) { 592 577 struct gpio_button_data *bdata = &ddata->data[i]; 593 - if (gpio_is_valid(bdata->button->gpio)) 578 + if (bdata->gpiod) 594 579 gpio_keys_gpio_report_event(bdata); 595 580 } 596 581 input_sync(input);