[PATCH 10/11] input: gpio_keys: switch to GPIO descriptor API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Pull-ups that are only configured in the OF GPIO description like:

  gpios = <&gpioe 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;

are currently ignored. This is because we open coded determination of
the GPIO flags and discarded all of them, except for active-low, thereby
giving gpiolib no chance to apply other flags.

Fix this by using dev_gpiod_get instead to parse the GPIO description
and request it.

This lets us support the aforementioned binding and handles active low
configuration transparently.

Reported-by: Chris Fiege <c.fiege@xxxxxxxxxxxxxx>
Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx>
---
 drivers/input/Kconfig     |  2 +-
 drivers/input/gpio_keys.c | 66 ++++++++++++++++++---------------------
 2 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 01e0b722c20f..fc4198b556f1 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -25,7 +25,7 @@ config INPUT_EVBUG
 
 config KEYBOARD_GPIO
 	bool "GPIO Buttons"
-	depends on GENERIC_GPIO
+	depends on GPIOLIB
 	select POLLER
 	select INPUT
 	help
diff --git a/drivers/input/gpio_keys.c b/drivers/input/gpio_keys.c
index c897acf3bd02..3701817788ca 100644
--- a/drivers/input/gpio_keys.c
+++ b/drivers/input/gpio_keys.c
@@ -9,16 +9,13 @@
 #include <clock.h>
 #include <gpio_keys.h>
 #include <poller.h>
-#include <gpio.h>
-#include <of_gpio.h>
+#include <linux/gpio/consumer.h>
 #include <input/input.h>
 
 struct gpio_key {
+	struct gpio_desc *gpio;
 	int code;
 
-	int gpio;
-	int active_low;
-
 	int previous_state;
 
 	int debounce_interval;
@@ -37,31 +34,29 @@ static void gpio_key_poller(void *data)
 {
 	struct gpio_keys *gk = data;
 	struct gpio_key *gb;
-	int i, val;
+	int i, pressed;
 
 	for (i = 0; i < gk->nbuttons; i++) {
 		gb = &gk->buttons[i];
 
-		if (gpio_slice_acquired(gb->gpio))
+		if (gpiod_slice_acquired(gb->gpio))
 			goto out;
 	}
 
 	for (i = 0; i < gk->nbuttons; i++) {
 
 		gb = &gk->buttons[i];
-		val = gpio_get_value(gb->gpio);
+		pressed = gpiod_get_value(gb->gpio);
 
 		if (!is_timeout(gb->debounce_start, gb->debounce_interval * MSECOND))
 			continue;
 
-		if (val != gb->previous_state) {
-			int pressed = val != gb->active_low;
-
+		if (pressed != gb->previous_state) {
 			gb->debounce_start = get_time_ns();
 			input_report_key_event(&gk->input, gb->code, pressed);
-			dev_dbg(gk->input.parent, "%s gpio(%d) as %d\n",
-				pressed ? "pressed" : "released", gb->gpio, gb->code);
-			gb->previous_state = val;
+			dev_dbg(gk->input.parent, "%s gpio #%d as %d\n",
+				pressed ? "pressed" : "released", i, gb->code);
+			gb->previous_state = pressed;
 		}
 	}
 out:
@@ -85,9 +80,20 @@ static int gpio_keys_probe_pdata(struct gpio_keys *gk, struct device *dev)
 	gk->nbuttons = pdata->nbuttons;
 
 	for (i = 0; i < gk->nbuttons; i++) {
-		gk->buttons[i].gpio = pdata->buttons[i].gpio;
+		struct gpio_desc *gpio;
+		ulong flags = GPIOF_DIR_IN;
+
+		if (pdata->buttons[i].active_low)
+			flags |= GPIOF_ACTIVE_LOW;
+
+		gpio = gpiod_request_one(pdata->buttons[i].gpio, flags, "gpio_keys");
+		if (IS_ERR(gpio)) {
+			pr_err("gpio_keys: gpio #%d can not be requested\n", i);
+			return PTR_ERR(gpio);
+		}
+
+		gk->buttons[i].gpio = gpio;
 		gk->buttons[i].code = pdata->buttons[i].code;
-		gk->buttons[i].active_low = pdata->buttons[i].active_low;
 		gk->buttons[i].debounce_interval = 20;
 	}
 
@@ -106,15 +112,16 @@ static int gpio_keys_probe_dt(struct gpio_keys *gk, struct device *dev)
 	gk->buttons = xzalloc(gk->nbuttons * sizeof(*gk->buttons));
 
 	for_each_child_of_node(np, npkey) {
-		enum of_gpio_flags gpioflags;
+		struct gpio_desc *gpio;
 		uint32_t keycode;
 
-		gk->buttons[i].gpio = of_get_named_gpio_flags(npkey, "gpios", 0, &gpioflags);
-		if (gk->buttons[i].gpio < 0)
-			return gk->buttons[i].gpio;
+		gpio = dev_gpiod_get(dev, npkey, "gpios", GPIOD_IN, NULL);
+		if (IS_ERR(gpio)) {
+			pr_err("gpio_keys: gpio #%d can not be requested\n", i);
+			return PTR_ERR(gpio);
+		}
 
-		if (gpioflags & OF_GPIO_ACTIVE_LOW)
-			gk->buttons[i].active_low = 1;
+		gk->buttons[i].gpio = gpio;
 
 		ret = of_property_read_u32(npkey, "linux,code", &keycode);
 		if (ret)
@@ -135,12 +142,12 @@ static int gpio_keys_probe_dt(struct gpio_keys *gk, struct device *dev)
 
 static int __init gpio_keys_probe(struct device *dev)
 {
-	int ret, i, gpio;
+	int ret;
 	struct gpio_keys *gk;
 
 	gk = xzalloc(sizeof(*gk));
 
-	if (dev->of_node)
+	if (dev_of_node(dev))
 		ret = gpio_keys_probe_dt(gk, dev);
 	else
 		ret = gpio_keys_probe_pdata(gk, dev);
@@ -148,17 +155,6 @@ static int __init gpio_keys_probe(struct device *dev)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < gk->nbuttons; i++) {
-		gpio = gk->buttons[i].gpio;
-		ret = gpio_request(gpio, "gpio_keys");
-		if (ret) {
-			pr_err("gpio_keys: (%d) can not be requested\n", gpio);
-			return ret;
-		}
-		gpio_direction_input(gpio);
-		gk->buttons[i].previous_state = gk->buttons[i].active_low;
-	}
-
 	gk->input.parent = dev;
 	ret = input_device_register(&gk->input);
 	if (ret)
-- 
2.39.2





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux