|
@@ -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;
|
|
|
+
|
|
|
+ if (button->active_low)
|
|
|
+ flags |= GPIOF_ACTIVE_LOW;
|
|
|
|
|
|
- error = devm_gpio_request_one(&pdev->dev, button->gpio,
|
|
|
- GPIOF_IN, desc);
|
|
|
+ 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);
|