[PATCH 1/1] input: Expose states of gpio keypad

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

 



Allow user to poll the gpio keypad states in sysfs

Signed-off-by: Clark Li <clark.li86@xxxxxxxxx>
---
 drivers/input/keyboard/gpio_keys.c | 38 ++++++++++++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index b29ca65..d3a0536 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -3,6 +3,7 @@
  *
  * Copyright 2005 Phil Blundell
  * Copyright 2010, 2011 David Jander <david@xxxxxxxxxxx>
+ * Copyright 2014 Clark Li <clark.li86@xxxxxxxxx>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -49,6 +50,12 @@ struct gpio_keys_drvdata {
 	struct gpio_button_data data[0];
 };
 
+/** What to display in sysfs attributes */
+enum gpio_attr_display {
+	gpio_attr_display_key,
+	gpio_attr_display_state
+};
+
 /*
  * SYSFS interface for enabling/disabling keys and switches:
  *
@@ -150,6 +157,7 @@ static void gpio_keys_enable_button(struct gpio_button_data *bdata)
  * @only_disabled: does caller want only those buttons that are
  *                 currently disabled or all buttons that can be
  *                 disabled
+ * @display: display the key or key state
  *
  * This function writes buttons that can be disabled to @buf. If
  * @only_disabled is true, then @buf contains only those buttons
@@ -158,12 +166,14 @@ static void gpio_keys_enable_button(struct gpio_button_data *bdata)
  */
 static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
 					  char *buf, unsigned int type,
-					  bool only_disabled)
+					  bool only_disabled,
+					  enum gpio_attr_display display)
 {
 	int n_events = get_n_events_by_type(type);
 	unsigned long *bits;
 	ssize_t ret;
 	int i;
+	int state;
 
 	bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL);
 	if (!bits)
@@ -178,7 +188,15 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
 		if (only_disabled && !bdata->disabled)
 			continue;
 
-		__set_bit(bdata->button->code, bits);
+		if (display == gpio_attr_display_key)
+			__set_bit(bdata->button->code, bits);
+		else if (display == gpio_attr_display_state) {
+			state = gpio_get_value_cansleep(bdata->button->gpio)
+				? 1 : 0;
+			state ^= bdata->button->active_low;
+			if (state)
+				__set_bit(bdata->button->code, bits);
+		}
 	}
 
 	ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events);
@@ -251,7 +269,7 @@ out:
 	return error;
 }
 
-#define ATTR_SHOW_FN(name, type, only_disabled)				\
+#define ATTR_SHOW_FN(name, type, only_disabled, display)		\
 static ssize_t gpio_keys_show_##name(struct device *dev,		\
 				     struct device_attribute *attr,	\
 				     char *buf)				\
@@ -260,22 +278,25 @@ static ssize_t gpio_keys_show_##name(struct device *dev,		\
 	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);	\
 									\
 	return gpio_keys_attr_show_helper(ddata, buf,			\
-					  type, only_disabled);		\
+		type, only_disabled, display);				\
 }
 
-ATTR_SHOW_FN(keys, EV_KEY, false);
-ATTR_SHOW_FN(switches, EV_SW, false);
-ATTR_SHOW_FN(disabled_keys, EV_KEY, true);
-ATTR_SHOW_FN(disabled_switches, EV_SW, true);
+ATTR_SHOW_FN(keys, EV_KEY, false, gpio_attr_display_key);
+ATTR_SHOW_FN(switches, EV_SW, false, gpio_attr_display_key);
+ATTR_SHOW_FN(states, EV_KEY, false, gpio_attr_display_state);
+ATTR_SHOW_FN(disabled_keys, EV_KEY, true, gpio_attr_display_key);
+ATTR_SHOW_FN(disabled_switches, EV_SW, true, gpio_attr_display_key);
 
 /*
  * ATTRIBUTES:
  *
  * /sys/devices/platform/gpio-keys/keys [ro]
  * /sys/devices/platform/gpio-keys/switches [ro]
+ * /sys/devices/platform/gpio-keys/states [ro]
  */
 static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL);
 static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL);
+static DEVICE_ATTR(states, S_IRUGO, gpio_keys_show_states, NULL);
 
 #define ATTR_STORE_FN(name, type)					\
 static ssize_t gpio_keys_store_##name(struct device *dev,		\
@@ -313,6 +334,7 @@ static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO,
 static struct attribute *gpio_keys_attrs[] = {
 	&dev_attr_keys.attr,
 	&dev_attr_switches.attr,
+	&dev_attr_states.attr,
 	&dev_attr_disabled_keys.attr,
 	&dev_attr_disabled_switches.attr,
 	NULL,
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux