blob: 08769dd88f56a99c81178420dbd2ab0933982ba2 [file] [log] [blame]
Arve Hjønnevågca984132008-10-15 18:23:47 -07001/* drivers/input/misc/gpio_matrix.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/interrupt.h>
21#include <linux/slab.h>
Arve Hjønnevågca984132008-10-15 18:23:47 -070022
23struct gpio_kp {
24 struct gpio_event_input_devs *input_devs;
25 struct gpio_event_matrix_info *keypad_info;
26 struct hrtimer timer;
Dmitry Shmidt1626ae32017-01-12 12:34:22 -080027 struct wakeup_source wake_src;
Arve Hjønnevågca984132008-10-15 18:23:47 -070028 int current_output;
29 unsigned int use_irq:1;
30 unsigned int key_state_changed:1;
31 unsigned int last_key_state_changed:1;
32 unsigned int some_keys_pressed:2;
33 unsigned int disabled_irq:1;
34 unsigned long keys_pressed[0];
35};
36
37static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
38{
39 struct gpio_event_matrix_info *mi = kp->keypad_info;
40 int key_index = out * mi->ninputs + in;
41 unsigned short keyentry = mi->keymap[key_index];
42 unsigned short keycode = keyentry & MATRIX_KEY_MASK;
43 unsigned short dev = keyentry >> MATRIX_CODE_BITS;
44
45 if (!test_bit(keycode, kp->input_devs->dev[dev]->key)) {
46 if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
47 pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
48 "cleared\n", keycode, out, in,
49 mi->output_gpios[out], mi->input_gpios[in]);
50 __clear_bit(key_index, kp->keys_pressed);
51 } else {
52 if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
53 pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
54 "not cleared\n", keycode, out, in,
55 mi->output_gpios[out], mi->input_gpios[in]);
56 }
57}
58
59static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
60{
61 int rv = 0;
62 int key_index;
63
64 key_index = out * kp->keypad_info->ninputs + in;
65 while (out < kp->keypad_info->noutputs) {
66 if (test_bit(key_index, kp->keys_pressed)) {
67 rv = 1;
68 clear_phantom_key(kp, out, in);
69 }
70 key_index += kp->keypad_info->ninputs;
71 out++;
72 }
73 return rv;
74}
75
76static void remove_phantom_keys(struct gpio_kp *kp)
77{
78 int out, in, inp;
79 int key_index;
80
81 if (kp->some_keys_pressed < 3)
82 return;
83
84 for (out = 0; out < kp->keypad_info->noutputs; out++) {
85 inp = -1;
86 key_index = out * kp->keypad_info->ninputs;
87 for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
88 if (test_bit(key_index, kp->keys_pressed)) {
89 if (inp == -1) {
90 inp = in;
91 continue;
92 }
93 if (inp >= 0) {
94 if (!restore_keys_for_input(kp, out + 1,
95 inp))
96 break;
97 clear_phantom_key(kp, out, inp);
98 inp = -2;
99 }
100 restore_keys_for_input(kp, out, in);
101 }
102 }
103 }
104}
105
106static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
107{
108 struct gpio_event_matrix_info *mi = kp->keypad_info;
109 int pressed = test_bit(key_index, kp->keys_pressed);
110 unsigned short keyentry = mi->keymap[key_index];
111 unsigned short keycode = keyentry & MATRIX_KEY_MASK;
112 unsigned short dev = keyentry >> MATRIX_CODE_BITS;
113
114 if (pressed != test_bit(keycode, kp->input_devs->dev[dev]->key)) {
115 if (keycode == KEY_RESERVED) {
116 if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
117 pr_info("gpiomatrix: unmapped key, %d-%d "
118 "(%d-%d) changed to %d\n",
119 out, in, mi->output_gpios[out],
120 mi->input_gpios[in], pressed);
121 } else {
122 if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
123 pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
124 "changed to %d\n", keycode,
125 out, in, mi->output_gpios[out],
126 mi->input_gpios[in], pressed);
127 input_report_key(kp->input_devs->dev[dev], keycode, pressed);
128 }
129 }
130}
131
132static void report_sync(struct gpio_kp *kp)
133{
134 int i;
135
136 for (i = 0; i < kp->input_devs->count; i++)
137 input_sync(kp->input_devs->dev[i]);
138}
139
140static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
141{
142 int out, in;
143 int key_index;
144 int gpio;
145 struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
146 struct gpio_event_matrix_info *mi = kp->keypad_info;
147 unsigned gpio_keypad_flags = mi->flags;
148 unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
149
150 out = kp->current_output;
151 if (out == mi->noutputs) {
152 out = 0;
153 kp->last_key_state_changed = kp->key_state_changed;
154 kp->key_state_changed = 0;
155 kp->some_keys_pressed = 0;
156 } else {
157 key_index = out * mi->ninputs;
158 for (in = 0; in < mi->ninputs; in++, key_index++) {
159 gpio = mi->input_gpios[in];
160 if (gpio_get_value(gpio) ^ !polarity) {
161 if (kp->some_keys_pressed < 3)
162 kp->some_keys_pressed++;
163 kp->key_state_changed |= !__test_and_set_bit(
164 key_index, kp->keys_pressed);
165 } else
166 kp->key_state_changed |= __test_and_clear_bit(
167 key_index, kp->keys_pressed);
168 }
169 gpio = mi->output_gpios[out];
170 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
171 gpio_set_value(gpio, !polarity);
172 else
173 gpio_direction_input(gpio);
174 out++;
175 }
176 kp->current_output = out;
177 if (out < mi->noutputs) {
178 gpio = mi->output_gpios[out];
179 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
180 gpio_set_value(gpio, polarity);
181 else
182 gpio_direction_output(gpio, polarity);
183 hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
184 return HRTIMER_NORESTART;
185 }
186 if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
187 if (kp->key_state_changed) {
188 hrtimer_start(&kp->timer, mi->debounce_delay,
189 HRTIMER_MODE_REL);
190 return HRTIMER_NORESTART;
191 }
192 kp->key_state_changed = kp->last_key_state_changed;
193 }
194 if (kp->key_state_changed) {
195 if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
196 remove_phantom_keys(kp);
197 key_index = 0;
198 for (out = 0; out < mi->noutputs; out++)
199 for (in = 0; in < mi->ninputs; in++, key_index++)
200 report_key(kp, key_index, out, in);
201 report_sync(kp);
202 }
203 if (!kp->use_irq || kp->some_keys_pressed) {
204 hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
205 return HRTIMER_NORESTART;
206 }
207
208 /* No keys are pressed, reenable interrupt */
209 for (out = 0; out < mi->noutputs; out++) {
210 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
211 gpio_set_value(mi->output_gpios[out], polarity);
212 else
213 gpio_direction_output(mi->output_gpios[out], polarity);
214 }
215 for (in = 0; in < mi->ninputs; in++)
216 enable_irq(gpio_to_irq(mi->input_gpios[in]));
Dmitry Shmidt1626ae32017-01-12 12:34:22 -0800217 __pm_relax(&kp->wake_src);
Arve Hjønnevågca984132008-10-15 18:23:47 -0700218 return HRTIMER_NORESTART;
219}
220
221static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
222{
223 int i;
224 struct gpio_kp *kp = dev_id;
225 struct gpio_event_matrix_info *mi = kp->keypad_info;
226 unsigned gpio_keypad_flags = mi->flags;
227
228 if (!kp->use_irq) {
229 /* ignore interrupt while registering the handler */
230 kp->disabled_irq = 1;
231 disable_irq_nosync(irq_in);
232 return IRQ_HANDLED;
233 }
234
235 for (i = 0; i < mi->ninputs; i++)
236 disable_irq_nosync(gpio_to_irq(mi->input_gpios[i]));
237 for (i = 0; i < mi->noutputs; i++) {
238 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
239 gpio_set_value(mi->output_gpios[i],
240 !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
241 else
242 gpio_direction_input(mi->output_gpios[i]);
243 }
Dmitry Shmidt1626ae32017-01-12 12:34:22 -0800244 __pm_stay_awake(&kp->wake_src);
Arve Hjønnevågca984132008-10-15 18:23:47 -0700245 hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
246 return IRQ_HANDLED;
247}
248
249static int gpio_keypad_request_irqs(struct gpio_kp *kp)
250{
251 int i;
252 int err;
253 unsigned int irq;
254 unsigned long request_flags;
255 struct gpio_event_matrix_info *mi = kp->keypad_info;
256
257 switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
258 default:
259 request_flags = IRQF_TRIGGER_FALLING;
260 break;
261 case GPIOKPF_ACTIVE_HIGH:
262 request_flags = IRQF_TRIGGER_RISING;
263 break;
264 case GPIOKPF_LEVEL_TRIGGERED_IRQ:
265 request_flags = IRQF_TRIGGER_LOW;
266 break;
267 case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
268 request_flags = IRQF_TRIGGER_HIGH;
269 break;
270 }
271
272 for (i = 0; i < mi->ninputs; i++) {
273 err = irq = gpio_to_irq(mi->input_gpios[i]);
274 if (err < 0)
275 goto err_gpio_get_irq_num_failed;
276 err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
277 "gpio_kp", kp);
278 if (err) {
279 pr_err("gpiomatrix: request_irq failed for input %d, "
280 "irq %d\n", mi->input_gpios[i], irq);
281 goto err_request_irq_failed;
282 }
283 err = enable_irq_wake(irq);
284 if (err) {
285 pr_err("gpiomatrix: set_irq_wake failed for input %d, "
286 "irq %d\n", mi->input_gpios[i], irq);
287 }
288 disable_irq(irq);
289 if (kp->disabled_irq) {
290 kp->disabled_irq = 0;
291 enable_irq(irq);
292 }
293 }
294 return 0;
295
296 for (i = mi->noutputs - 1; i >= 0; i--) {
297 free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
298err_request_irq_failed:
299err_gpio_get_irq_num_failed:
300 ;
301 }
302 return err;
303}
304
305int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs,
306 struct gpio_event_info *info, void **data, int func)
307{
308 int i;
309 int err;
310 int key_count;
311 struct gpio_kp *kp;
312 struct gpio_event_matrix_info *mi;
313
314 mi = container_of(info, struct gpio_event_matrix_info, info);
315 if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
316 /* TODO: disable scanning */
317 return 0;
318 }
319
320 if (func == GPIO_EVENT_FUNC_INIT) {
321 if (mi->keymap == NULL ||
322 mi->input_gpios == NULL ||
323 mi->output_gpios == NULL) {
324 err = -ENODEV;
325 pr_err("gpiomatrix: Incomplete pdata\n");
326 goto err_invalid_platform_data;
327 }
328 key_count = mi->ninputs * mi->noutputs;
329
330 *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
331 BITS_TO_LONGS(key_count), GFP_KERNEL);
332 if (kp == NULL) {
333 err = -ENOMEM;
334 pr_err("gpiomatrix: Failed to allocate private data\n");
335 goto err_kp_alloc_failed;
336 }
337 kp->input_devs = input_devs;
338 kp->keypad_info = mi;
339 for (i = 0; i < key_count; i++) {
340 unsigned short keyentry = mi->keymap[i];
341 unsigned short keycode = keyentry & MATRIX_KEY_MASK;
342 unsigned short dev = keyentry >> MATRIX_CODE_BITS;
343 if (dev >= input_devs->count) {
344 pr_err("gpiomatrix: bad device index %d >= "
345 "%d for key code %d\n",
346 dev, input_devs->count, keycode);
347 err = -EINVAL;
348 goto err_bad_keymap;
349 }
350 if (keycode && keycode <= KEY_MAX)
351 input_set_capability(input_devs->dev[dev],
352 EV_KEY, keycode);
353 }
354
355 for (i = 0; i < mi->noutputs; i++) {
356 err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
357 if (err) {
358 pr_err("gpiomatrix: gpio_request failed for "
359 "output %d\n", mi->output_gpios[i]);
360 goto err_request_output_gpio_failed;
361 }
362 if (gpio_cansleep(mi->output_gpios[i])) {
363 pr_err("gpiomatrix: unsupported output gpio %d,"
364 " can sleep\n", mi->output_gpios[i]);
365 err = -EINVAL;
366 goto err_output_gpio_configure_failed;
367 }
368 if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
369 err = gpio_direction_output(mi->output_gpios[i],
370 !(mi->flags & GPIOKPF_ACTIVE_HIGH));
371 else
372 err = gpio_direction_input(mi->output_gpios[i]);
373 if (err) {
374 pr_err("gpiomatrix: gpio_configure failed for "
375 "output %d\n", mi->output_gpios[i]);
376 goto err_output_gpio_configure_failed;
377 }
378 }
379 for (i = 0; i < mi->ninputs; i++) {
380 err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
381 if (err) {
382 pr_err("gpiomatrix: gpio_request failed for "
383 "input %d\n", mi->input_gpios[i]);
384 goto err_request_input_gpio_failed;
385 }
386 err = gpio_direction_input(mi->input_gpios[i]);
387 if (err) {
388 pr_err("gpiomatrix: gpio_direction_input failed"
389 " for input %d\n", mi->input_gpios[i]);
390 goto err_gpio_direction_input_failed;
391 }
392 }
393 kp->current_output = mi->noutputs;
394 kp->key_state_changed = 1;
395
396 hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
397 kp->timer.function = gpio_keypad_timer_func;
Dmitry Shmidt1626ae32017-01-12 12:34:22 -0800398 wakeup_source_init(&kp->wake_src, "gpio_kp");
Arve Hjønnevågca984132008-10-15 18:23:47 -0700399 err = gpio_keypad_request_irqs(kp);
400 kp->use_irq = err == 0;
401
402 pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for "
403 "%s%s in %s mode\n", input_devs->dev[0]->name,
404 (input_devs->count > 1) ? "..." : "",
405 kp->use_irq ? "interrupt" : "polling");
406
407 if (kp->use_irq)
Dmitry Shmidt1626ae32017-01-12 12:34:22 -0800408 __pm_stay_awake(&kp->wake_src);
Arve Hjønnevågca984132008-10-15 18:23:47 -0700409 hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
410
411 return 0;
412 }
413
414 err = 0;
415 kp = *data;
416
417 if (kp->use_irq)
418 for (i = mi->noutputs - 1; i >= 0; i--)
419 free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
420
421 hrtimer_cancel(&kp->timer);
Dmitry Shmidt1626ae32017-01-12 12:34:22 -0800422 wakeup_source_trash(&kp->wake_src);
Arve Hjønnevågca984132008-10-15 18:23:47 -0700423 for (i = mi->noutputs - 1; i >= 0; i--) {
424err_gpio_direction_input_failed:
425 gpio_free(mi->input_gpios[i]);
426err_request_input_gpio_failed:
427 ;
428 }
429 for (i = mi->noutputs - 1; i >= 0; i--) {
430err_output_gpio_configure_failed:
431 gpio_free(mi->output_gpios[i]);
432err_request_output_gpio_failed:
433 ;
434 }
435err_bad_keymap:
436 kfree(kp);
437err_kp_alloc_failed:
438err_invalid_platform_data:
439 return err;
440}