Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: nomadik-ske-keypad - add multi key press support

Added the multi key press support for SKE keypad by modifying the irq
function for handling the two different keys on the same column and also
pressing the two different keys of different columns on the same ASR
register.

Signed-off-by: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>
Reviewed-by: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by

Naveen Kumar Gaddipati and committed by
Dmitry Torokhov
af77c88b e7ec014a

+41 -26
+41 -26
drivers/input/keyboard/nomadik-ske-keypad.c
··· 135 135 return 0; 136 136 } 137 137 138 + static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col) 139 + { 140 + int row = 0, code, pos; 141 + struct input_dev *input = keypad->input; 142 + u32 ske_ris; 143 + int key_pressed; 144 + int num_of_rows; 145 + 146 + /* find out the row */ 147 + num_of_rows = hweight8(status); 148 + do { 149 + pos = __ffs(status); 150 + row = pos; 151 + status &= ~(1 << pos); 152 + 153 + code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); 154 + ske_ris = readl(keypad->reg_base + SKE_RIS); 155 + key_pressed = ske_ris & SKE_KPRISA; 156 + 157 + input_event(input, EV_MSC, MSC_SCAN, code); 158 + input_report_key(input, keypad->keymap[code], key_pressed); 159 + input_sync(input); 160 + num_of_rows--; 161 + } while (num_of_rows); 162 + } 163 + 138 164 static void ske_keypad_read_data(struct ske_keypad *keypad) 139 165 { 140 - struct input_dev *input = keypad->input; 141 - u16 status; 142 - int col = 0, row = 0, code; 143 - int ske_asr, ske_ris, key_pressed, i; 166 + u8 status; 167 + int col = 0; 168 + int ske_asr, i; 144 169 145 170 /* 146 171 * Read the auto scan registers ··· 179 154 if (!ske_asr) 180 155 continue; 181 156 182 - /* now that ASRx is zero, find out the column x and row y*/ 183 - if (ske_asr & 0xff) { 157 + /* now that ASRx is zero, find out the coloumn x and row y */ 158 + status = ske_asr & 0xff; 159 + if (status) { 184 160 col = i * 2; 185 - status = ske_asr & 0xff; 186 - } else { 187 - col = (i * 2) + 1; 188 - status = (ske_asr & 0xff00) >> 8; 161 + ske_keypad_report(keypad, status, col); 189 162 } 190 - 191 - /* find out the row */ 192 - row = __ffs(status); 193 - 194 - code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT); 195 - ske_ris = readl(keypad->reg_base + SKE_RIS); 196 - key_pressed = ske_ris & SKE_KPRISA; 197 - 198 - input_event(input, EV_MSC, MSC_SCAN, code); 199 - input_report_key(input, keypad->keymap[code], key_pressed); 200 - input_sync(input); 163 + status = (ske_asr & 0xff00) >> 8; 164 + if (status) { 165 + col = (i * 2) + 1; 166 + ske_keypad_report(keypad, status, col); 167 + } 201 168 } 202 169 } 203 170 ··· 203 186 ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA); 204 187 205 188 while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries) 206 - msleep(5); 189 + cpu_relax(); 207 190 208 - if (retries) { 209 - /* SKEx registers are stable and can be read */ 210 - ske_keypad_read_data(keypad); 211 - } 191 + /* SKEx registers are stable and can be read */ 192 + ske_keypad_read_data(keypad); 212 193 213 194 /* enable auto scan interrupts */ 214 195 ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);