mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
Input: gpio_keys - add support for GPIO descriptors
[ Upstream commit5feeca3c1e] 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 commits633a21d80b("input: gpio_keys_polled: Add support for GPIO descriptors") and1ae5ddb6f8("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> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
80b0d7e623
commit
db7c1706fa
@@ -26,6 +26,7 @@
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_gpio.h>
|
||||
@@ -35,6 +36,7 @@
|
||||
struct gpio_button_data {
|
||||
const struct gpio_keys_button *button;
|
||||
struct input_dev *input;
|
||||
struct gpio_desc *gpiod;
|
||||
|
||||
struct timer_list release_timer;
|
||||
unsigned int release_delay; /* in msecs, for IRQ-only buttons */
|
||||
@@ -140,7 +142,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
|
||||
*/
|
||||
disable_irq(bdata->irq);
|
||||
|
||||
if (gpio_is_valid(bdata->button->gpio))
|
||||
if (bdata->gpiod)
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
else
|
||||
del_timer_sync(&bdata->release_timer);
|
||||
@@ -358,19 +360,20 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
|
||||
const struct gpio_keys_button *button = bdata->button;
|
||||
struct input_dev *input = bdata->input;
|
||||
unsigned int type = button->type ?: EV_KEY;
|
||||
int state = gpio_get_value_cansleep(button->gpio);
|
||||
int state;
|
||||
|
||||
state = gpiod_get_value_cansleep(bdata->gpiod);
|
||||
if (state < 0) {
|
||||
dev_err(input->dev.parent, "failed to get gpio state\n");
|
||||
dev_err(input->dev.parent,
|
||||
"failed to get gpio state: %d\n", state);
|
||||
return;
|
||||
}
|
||||
|
||||
state = (state ? 1 : 0) ^ button->active_low;
|
||||
if (type == EV_ABS) {
|
||||
if (state)
|
||||
input_event(input, type, button->code, button->value);
|
||||
} else {
|
||||
input_event(input, type, button->code, !!state);
|
||||
input_event(input, type, button->code, state);
|
||||
}
|
||||
input_sync(input);
|
||||
}
|
||||
@@ -456,7 +459,7 @@ static void gpio_keys_quiesce_key(void *data)
|
||||
{
|
||||
struct gpio_button_data *bdata = data;
|
||||
|
||||
if (gpio_is_valid(bdata->button->gpio))
|
||||
if (bdata->gpiod)
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
else
|
||||
del_timer_sync(&bdata->release_timer);
|
||||
@@ -478,18 +481,30 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
||||
bdata->button = button;
|
||||
spin_lock_init(&bdata->lock);
|
||||
|
||||
/*
|
||||
* Legacy GPIO number, so request the GPIO here and
|
||||
* convert it to descriptor.
|
||||
*/
|
||||
if (gpio_is_valid(button->gpio)) {
|
||||
unsigned flags = GPIOF_IN;
|
||||
|
||||
error = devm_gpio_request_one(&pdev->dev, button->gpio,
|
||||
GPIOF_IN, desc);
|
||||
if (button->active_low)
|
||||
flags |= GPIOF_ACTIVE_LOW;
|
||||
|
||||
error = devm_gpio_request_one(&pdev->dev, button->gpio, flags,
|
||||
desc);
|
||||
if (error < 0) {
|
||||
dev_err(dev, "Failed to request GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
bdata->gpiod = gpio_to_desc(button->gpio);
|
||||
if (!bdata->gpiod)
|
||||
return -EINVAL;
|
||||
|
||||
if (button->debounce_interval) {
|
||||
error = gpio_set_debounce(button->gpio,
|
||||
error = gpiod_set_debounce(bdata->gpiod,
|
||||
button->debounce_interval * 1000);
|
||||
/* use timer if gpiolib doesn't provide debounce */
|
||||
if (error < 0)
|
||||
@@ -500,7 +515,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
||||
if (button->irq) {
|
||||
bdata->irq = button->irq;
|
||||
} else {
|
||||
irq = gpio_to_irq(button->gpio);
|
||||
irq = gpiod_to_irq(bdata->gpiod);
|
||||
if (irq < 0) {
|
||||
error = irq;
|
||||
dev_err(dev,
|
||||
@@ -575,7 +590,7 @@ static void gpio_keys_report_state(struct gpio_keys_drvdata *ddata)
|
||||
|
||||
for (i = 0; i < ddata->pdata->nbuttons; i++) {
|
||||
struct gpio_button_data *bdata = &ddata->data[i];
|
||||
if (gpio_is_valid(bdata->button->gpio))
|
||||
if (bdata->gpiod)
|
||||
gpio_keys_gpio_report_event(bdata);
|
||||
}
|
||||
input_sync(input);
|
||||
|
||||
Reference in New Issue
Block a user