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:
parent
20f2e1aa77
commit
8d7a77ce56
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue