1 /* drivers/input/misc/gpio_event.c
3 * Copyright (C) 2007 Google, Inc.
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.
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.
16 #include <linux/earlysuspend.h>
17 #include <linux/module.h>
18 #include <linux/input.h>
19 #include <linux/gpio_event.h>
20 #include <linux/hrtimer.h>
21 #include <linux/platform_device.h>
24 struct input_dev
*input_dev
;
25 const struct gpio_event_platform_data
*info
;
26 struct early_suspend early_suspend
;
30 static int gpio_input_event(
31 struct input_dev
*dev
, unsigned int type
, unsigned int code
, int value
)
36 struct gpio_event_info
**ii
;
37 struct gpio_event
*ip
= input_get_drvdata(dev
);
39 for (i
= 0, ii
= ip
->info
->info
; i
< ip
->info
->info_count
; i
++, ii
++) {
41 tmp_ret
= (*ii
)->event(ip
->input_dev
, *ii
,
42 &ip
->state
[i
], type
, code
, value
);
50 static int gpio_event_call_all_func(struct gpio_event
*ip
, int func
)
54 struct gpio_event_info
**ii
;
56 if (func
== GPIO_EVENT_FUNC_INIT
|| func
== GPIO_EVENT_FUNC_RESUME
) {
58 for (i
= 0; i
< ip
->info
->info_count
; i
++, ii
++) {
59 if ((*ii
)->func
== NULL
) {
61 pr_err("gpio_event_probe: Incomplete pdata, "
65 ret
= (*ii
)->func(ip
->input_dev
, *ii
, &ip
->state
[i
],
68 pr_err("gpio_event_probe: function failed\n");
76 i
= ip
->info
->info_count
;
77 ii
= ip
->info
->info
+ i
;
81 (*ii
)->func(ip
->input_dev
, *ii
, &ip
->state
[i
], func
& ~1);
89 #ifdef CONFIG_HAS_EARLYSUSPEND
90 void gpio_event_suspend(struct early_suspend
*h
)
92 struct gpio_event
*ip
;
93 ip
= container_of(h
, struct gpio_event
, early_suspend
);
94 gpio_event_call_all_func(ip
, GPIO_EVENT_FUNC_SUSPEND
);
95 ip
->info
->power(ip
->info
, 0);
98 void gpio_event_resume(struct early_suspend
*h
)
100 struct gpio_event
*ip
;
101 ip
= container_of(h
, struct gpio_event
, early_suspend
);
102 ip
->info
->power(ip
->info
, 1);
103 gpio_event_call_all_func(ip
, GPIO_EVENT_FUNC_RESUME
);
107 static int __init
gpio_event_probe(struct platform_device
*pdev
)
110 struct gpio_event
*ip
;
111 struct input_dev
*input_dev
;
112 struct gpio_event_platform_data
*event_info
;
114 event_info
= pdev
->dev
.platform_data
;
115 if (event_info
== NULL
) {
116 pr_err("gpio_event_probe: No pdata\n");
119 if (event_info
->name
== NULL
||
120 event_info
->info
== NULL
||
121 event_info
->info_count
== 0) {
122 pr_err("gpio_event_probe: Incomplete pdata\n");
125 ip
= kzalloc(sizeof(*ip
) +
126 sizeof(ip
->state
[0]) * event_info
->info_count
, GFP_KERNEL
);
129 pr_err("gpio_event_probe: Failed to allocate private data\n");
130 goto err_kp_alloc_failed
;
132 platform_set_drvdata(pdev
, ip
);
134 input_dev
= input_allocate_device();
135 if (input_dev
== NULL
) {
137 pr_err("gpio_event_probe: Failed to allocate input device\n");
138 goto err_input_dev_alloc_failed
;
140 input_set_drvdata(input_dev
, ip
);
141 ip
->input_dev
= input_dev
;
142 ip
->info
= event_info
;
143 if (event_info
->power
) {
144 #ifdef CONFIG_HAS_EARLYSUSPEND
145 ip
->early_suspend
.level
= EARLY_SUSPEND_LEVEL_BLANK_SCREEN
+ 1;
146 ip
->early_suspend
.suspend
= gpio_event_suspend
;
147 ip
->early_suspend
.resume
= gpio_event_resume
;
148 register_early_suspend(&ip
->early_suspend
);
150 ip
->info
->power(ip
->info
, 1);
153 input_dev
->name
= ip
->info
->name
;
154 input_dev
->event
= gpio_input_event
;
156 err
= gpio_event_call_all_func(ip
, GPIO_EVENT_FUNC_INIT
);
158 goto err_call_all_func_failed
;
160 err
= input_register_device(input_dev
);
162 pr_err("gpio_event_probe: Unable to register %s input device\n",
164 goto err_input_register_device_failed
;
169 err_input_register_device_failed
:
170 gpio_event_call_all_func(ip
, GPIO_EVENT_FUNC_UNINIT
);
171 err_call_all_func_failed
:
172 if (event_info
->power
) {
173 #ifdef CONFIG_HAS_EARLYSUSPEND
174 unregister_early_suspend(&ip
->early_suspend
);
176 ip
->info
->power(ip
->info
, 0);
178 input_free_device(input_dev
);
179 err_input_dev_alloc_failed
:
185 static int gpio_event_remove(struct platform_device
*pdev
)
187 struct gpio_event
*ip
= platform_get_drvdata(pdev
);
189 gpio_event_call_all_func(ip
, GPIO_EVENT_FUNC_UNINIT
);
190 if (ip
->info
->power
) {
191 #ifdef CONFIG_HAS_EARLYSUSPEND
192 unregister_early_suspend(&ip
->early_suspend
);
194 ip
->info
->power(ip
->info
, 0);
196 input_unregister_device(ip
->input_dev
);
201 static struct platform_driver gpio_event_driver
= {
202 .probe
= gpio_event_probe
,
203 .remove
= gpio_event_remove
,
205 .name
= GPIO_EVENT_DEV_NAME
,
209 static int __devinit
gpio_event_init(void)
211 return platform_driver_register(&gpio_event_driver
);
214 static void __exit
gpio_event_exit(void)
216 platform_driver_unregister(&gpio_event_driver
);
219 module_init(gpio_event_init
);
220 module_exit(gpio_event_exit
);
222 MODULE_DESCRIPTION("GPIO Event Driver");
223 MODULE_LICENSE("GPL");