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