Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: another patch for remote control with rev 2.1



Ralph Metzler writes:
 > Matthias Hilbig writes:
 >  > Here is another patch for the remote control delivered with rev 2.1.
 >  > Because I think vdr should use ir in this case directly and not through
 >  > LIRC I added 6 ioctls to the dvb-driver and changed vdr to use these
 >  > calls.
 >  >
 >  > It should be possible to write a LIRC-Interface with these calls, too.
 >  > I don't know how the driver developers wanted the ir-interface if they
 >  > wanted one.
 > 
 > I already included the LIRC patch by Christoph Martin in the last 
 > CVS version. Since LIRC is well established and automatically 
 > provides control for many other Linux applications, a solution
 > specific to the DVB API is not such a good idea. 
 > 
 > But your patch is better in some other aspects (e.g. buffering of
 > events). Maybe the two patches can be combined without too much work.

I have appended a second patch which adds some of the functions of
Matthias to my ir code. Mainly I added the buffering and also fixed
some problems in Matthias' code. In irb_dequeue you forgot to
spin_unlock when irend == irbeg. Also you said spin_lock at the end of
this function. I modified the code to return the last command value
even if the queue is empty. This way the buildin repeat feature of
lirc is working.

I have tested dtv and vdr with this code and it seams to work. The
repeat mode seams to work to.

Christoph

--- dvb.c.2	Sun Aug 19 14:46:06 2001
+++ dvb.c	Sun Aug 26 18:50:01 2001
@@ -734,13 +734,44 @@
  * IRQ handling
  ****************************************************************************/
 
-wait_queue_head_t gpioq;
-static u32 irdata = 0;
+DECLARE_WAIT_QUEUE_HEAD(gpioq);
+#define IR_BUF_LENGTH 20
+#define IR_INC(x) x = (x + 1) % IR_BUF_LENGTH
+static u32 irbuf[IR_BUF_LENGTH];
+static u32 irbeg,irend;
+static spinlock_t irlock = SPIN_LOCK_UNLOCKED;
+
+static inline void irb_enqueue(u32 value) {
+        spin_lock(&irlock); //probably need no lock...
+        irbuf[irend] = value; 
+        IR_INC(irend);
+        if (irend == irbeg) //overflow: remove first buffered value
+                IR_INC(irbeg);
+        spin_unlock(&irlock);
+        printk("dvb: ircommand %08x enqueued (%d,%d)\n",value,irbeg,irend);
+}
+
+static inline u32 irb_dequeue(void) {
+        u32 value;
+        static u32 lastvalue;
+
+        spin_lock(&irlock);
+        if (irend == irbeg) {
+          spin_unlock(&irlock);
+          printk("dvb: last ircommand %08x dequeued (%d,%d)\n",lastvalue,irbeg,irend);
+          return lastvalue;
+        }
+        value = lastvalue = irbuf[irbeg];
+        IR_INC(irbeg);
+        spin_unlock(&irlock);
+        printk("dvb: ircommand %08x dequeued (%d,%d)\n",value,irbeg,irend);
+        return value;
+}
 
 void IR_handle(struct dvb_struct *dvb, u32 ircom)
 {
         printk("dvb: ircommand = %08x\n", ircom);
-        irdata = ircom;
+        irb_enqueue(ircom);
         wake_up_interruptible(&gpioq);
 }
 
@@ -6125,6 +6156,7 @@
 {
   static unsigned char codes[4];
   int index = code_bytes - key_no - 1;
+  u32 irdata;
   
   if (key_no > 0)	{
     if (code_bytes < 2 || key_no >= code_bytes) {
@@ -6136,6 +6168,7 @@
     return SUCCESS;
   }
 
+  irdata = irb_dequeue();
   memcpy(codes, &irdata, code_bytes);
 
   *key = codes[index];
@@ -6179,6 +6212,11 @@
   plugin.code_length = code_length;
   plugin.minor = minor;
   plugin.sample_rate = 10;
+
+  irbeg = 0;
+  irend = 0;
+
+  spin_lock_init(&irlock);
 
   request_module("lirc_dev");
 


-- 
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe linux-dvb" as subject.


Home | Main Index | Thread Index