/* 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; }