summaryrefslogtreecommitdiffstats
path: root/drivers/staging/dream/gpio_output.c
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2009-08-08 15:03:15 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-15 12:02:05 -0700
commit420818f9755a5676db7c392ba6f77d795f13675b (patch)
tree3a82e485feb57274a72721b712f678fc7ca57d52 /drivers/staging/dream/gpio_output.c
parent347a799cef17e66bd532fca4e55a5f5a2f9ff36c (diff)
downloadop-kernel-dev-420818f9755a5676db7c392ba6f77d795f13675b.zip
op-kernel-dev-420818f9755a5676db7c392ba6f77d795f13675b.tar.gz
Staging: dream: add support for input on GPIO pins
Support for input devices connected to GPIO pins. This adds support for HTC Dream's keyboard and its trackball. Generic support already exists for keyboard on GPIO, but this one is more advanced because it can detect shadow key presses (and actually works with Dream :-). (It also contains Kconfig/Makefile changes, including some that were missing from previous commit. Sorry.) Signed-off-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/dream/gpio_output.c')
-rw-r--r--drivers/staging/dream/gpio_output.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/staging/dream/gpio_output.c b/drivers/staging/dream/gpio_output.c
new file mode 100644
index 0000000..6f8453c
--- /dev/null
+++ b/drivers/staging/dream/gpio_output.c
@@ -0,0 +1,84 @@
+/* drivers/input/misc/gpio_output.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+
+int gpio_event_output_event(
+ struct input_dev *input_dev, struct gpio_event_info *info, void **data,
+ unsigned int type, unsigned int code, int value)
+{
+ int i;
+ struct gpio_event_output_info *oi;
+ oi = container_of(info, struct gpio_event_output_info, info);
+ if (type != oi->type)
+ return 0;
+ if (!(oi->flags & GPIOEDF_ACTIVE_HIGH))
+ value = !value;
+ for (i = 0; i < oi->keymap_size; i++)
+ if (code == oi->keymap[i].code)
+ gpio_set_value(oi->keymap[i].gpio, value);
+ return 0;
+}
+
+int gpio_event_output_func(
+ struct input_dev *input_dev, struct gpio_event_info *info, void **data,
+ int func)
+{
+ int ret;
+ int i;
+ struct gpio_event_output_info *oi;
+ oi = container_of(info, struct gpio_event_output_info, info);
+
+ if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME)
+ return 0;
+
+ if (func == GPIO_EVENT_FUNC_INIT) {
+ int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH);
+ for (i = 0; i < oi->keymap_size; i++)
+ input_set_capability(input_dev, oi->type,
+ oi->keymap[i].code);
+
+ for (i = 0; i < oi->keymap_size; i++) {
+ ret = gpio_request(oi->keymap[i].gpio,
+ "gpio_event_output");
+ if (ret) {
+ pr_err("gpio_event_output_func: gpio_request "
+ "failed for %d\n", oi->keymap[i].gpio);
+ goto err_gpio_request_failed;
+ }
+ ret = gpio_direction_output(oi->keymap[i].gpio,
+ output_level);
+ if (ret) {
+ pr_err("gpio_event_output_func: "
+ "gpio_direction_output failed for %d\n",
+ oi->keymap[i].gpio);
+ goto err_gpio_direction_output_failed;
+ }
+ }
+ return 0;
+ }
+
+ ret = 0;
+ for (i = oi->keymap_size - 1; i >= 0; i--) {
+err_gpio_direction_output_failed:
+ gpio_free(oi->keymap[i].gpio);
+err_gpio_request_failed:
+ ;
+ }
+ return ret;
+}
+
OpenPOWER on IntegriCloud