linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mika Westerberg <ext-mika.1.westerberg@nokia.com>
To: dmitry.torokhov@gmail.com
Cc: linux-input@vger.kernel.org
Subject: [RFC PATCH 1/1] Input: gpio-keys: export gpio key information through sysfs
Date: Fri, 23 Oct 2009 15:15:46 +0300	[thread overview]
Message-ID: <937a56e01181bef04c6661dc61032c1d08269cfa.1256298993.git.ext-mika.1.westerberg@nokia.com> (raw)
In-Reply-To: <cover.1256298993.git.ext-mika.1.westerberg@nokia.com>
In-Reply-To: <cover.1256298993.git.ext-mika.1.westerberg@nokia.com>

From: Mika Westerberg <ext-mika.1.westerberg@nokia.com>

In some embedded devices gpio lines are used as keys/buttons
through input layer and gpio-keys.  It is, however, impossible
to disable gpio lines separately from waking up the cpu.  For
example when device is locked we don't want accidental camera
button press to cause the device to wakeup just to notice that
it should continue sleeping.

This patch exports gpio-keys through sysfs and allows userland
to control whether single gpio line should wakeup the cpu or not.

Sysfs interface is accessible via:

	/sys/class/input/gpio-keys/input/input0/gpio-key.N/

Following attributes are exported per gpio key:

	/code    ... input event code (ro)
	/type    ... input event type (ro)
	/desc    ... description of the button (ro)
	/disable ... enable/disable gpio line (rw)

Userspace should be able to find out what key to disable/enable
by investigating {code, type, desc} tuple.

Signed-off-by: Mika Westerberg <ext-mika.1.westerberg@nokia.com>
---
 drivers/input/keyboard/gpio_keys.c |  162 ++++++++++++++++++++++++++++++++++++
 1 files changed, 162 insertions(+), 0 deletions(-)

diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index a88aff3..76e7c5c 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -31,6 +31,8 @@ struct gpio_button_data {
 	struct input_dev *input;
 	struct timer_list timer;
 	struct work_struct work;
+	struct device *dev;	/* device used to export button to sysfs */
+	bool disable;		/* is this gpio button disabled */
 };
 
 struct gpio_keys_drvdata {
@@ -38,6 +40,159 @@ struct gpio_keys_drvdata {
 	struct gpio_button_data data[0];
 };
 
+/*
+ * gpio-keys sysfs interface
+ *
+ * Following interface is export to userspace through
+ * sysfs.  This interface can be used to enable/disable
+ * single GPIO lines from generating events.
+ *
+ * /sys/class/input/gpio-keys/input/input0/gpio-key.N/
+ * 	/code	 ... input event code (ro)
+ *	/type	 ... input event type (ro)
+ *	/desc	 ... description of the button (ro)
+ *	/disable ... enable/disable gpio line from
+ *	             generating events (rw)
+ *
+ * Userspace program can enumerate these keys and based
+ * on {code,type,desc} tuple disable or enable the line
+ * depending on the system state.
+ */
+
+static ssize_t gpio_keys_code_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	const struct gpio_button_data *bdata = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", bdata->button->code);
+}
+
+static DEVICE_ATTR(code, S_IRUGO, gpio_keys_code_show, NULL);
+
+static ssize_t gpio_keys_type_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	const struct gpio_button_data *bdata = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", bdata->button->type);
+}
+
+static DEVICE_ATTR(type, S_IRUGO, gpio_keys_type_show, NULL);
+
+static ssize_t gpio_keys_desc_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	const struct gpio_button_data *bdata = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", bdata->button->desc);
+}
+
+static DEVICE_ATTR(desc, S_IRUGO, gpio_keys_desc_show, NULL);
+
+static ssize_t gpio_keys_disable_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	const struct gpio_button_data *bdata = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", (int)bdata->disable);
+}
+
+static ssize_t gpio_keys_disable_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct gpio_button_data *bdata = dev_get_drvdata(dev);
+	int val;
+
+	if (sscanf(buf, "%d", &val) != 1)
+		return -EINVAL;
+
+	val = !!val;
+	if (bdata->disable == val)
+		return size;
+
+	if (val) {
+		disable_irq(gpio_to_irq(bdata->button->gpio));
+	} else {
+		enable_irq(gpio_to_irq(bdata->button->gpio));
+	}
+
+	bdata->disable = val;
+	return size;
+}
+
+static DEVICE_ATTR(disable, S_IWUSR | S_IRUGO,
+	gpio_keys_disable_show, gpio_keys_disable_store);
+
+static struct attribute *gpio_keys_attrs[] = {
+	&dev_attr_code.attr,
+	&dev_attr_type.attr,
+	&dev_attr_desc.attr,
+	&dev_attr_disable.attr,
+	NULL,
+};
+
+static const struct attribute_group gpio_keys_attr_group = {
+	.attrs = gpio_keys_attrs,
+};
+
+static void gpio_keys_unexport(struct platform_device *pdev)
+{
+	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < pdata->nbuttons; i++) {
+		struct gpio_button_data *bdata = &ddata->data[i];
+
+		if (bdata->dev != NULL) {
+			sysfs_remove_group(&bdata->dev->kobj,
+				&gpio_keys_attr_group);
+			device_unregister(bdata->dev);
+			bdata->dev = NULL;
+		}
+	}
+}
+
+static int gpio_keys_export(struct platform_device *pdev)
+{
+	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
+	struct input_dev *input = ddata->input;
+	int i, error = 0;
+
+	for (i = 0; i < pdata->nbuttons; i++) {
+		struct gpio_button_data *bdata = &ddata->data[i];
+		struct device *dev;
+
+		/*
+		 * We create one "device" per gpio line that is used
+		 * as input gpio key device.
+		 */
+		dev = device_create(input->dev.class, &input->dev,
+			MKDEV(0, 0), bdata, "gpio-key.%d", i);
+		if (dev == NULL) {
+			error = -ENOMEM;
+			break;
+		}
+
+		error = sysfs_create_group(&dev->kobj, &gpio_keys_attr_group);
+		if (error != 0) {
+			device_unregister(dev);
+			break;
+		}
+
+		bdata->disable = false;
+		bdata->dev = dev;
+	}
+
+	if (error != 0) {
+		/* something failed, clean up all entries */
+		gpio_keys_unexport(pdev);
+	}
+
+	return error;
+}
+
 static void gpio_keys_report_event(struct work_struct *work)
 {
 	struct gpio_button_data *bdata =
@@ -170,6 +325,12 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 		goto fail2;
 	}
 
