1 /* Driver for the keypad attached to the TI Calypso */
3 /* (C) 2010 by roh <roh@hyte.de>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <calypso/irq.h>
33 #include <abb/twl3025.h>
36 #define KBR_LATCH_REG 0xfffe480a
37 #define KBC_REG 0xfffe480c
38 #define KBD_GPIO_INT 0xfffe4816
39 #define KBD_GPIO_MASKIT 0xfffe4818
41 static key_handler_t key_handler = NULL;
43 void emit_key(uint8_t key, uint8_t state)
45 printf("key=%u %s\n", key, state == PRESSED ? "pressed" : "released");
47 if (state == RELEASED)
52 key_handler(key, state);
56 volatile uint32_t lastbuttons = 0;
58 #define BTN_TO_KEY(name) \
59 ((diff & BTN_##name) == BTN_##name) \
62 diff = diff & ~BTN_##name; \
63 state = (buttons & BTN_##name) ? PRESSED : RELEASED; \
66 void dispatch_buttons(uint32_t buttons)
70 if (buttons == lastbuttons)
73 uint32_t diff = buttons ^ lastbuttons;
89 else if BTN_TO_KEY(STAR)
90 else if BTN_TO_KEY(HASH)
91 else if BTN_TO_KEY(MENU)
92 else if BTN_TO_KEY(LEFT_SB)
93 else if BTN_TO_KEY(RIGHT_SB)
94 else if BTN_TO_KEY(UP)
95 else if BTN_TO_KEY(DOWN)
96 else if BTN_TO_KEY(LEFT)
97 else if BTN_TO_KEY(RIGHT)
98 else if BTN_TO_KEY(OK)
101 printf("\nunknown keycode: 0x%08x\n", diff);
104 emit_key(key, state);
106 lastbuttons = buttons;
109 static uint8_t polling = 0;
110 static uint8_t with_interrupts = 0;
112 static void keypad_irq(__unused enum irq_nr nr)
116 irq_disable(IRQ_KEYPAD_GPIO);
119 void keypad_init(uint8_t interrupts)
123 writew(0, KBD_GPIO_MASKIT);
128 irq_register_handler(IRQ_KEYPAD_GPIO, &keypad_irq);
129 irq_config(IRQ_KEYPAD_GPIO, 0, 0, 0);
130 irq_enable(IRQ_KEYPAD_GPIO);
134 void keypad_set_handler(key_handler_t handler)
136 key_handler = handler;
143 static uint32_t buttons = 0, debounce1 = 0, debounce2 = 0;
145 if (with_interrupts && !polling)
150 writew(0x1f & ~0x1, KBC_REG); /* first col */
156 /* enable keypad irq after the signal settles */
158 if(with_interrupts) {
159 irq_enable(IRQ_KEYPAD_GPIO);
167 reg = readw(KBR_LATCH_REG);
168 buttons = (buttons & ~(0x1f << (col * 5)))
169 | ((~reg & 0x1f) << (col * 5 ));
170 /* if key is released, stay in column for faster debounce */
171 if ((debounce1 | debounce2) & ~buttons) {
172 debounce2 = debounce1;
180 /* if power button, ignore other states */
181 if (buttons & BTN_POWER)
182 buttons = lastbuttons | BTN_POWER;
183 else if (lastbuttons & BTN_POWER)
184 buttons = lastbuttons & ~BTN_POWER;
185 dispatch_buttons(buttons);
187 writew(0x0, KBC_REG);
193 writew(0xff, KBC_REG);
195 writew(0x1f & ~(0x1 << col ), KBC_REG);