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