1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- /* 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 gpio_event_input_devs *input_devs, struct gpio_event_info *info,
- void **data, unsigned int dev, 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 (dev == oi->keymap[i].dev && code == oi->keymap[i].code)
- gpio_set_value(oi->keymap[i].gpio, value);
- return 0;
- }
- int gpio_event_output_func(
- struct gpio_event_input_devs *input_devs, 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++) {
- int dev = oi->keymap[i].dev;
- if (dev >= input_devs->count) {
- pr_err("gpio_event_output_func: bad device "
- "index %d >= %d for key code %d\n",
- dev, input_devs->count,
- oi->keymap[i].code);
- ret = -EINVAL;
- goto err_bad_keymap;
- }
- input_set_capability(input_devs->dev[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:
- ;
- }
- err_bad_keymap:
- return ret;
- }
|