+	error = gpio_keys_export(pdev);
+	if (error) {
+		pr_warning("gpio-keys: Unable to export gpio-keys to sysfs, "
+			" error %d", error);
+	}
+
 	device_init_wakeup(&pdev->dev, wakeup);
 
 	return 0;
@@ -199,6 +360,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
 	int i;
 
 	device_init_wakeup(&pdev->dev, 0);
+	gpio_keys_unexport(pdev);
 
 	for (i = 0; i < pdata->nbuttons; i++) {
 		int irq = gpio_to_irq(pdata->buttons[i].gpio);
-- 
1.5.6.5


  reply	other threads:[~2009-10-23 12:19 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-23 12:15 [RFC PATCH 0/1] Enabling/disabling separate gpio-keys buttons Mika Westerberg
2009-10-23 12:15 ` Mika Westerberg [this message]
2009-10-28  5:43   ` [RFC PATCH 1/1] Input: gpio-keys: export gpio key information through sysfs Dmitry Torokhov
2009-10-28 10:50     ` Mika Westerberg
2009-11-04  9:06       ` Mika Westerberg
2009-11-04  9:25         ` Artem Bityutskiy
2009-11-06  7:52           ` Dmitry Torokhov
2009-11-09 15:09             ` Artem Bityutskiy
2009-11-09 17:18               ` Dmitry Torokhov
2009-11-10 11:04                 ` Artem Bityutskiy
2009-11-10 17:19                   ` Dmitry Torokhov
2009-11-11  6:50                     ` Artem Bityutskiy
2009-11-11  8:19                       ` Dmitry Torokhov
2009-11-11  8:52                         ` Artem Bityutskiy
2009-11-11  9:59                           ` Dmitry Torokhov
2009-11-11 10:26                             ` Artem Bityutskiy
2009-11-11 10:30                               ` Artem Bityutskiy
2009-11-11 17:40                               ` Dmitry Torokhov
2009-11-12  5:31                                 ` Artem Bityutskiy
2009-11-19  7:23                               ` [PATCH 0/2] Input: gpio-keys: support for disabling GPIOs Mika Westerberg
2009-11-19  7:23                                 ` [PATCH 1/2] Input: gpio-keys: allow drivers to specify whether IRQ can be shared Mika Westerberg
2009-11-19  7:23                                   ` [PATCH 2/2] Input: gpio-keys: added support for disabling gpios through sysfs Mika Westerberg
2009-11-20  8:40                                     ` Dmitry Torokhov
2009-11-20 12:17                                       ` Mika Westerberg
2009-11-23 12:39                                       ` [PATCH v2 0/2] Input: gpio-keys: support for disabling GPIOs Mika Westerberg
2009-11-23 12:39                                         ` [PATCH v2 1/2] Input: gpio-keys - allow platform to specify exact irq flags Mika Westerberg
2009-11-23 12:39                                           ` [PATCH v2 2/2] Input: gpio-keys - added support for disabling gpios through sysfs Mika Westerberg
2009-11-23 16:42                                           ` [PATCH v2 1/2] Input: gpio-keys - allow platform to specify exact irq flags Ferenc Wagner
2009-11-23 17:24                                             ` Dmitry Torokhov
2009-11-23 18:50                                               ` Ferenc Wagner
2009-11-24  6:37                                                 ` Mika Westerberg
2009-11-24 11:05                                                   ` Ferenc Wagner
2009-11-24 17:02                                                     ` Mika Westerberg
2009-11-24 18:39                                                       ` Ferenc Wagner
2009-11-26  6:35                                                         ` Dmitry Torokhov
2009-11-27 10:54                                                           ` Mika Westerberg
2009-11-28 12:16                                                             ` Ferenc Wagner
2009-11-28 13:27                                                               ` Mika Westerberg
2009-11-29 12:26                                                                 ` Ferenc Wagner
2009-11-29 16:04                                                                   ` [linux-pm] " Alan Stern
2009-11-29 22:58                                                                     ` Ferenc Wagner
2009-11-30  8:27                                                                       ` Mika Westerberg
2009-11-30  9:14                                                                         ` Dmitry Torokhov
2009-11-30  9:37                                                                           ` Mika Westerberg
2009-12-01  0:07                                                                             ` Ferenc Wagner
2009-11-30 20:59                                                                         ` Ferenc Wagner
2009-12-01  0:37                                                                           ` Dmitry Torokhov
2009-12-01  1:05                                                                             ` Ferenc Wagner
2009-11-30  9:16                                                                     ` Dmitry Torokhov
2009-11-30 15:00                                                                       ` Alan Stern
2009-11-30 19:05                                                                         ` Ferenc Wagner
2009-11-30 19:30                                                                           ` Alan Stern
2009-11-30 20:51                                                                             ` Ferenc Wagner
2009-11-30 21:59                                                                               ` Alan Stern
2009-12-01 10:08                                                                                 ` Ferenc Wagner
2009-12-01 15:11                                                                                   ` Alan Stern
2009-12-06  8:47                                                                           ` Pavel Machek
2009-12-08  4:22                                                                             ` Dmitry Torokhov
2009-12-08 13:03                                                                               ` Artem Bityutskiy
2009-12-08 17:42                                                                                 ` Dmitry Torokhov
2009-12-09  7:31                                                                                   ` Artem Bityutskiy
2009-12-09 18:03                                                                                     ` Dmitry Torokhov
2009-12-09 21:08                                                                                       ` Pavel Machek
2009-12-09 21:48                                                                                         ` Dmitry Torokhov
2009-12-10 10:13                                                                                           ` Pavel Machek
2009-12-10  9:19                                                                                       ` Artem Bityutskiy
2009-12-06  8:46                                                                   ` Pavel Machek
2009-11-20  8:38                                   ` [PATCH 1/2] Input: gpio-keys: allow drivers to specify whether IRQ can be shared Dmitry Torokhov
2009-11-20 10:08                                     ` Ferenc Wagner
2009-11-11 10:36                           ` [RFC PATCH 0/2] Input: adding new ioctl()s for enabling/disabling events Mika Westerberg
2009-11-11 10:36                             ` [RFC PATCH 1/2] Input: added 2 new ioctl()s for setting/getting event state Mika Westerberg
2009-11-11 10:36                               ` [RFC PATCH 2/2] Input: gpio-keys: implemented support for enabling/disabling gpios Mika Westerberg
2009-11-11 14:37                                 ` Ferenc Wagner
2009-11-11 14:52                                   ` Mika Westerberg
2009-11-11 17:08                                     ` Dmitry Torokhov
2009-11-12  6:23                                       ` Mika Westerberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=937a56e01181bef04c6661dc61032c1d08269cfa.1256298993.git.ext-mika.1.westerberg@nokia.com \
    --to=ext-mika.1.westerberg@nokia.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).