media: rc: meson-ir: add timeout on idle

Meson doesn't seem to be able to generate timeout events in hardware. So
install a software timer to generate the timeout events required by the
decoders to prevent "ghost keypresses".

Reported-by: Matthias Reichl <hias@horus.com>
Tested-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Sean Young 2018-03-08 09:42:44 -05:00 committed by Mauro Carvalho Chehab
parent 20f2e1aa77
commit 8d7a77ce56
3 changed files with 31 additions and 6 deletions

View File

@ -97,8 +97,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id)
status = readl_relaxed(ir->reg + IR_DEC_STATUS);
rawir.pulse = !!(status & STATUS_IR_DEC_IN);
ir_raw_event_store(ir->rc, &rawir);
ir_raw_event_handle(ir->rc);
ir_raw_event_store_with_timeout(ir->rc, &rawir);
spin_unlock(&ir->lock);

View File

@ -92,7 +92,6 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse)
{
ktime_t now;
DEFINE_IR_RAW_EVENT(ev);
int rc = 0;
if (!dev->raw)
return -EINVAL;
@ -101,8 +100,33 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse)
ev.duration = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
ev.pulse = !pulse;
return ir_raw_event_store_with_timeout(dev, &ev);
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
/*
* ir_raw_event_store_with_timeout() - pass a pulse/space duration to the raw
* ir decoders, schedule decoding and
* timeout
* @dev: the struct rc_dev device descriptor
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This routine (which may be called from an interrupt context) stores a
* pulse/space duration for the raw ir decoding state machines, schedules
* decoding and generates a timeout.
*/
int ir_raw_event_store_with_timeout(struct rc_dev *dev, struct ir_raw_event *ev)
{
ktime_t now;
int rc = 0;
if (!dev->raw)
return -EINVAL;
now = ktime_get();
spin_lock(&dev->raw->edge_spinlock);
rc = ir_raw_event_store(dev, &ev);
rc = ir_raw_event_store(dev, ev);
dev->raw->last_event = now;
@ -117,7 +141,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse)
return rc;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_timeout);
/**
* ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing

View File

@ -334,7 +334,9 @@ void ir_raw_event_handle(struct rc_dev *dev);
int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev);
int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse);
int ir_raw_event_store_with_filter(struct rc_dev *dev,
struct ir_raw_event *ev);
struct ir_raw_event *ev);
int ir_raw_event_store_with_timeout(struct rc_dev *dev,
struct ir_raw_event *ev);
void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode,
struct ir_raw_event *events, unsigned int max);