blob: eefd02725aff406b0b30e11c37529ee017b05d35 [file] [log] [blame]
Arve Hjønnevågca984132008-10-15 18:23:47 -07001/* drivers/input/misc/gpio_input.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#include <linux/hrtimer.h>
20#include <linux/input.h>
21#include <linux/interrupt.h>
22#include <linux/slab.h>
Todd Poynorbffb6b82012-06-19 21:06:47 -070023#include <linux/pm_wakeup.h>
Arve Hjønnevågca984132008-10-15 18:23:47 -070024
25enum {
26 DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */
27 DEBOUNCE_PRESSED = BIT(1),
28 DEBOUNCE_NOTPRESSED = BIT(2),
29 DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */
30 DEBOUNCE_POLL = BIT(4), /* Stable polling state */
31
32 DEBOUNCE_UNKNOWN =
33 DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
34};
35
36struct gpio_key_state {
37 struct gpio_input_state *ds;
38 uint8_t debounce;
39};
40
41struct gpio_input_state {
42 struct gpio_event_input_devs *input_devs;
43 const struct gpio_event_input_info *info;
44 struct hrtimer timer;
45 int use_irq;
46 int debounce_count;
47 spinlock_t irq_lock;
Todd Poynorbffb6b82012-06-19 21:06:47 -070048 struct wakeup_source *ws;
Arve Hjønnevågca984132008-10-15 18:23:47 -070049 struct gpio_key_state key_state[0];
50};
51
52static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
53{
54 int i;
55 int pressed;
56 struct gpio_input_state *ds =
57 container_of(timer, struct gpio_input_state, timer);
58 unsigned gpio_flags = ds->info->flags;
59 unsigned npolarity;
60 int nkeys = ds->info->keymap_size;
61 const struct gpio_event_direct_entry *key_entry;
62 struct gpio_key_state *key_state;
63 unsigned long irqflags;
64 uint8_t debounce;
65 bool sync_needed;
66
67#if 0
68 key_entry = kp->keys_info->keymap;
69 key_state = kp->key_state;
70 for (i = 0; i < nkeys; i++, key_entry++, key_state++)
71 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
72 gpio_read_detect_status(key_entry->gpio));
73#endif
74 key_entry = ds->info->keymap;
75 key_state = ds->key_state;
76 sync_needed = false;
77 spin_lock_irqsave(&ds->irq_lock, irqflags);
78 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
79 debounce = key_state->debounce;
80 if (debounce & DEBOUNCE_WAIT_IRQ)
81 continue;
82 if (key_state->debounce & DEBOUNCE_UNSTABLE) {
83 debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
84 enable_irq(gpio_to_irq(key_entry->gpio));
85 if (gpio_flags & GPIOEDF_PRINT_KEY_UNSTABLE)
86 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
87 "(%d) continue debounce\n",
88 ds->info->type, key_entry->code,
89 i, key_entry->gpio);
90 }
91 npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
92 pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
93 if (debounce & DEBOUNCE_POLL) {
94 if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
95 ds->debounce_count++;
96 key_state->debounce = DEBOUNCE_UNKNOWN;
97 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
98 pr_info("gpio_keys_scan_keys: key %x-"
99 "%x, %d (%d) start debounce\n",
100 ds->info->type, key_entry->code,
101 i, key_entry->gpio);
102 }
103 continue;
104 }
105 if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
106 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
107 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
108 "(%d) debounce pressed 1\n",
109 ds->info->type, key_entry->code,
110 i, key_entry->gpio);
111 key_state->debounce = DEBOUNCE_PRESSED;
112 continue;
113 }
114 if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
115 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
116 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
117 "(%d) debounce pressed 0\n",
118 ds->info->type, key_entry->code,
119 i, key_entry->gpio);
120 key_state->debounce = DEBOUNCE_NOTPRESSED;
121 continue;
122 }
123 /* key is stable */
124 ds->debounce_count--;
125 if (ds->use_irq)
126 key_state->debounce |= DEBOUNCE_WAIT_IRQ;
127 else
128 key_state->debounce |= DEBOUNCE_POLL;
129 if (gpio_flags & GPIOEDF_PRINT_KEYS)
130 pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
131 "changed to %d\n", ds->info->type,
132 key_entry->code, i, key_entry->gpio, pressed);
133 input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
134 key_entry->code, pressed);
135 sync_needed = true;
136 }
137 if (sync_needed) {
138 for (i = 0; i < ds->input_devs->count; i++)
139 input_sync(ds->input_devs->dev[i]);
140 }
141
142#if 0
143 key_entry = kp->keys_info->keymap;
144 key_state = kp->key_state;
145 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
146 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
147 gpio_read_detect_status(key_entry->gpio));
148 }
149#endif
150
151 if (ds->debounce_count)
152 hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
153 else if (!ds->use_irq)
154 hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
155 else
Todd Poynorbffb6b82012-06-19 21:06:47 -0700156 __pm_relax(ds->ws);
Arve Hjønnevågca984132008-10-15 18:23:47 -0700157
158 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
159
160 return HRTIMER_NORESTART;
161}
162
163static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
164{
165 struct gpio_key_state *ks = dev_id;
166 struct gpio_input_state *ds = ks->ds;
167 int keymap_index = ks - ds->key_state;
168 const struct gpio_event_direct_entry *key_entry;
169 unsigned long irqflags;
170 int pressed;
171
172 if (!ds->use_irq)
173 return IRQ_HANDLED;
174
175 key_entry = &ds->info->keymap[keymap_index];
176
177 if (ds->info->debounce_time.tv64) {
178 spin_lock_irqsave(&ds->irq_lock, irqflags);
179 if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
180 ks->debounce = DEBOUNCE_UNKNOWN;
181 if (ds->debounce_count++ == 0) {
Todd Poynorbffb6b82012-06-19 21:06:47 -0700182 __pm_stay_awake(ds->ws);
Arve Hjønnevågca984132008-10-15 18:23:47 -0700183 hrtimer_start(
184 &ds->timer, ds->info->debounce_time,
185 HRTIMER_MODE_REL);
186 }
187 if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
188 pr_info("gpio_event_input_irq_handler: "
189 "key %x-%x, %d (%d) start debounce\n",
190 ds->info->type, key_entry->code,
191 keymap_index, key_entry->gpio);
192 } else {
193 disable_irq_nosync(irq);
194 ks->debounce = DEBOUNCE_UNSTABLE;
195 }
196 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
197 } else {
198 pressed = gpio_get_value(key_entry->gpio) ^
199 !(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
200 if (ds->info->flags & GPIOEDF_PRINT_KEYS)
201 pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
202 "(%d) changed to %d\n",
203 ds->info->type, key_entry->code, keymap_index,
204 key_entry->gpio, pressed);
205 input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
206 key_entry->code, pressed);
207 input_sync(ds->input_devs->dev[key_entry->dev]);
208 }
209 return IRQ_HANDLED;
210}
211
212static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
213{
214 int i;
215 int err;
216 unsigned int irq;
217 unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
218
219 for (i = 0; i < ds->info->keymap_size; i++) {
220 err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
221 if (err < 0)
222 goto err_gpio_get_irq_num_failed;
223 err = request_irq(irq, gpio_event_input_irq_handler,
224 req_flags, "gpio_keys", &ds->key_state[i]);
225 if (err) {
226 pr_err("gpio_event_input_request_irqs: request_irq "
227 "failed for input %d, irq %d\n",
228 ds->info->keymap[i].gpio, irq);
229 goto err_request_irq_failed;
230 }
231 if (ds->info->info.no_suspend) {
232 err = enable_irq_wake(irq);
233 if (err) {
234 pr_err("gpio_event_input_request_irqs: "
235 "enable_irq_wake failed for input %d, "
236 "irq %d\n",
237 ds->info->keymap[i].gpio, irq);
238 goto err_enable_irq_wake_failed;
239 }
240 }
241 }
242 return 0;
243
244 for (i = ds->info->keymap_size - 1; i >= 0; i--) {
245 irq = gpio_to_irq(ds->info->keymap[i].gpio);
246 if (ds->info->info.no_suspend)
247 disable_irq_wake(irq);
248err_enable_irq_wake_failed:
249 free_irq(irq, &ds->key_state[i]);
250err_request_irq_failed:
251err_gpio_get_irq_num_failed:
252 ;
253 }
254 return err;
255}
256
257int gpio_event_input_func(struct gpio_event_input_devs *input_devs,
258 struct gpio_event_info *info, void **data, int func)
259{
260 int ret;
261 int i;
262 unsigned long irqflags;
263 struct gpio_event_input_info *di;
264 struct gpio_input_state *ds = *data;
Todd Poynorbffb6b82012-06-19 21:06:47 -0700265 char *wlname;
Arve Hjønnevågca984132008-10-15 18:23:47 -0700266
267 di = container_of(info, struct gpio_event_input_info, info);
268
269 if (func == GPIO_EVENT_FUNC_SUSPEND) {
270 if (ds->use_irq)
271 for (i = 0; i < di->keymap_size; i++)
272 disable_irq(gpio_to_irq(di->keymap[i].gpio));
273 hrtimer_cancel(&ds->timer);
274 return 0;
275 }
276 if (func == GPIO_EVENT_FUNC_RESUME) {
277 spin_lock_irqsave(&ds->irq_lock, irqflags);
278 if (ds->use_irq)
279 for (i = 0; i < di->keymap_size; i++)
280 enable_irq(gpio_to_irq(di->keymap[i].gpio));
281 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
282 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
283 return 0;
284 }
285
286 if (func == GPIO_EVENT_FUNC_INIT) {
287 if (ktime_to_ns(di->poll_time) <= 0)
288 di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
289
290 *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
291 di->keymap_size, GFP_KERNEL);
292 if (ds == NULL) {
293 ret = -ENOMEM;
294 pr_err("gpio_event_input_func: "
295 "Failed to allocate private data\n");
296 goto err_ds_alloc_failed;
297 }
298 ds->debounce_count = di->keymap_size;
299 ds->input_devs = input_devs;
300 ds->info = di;
Todd Poynorbffb6b82012-06-19 21:06:47 -0700301 wlname = kasprintf(GFP_KERNEL, "gpio_input:%s%s",
302 input_devs->dev[0]->name,
303 (input_devs->count > 1) ? "..." : "");
304
305 ds->ws = wakeup_source_register(wlname);
306 kfree(wlname);
307 if (!ds->ws) {
308 ret = -ENOMEM;
309 pr_err("gpio_event_input_func: "
310 "Failed to allocate wakeup source\n");
311 goto err_ws_failed;
312 }
313
Arve Hjønnevågca984132008-10-15 18:23:47 -0700314 spin_lock_init(&ds->irq_lock);
315
316 for (i = 0; i < di->keymap_size; i++) {
317 int dev = di->keymap[i].dev;
318 if (dev >= input_devs->count) {
319 pr_err("gpio_event_input_func: bad device "
320 "index %d >= %d for key code %d\n",
321 dev, input_devs->count,
322 di->keymap[i].code);
323 ret = -EINVAL;
324 goto err_bad_keymap;
325 }
326 input_set_capability(input_devs->dev[dev], di->type,
327 di->keymap[i].code);
328 ds->key_state[i].ds = ds;
329 ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
330 }
331
332 for (i = 0; i < di->keymap_size; i++) {
333 ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
334 if (ret) {
335 pr_err("gpio_event_input_func: gpio_request "
336 "failed for %d\n", di->keymap[i].gpio);
337 goto err_gpio_request_failed;
338 }
339 ret = gpio_direction_input(di->keymap[i].gpio);
340 if (ret) {
341 pr_err("gpio_event_input_func: "
342 "gpio_direction_input failed for %d\n",
343 di->keymap[i].gpio);
344 goto err_gpio_configure_failed;
345 }
346 }
347
348 ret = gpio_event_input_request_irqs(ds);
349
350 spin_lock_irqsave(&ds->irq_lock, irqflags);
351 ds->use_irq = ret == 0;
352
353 pr_info("GPIO Input Driver: Start gpio inputs for %s%s in %s "
354 "mode\n", input_devs->dev[0]->name,
355 (input_devs->count > 1) ? "..." : "",
356 ret == 0 ? "interrupt" : "polling");
357
358 hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
359 ds->timer.function = gpio_event_input_timer_func;
360 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
361 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
362 return 0;
363 }
364
365 ret = 0;
366 spin_lock_irqsave(&ds->irq_lock, irqflags);
367 hrtimer_cancel(&ds->timer);
368 if (ds->use_irq) {
369 for (i = di->keymap_size - 1; i >= 0; i--) {
370 int irq = gpio_to_irq(di->keymap[i].gpio);
371 if (ds->info->info.no_suspend)
372 disable_irq_wake(irq);
373 free_irq(irq, &ds->key_state[i]);
374 }
375 }
376 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
377
378 for (i = di->keymap_size - 1; i >= 0; i--) {
379err_gpio_configure_failed:
380 gpio_free(di->keymap[i].gpio);
381err_gpio_request_failed:
382 ;
383 }
384err_bad_keymap:
Todd Poynorbffb6b82012-06-19 21:06:47 -0700385 wakeup_source_unregister(ds->ws);
386err_ws_failed:
Arve Hjønnevågca984132008-10-15 18:23:47 -0700387 kfree(ds);
388err_ds_alloc_failed:
389 return ret;
390}