diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/keyboard/tegra-kbc.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 1a91314319bd..b43f1cdda1d6 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -32,6 +32,8 @@ #include <linux/interrupt.h> #include <linux/clk.h> #include <mach/kbc.h> +#include <mach/pmc.h> +#include <mach/clk.h> #define KBC_CONTROL_0 0 #define KBC_INT_0 4 @@ -48,6 +50,8 @@ struct tegra_kbc { void __iomem *mmio; struct input_dev *idev; int irq; + unsigned int wake_enable_rows; + unsigned int wake_enable_cols; spinlock_t lock; unsigned int repoll_time; struct tegra_kbc_plat *pdata; @@ -77,6 +81,10 @@ static int tegra_kbc_suspend(struct platform_device *pdev, pm_message_t state) if (device_may_wakeup(&pdev->dev)) { tegra_kbc_setup_wakekeys(kbc, true); enable_irq_wake(kbc->irq); + tegra_configure_dpd_kbc(kbc->wake_enable_rows, kbc->wake_enable_cols); + /* Forcefully clear the interrupt status */ + writel(0x7, kbc->mmio + KBC_INT_0); + msleep(30); } else { tegra_kbc_close(kbc->idev); } @@ -91,6 +99,7 @@ static int tegra_kbc_resume(struct platform_device *pdev) if (device_may_wakeup(&pdev->dev)) { disable_irq_wake(kbc->irq); tegra_kbc_setup_wakekeys(kbc, false); + tegra_configure_dpd_kbc(0, 0); } else if (kbc->idev->users) return tegra_kbc_open(kbc->idev); @@ -258,6 +267,12 @@ static int tegra_kbc_open(struct input_dev *dev) clk_enable(kbc->clk); + /* Reset the KBC controller to clear all previous status.*/ + tegra_periph_reset_assert(kbc->clk); + udelay(100); + tegra_periph_reset_deassert(kbc->clk); + udelay(100); + tegra_kbc_config_pins(kbc); tegra_kbc_setup_wakekeys(kbc, false); @@ -430,6 +445,13 @@ static int __init tegra_kbc_probe(struct platform_device *pdev) cols[pdata->pin_cfg[i].num] = 1; } } + kbc->wake_enable_rows = 0; + kbc->wake_enable_cols = 0; + + for (i=0; i<pdata->wake_cnt; i++) { + kbc->wake_enable_rows |= (1 << kbc->pdata->wake_cfg[i].row); + kbc->wake_enable_cols |= (1 << kbc->pdata->wake_cfg[i].col); + } pdata->debounce_cnt = min_t(unsigned int, pdata->debounce_cnt, 0x3fful); kbc->repoll_time = 5 + (16+pdata->debounce_cnt)*nr + pdata->repeat_cnt; |