aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/misc/twl6030-pwrbutton.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/input/misc/twl6030-pwrbutton.c b/drivers/input/misc/twl6030-pwrbutton.c
index d653eae..ad9cd97 100644
--- a/drivers/input/misc/twl6030-pwrbutton.c
+++ b/drivers/input/misc/twl6030-pwrbutton.c
@@ -33,6 +33,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/i2c/twl.h>
+#include <linux/delay.h>
#define PWR_PWRON_IRQ (1 << 0)
#define STS_HW_CONDITIONS 0x21
@@ -76,12 +77,28 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr)
{
struct twl6030_pwr_button *pwr = _pwr;
int hw_state;
+ int pwr_val;
+ static int prev_hw_state = 0xFFFF;
hw_state = twl6030_readb(pwr, TWL6030_MODULE_ID0, STS_HW_CONDITIONS);
+ pwr_val = !(hw_state & PWR_PWRON_IRQ);
+ if (prev_hw_state != pwr_val) {
+ input_report_key(pwr->input_dev, pwr->report_key,
+ pwr_val);
+ input_sync(pwr->input_dev);
+ } else {
+ input_report_key(pwr->input_dev, pwr->report_key,
+ !pwr_val);
+ input_sync(pwr->input_dev);
+
+ msleep(20);
+
+ input_report_key(pwr->input_dev, pwr->report_key,
+ pwr_val);
+ input_sync(pwr->input_dev);
+ }
- input_report_key(pwr->input_dev, pwr->report_key,
- !(hw_state & PWR_PWRON_IRQ));
- input_sync(pwr->input_dev);
+ prev_hw_state = pwr_val;
return IRQ_HANDLED;
}