input: gpio_keys_polled: Add support for GPIO descriptors
authorAaron Lu <aaron.lu@intel.com>
Tue, 21 Oct 2014 21:30:25 +0000 (23:30 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 4 Nov 2014 20:58:23 +0000 (21:58 +0100)
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>
drivers/input/keyboard/gpio_keys_polled.c
include/linux/gpio_keys.h

index 432d36395f3503d7ffcaeae88fb6a02c85c48fd3..b7a514ced5090e241f99e2424e090a5705420bbf 100644 (file)
@@ -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>
@@ -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;
@@ -259,7 +259,6 @@ 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) {
@@ -267,15 +266,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
                        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);
index 8b622468952c427470fa44905ba991d7220a0d68..ee2d8c6f91300db725b3681c830d4568de71cb19 100644 (file)
@@ -2,6 +2,7 @@
 #define _GPIO_KEYS_H
 
 struct device;
+struct gpio_desc;
 
 /**
  * struct gpio_keys_button - configuration parameters
@@ -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;
@@ -29,6 +31,7 @@ struct gpio_keys_button {
        bool can_disable;
        int value;
        unsigned int irq;
+       struct gpio_desc *gpiod;
 };
 
 /**