blob: f4b9a5a00e18ff727492d930510c77811cd2ddd8 [file] [log] [blame]
Arve Hjønnevågc3fffcb2008-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>
23#include <linux/wakelock.h>
24
Flemmardce3c2c32013-05-23 16:53:44 -070025#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
26static uint8_t power_key_state;
27static spinlock_t power_key_state_lock;
28
29#define PWRKEY_PRESS_DUE 1*HZ
30#include <linux/module.h>
31static void init_power_key_api(void)
32{
33 spin_lock_init(&power_key_state_lock);
34 power_key_state = 0;
35}
36
37static void setPowerKeyState(uint8_t flag)
38{
39 spin_lock(&power_key_state_lock);
40 power_key_state = flag;
41 spin_unlock(&power_key_state_lock);
42}
43
44uint8_t getPowerKeyState(void)
45{
46 uint8_t value;
47
48 spin_lock(&power_key_state_lock);
49 value = power_key_state;
50 spin_unlock(&power_key_state_lock);
51
52 return value;
53}
54EXPORT_SYMBOL(getPowerKeyState);
55
56static void power_key_state_disable_work_func(struct work_struct *dummy)
57{
58 setPowerKeyState(0);
59 printk(KERN_INFO "[KEY][PWR][STATE]power key pressed outdated\n");
60}
61static DECLARE_DELAYED_WORK(power_key_state_disable_work, power_key_state_disable_work_func);
62
63static void handle_power_key_state(unsigned int code, int value)
64{
65 int ret = 0;
66 if (code == KEY_POWER && value == 1) {
67 printk(KERN_INFO "[PWR][STATE]try to schedule power key pressed due\n");
68 ret = schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE);
69 if (!ret) {
70 printk(KERN_INFO "[PWR][STATE]Schedule power key pressed due failed, seems already have one, try to cancel...\n");
71 ret = cancel_delayed_work(&power_key_state_disable_work);
72 if (!ret) {
73 setPowerKeyState(1);
74 if (schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE)) {
75 printk(KERN_INFO "[PWR][STATE]Re-schedule power key pressed due SCCUESS.\n");
76 printk(KERN_INFO "[PWR][STATE] start count for power key pressed due\n");
77 setPowerKeyState(1);
78 } else
79 printk(KERN_INFO "[PWR][STATE]Re-schedule power key pressed due FAILED, reason unknown, give up.\n");
80 } else {
81 printk(KERN_INFO "[PWR][STATE]Cancel scheduled power key due success, now re-schedule.\n");
82 if (schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE)) {
83 printk(KERN_INFO "[PWR][STATE]Re-schedule power key pressed due SCCUESS.\n");
84 printk(KERN_INFO "[PWR][STATE] start count for power key pressed due\n");
85 setPowerKeyState(1);
86 } else
87 printk(KERN_INFO "[PWR][STATE]Re-schedule power key pressed due FAILED, reason unknown, give up.\n");
88 }
89 } else {
90 printk(KERN_INFO "[PWR][STATE] start count for power key pressed due\n");
91 setPowerKeyState(1);
92 }
93 }
94}
95#endif /* CONFIG_TOUCHSCREEN_SYNAPTICS_3K */
96
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -070097enum {
98 DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */
99 DEBOUNCE_PRESSED = BIT(1),
100 DEBOUNCE_NOTPRESSED = BIT(2),
101 DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */
102 DEBOUNCE_POLL = BIT(4), /* Stable polling state */
103
104 DEBOUNCE_UNKNOWN =
105 DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
106};
107
108struct gpio_key_state {
109 struct gpio_input_state *ds;
110 uint8_t debounce;
111};
112
113struct gpio_input_state {
114 struct gpio_event_input_devs *input_devs;
115 const struct gpio_event_input_info *info;
116 struct hrtimer timer;
117 int use_irq;
118 int debounce_count;
119 spinlock_t irq_lock;
120 struct wake_lock wake_lock;
121 struct gpio_key_state key_state[0];
122};
123
124static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
125{
126 int i;
127 int pressed;
128 struct gpio_input_state *ds =
129 container_of(timer, struct gpio_input_state, timer);
130 unsigned gpio_flags = ds->info->flags;
131 unsigned npolarity;
132 int nkeys = ds->info->keymap_size;
133 const struct gpio_event_direct_entry *key_entry;
134 struct gpio_key_state *key_state;
135 unsigned long irqflags;
136 uint8_t debounce;
137 bool sync_needed;
138
139#if 0
140 key_entry = kp->keys_info->keymap;
141 key_state = kp->key_state;
142 for (i = 0; i < nkeys; i++, key_entry++, key_state++)
143 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
144 gpio_read_detect_status(key_entry->gpio));
145#endif
146 key_entry = ds->info->keymap;
147 key_state = ds->key_state;
148 sync_needed = false;
149 spin_lock_irqsave(&ds->irq_lock, irqflags);
150 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
151 debounce = key_state->debounce;
152 if (debounce & DEBOUNCE_WAIT_IRQ)
153 continue;
154 if (key_state->debounce & DEBOUNCE_UNSTABLE) {
155 debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
156 enable_irq(gpio_to_irq(key_entry->gpio));
157 if (gpio_flags & GPIOEDF_PRINT_KEY_UNSTABLE)
158 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
159 "(%d) continue debounce\n",
160 ds->info->type, key_entry->code,
161 i, key_entry->gpio);
162 }
163 npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
164 pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
165 if (debounce & DEBOUNCE_POLL) {
166 if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
167 ds->debounce_count++;
168 key_state->debounce = DEBOUNCE_UNKNOWN;
169 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
170 pr_info("gpio_keys_scan_keys: key %x-"
171 "%x, %d (%d) start debounce\n",
172 ds->info->type, key_entry->code,
173 i, key_entry->gpio);
174 }
175 continue;
176 }
177 if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
178 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
179 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
180 "(%d) debounce pressed 1\n",
181 ds->info->type, key_entry->code,
182 i, key_entry->gpio);
183 key_state->debounce = DEBOUNCE_PRESSED;
184 continue;
185 }
186 if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
187 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
188 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
189 "(%d) debounce pressed 0\n",
190 ds->info->type, key_entry->code,
191 i, key_entry->gpio);
192 key_state->debounce = DEBOUNCE_NOTPRESSED;
193 continue;
194 }
195 /* key is stable */
196 ds->debounce_count--;
197 if (ds->use_irq)
198 key_state->debounce |= DEBOUNCE_WAIT_IRQ;
199 else
200 key_state->debounce |= DEBOUNCE_POLL;
201 if (gpio_flags & GPIOEDF_PRINT_KEYS)
202 pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
203 "changed to %d\n", ds->info->type,
204 key_entry->code, i, key_entry->gpio, pressed);
Flemmardce3c2c32013-05-23 16:53:44 -0700205#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
206 handle_power_key_state(key_entry->code, pressed);
207#endif
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -0700208 input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
209 key_entry->code, pressed);
210 sync_needed = true;
211 }
212 if (sync_needed) {
213 for (i = 0; i < ds->input_devs->count; i++)
214 input_sync(ds->input_devs->dev[i]);
215 }
216
217#if 0
218 key_entry = kp->keys_info->keymap;
219 key_state = kp->key_state;
220 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
221 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
222 gpio_read_detect_status(key_entry->gpio));
223 }
224#endif
225
226 if (ds->debounce_count)
227 hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
228 else if (!ds->use_irq)
229 hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
230 else
231 wake_unlock(&ds->wake_lock);
232
233 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
234
235 return HRTIMER_NORESTART;
236}
237
238static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
239{
240 struct gpio_key_state *ks = dev_id;
241 struct gpio_input_state *ds = ks->ds;
242 int keymap_index = ks - ds->key_state;
243 const struct gpio_event_direct_entry *key_entry;
244 unsigned long irqflags;
245 int pressed;
246
247 if (!ds->use_irq)
248 return IRQ_HANDLED;
249
250 key_entry = &ds->info->keymap[keymap_index];
251
252 if (ds->info->debounce_time.tv64) {
253 spin_lock_irqsave(&ds->irq_lock, irqflags);
254 if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
255 ks->debounce = DEBOUNCE_UNKNOWN;
256 if (ds->debounce_count++ == 0) {
257 wake_lock(&ds->wake_lock);
258 hrtimer_start(
259 &ds->timer, ds->info->debounce_time,
260 HRTIMER_MODE_REL);
261 }
262 if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
263 pr_info("gpio_event_input_irq_handler: "
264 "key %x-%x, %d (%d) start debounce\n",
265 ds->info->type, key_entry->code,
266 keymap_index, key_entry->gpio);
267 } else {
268 disable_irq_nosync(irq);
269 ks->debounce = DEBOUNCE_UNSTABLE;
270 }
271 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
272 } else {
273 pressed = gpio_get_value(key_entry->gpio) ^
274 !(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
275 if (ds->info->flags & GPIOEDF_PRINT_KEYS)
276 pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
277 "(%d) changed to %d\n",
278 ds->info->type, key_entry->code, keymap_index,
279 key_entry->gpio, pressed);
280 input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
281 key_entry->code, pressed);
282 input_sync(ds->input_devs->dev[key_entry->dev]);
283 }
284 return IRQ_HANDLED;
285}
286
287static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
288{
289 int i;
290 int err;
291 unsigned int irq;
292 unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
293
294 for (i = 0; i < ds->info->keymap_size; i++) {
295 err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
296 if (err < 0)
297 goto err_gpio_get_irq_num_failed;
298 err = request_irq(irq, gpio_event_input_irq_handler,
299 req_flags, "gpio_keys", &ds->key_state[i]);
300 if (err) {
301 pr_err("gpio_event_input_request_irqs: request_irq "
302 "failed for input %d, irq %d\n",
303 ds->info->keymap[i].gpio, irq);
304 goto err_request_irq_failed;
305 }
306 if (ds->info->info.no_suspend) {
307 err = enable_irq_wake(irq);
308 if (err) {
309 pr_err("gpio_event_input_request_irqs: "
310 "enable_irq_wake failed for input %d, "
311 "irq %d\n",
312 ds->info->keymap[i].gpio, irq);
313 goto err_enable_irq_wake_failed;
314 }
315 }
316 }
Flemmardce3c2c32013-05-23 16:53:44 -0700317#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
318 init_power_key_api();
319#endif
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -0700320 return 0;
321
322 for (i = ds->info->keymap_size - 1; i >= 0; i--) {
323 irq = gpio_to_irq(ds->info->keymap[i].gpio);
324 if (ds->info->info.no_suspend)
325 disable_irq_wake(irq);
326err_enable_irq_wake_failed:
327 free_irq(irq, &ds->key_state[i]);
328err_request_irq_failed:
329err_gpio_get_irq_num_failed:
330 ;
331 }
332 return err;
333}
334
335int gpio_event_input_func(struct gpio_event_input_devs *input_devs,
336 struct gpio_event_info *info, void **data, int func)
337{
338 int ret;
339 int i;
340 unsigned long irqflags;
341 struct gpio_event_input_info *di;
342 struct gpio_input_state *ds = *data;
343
344 di = container_of(info, struct gpio_event_input_info, info);
345
346 if (func == GPIO_EVENT_FUNC_SUSPEND) {
347 if (ds->use_irq)
348 for (i = 0; i < di->keymap_size; i++)
349 disable_irq(gpio_to_irq(di->keymap[i].gpio));
350 hrtimer_cancel(&ds->timer);
351 return 0;
352 }
353 if (func == GPIO_EVENT_FUNC_RESUME) {
354 spin_lock_irqsave(&ds->irq_lock, irqflags);
355 if (ds->use_irq)
356 for (i = 0; i < di->keymap_size; i++)
357 enable_irq(gpio_to_irq(di->keymap[i].gpio));
358 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
359 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
360 return 0;
361 }
362
363 if (func == GPIO_EVENT_FUNC_INIT) {
364 if (ktime_to_ns(di->poll_time) <= 0)
365 di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
366
367 *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
368 di->keymap_size, GFP_KERNEL);
369 if (ds == NULL) {
370 ret = -ENOMEM;
371 pr_err("gpio_event_input_func: "
372 "Failed to allocate private data\n");
373 goto err_ds_alloc_failed;
374 }
375 ds->debounce_count = di->keymap_size;
376 ds->input_devs = input_devs;
377 ds->info = di;
378 wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input");
379 spin_lock_init(&ds->irq_lock);
380
381 for (i = 0; i < di->keymap_size; i++) {
382 int dev = di->keymap[i].dev;
383 if (dev >= input_devs->count) {
384 pr_err("gpio_event_input_func: bad device "
385 "index %d >= %d for key code %d\n",
386 dev, input_devs->count,
387 di->keymap[i].code);
388 ret = -EINVAL;
389 goto err_bad_keymap;
390 }
391 input_set_capability(input_devs->dev[dev], di->type,
392 di->keymap[i].code);
393 ds->key_state[i].ds = ds;
394 ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
395 }
396
397 for (i = 0; i < di->keymap_size; i++) {
398 ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
399 if (ret) {
400 pr_err("gpio_event_input_func: gpio_request "
401 "failed for %d\n", di->keymap[i].gpio);
402 goto err_gpio_request_failed;
403 }
404 ret = gpio_direction_input(di->keymap[i].gpio);
405 if (ret) {
406 pr_err("gpio_event_input_func: "
407 "gpio_direction_input failed for %d\n",
408 di->keymap[i].gpio);
409 goto err_gpio_configure_failed;
410 }
411 }
412
413 ret = gpio_event_input_request_irqs(ds);
414
415 spin_lock_irqsave(&ds->irq_lock, irqflags);
416 ds->use_irq = ret == 0;
417
418 pr_info("GPIO Input Driver: Start gpio inputs for %s%s in %s "
419 "mode\n", input_devs->dev[0]->name,
420 (input_devs->count > 1) ? "..." : "",
421 ret == 0 ? "interrupt" : "polling");
422
423 hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
424 ds->timer.function = gpio_event_input_timer_func;
425 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
426 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
427 return 0;
428 }
429
430 ret = 0;
431 spin_lock_irqsave(&ds->irq_lock, irqflags);
432 hrtimer_cancel(&ds->timer);
433 if (ds->use_irq) {
434 for (i = di->keymap_size - 1; i >= 0; i--) {
435 int irq = gpio_to_irq(di->keymap[i].gpio);
436 if (ds->info->info.no_suspend)
437 disable_irq_wake(irq);
438 free_irq(irq, &ds->key_state[i]);
439 }
440 }
441 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
442
443 for (i = di->keymap_size - 1; i >= 0; i--) {
444err_gpio_configure_failed:
445 gpio_free(di->keymap[i].gpio);
446err_gpio_request_failed:
447 ;
448 }
449err_bad_keymap:
450 wake_lock_destroy(&ds->wake_lock);
451 kfree(ds);
452err_ds_alloc_failed:
453 return ret;
454}