• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* drivers/input/misc/gpio_event.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/module.h>
17 #include <linux/input.h>
18 #include <linux/gpio_event.h>
19 #include <linux/hrtimer.h>
20 #include <linux/platform_device.h>
21 #include <linux/slab.h>
22 
23 struct gpio_event {
24 	struct gpio_event_input_devs *input_devs;
25 	const struct gpio_event_platform_data *info;
26 	void *state[0];
27 };
28 
gpio_input_event(struct input_dev * dev,unsigned int type,unsigned int code,int value)29 static int gpio_input_event(
30 	struct input_dev *dev, unsigned int type, unsigned int code, int value)
31 {
32 	int i;
33 	int devnr;
34 	int ret = 0;
35 	int tmp_ret;
36 	struct gpio_event_info **ii;
37 	struct gpio_event *ip = input_get_drvdata(dev);
38 
39 	for (devnr = 0; devnr < ip->input_devs->count; devnr++)
40 		if (ip->input_devs->dev[devnr] == dev)
41 			break;
42 	if (devnr == ip->input_devs->count) {
43 		pr_err("gpio_input_event: unknown device %p\n", dev);
44 		return -EIO;
45 	}
46 
47 	for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) {
48 		if ((*ii)->event) {
49 			tmp_ret = (*ii)->event(ip->input_devs, *ii,
50 						&ip->state[i],
51 						devnr, type, code, value);
52 			if (tmp_ret)
53 				ret = tmp_ret;
54 		}
55 	}
56 	return ret;
57 }
58 
gpio_event_call_all_func(struct gpio_event * ip,int func)59 static int gpio_event_call_all_func(struct gpio_event *ip, int func)
60 {
61 	int i;
62 	int ret;
63 	struct gpio_event_info **ii;
64 
65 	if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) {
66 		ii = ip->info->info;
67 		for (i = 0; i < ip->info->info_count; i++, ii++) {
68 			if ((*ii)->func == NULL) {
69 				ret = -ENODEV;
70 				pr_err("gpio_event_probe: Incomplete pdata, "
71 					"no function\n");
72 				goto err_no_func;
73 			}
74 			if (func == GPIO_EVENT_FUNC_RESUME && (*ii)->no_suspend)
75 				continue;
76 			ret = (*ii)->func(ip->input_devs, *ii, &ip->state[i],
77 					  func);
78 			if (ret) {
79 				pr_err("gpio_event_probe: function failed\n");
80 				goto err_func_failed;
81 			}
82 		}
83 		return 0;
84 	}
85 
86 	ret = 0;
87 	i = ip->info->info_count;
88 	ii = ip->info->info + i;
89 	while (i > 0) {
90 		i--;
91 		ii--;
92 		if ((func & ~1) == GPIO_EVENT_FUNC_SUSPEND && (*ii)->no_suspend)
93 			continue;
94 		(*ii)->func(ip->input_devs, *ii, &ip->state[i], func & ~1);
95 err_func_failed:
96 err_no_func:
97 		;
98 	}
99 	return ret;
100 }
101 
gpio_event_suspend(struct gpio_event * ip)102 static void __maybe_unused gpio_event_suspend(struct gpio_event *ip)
103 {
104 	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND);
105 	if (ip->info->power)
106 		ip->info->power(ip->info, 0);
107 }
108 
gpio_event_resume(struct gpio_event * ip)109 static void __maybe_unused gpio_event_resume(struct gpio_event *ip)
110 {
111 	if (ip->info->power)
112 		ip->info->power(ip->info, 1);
113 	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME);
114 }
115 
gpio_event_probe(struct platform_device * pdev)116 static int gpio_event_probe(struct platform_device *pdev)
117 {
118 	int err;
119 	struct gpio_event *ip;
120 	struct gpio_event_platform_data *event_info;
121 	int dev_count = 1;
122 	int i;
123 	int registered = 0;
124 
125 	event_info = pdev->dev.platform_data;
126 	if (event_info == NULL) {
127 		pr_err("gpio_event_probe: No pdata\n");
128 		return -ENODEV;
129 	}
130 	if ((!event_info->name && !event_info->names[0]) ||
131 	    !event_info->info || !event_info->info_count) {
132 		pr_err("gpio_event_probe: Incomplete pdata\n");
133 		return -ENODEV;
134 	}
135 	if (!event_info->name)
136 		while (event_info->names[dev_count])
137 			dev_count++;
138 	ip = kzalloc(sizeof(*ip) +
139 		     sizeof(ip->state[0]) * event_info->info_count +
140 		     sizeof(*ip->input_devs) +
141 		     sizeof(ip->input_devs->dev[0]) * dev_count, GFP_KERNEL);
142 	if (ip == NULL) {
143 		err = -ENOMEM;
144 		pr_err("gpio_event_probe: Failed to allocate private data\n");
145 		goto err_kp_alloc_failed;
146 	}
147 	ip->input_devs = (void*)&ip->state[event_info->info_count];
148 	platform_set_drvdata(pdev, ip);
149 
150 	for (i = 0; i < dev_count; i++) {
151 		struct input_dev *input_dev = input_allocate_device();
152 		if (input_dev == NULL) {
153 			err = -ENOMEM;
154 			pr_err("gpio_event_probe: "
155 				"Failed to allocate input device\n");
156 			goto err_input_dev_alloc_failed;
157 		}
158 		input_set_drvdata(input_dev, ip);
159 		input_dev->name = event_info->name ?
160 					event_info->name : event_info->names[i];
161 		input_dev->event = gpio_input_event;
162 		ip->input_devs->dev[i] = input_dev;
163 	}
164 	ip->input_devs->count = dev_count;
165 	ip->info = event_info;
166 	if (event_info->power)
167 		ip->info->power(ip->info, 1);
168 
169 	err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
170 	if (err)
171 		goto err_call_all_func_failed;
172 
173 	for (i = 0; i < dev_count; i++) {
174 		err = input_register_device(ip->input_devs->dev[i]);
175 		if (err) {
176 			pr_err("gpio_event_probe: Unable to register %s "
177 				"input device\n", ip->input_devs->dev[i]->name);
178 			goto err_input_register_device_failed;
179 		}
180 		registered++;
181 	}
182 
183 	return 0;
184 
185 err_input_register_device_failed:
186 	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
187 err_call_all_func_failed:
188 	if (event_info->power)
189 		ip->info->power(ip->info, 0);
190 	for (i = 0; i < registered; i++)
191 		input_unregister_device(ip->input_devs->dev[i]);
192 	for (i = dev_count - 1; i >= registered; i--) {
193 		input_free_device(ip->input_devs->dev[i]);
194 err_input_dev_alloc_failed:
195 		;
196 	}
197 	kfree(ip);
198 err_kp_alloc_failed:
199 	return err;
200 }
201 
gpio_event_remove(struct platform_device * pdev)202 static int gpio_event_remove(struct platform_device *pdev)
203 {
204 	struct gpio_event *ip = platform_get_drvdata(pdev);
205 	int i;
206 
207 	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
208 	if (ip->info->power)
209 		ip->info->power(ip->info, 0);
210 	for (i = 0; i < ip->input_devs->count; i++)
211 		input_unregister_device(ip->input_devs->dev[i]);
212 	kfree(ip);
213 	return 0;
214 }
215 
216 static struct platform_driver gpio_event_driver = {
217 	.probe		= gpio_event_probe,
218 	.remove		= gpio_event_remove,
219 	.driver		= {
220 		.name	= GPIO_EVENT_DEV_NAME,
221 	},
222 };
223 
224 module_platform_driver(gpio_event_driver);
225 
226 MODULE_DESCRIPTION("GPIO Event Driver");
227 MODULE_LICENSE("GPL");
228 
229