[vdr] Key-repeat or release magic in RCU drivers

Marko Mäkelä marko.makela at hut.fi
Mon Feb 6 23:16:52 CET 2006


On Wed, Feb 01, 2006 at 09:56:40PM +0000, Darren Salt wrote:
> I demand that Marko Mäkelä may or may not have written...
> 
> > On Wed, Feb 01, 2006 at 07:51:04PM +0100, Oliver Endriss wrote:
> [snip]
> >> (1) The repeat timer of the input layer must be turned off, and the
> >>     natural repeat rate of the RC5 frames should be used. Anything else
> >>     will result in inaccurate operation.
> 
> >> (2) The key-up timeout should be set to 280ms or higher (>= 2x repeat
> >>     rate). This will allow for one missing RC5 frame which may happen due
> >>     to transmission errors.
> 
> > Thanks, this sounds exactly what I'm looking for!
> 
> > The 280 ms you mention matches the #define UP_TIMEOUT (HZ*7/25) in
> > /usr/src/linux-2.6.14.3/drivers/media/dvb/ttpci/av7110_ir.c on my vdr box.
> > I'll see if I'm smart enough to port the code to the cx88 driver.
> 
> linux/drivers/media/common/ir-functions.c would seem to be the right place
> for that code...

I guess you meant ir-common.c, after all.

I made a quick&dirty patch to ir-common.c and cx88-input.c that maps each
incoming RC5 frame to a key-press or a key-repeat event.  The key-release
timeout is set to 280 ms.  I tried blocking the IR beam for a couple of
seconds while holding the Volume+ button down.  After I unblocked the beam,
the repeat events would continue.

Thanks to the patch, it is now possible to reach any line on long listings
such as the EPG menu, by holding the Down button and releasing it when the
selection mark reaches the line.

The only drawback in my patch is that it is sometimes hard to press a
repeating key (e.g., Channel+) quickly enough to only generate a key-press
event without any key-repeat.  After all, it might be good to discard the
first key-repeat event.  Do av7110 users have this problem?

It'd be nice if this patch could be polished and submitted to the kernel.
Are there any v4l-dvb developers on this list?

	Marko
-------------- next part --------------
diff -rup linux-2.6.15.2/drivers/media/common/ir-common.c linux-2.6.15.2-cx88_input/drivers/media/common/ir-common.c
--- linux-2.6.15.2/drivers/media/common/ir-common.c	2006-01-31 08:25:07.000000000 +0200
+++ linux-2.6.15.2-cx88_input/drivers/media/common/ir-common.c	2006-02-06 23:46:12.000000000 +0200
@@ -298,7 +298,7 @@ static void ir_input_key_event(struct in
 	}
 	dprintk(1,"%s: key event code=%d down=%d\n",
 		dev->name,ir->keycode,ir->keypressed);
-	input_report_key(dev,ir->keycode,ir->keypressed);
+	input_event(dev, EV_KEY, ir->keycode, ir->keypressed);
 	input_sync(dev);
 }
 
@@ -343,13 +343,12 @@ void ir_input_keydown(struct input_dev *
 		ir->keypressed = 0;
 		ir_input_key_event(dev,ir);
 	}
-	if (!ir->keypressed) {
-		ir->ir_key  = ir_key;
-		ir->ir_raw  = ir_raw;
-		ir->keycode = keycode;
-		ir->keypressed = 1;
-		ir_input_key_event(dev,ir);
-	}
+	/* same RC5 code -> it is a repeated key */
+	ir->keypressed = ir->ir_raw == ir_raw ? 2 : 1;
+	ir->ir_key  = ir_key;
+	ir->ir_raw  = ir_raw;
+	ir->keycode = keycode;
+	ir_input_key_event(dev,ir);
 }
 
 /* -------------------------------------------------------------------------- */
diff -rup linux-2.6.15.2/drivers/media/video/cx88/cx88-input.c linux-2.6.15.2-cx88_input/drivers/media/video/cx88/cx88-input.c
--- linux-2.6.15.2/drivers/media/video/cx88/cx88-input.c	2006-01-31 08:25:07.000000000 +0200
+++ linux-2.6.15.2-cx88_input/drivers/media/video/cx88/cx88-input.c	2006-02-06 23:04:39.000000000 +0200
@@ -289,6 +289,11 @@ MODULE_PARM_DESC(ir_debug, "enable debug
 #define ir_dprintk(fmt, arg...)	if (ir_debug) \
 	printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg)
 
+static void input_repeat_key(unsigned long data)
+{
+       /* dummy routine to disable autorepeat in the input driver */
+}
+
 /* ---------------------------------------------------------------------- */
 
 static void cx88_ir_handle_key(struct cx88_IR *ir)
@@ -472,6 +477,7 @@ int cx88_ir_init(struct cx88_core *core,
 
 	/* all done */
 	input_register_device(ir->input);
+	ir->input->timer.function = input_repeat_key;
 
 	return 0;
 }
@@ -572,7 +578,7 @@ void cx88_ir_irq(struct cx88_core *core)
 		if ((ircode & 0xfffff000) != 0x3000)
 			break;
 		ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode);
-		ir->release = jiffies + msecs_to_jiffies(120);
+		ir->release = jiffies + msecs_to_jiffies(280);
 		break;
 	}
 


More information about the vdr mailing list