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 {
/* direct keys */
int 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 */
int enable_rotary0;
......
......@@ -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;
}
......
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