• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* drivers/input/misc/gpio_output.c
2  *
3  * Copyright (C) 2007 Google, Inc.
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15 
16 #include <linux/kernel.h>
17 #include <linux/gpio.h>
18 #include <linux/gpio_event.h>
19 
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)20 int gpio_event_output_event(
21 	struct gpio_event_input_devs *input_devs, struct gpio_event_info *info,
22 	void **data, unsigned int dev, unsigned int type,
23 	unsigned int code, int value)
24 {
25 	int i;
26 	struct gpio_event_output_info *oi;
27 	oi = container_of(info, struct gpio_event_output_info, info);
28 	if (type != oi->type)
29 		return 0;
30 	if (!(oi->flags & GPIOEDF_ACTIVE_HIGH))
31 		value = !value;
32 	for (i = 0; i < oi->keymap_size; i++)
33 		if (dev == oi->keymap[i].dev && code == oi->keymap[i].code)
34 			gpio_set_value(oi->keymap[i].gpio, value);
35 	return 0;
36 }
37 
gpio_event_output_func(struct gpio_event_input_devs * input_devs,struct gpio_event_info * info,void ** data,int func)38 int gpio_event_output_func(
39 	struct gpio_event_input_devs *input_devs, struct gpio_event_info *info,
40 	void **data, int func)
41 {
42 	int ret;
43 	int i;
44 	struct gpio_event_output_info *oi;
45 	oi = container_of(info, struct gpio_event_output_info, info);
46 
47 	if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME)
48 		return 0;
49 
50 	if (func == GPIO_EVENT_FUNC_INIT) {
51 		int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH);
52 
53 		for (i = 0; i < oi->keymap_size; i++) {
54 			int dev = oi->keymap[i].dev;
55 			if (dev >= input_devs->count) {
56 				pr_err("gpio_event_output_func: bad device "
57 					"index %d >= %d for key code %d\n",
58 					dev, input_devs->count,
59 					oi->keymap[i].code);
60 				ret = -EINVAL;
61 				goto err_bad_keymap;
62 			}
63 			input_set_capability(input_devs->dev[dev], oi->type,
64 					     oi->keymap[i].code);
65 		}
66 
67 		for (i = 0; i < oi->keymap_size; i++) {
68 			ret = gpio_request(oi->keymap[i].gpio,
69 					   "gpio_event_output");
70 			if (ret) {
71 				pr_err("gpio_event_output_func: gpio_request "
72 					"failed for %d\n", oi->keymap[i].gpio);
73 				goto err_gpio_request_failed;
74 			}
75 			ret = gpio_direction_output(oi->keymap[i].gpio,
76 						    output_level);
77 			if (ret) {
78 				pr_err("gpio_event_output_func: "
79 					"gpio_direction_output failed for %d\n",
80 					oi->keymap[i].gpio);
81 				goto err_gpio_direction_output_failed;
82 			}
83 		}
84 		return 0;
85 	}
86 
87 	ret = 0;
88 	for (i = oi->keymap_size - 1; i >= 0; i--) {
89 err_gpio_direction_output_failed:
90 		gpio_free(oi->keymap[i].gpio);
91 err_gpio_request_failed:
92 		;
93 	}
94 err_bad_keymap:
95 	return ret;
96 }
97 
98