• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <boot/boot.h>
30 #include <boot/gpio.h>
31 #include <boot/gpio_keypad.h>
32 
gpio_keypad_init(gpio_keypad_info * keypad)33 int gpio_keypad_init(gpio_keypad_info *keypad)
34 {
35 	unsigned i;
36 	for(i = 0; i < keypad->noutputs; i++) {
37 		gpio_set(keypad->output_gpios[i], keypad->polarity ^ keypad->drive_inactive_outputs);
38 		gpio_dir(keypad->output_gpios[i], keypad->drive_inactive_outputs);
39 	}
40 	for(i = 0; i < keypad->ninputs; i++) {
41 		gpio_dir(keypad->input_gpios[i], 0);
42 	}
43 	keypad->state = 0;
44 	return 0;
45 }
46 
gpio_keypad_scan_keys(gpio_keypad_info * keypad)47 void gpio_keypad_scan_keys(gpio_keypad_info *keypad)
48 {
49 	unsigned out, in;
50 	unsigned long long keys;
51 	unsigned npolarity = !keypad->polarity;
52 	unsigned int shift;
53 
54 	keys = 0;
55 	out = keypad->noutputs;
56 	shift = keypad->noutputs * keypad->ninputs;
57 	while(out > 0) {
58 		out--;
59 		if(keypad->drive_inactive_outputs)
60 			gpio_set(keypad->output_gpios[out], !npolarity);
61 		else
62 			gpio_dir(keypad->output_gpios[out], 1);
63 		udelay(keypad->settle_time);
64 		in = keypad->ninputs;
65 		while(in > 0) {
66 			in--;
67 			shift--;
68 			keys = (keys << 1) | (gpio_get(keypad->input_gpios[in]) ^ npolarity);
69 			if(((unsigned)(keypad->state >> shift) ^ (unsigned)keys) & 1) {
70 				unsigned int mapped_key = 0;
71 				if(keypad->key_map)
72 					mapped_key = keypad->key_map[shift];
73 				//dprintf("gpio_keypad_scan_keys: %d-%d (%d-%d) %d (%d): %d\n", out, in,
74 				//        keypad->output_gpios[out], keypad->input_gpios[in],
75 				//        shift, mapped_key, keys & 1);
76 				if(mapped_key && key_changed)
77 					key_changed(mapped_key, keys & 1);
78 			}
79 		}
80 		if(keypad->drive_inactive_outputs)
81 			gpio_set(keypad->output_gpios[out], npolarity);
82 		else
83 			gpio_dir(keypad->output_gpios[out], 0);
84 	}
85 	if(keys != keypad->state) {
86 		keypad->state = keys;
87 		//dprintf("gpio_keypad_scan_keys: %x %x\n", (unsigned long)(keys >> 32), (unsigned long)keys);
88 	}
89 }
90 
91