diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-08-25 16:20:41 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-08-25 16:20:41 +1000 |
commit | b3f5d1bea9631022198ccf1160db6e5163e334ea (patch) | |
tree | de8fb28a80622afe74963c78a30280ef7b7c1062 /drivers/staging/dream/gpio_output.c | |
parent | 6fb212813333179684879237b18d1712c61e3ad2 (diff) | |
parent | 19464c2d243f08d8caad28f5c002c44e93470967 (diff) |
Merge branch 'quilt/staging'
Conflicts:
drivers/staging/epl/VirtualEthernetLinux.c
Diffstat (limited to 'drivers/staging/dream/gpio_output.c')
-rw-r--r-- | drivers/staging/dream/gpio_output.c | 84 |
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 000000000000..6f8453c97bd2 --- /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; +} + |