Skip to content

Commit

Permalink
input: gpio_keys_polled: Add support for GPIO descriptors
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Aaron Lu authored and Rafael J. Wysocki committed Nov 4, 2014
1 parent 5c51277 commit 633a21d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 12 deletions.
39 changes: 27 additions & 12 deletions drivers/input/keyboard/gpio_keys_polled.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio_keys.h>
#include <linux/of.h>
#include <linux/of_platform.h>
Expand Down Expand Up @@ -51,15 +52,14 @@ static void gpio_keys_polled_check_state(struct input_dev *input,
int state;

if (bdata->can_sleep)
state = !!gpio_get_value_cansleep(button->gpio);
state = !!gpiod_get_value_cansleep(button->gpiod);
else
state = !!gpio_get_value(button->gpio);
state = !!gpiod_get_value(button->gpiod);

if (state != bdata->last_state) {
unsigned int type = button->type ?: EV_KEY;

input_event(input, type, button->code,
!!(state ^ button->active_low));
input_event(input, type, button->code, state);
input_sync(input);
bdata->count = 0;
bdata->last_state = state;
Expand Down Expand Up @@ -259,23 +259,38 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
for (i = 0; i < pdata->nbuttons; i++) {
struct gpio_keys_button *button = &pdata->buttons[i];
struct gpio_keys_button_data *bdata = &bdev->data[i];
unsigned int gpio = button->gpio;
unsigned int type = button->type ?: EV_KEY;

if (button->wakeup) {
dev_err(dev, DRV_NAME " does not support wakeup\n");
return -EINVAL;
}

error = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_IN,
button->desc ? : DRV_NAME);
if (error) {
dev_err(dev, "unable to claim gpio %u, err=%d\n",
gpio, error);
return error;
/*
* Legacy GPIO number so request the GPIO here and
* convert it to descriptor.
*/
if (!button->gpiod && gpio_is_valid(button->gpio)) {
unsigned flags = 0;

if (button->active_low)
flags |= GPIOF_ACTIVE_LOW;

error = devm_gpio_request_one(&pdev->dev, button->gpio,
flags, button->desc ? : DRV_NAME);
if (error) {
dev_err(dev, "unable to claim gpio %u, err=%d\n",
button->gpio, error);
return error;
}

button->gpiod = gpio_to_desc(button->gpio);
}

bdata->can_sleep = gpio_cansleep(gpio);
if (IS_ERR(button->gpiod))
return PTR_ERR(button->gpiod);

bdata->can_sleep = gpiod_cansleep(button->gpiod);
bdata->last_state = -1;
bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
pdata->poll_interval);
Expand Down
3 changes: 3 additions & 0 deletions include/linux/gpio_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _GPIO_KEYS_H

struct device;
struct gpio_desc;

/**
* struct gpio_keys_button - configuration parameters
Expand All @@ -17,6 +18,7 @@ struct device;
* disable button via sysfs
* @value: axis value for %EV_ABS
* @irq: Irq number in case of interrupt keys
* @gpiod: GPIO descriptor
*/
struct gpio_keys_button {
unsigned int code;
Expand All @@ -29,6 +31,7 @@ struct gpio_keys_button {
bool can_disable;
int value;
unsigned int irq;
struct gpio_desc *gpiod;
};

/**
Expand Down

0 comments on commit 633a21d

Please sign in to comment.