blob: 975f4d16f5582466dbec5190c809508a51f530c9 [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
Matt Mowere727d6c2013-10-17 03:36:09 -050097#ifdef CONFIG_HTC_WAKE_ON_VOL
98static DEFINE_MUTEX(wakeup_mutex);
99static unsigned char wakeup_bitmask;
100static unsigned char set_wakeup;
101static unsigned int vol_up_irq;
102static unsigned int vol_down_irq;
103static ssize_t vol_wakeup_store(struct device *dev,
104 struct device_attribute *attr,
105 const char *buf, size_t count)
106{
107 unsigned char bitmask = 0;
108 bitmask = simple_strtoull(buf, NULL, 10);
109 mutex_lock(&wakeup_mutex);
110 if (bitmask) {
111 if (bitmask == 127)
112 wakeup_bitmask &= bitmask;
113 else if (bitmask > 128)
114 wakeup_bitmask &= bitmask;
115 else
116 wakeup_bitmask |= bitmask;
117 }
118
119 if (wakeup_bitmask && (!set_wakeup)) {
120 enable_irq_wake(vol_up_irq);
121 enable_irq_wake(vol_down_irq);
122 set_wakeup = 1;
123 printk(KERN_INFO "%s:change to wake up function(%d, %d)\n", __func__, vol_up_irq, vol_down_irq);
124 } else if ((!wakeup_bitmask) && set_wakeup){
125 disable_irq_wake(vol_up_irq);
126 disable_irq_wake(vol_down_irq);
127 set_wakeup = 0;
128 printk(KERN_INFO "%s:change to non-wake up function(%d, %d)\n", __func__, vol_up_irq, vol_down_irq);
129 }
130 mutex_unlock(&wakeup_mutex);
131 return count;
132}
133static ssize_t vol_wakeup_show(struct device *dev,
134 struct device_attribute *attr, char *buf)
135{
136 return sprintf(buf, "%x\n", wakeup_bitmask);
137}
138
139static DEVICE_ATTR(vol_wakeup, 0664, vol_wakeup_show, vol_wakeup_store);
140#endif /* CONFIG_HTC_WAKE_ON_VOL */
141
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -0700142enum {
143 DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */
144 DEBOUNCE_PRESSED = BIT(1),
145 DEBOUNCE_NOTPRESSED = BIT(2),
146 DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */
147 DEBOUNCE_POLL = BIT(4), /* Stable polling state */
148
149 DEBOUNCE_UNKNOWN =
150 DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
151};
152
153struct gpio_key_state {
154 struct gpio_input_state *ds;
155 uint8_t debounce;
156};
157
158struct gpio_input_state {
159 struct gpio_event_input_devs *input_devs;
160 const struct gpio_event_input_info *info;
161 struct hrtimer timer;
162 int use_irq;
163 int debounce_count;
164 spinlock_t irq_lock;
165 struct wake_lock wake_lock;
166 struct gpio_key_state key_state[0];
167};
168
169static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
170{
171 int i;
172 int pressed;
173 struct gpio_input_state *ds =
174 container_of(timer, struct gpio_input_state, timer);
175 unsigned gpio_flags = ds->info->flags;
176 unsigned npolarity;
177 int nkeys = ds->info->keymap_size;
178 const struct gpio_event_direct_entry *key_entry;
179 struct gpio_key_state *key_state;
180 unsigned long irqflags;
181 uint8_t debounce;
182 bool sync_needed;
183
184#if 0
185 key_entry = kp->keys_info->keymap;
186 key_state = kp->key_state;
187 for (i = 0; i < nkeys; i++, key_entry++, key_state++)
188 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
189 gpio_read_detect_status(key_entry->gpio));
190#endif
191 key_entry = ds->info->keymap;
192 key_state = ds->key_state;
193 sync_needed = false;
194 spin_lock_irqsave(&ds->irq_lock, irqflags);
195 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
196 debounce = key_state->debounce;
197 if (debounce & DEBOUNCE_WAIT_IRQ)
198 continue;
199 if (key_state->debounce & DEBOUNCE_UNSTABLE) {
200 debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
201 enable_irq(gpio_to_irq(key_entry->gpio));
202 if (gpio_flags & GPIOEDF_PRINT_KEY_UNSTABLE)
203 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
204 "(%d) continue debounce\n",
205 ds->info->type, key_entry->code,
206 i, key_entry->gpio);
207 }
208 npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
209 pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
210 if (debounce & DEBOUNCE_POLL) {
211 if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
212 ds->debounce_count++;
213 key_state->debounce = DEBOUNCE_UNKNOWN;
214 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
215 pr_info("gpio_keys_scan_keys: key %x-"
216 "%x, %d (%d) start debounce\n",
217 ds->info->type, key_entry->code,
218 i, key_entry->gpio);
219 }
220 continue;
221 }
222 if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
223 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
224 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
225 "(%d) debounce pressed 1\n",
226 ds->info->type, key_entry->code,
227 i, key_entry->gpio);
228 key_state->debounce = DEBOUNCE_PRESSED;
229 continue;
230 }
231 if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
232 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
233 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
234 "(%d) debounce pressed 0\n",
235 ds->info->type, key_entry->code,
236 i, key_entry->gpio);
237 key_state->debounce = DEBOUNCE_NOTPRESSED;
238 continue;
239 }
240 /* key is stable */
241 ds->debounce_count--;
242 if (ds->use_irq)
243 key_state->debounce |= DEBOUNCE_WAIT_IRQ;
244 else
245 key_state->debounce |= DEBOUNCE_POLL;
246 if (gpio_flags & GPIOEDF_PRINT_KEYS)
247 pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
248 "changed to %d\n", ds->info->type,
249 key_entry->code, i, key_entry->gpio, pressed);
Flemmardce3c2c32013-05-23 16:53:44 -0700250#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
251 handle_power_key_state(key_entry->code, pressed);
252#endif
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -0700253 input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
254 key_entry->code, pressed);
255 sync_needed = true;
256 }
257 if (sync_needed) {
258 for (i = 0; i < ds->input_devs->count; i++)
259 input_sync(ds->input_devs->dev[i]);
260 }
261
262#if 0
263 key_entry = kp->keys_info->keymap;
264 key_state = kp->key_state;
265 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
266 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
267 gpio_read_detect_status(key_entry->gpio));
268 }
269#endif
270
271 if (ds->debounce_count)
272 hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
273 else if (!ds->use_irq)
274 hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
275 else
276 wake_unlock(&ds->wake_lock);
277
278 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
279
280 return HRTIMER_NORESTART;
281}
282
283static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
284{
285 struct gpio_key_state *ks = dev_id;
286 struct gpio_input_state *ds = ks->ds;
287 int keymap_index = ks - ds->key_state;
288 const struct gpio_event_direct_entry *key_entry;
289 unsigned long irqflags;
290 int pressed;
291
292 if (!ds->use_irq)
293 return IRQ_HANDLED;
294
295 key_entry = &ds->info->keymap[keymap_index];
296
297 if (ds->info->debounce_time.tv64) {
298 spin_lock_irqsave(&ds->irq_lock, irqflags);
299 if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
300 ks->debounce = DEBOUNCE_UNKNOWN;
301 if (ds->debounce_count++ == 0) {
302 wake_lock(&ds->wake_lock);
303 hrtimer_start(
304 &ds->timer, ds->info->debounce_time,
305 HRTIMER_MODE_REL);
306 }
307 if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
308 pr_info("gpio_event_input_irq_handler: "
309 "key %x-%x, %d (%d) start debounce\n",
310 ds->info->type, key_entry->code,
311 keymap_index, key_entry->gpio);
312 } else {
313 disable_irq_nosync(irq);
314 ks->debounce = DEBOUNCE_UNSTABLE;
315 }
316 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
317 } else {
318 pressed = gpio_get_value(key_entry->gpio) ^
319 !(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
320 if (ds->info->flags & GPIOEDF_PRINT_KEYS)
321 pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
322 "(%d) changed to %d\n",
323 ds->info->type, key_entry->code, keymap_index,
324 key_entry->gpio, pressed);
325 input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
326 key_entry->code, pressed);
327 input_sync(ds->input_devs->dev[key_entry->dev]);
328 }
329 return IRQ_HANDLED;
330}
331
332static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
333{
334 int i;
335 int err;
336 unsigned int irq;
337 unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
338
339 for (i = 0; i < ds->info->keymap_size; i++) {
340 err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
341 if (err < 0)
342 goto err_gpio_get_irq_num_failed;
343 err = request_irq(irq, gpio_event_input_irq_handler,
344 req_flags, "gpio_keys", &ds->key_state[i]);
345 if (err) {
346 pr_err("gpio_event_input_request_irqs: request_irq "
347 "failed for input %d, irq %d\n",
348 ds->info->keymap[i].gpio, irq);
349 goto err_request_irq_failed;
350 }
Matt Mowere727d6c2013-10-17 03:36:09 -0500351#ifdef CONFIG_HTC_WAKE_ON_VOL
352 if (ds->info->keymap[i].code == KEY_VOLUMEUP ||
353 ds->info->keymap[i].code == KEY_VOLUMEDOWN) {
354 pr_info("keycode = %d, gpio = %d, irq = %d\n",
355 ds->info->keymap[i].code,
356 ds->info->keymap[i].gpio, irq);
357 if (ds->info->keymap[i].code == KEY_VOLUMEUP)
358 vol_up_irq = irq;
359 else
360 vol_down_irq = irq;
361 } else {
362 enable_irq_wake(irq);
363 }
364#endif
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -0700365 if (ds->info->info.no_suspend) {
366 err = enable_irq_wake(irq);
367 if (err) {
368 pr_err("gpio_event_input_request_irqs: "
369 "enable_irq_wake failed for input %d, "
370 "irq %d\n",
371 ds->info->keymap[i].gpio, irq);
372 goto err_enable_irq_wake_failed;
373 }
374 }
375 }
Flemmardce3c2c32013-05-23 16:53:44 -0700376#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
377 init_power_key_api();
378#endif
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -0700379 return 0;
380
381 for (i = ds->info->keymap_size - 1; i >= 0; i--) {
382 irq = gpio_to_irq(ds->info->keymap[i].gpio);
383 if (ds->info->info.no_suspend)
384 disable_irq_wake(irq);
385err_enable_irq_wake_failed:
386 free_irq(irq, &ds->key_state[i]);
387err_request_irq_failed:
388err_gpio_get_irq_num_failed:
389 ;
390 }
391 return err;
392}
393
394int gpio_event_input_func(struct gpio_event_input_devs *input_devs,
395 struct gpio_event_info *info, void **data, int func)
396{
397 int ret;
398 int i;
399 unsigned long irqflags;
400 struct gpio_event_input_info *di;
401 struct gpio_input_state *ds = *data;
Matt Mowere727d6c2013-10-17 03:36:09 -0500402#ifdef CONFIG_HTC_WAKE_ON_VOL
403 struct kobject *keyboard_kobj;
404#endif
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -0700405
406 di = container_of(info, struct gpio_event_input_info, info);
407
408 if (func == GPIO_EVENT_FUNC_SUSPEND) {
409 if (ds->use_irq)
410 for (i = 0; i < di->keymap_size; i++)
411 disable_irq(gpio_to_irq(di->keymap[i].gpio));
412 hrtimer_cancel(&ds->timer);
413 return 0;
414 }
415 if (func == GPIO_EVENT_FUNC_RESUME) {
416 spin_lock_irqsave(&ds->irq_lock, irqflags);
417 if (ds->use_irq)
418 for (i = 0; i < di->keymap_size; i++)
419 enable_irq(gpio_to_irq(di->keymap[i].gpio));
420 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
421 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
422 return 0;
423 }
424
425 if (func == GPIO_EVENT_FUNC_INIT) {
426 if (ktime_to_ns(di->poll_time) <= 0)
427 di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
428
429 *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
430 di->keymap_size, GFP_KERNEL);
431 if (ds == NULL) {
432 ret = -ENOMEM;
433 pr_err("gpio_event_input_func: "
434 "Failed to allocate private data\n");
435 goto err_ds_alloc_failed;
436 }
437 ds->debounce_count = di->keymap_size;
438 ds->input_devs = input_devs;
439 ds->info = di;
440 wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input");
441 spin_lock_init(&ds->irq_lock);
442
443 for (i = 0; i < di->keymap_size; i++) {
444 int dev = di->keymap[i].dev;
445 if (dev >= input_devs->count) {
446 pr_err("gpio_event_input_func: bad device "
447 "index %d >= %d for key code %d\n",
448 dev, input_devs->count,
449 di->keymap[i].code);
450 ret = -EINVAL;
451 goto err_bad_keymap;
452 }
453 input_set_capability(input_devs->dev[dev], di->type,
454 di->keymap[i].code);
455 ds->key_state[i].ds = ds;
456 ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
457 }
458
459 for (i = 0; i < di->keymap_size; i++) {
460 ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
461 if (ret) {
462 pr_err("gpio_event_input_func: gpio_request "
463 "failed for %d\n", di->keymap[i].gpio);
464 goto err_gpio_request_failed;
465 }
466 ret = gpio_direction_input(di->keymap[i].gpio);
467 if (ret) {
468 pr_err("gpio_event_input_func: "
469 "gpio_direction_input failed for %d\n",
470 di->keymap[i].gpio);
471 goto err_gpio_configure_failed;
472 }
473 }
474
475 ret = gpio_event_input_request_irqs(ds);
476
Matt Mowere727d6c2013-10-17 03:36:09 -0500477#ifdef CONFIG_HTC_WAKE_ON_VOL
478 keyboard_kobj = kobject_create_and_add("keyboard", NULL);
479 if (keyboard_kobj == NULL) {
480 printk(KERN_ERR "KEY_ERR: %s: subsystem_register failed\n", __func__);
481 ret = -ENOMEM;
482 return ret;
483 }
484 if (sysfs_create_file(keyboard_kobj, &dev_attr_vol_wakeup.attr))
485 printk(KERN_ERR "KEY_ERR: %s: sysfs_create_file "
486 "return %d\n", __func__, ret);
487 wakeup_bitmask = 0;
488 set_wakeup = 0;
489#endif
490
Arve Hjønnevågc3fffcb2008-10-15 18:23:47 -0700491 spin_lock_irqsave(&ds->irq_lock, irqflags);
492 ds->use_irq = ret == 0;
493
494 pr_info("GPIO Input Driver: Start gpio inputs for %s%s in %s "
495 "mode\n", input_devs->dev[0]->name,
496 (input_devs->count > 1) ? "..." : "",
497 ret == 0 ? "interrupt" : "polling");
498
499 hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
500 ds->timer.function = gpio_event_input_timer_func;
501 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
502 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
503 return 0;
504 }
505
506 ret = 0;
507 spin_lock_irqsave(&ds->irq_lock, irqflags);
508 hrtimer_cancel(&ds->timer);
509 if (ds->use_irq) {
510 for (i = di->keymap_size - 1; i >= 0; i--) {
511 int irq = gpio_to_irq(di->keymap[i].gpio);
512 if (ds->info->info.no_suspend)
513 disable_irq_wake(irq);
514 free_irq(irq, &ds->key_state[i]);
515 }
516 }
517 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
518
519 for (i = di->keymap_size - 1; i >= 0; i--) {
520err_gpio_configure_failed:
521 gpio_free(di->keymap[i].gpio);
522err_gpio_request_failed:
523 ;
524 }
525err_bad_keymap:
526 wake_lock_destroy(&ds->wake_lock);
527 kfree(ds);
528err_ds_alloc_failed:
529 return ret;
530}