diff options
Diffstat (limited to 'drivers/input/keyboard/tegra-kbc.c')
-rw-r--r-- | drivers/input/keyboard/tegra-kbc.c | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 99ce9032d08c..2b3b73ec6689 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -66,12 +66,11 @@ struct tegra_kbc { | |||
66 | void __iomem *mmio; | 66 | void __iomem *mmio; |
67 | struct input_dev *idev; | 67 | struct input_dev *idev; |
68 | unsigned int irq; | 68 | unsigned int irq; |
69 | unsigned int wake_enable_rows; | ||
70 | unsigned int wake_enable_cols; | ||
71 | spinlock_t lock; | 69 | spinlock_t lock; |
72 | unsigned int repoll_dly; | 70 | unsigned int repoll_dly; |
73 | unsigned long cp_dly_jiffies; | 71 | unsigned long cp_dly_jiffies; |
74 | bool use_fn_map; | 72 | bool use_fn_map; |
73 | bool use_ghost_filter; | ||
75 | const struct tegra_kbc_platform_data *pdata; | 74 | const struct tegra_kbc_platform_data *pdata; |
76 | unsigned short keycode[KBC_MAX_KEY * 2]; | 75 | unsigned short keycode[KBC_MAX_KEY * 2]; |
77 | unsigned short current_keys[KBC_MAX_KPENT]; | 76 | unsigned short current_keys[KBC_MAX_KPENT]; |
@@ -260,6 +259,8 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) | |||
260 | unsigned int num_down = 0; | 259 | unsigned int num_down = 0; |
261 | unsigned long flags; | 260 | unsigned long flags; |
262 | bool fn_keypress = false; | 261 | bool fn_keypress = false; |
262 | bool key_in_same_row = false; | ||
263 | bool key_in_same_col = false; | ||
263 | 264 | ||
264 | spin_lock_irqsave(&kbc->lock, flags); | 265 | spin_lock_irqsave(&kbc->lock, flags); |
265 | for (i = 0; i < KBC_MAX_KPENT; i++) { | 266 | for (i = 0; i < KBC_MAX_KPENT; i++) { |
@@ -285,6 +286,34 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) | |||
285 | } | 286 | } |
286 | 287 | ||
287 | /* | 288 | /* |
289 | * Matrix keyboard designs are prone to keyboard ghosting. | ||
290 | * Ghosting occurs if there are 3 keys such that - | ||
291 | * any 2 of the 3 keys share a row, and any 2 of them share a column. | ||
292 | * If so ignore the key presses for this iteration. | ||
293 | */ | ||
294 | if ((kbc->use_ghost_filter) && (num_down >= 3)) { | ||
295 | for (i = 0; i < num_down; i++) { | ||
296 | unsigned int j; | ||
297 | u8 curr_col = scancodes[i] & 0x07; | ||
298 | u8 curr_row = scancodes[i] >> KBC_ROW_SHIFT; | ||
299 | |||
300 | /* | ||
301 | * Find 2 keys such that one key is in the same row | ||
302 | * and the other is in the same column as the i-th key. | ||
303 | */ | ||
304 | for (j = i + 1; j < num_down; j++) { | ||
305 | u8 col = scancodes[j] & 0x07; | ||
306 | u8 row = scancodes[j] >> KBC_ROW_SHIFT; | ||
307 | |||
308 | if (col == curr_col) | ||
309 | key_in_same_col = true; | ||
310 | if (row == curr_row) | ||
311 | key_in_same_row = true; | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* | ||
288 | * If the platform uses Fn keymaps, translate keys on a Fn keypress. | 317 | * If the platform uses Fn keymaps, translate keys on a Fn keypress. |
289 | * Function keycodes are KBC_MAX_KEY apart from the plain keycodes. | 318 | * Function keycodes are KBC_MAX_KEY apart from the plain keycodes. |
290 | */ | 319 | */ |
@@ -297,6 +326,10 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) | |||
297 | 326 | ||
298 | spin_unlock_irqrestore(&kbc->lock, flags); | 327 | spin_unlock_irqrestore(&kbc->lock, flags); |
299 | 328 | ||
329 | /* Ignore the key presses for this iteration? */ | ||
330 | if (key_in_same_col && key_in_same_row) | ||
331 | return; | ||
332 | |||
300 | tegra_kbc_report_released_keys(kbc->idev, | 333 | tegra_kbc_report_released_keys(kbc->idev, |
301 | kbc->current_keys, kbc->num_pressed_keys, | 334 | kbc->current_keys, kbc->num_pressed_keys, |
302 | keycodes, num_down); | 335 | keycodes, num_down); |
@@ -383,21 +416,11 @@ static void tegra_kbc_setup_wakekeys(struct tegra_kbc *kbc, bool filter) | |||
383 | int i; | 416 | int i; |
384 | unsigned int rst_val; | 417 | unsigned int rst_val; |
385 | 418 | ||
386 | BUG_ON(pdata->wake_cnt > KBC_MAX_KEY); | 419 | /* Either mask all keys or none. */ |
387 | rst_val = (filter && pdata->wake_cnt) ? ~0 : 0; | 420 | rst_val = (filter && !pdata->wakeup) ? ~0 : 0; |
388 | 421 | ||
389 | for (i = 0; i < KBC_MAX_ROW; i++) | 422 | for (i = 0; i < KBC_MAX_ROW; i++) |
390 | writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); | 423 | writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); |
391 | |||
392 | if (filter) { | ||
393 | for (i = 0; i < pdata->wake_cnt; i++) { | ||
394 | u32 val, addr; | ||
395 | addr = pdata->wake_cfg[i].row * 4 + KBC_ROW0_MASK_0; | ||
396 | val = readl(kbc->mmio + addr); | ||
397 | val &= ~(1 << pdata->wake_cfg[i].col); | ||
398 | writel(val, kbc->mmio + addr); | ||
399 | } | ||
400 | } | ||
401 | } | 424 | } |
402 | 425 | ||
403 | static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | 426 | static void tegra_kbc_config_pins(struct tegra_kbc *kbc) |
@@ -559,7 +582,6 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) | |||
559 | struct resource *res; | 582 | struct resource *res; |
560 | int irq; | 583 | int irq; |
561 | int err; | 584 | int err; |
562 | int i; | ||
563 | int num_rows = 0; | 585 | int num_rows = 0; |
564 | unsigned int debounce_cnt; | 586 | unsigned int debounce_cnt; |
565 | unsigned int scan_time_rows; | 587 | unsigned int scan_time_rows; |
@@ -616,13 +638,6 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) | |||
616 | goto err_iounmap; | 638 | goto err_iounmap; |
617 | } | 639 | } |
618 | 640 | ||
619 | kbc->wake_enable_rows = 0; | ||
620 | kbc->wake_enable_cols = 0; | ||
621 | for (i = 0; i < pdata->wake_cnt; i++) { | ||
622 | kbc->wake_enable_rows |= (1 << pdata->wake_cfg[i].row); | ||
623 | kbc->wake_enable_cols |= (1 << pdata->wake_cfg[i].col); | ||
624 | } | ||
625 | |||
626 | /* | 641 | /* |
627 | * The time delay between two consecutive reads of the FIFO is | 642 | * The time delay between two consecutive reads of the FIFO is |
628 | * the sum of the repeat time and the time taken for scanning | 643 | * the sum of the repeat time and the time taken for scanning |
@@ -652,6 +667,7 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) | |||
652 | input_dev->keycodemax *= 2; | 667 | input_dev->keycodemax *= 2; |
653 | 668 | ||
654 | kbc->use_fn_map = pdata->use_fn_map; | 669 | kbc->use_fn_map = pdata->use_fn_map; |
670 | kbc->use_ghost_filter = pdata->use_ghost_filter; | ||
655 | keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data; | 671 | keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data; |
656 | matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT, | 672 | matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT, |
657 | input_dev->keycode, input_dev->keybit); | 673 | input_dev->keycode, input_dev->keybit); |