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
23struct gpio_event {
24	struct gpio_event_input_devs *input_devs;
25	const struct gpio_event_platform_data *info;
26	void *state[0];
27};
28
29static 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
59static 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);
95err_func_failed:
96err_no_func:
97		;
98	}
99	return ret;
100}
101
102static 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
109static 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
116static 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
185err_input_register_device_failed:
186	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
187err_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]);
194err_input_dev_alloc_failed:
195		;
196	}
197	kfree(ip);
198err_kp_alloc_failed:
199	return err;
200}
201
202static 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
216static 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
224static int __devinit gpio_event_init(void)
225{
226	return platform_driver_register(&gpio_event_driver);
227}
228
229static void __exit gpio_event_exit(void)
230{
231	platform_driver_unregister(&gpio_event_driver);
232}
233
234module_init(gpio_event_init);
235module_exit(gpio_event_exit);
236
237MODULE_DESCRIPTION("GPIO Event Driver");
238MODULE_LICENSE("GPL");
239
240