Commit f7269a82 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge branch 'keyboard' of git://github.com/hzhuang1/linux into next/drivers

From Haojian Zhuang <haojian.zhuang@gmail.com>

* 'keyboard' of git://github.com/hzhuang1/linux:
  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
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 66f75a5d fb054bf2
...@@ -44,6 +44,10 @@ struct pxa27x_keypad_platform_data { ...@@ -44,6 +44,10 @@ struct pxa27x_keypad_platform_data {
/* direct keys */ /* direct keys */
int direct_key_num; int direct_key_num;
unsigned int direct_key_map[MAX_DIRECT_KEY_NUM]; unsigned int direct_key_map[MAX_DIRECT_KEY_NUM];
/* the key output may be low active */
int direct_key_low_active;
/* give board a chance to choose the start direct key */
unsigned int direct_key_mask;
/* rotary encoders 0 */ /* rotary encoders 0 */
int enable_rotary0; int enable_rotary0;
......
...@@ -311,7 +311,15 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) ...@@ -311,7 +311,15 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
if (pdata->enable_rotary0 || pdata->enable_rotary1) if (pdata->enable_rotary0 || pdata->enable_rotary1)
pxa27x_keypad_scan_rotary(keypad); pxa27x_keypad_scan_rotary(keypad);
/*
* 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; new_state = KPDK_DK(kpdk) & keypad->direct_key_mask;
bits_changed = keypad->direct_key_state ^ new_state; bits_changed = keypad->direct_key_state ^ new_state;
if (bits_changed == 0) if (bits_changed == 0)
...@@ -383,7 +391,14 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) ...@@ -383,7 +391,14 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
if (pdata->direct_key_num > direct_key_num) if (pdata->direct_key_num > direct_key_num)
direct_key_num = pdata->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 */ /* enable direct key */
if (direct_key_num) if (direct_key_num)
...@@ -399,7 +414,7 @@ static int pxa27x_keypad_open(struct input_dev *dev) ...@@ -399,7 +414,7 @@ static int pxa27x_keypad_open(struct input_dev *dev)
struct pxa27x_keypad *keypad = input_get_drvdata(dev); struct pxa27x_keypad *keypad = input_get_drvdata(dev);
/* Enable unit clock */ /* Enable unit clock */
clk_enable(keypad->clk); clk_prepare_enable(keypad->clk);
pxa27x_keypad_config(keypad); pxa27x_keypad_config(keypad);
return 0; return 0;
...@@ -410,7 +425,7 @@ static void pxa27x_keypad_close(struct input_dev *dev) ...@@ -410,7 +425,7 @@ static void pxa27x_keypad_close(struct input_dev *dev)
struct pxa27x_keypad *keypad = input_get_drvdata(dev); struct pxa27x_keypad *keypad = input_get_drvdata(dev);
/* Disable clock unit */ /* Disable clock unit */
clk_disable(keypad->clk); clk_disable_unprepare(keypad->clk);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -419,10 +434,14 @@ static int pxa27x_keypad_suspend(struct device *dev) ...@@ -419,10 +434,14 @@ static int pxa27x_keypad_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); 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)) if (device_may_wakeup(&pdev->dev))
enable_irq_wake(keypad->irq); enable_irq_wake(keypad->irq);
else
clk_disable_unprepare(keypad->clk);
return 0; return 0;
} }
...@@ -433,18 +452,23 @@ static int pxa27x_keypad_resume(struct device *dev) ...@@ -433,18 +452,23 @@ static int pxa27x_keypad_resume(struct device *dev)
struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
struct input_dev *input_dev = keypad->input_dev; 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); disable_irq_wake(keypad->irq);
} else {
mutex_lock(&input_dev->mutex); mutex_lock(&input_dev->mutex);
if (input_dev->users) { if (input_dev->users) {
/* Enable unit clock */ /* Enable unit clock */
clk_enable(keypad->clk); clk_prepare_enable(keypad->clk);
pxa27x_keypad_config(keypad); pxa27x_keypad_config(keypad);
} }
mutex_unlock(&input_dev->mutex); mutex_unlock(&input_dev->mutex);
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment