diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-26 23:22:27 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-26 23:22:27 +0400 |
commit | ce53044c68cf4fb6c50a2a0d88786be65fae7235 (patch) | |
tree | 19c21da7d261412192e189ef3fd1a9ff4e7ba5c2 /drivers/input/keyboard/pxa27x_keypad.c | |
parent | 0877aa3908aaeeae8fc2850691668c4315d3db56 (diff) | |
parent | 046fae440d32cc6dec8148c7e06a8b4b987f8a2f (diff) | |
download | linux-ce53044c68cf4fb6c50a2a0d88786be65fae7235.tar.xz |
Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull arm-soc driver specific updates from Olof Johansson:
"These changes are specific to some driver that may be used by multiple
boards or socs. The most significant change in here is the move of
the samsung iommu code from a platform specific in-kernel interface to
the generic iommu subsystem."
Fix up trivial conflicts in arch/arm/mach-exynos/Kconfig
* tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (28 commits)
mmc: dt: Consolidate DT bindings
iommu/exynos: Add iommu driver for EXYNOS Platforms
ARM: davinci: optimize the DMA ISR
ARM: davinci: implement DEBUG_LL port choice
ARM: tegra: Add SMMU enabler in AHB
ARM: tegra: Add Tegra AHB driver
Input: pxa27x_keypad add choice to set direct_key_mask
Input: pxa27x_keypad direct key may be low active
Input: pxa27x_keypad bug fix for direct_key_mask
Input: pxa27x_keypad keep clock on as wakeup source
ARM: dt: tegra: pinmux changes for USB ULPI
ARM: tegra: add USB ULPI PHY reset GPIO to device tree
ARM: tegra: don't hard-code USB ULPI PHY reset_gpio
ARM: tegra: change pll_p_out4's rate to 24MHz
ARM: tegra: fix pclk rate
ARM: tegra: reparent sclk to pll_c_out1
ARM: tegra: Add pllc clock init table
ARM: dt: tegra cardhu: basic audio support
ARM: dt: tegra30.dtsi: Add audio-related nodes
ARM: tegra: add AUXDATA required for audio
...
Diffstat (limited to 'drivers/input/keyboard/pxa27x_keypad.c')
-rw-r--r-- | drivers/input/keyboard/pxa27x_keypad.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 29fe1b2be1c1..7f7b72464a37 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -311,7 +311,15 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) if (pdata->enable_rotary0 || pdata->enable_rotary1) pxa27x_keypad_scan_rotary(keypad); - new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; + /* + * The KPDR_DK only output the key pin level, so it relates to board, + * and low level may be active. + */ + if (pdata->direct_key_low_active) + new_state = ~KPDK_DK(kpdk) & keypad->direct_key_mask; + else + new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; + bits_changed = keypad->direct_key_state ^ new_state; if (bits_changed == 0) @@ -383,7 +391,14 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) if (pdata->direct_key_num > direct_key_num) direct_key_num = pdata->direct_key_num; - keypad->direct_key_mask = ((2 << direct_key_num) - 1) & ~mask; + /* + * Direct keys usage may not start from KP_DKIN0, check the platfrom + * mask data to config the specific. + */ + if (pdata->direct_key_mask) + keypad->direct_key_mask = pdata->direct_key_mask; + else + keypad->direct_key_mask = ((1 << direct_key_num) - 1) & ~mask; /* enable direct key */ if (direct_key_num) @@ -399,7 +414,7 @@ static int pxa27x_keypad_open(struct input_dev *dev) struct pxa27x_keypad *keypad = input_get_drvdata(dev); /* Enable unit clock */ - clk_enable(keypad->clk); + clk_prepare_enable(keypad->clk); pxa27x_keypad_config(keypad); return 0; @@ -410,7 +425,7 @@ static void pxa27x_keypad_close(struct input_dev *dev) struct pxa27x_keypad *keypad = input_get_drvdata(dev); /* Disable clock unit */ - clk_disable(keypad->clk); + clk_disable_unprepare(keypad->clk); } #ifdef CONFIG_PM @@ -419,10 +434,14 @@ static int pxa27x_keypad_suspend(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); - clk_disable(keypad->clk); - + /* + * If the keypad is used a wake up source, clock can not be disabled. + * Or it can not detect the key pressing. + */ if (device_may_wakeup(&pdev->dev)) enable_irq_wake(keypad->irq); + else + clk_disable_unprepare(keypad->clk); return 0; } @@ -433,19 +452,24 @@ static int pxa27x_keypad_resume(struct device *dev) struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); struct input_dev *input_dev = keypad->input_dev; - if (device_may_wakeup(&pdev->dev)) + /* + * If the keypad is used as wake up source, the clock is not turned + * off. So do not need configure it again. + */ + if (device_may_wakeup(&pdev->dev)) { disable_irq_wake(keypad->irq); + } else { + mutex_lock(&input_dev->mutex); - mutex_lock(&input_dev->mutex); + if (input_dev->users) { + /* Enable unit clock */ + clk_prepare_enable(keypad->clk); + pxa27x_keypad_config(keypad); + } - if (input_dev->users) { - /* Enable unit clock */ - clk_enable(keypad->clk); - pxa27x_keypad_config(keypad); + mutex_unlock(&input_dev->mutex); } - mutex_unlock(&input_dev->mutex); - return 0; } |