mirror of
https://github.com/armbian/build.git
synced 2025-08-13 22:56:57 +02:00
84 lines
2.6 KiB
Diff
84 lines
2.6 KiB
Diff
From 3f1ad6a105b445354dcb919b7c153f9d8022f7de Mon Sep 17 00:00:00 2001
|
|
From: Matthias Reichl <hias@horus.com>
|
|
Date: Tue, 23 Jan 2018 09:40:02 +0100
|
|
Subject: [PATCH] media: rc: meson-ir: add timeout on idle
|
|
|
|
Meson hardware doesn't generate timeout events, so install a
|
|
software timer to prevent "ghost keypresses".
|
|
|
|
Signed-off-by: Matthias Reichl <hias@horus.com>
|
|
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
|
---
|
|
drivers/media/rc/meson-ir.c | 22 ++++++++++++++++++++++
|
|
1 file changed, 22 insertions(+)
|
|
|
|
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
|
|
index f2204eb..f34c583 100644
|
|
--- a/drivers/media/rc/meson-ir.c
|
|
+++ b/drivers/media/rc/meson-ir.c
|
|
@@ -69,6 +69,7 @@ struct meson_ir {
|
|
void __iomem *reg;
|
|
struct rc_dev *rc;
|
|
spinlock_t lock;
|
|
+ struct timer_list timeout_timer;
|
|
};
|
|
|
|
static void meson_ir_set_mask(struct meson_ir *ir, unsigned int reg,
|
|
@@ -98,6 +99,10 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id)
|
|
rawir.pulse = !!(status & STATUS_IR_DEC_IN);
|
|
|
|
ir_raw_event_store(ir->rc, &rawir);
|
|
+
|
|
+ mod_timer(&ir->timeout_timer,
|
|
+ jiffies + nsecs_to_jiffies(ir->rc->timeout));
|
|
+
|
|
ir_raw_event_handle(ir->rc);
|
|
|
|
spin_unlock(&ir->lock);
|
|
@@ -105,6 +110,17 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id)
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
+static void meson_ir_timeout_timer(struct timer_list *t)
|
|
+{
|
|
+ struct meson_ir *ir = from_timer(ir, t, timeout_timer);
|
|
+ DEFINE_IR_RAW_EVENT(rawir);
|
|
+
|
|
+ rawir.timeout = true;
|
|
+ rawir.duration = ir->rc->timeout;
|
|
+ ir_raw_event_store(ir->rc, &rawir);
|
|
+ ir_raw_event_handle(ir->rc);
|
|
+}
|
|
+
|
|
static int meson_ir_probe(struct platform_device *pdev)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
@@ -145,7 +161,9 @@ static int meson_ir_probe(struct platform_device *pdev)
|
|
ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
|
|
ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
|
|
ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
|
|
+ ir->rc->min_timeout = 1;
|
|
ir->rc->timeout = MS_TO_NS(200);
|
|
+ ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
|
|
ir->rc->driver_name = DRIVER_NAME;
|
|
|
|
spin_lock_init(&ir->lock);
|
|
@@ -157,6 +175,8 @@ static int meson_ir_probe(struct platform_device *pdev)
|
|
return ret;
|
|
}
|
|
|
|
+ timer_setup(&ir->timeout_timer, meson_ir_timeout_timer, 0);
|
|
+
|
|
ret = devm_request_irq(dev, irq, meson_ir_irq, 0, NULL, ir);
|
|
if (ret) {
|
|
dev_err(dev, "failed to request irq\n");
|
|
@@ -198,6 +218,8 @@ static int meson_ir_remove(struct platform_device *pdev)
|
|
meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, 0);
|
|
spin_unlock_irqrestore(&ir->lock, flags);
|
|
|
|
+ del_timer_sync(&ir->timeout_timer);
|
|
+
|
|
return 0;
|
|
}
|
|
|