aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/tegra-kbc.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-05-24 03:06:26 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-05-24 03:06:26 -0400
commitb73077eb03f510a84b102fb97640e595a958403c (patch)
tree8b639000418e2756bf6baece4e00e07d2534bccc /drivers/input/keyboard/tegra-kbc.c
parent28350e330cfab46b60a1dbf763b678d859f9f3d9 (diff)
parent9d2e173644bb5c42ff1b280fbdda3f195a7cf1f7 (diff)
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/input/keyboard/tegra-kbc.c')
-rw-r--r--drivers/input/keyboard/tegra-kbc.c60
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
403static void tegra_kbc_config_pins(struct tegra_kbc *kbc) 426static 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);