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