|
@@ -135,12 +135,37 @@ static int __init ske_keypad_chip_init(struct ske_keypad *keypad)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void ske_keypad_read_data(struct ske_keypad *keypad)
|
|
|
+static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col)
|
|
|
{
|
|
|
+ int row = 0, code, pos;
|
|
|
struct input_dev *input = keypad->input;
|
|
|
- u16 status;
|
|
|
- int col = 0, row = 0, code;
|
|
|
- int ske_asr, ske_ris, key_pressed, i;
|
|
|
+ u32 ske_ris;
|
|
|
+ int key_pressed;
|
|
|
+ int num_of_rows;
|
|
|
+
|
|
|
+ /* find out the row */
|
|
|
+ num_of_rows = hweight8(status);
|
|
|
+ do {
|
|
|
+ pos = __ffs(status);
|
|
|
+ row = pos;
|
|
|
+ status &= ~(1 << pos);
|
|
|
+
|
|
|
+ code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT);
|
|
|
+ ske_ris = readl(keypad->reg_base + SKE_RIS);
|
|
|
+ key_pressed = ske_ris & SKE_KPRISA;
|
|
|
+
|
|
|
+ input_event(input, EV_MSC, MSC_SCAN, code);
|
|
|
+ input_report_key(input, keypad->keymap[code], key_pressed);
|
|
|
+ input_sync(input);
|
|
|
+ num_of_rows--;
|
|
|
+ } while (num_of_rows);
|
|
|
+}
|
|
|
+
|
|
|
+static void ske_keypad_read_data(struct ske_keypad *keypad)
|
|
|
+{
|
|
|
+ u8 status;
|
|
|
+ int col = 0;
|
|
|
+ int ske_asr, i;
|
|
|
|
|
|
/*
|
|
|
* Read the auto scan registers
|
|
@@ -154,25 +179,17 @@ static void ske_keypad_read_data(struct ske_keypad *keypad)
|
|
|
if (!ske_asr)
|
|
|
continue;
|
|
|
|
|
|
- /* now that ASRx is zero, find out the column x and row y*/
|
|
|
- if (ske_asr & 0xff) {
|
|
|
+ /* now that ASRx is zero, find out the coloumn x and row y */
|
|
|
+ status = ske_asr & 0xff;
|
|
|
+ if (status) {
|
|
|
col = i * 2;
|
|
|
- status = ske_asr & 0xff;
|
|
|
- } else {
|
|
|
+ ske_keypad_report(keypad, status, col);
|
|
|
+ }
|
|
|
+ status = (ske_asr & 0xff00) >> 8;
|
|
|
+ if (status) {
|
|
|
col = (i * 2) + 1;
|
|
|
- status = (ske_asr & 0xff00) >> 8;
|
|
|
+ ske_keypad_report(keypad, status, col);
|
|
|
}
|
|
|
-
|
|
|
- /* find out the row */
|
|
|
- row = __ffs(status);
|
|
|
-
|
|
|
- code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT);
|
|
|
- ske_ris = readl(keypad->reg_base + SKE_RIS);
|
|
|
- key_pressed = ske_ris & SKE_KPRISA;
|
|
|
-
|
|
|
- input_event(input, EV_MSC, MSC_SCAN, code);
|
|
|
- input_report_key(input, keypad->keymap[code], key_pressed);
|
|
|
- input_sync(input);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -186,12 +203,10 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id)
|
|
|
ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA);
|
|
|
|
|
|
while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries)
|
|
|
- msleep(5);
|
|
|
+ cpu_relax();
|
|
|
|
|
|
- if (retries) {
|
|
|
- /* SKEx registers are stable and can be read */
|
|
|
- ske_keypad_read_data(keypad);
|
|
|
- }
|
|
|
+ /* SKEx registers are stable and can be read */
|
|
|
+ ske_keypad_read_data(keypad);
|
|
|
|
|
|
/* enable auto scan interrupts */
|
|
|
ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);
|