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

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

media: rc-core: improve ir_raw_store_edge() handling



The gpio-ir-recv driver does many wakeups (once per edge); the saa7134
driver has special handling to only wakeup 15ms after the first edge.
Make this part of rc-core so gpio-ir-recv also benefits from
this (so a rc-5 keypress now causes 3 wakeups rather than 24).

Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 4fe055ec
Loading
Loading
Loading
Loading
+1 −25
Original line number Diff line number Diff line
@@ -452,13 +452,6 @@ static void saa7134_input_timer(unsigned long data)
	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
}

static void ir_raw_decode_timer_end(unsigned long data)
{
	struct saa7134_dev *dev = (struct saa7134_dev *)data;

	ir_raw_event_handle(dev->remote->dev);
}

static int __saa7134_ir_start(void *priv)
{
	struct saa7134_dev *dev = priv;
@@ -514,10 +507,6 @@ static int __saa7134_ir_start(void *priv)
			    (unsigned long)dev);
		ir->timer.expires = jiffies + HZ;
		add_timer(&ir->timer);
	} else if (ir->raw_decode) {
		/* set timer_end for code completion */
		setup_timer(&ir->timer, ir_raw_decode_timer_end,
			    (unsigned long)dev);
	}

	return 0;
@@ -535,7 +524,7 @@ static void __saa7134_ir_stop(void *priv)
	if (!ir->running)
		return;

	if (ir->polling || ir->raw_decode)
	if (ir->polling)
		del_timer_sync(&ir->timer);

	ir->running = false;
@@ -1057,7 +1046,6 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
{
	struct saa7134_card_ir *ir = dev->remote;
	unsigned long timeout;
	int space;

	/* Generate initial event */
@@ -1066,17 +1054,5 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
	space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
	ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE);

	/*
	 * Wait 15 ms from the start of the first IR event before processing
	 * the event. This time is enough for NEC protocol. May need adjustments
	 * to work with other protocols.
	 */
	smp_mb();

	if (!timer_pending(&ir->timer)) {
		timeout = jiffies + msecs_to_jiffies(15);
		mod_timer(&ir->timer, timeout);
	}

	return 1;
}
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ struct ir_raw_event_ctrl {
	ktime_t				last_event;	/* when last event occurred */
	enum raw_event_type		last_type;	/* last event type */
	struct rc_dev			*dev;		/* pointer to the parent rc_dev */
	/* edge driver */
	struct timer_list edge_handle;

	/* raw decoder state follows */
	struct ir_raw_event prev_ev;
+15 −0
Original line number Diff line number Diff line
@@ -133,6 +133,11 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type)

	dev->raw->last_event = now;
	dev->raw->last_type = type;

	if (!timer_pending(&dev->raw->edge_handle))
		mod_timer(&dev->raw->edge_handle,
			  jiffies + msecs_to_jiffies(15));

	return rc;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
@@ -483,6 +488,13 @@ int ir_raw_encode_scancode(enum rc_type protocol, u32 scancode,
}
EXPORT_SYMBOL(ir_raw_encode_scancode);

static void edge_handle(unsigned long arg)
{
	struct rc_dev *dev = (struct rc_dev *)arg;

	ir_raw_event_handle(dev);
}

/*
 * Used to (un)register raw event clients
 */
@@ -504,6 +516,8 @@ int ir_raw_event_prepare(struct rc_dev *dev)

	dev->raw->dev = dev;
	dev->change_protocol = change_protocol;
	setup_timer(&dev->raw->edge_handle, edge_handle,
		    (unsigned long)dev);
	INIT_KFIFO(dev->raw->kfifo);

	return 0;
@@ -555,6 +569,7 @@ void ir_raw_event_unregister(struct rc_dev *dev)
		return;

	kthread_stop(dev->raw->thread);
	del_timer_sync(&dev->raw->edge_handle);

	mutex_lock(&ir_raw_handler_lock);
	list_del(&dev->raw->list);