diff options
author | Arve Hjønnevåg <arve@android.com> | 2008-10-15 18:23:47 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2010-09-29 17:49:11 -0700 |
commit | 4e68fb60262a28c07525cc1a65dbfd41a396b37a (patch) | |
tree | 079d666a12e4a7263cd4be622f71ccb067c5dd42 /drivers/input/misc/gpio_output.c | |
parent | 114e891fc7589f3e49c0b255e57f0581c62b4442 (diff) |
Input: Generic GPIO Input device.
Supports keyboard matrixces, direct inputs, direct outputs and axes connected to gpios.
Change-Id: I5e921e6e3a1cc169316ee3b665f4cc21b5735114
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'drivers/input/misc/gpio_output.c')
-rw-r--r-- | drivers/input/misc/gpio_output.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/input/misc/gpio_output.c b/drivers/input/misc/gpio_output.c new file mode 100644 index 000000000000..6f8453c97bd2 --- /dev/null +++ b/drivers/input/misc/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; +} + |