Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d7a77ce authored by Sean Young's avatar Sean Young Committed by Mauro Carvalho Chehab
Browse files

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: default avatarMatthias Reichl <hias@horus.com>
Tested-by: default avatarMatthias Reichl <hias@horus.com>
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 20f2e1aa
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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);

+27 −3
Original line number Diff line number Diff line
@@ -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
+3 −1
Original line number Diff line number Diff line
@@ -335,6 +335,8 @@ 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);
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);