Mailing List archive

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

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



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.

Matthias Hilbig

dvb.patch:
-------------------------cut here ----------------------------------
diff -r -u DVB/driver/dvb.c DVBmod/driver/dvb.c
--- DVB/driver/dvb.c	Tue Aug 14 02:43:07 2001
+++ DVBmod/driver/dvb.c	Wed Aug 22 15:14:41 2001
@@ -770,10 +770,78 @@

/****************************************************************************
  * IRQ handling
  ****************************************************************************/
+DECLARE_WAIT_QUEUE_HEAD(irqueue);
+#define IR_BUF_LENGTH 10
+#define IR_INC(x) x = (x + 1) % IR_BUF_LENGTH
+static u32 irbuf[IR_BUF_LENGTH];
+static u32 irbeg,irend,irrepeatdelay,irrepeatlimit;
+static boolean irpressed;
+static struct timer_list ir_timer;
+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() {
+        u32 value;
+        spin_lock(&irlock);
+        if (irend == irbeg) return -1; //queue empty
+        value = irbuf[irbeg];
+        IR_INC(irbeg);
+        spin_lock(&irlock);
+        //printk("dvb: ircommand %08x dequeued (%d,%d)\n",value,irbeg,irend);
+        return value;
+}
+
+static inline void irb_reset() {
+        irbeg = 0;
+        irend = 0;
+}
+
+void ir_repeat_timer(unsigned long data) {
+        if (irpressed) {
+                //restart timer
+                ir_timer.expires = jiffies + irrepeatlimit;
+                add_timer(&ir_timer);
+                //enqueue repeat
+                irb_enqueue((u32) data | (3 << 30));//first bit: pressed, second: repeated
+                irb_enqueue((u32) data & 0x3fffffff);
+                //wake up waiting processes
+                wake_up_interruptible(&irqueue);
+        }
+}
+
+inline static void ir_init() {
+        init_timer(&ir_timer);
+        ir_timer.function = ir_repeat_timer;
+        irrepeatdelay = 350;
+        irrepeatlimit = 100;
+}

 void IR_handle(struct dvb_struct *dvb, u32 ircom)
 {
-        printk("dvb: ircommand = %08x\n", ircom);
+        irpressed = ircom & (1 << 31);
+        //irrepeatdelay 0 means no repeat
+        if (irrepeatdelay) {
+                if (irpressed) {
+                        //start timer
+                        ir_timer.data = (unsigned long) ircom;
+                        ir_timer.expires = jiffies + irrepeatdelay;
+                        add_timer(&ir_timer);
+                }  else {
+                        //stop timer
+                        del_timer_sync(&ir_timer);
+                }
+        }
+        irb_enqueue(ircom);
+        wake_up_interruptible(&irqueue);
 }

 void CI_handle(struct dvb_struct *dvb, u8 *data, u16 len)
@@ -5228,6 +5296,41 @@
                                  return -EFAULT;
                         break;

+                case IR_READY:
+                        if (put_user((irbeg != irend),(u32 *) parg))
+                                return -EFAULT;
+                        break;
+                case IR_GET_COMMAND_NB: {//not blocking
+                        u32 command;
+                        command = irb_dequeue();
+                        if(put_user(command,(u32 *)parg))
+                                return -EFAULT;
+                        break;
+                }
+                case IR_GET_COMMAND: { //blocking
+                        u32 command;
+                        command = irb_dequeue();
+                        if (command == -1) {
+                                interruptible_sleep_on(&irqueue);
+                                command = irb_dequeue();
+                        }
+                        if(put_user(command,(u32 *)parg))
+                                return -EFAULT;
+                        break;
+                }
+                case IR_FLUSH:
+                        irb_reset();
+                        break;
+                case IR_SET_REPEATDELAY:
+                        if (get_user(irrepeatdelay,(u32 *)parg))
+                                return -EFAULT;
+                        break;
+                case IR_SET_REPEATLIMIT:
+                        if (get_user(irrepeatlimit,(u32 *)parg))
+                                return -EFAULT;
+                        if (irrepeatlimit <= 10)
+                                irrepeatlimit = 10;
+                        break;
                 case FE_READ_STATUS:
                 {
                         feStatus stat;
@@ -6086,6 +6189,7 @@
                 //setgpio(dvb, 1, GPIO_OUTHI); // RGB on, SCART pin 16
                 //setgpio(dvb, 3, GPIO_OUTLO); // SCARTpin 8
         }
+        ir_init(); //init infrared control (just some vars)
         return 0;
 }

diff -r -u DVB/ost/include/ost/frontend.h
DVBmod/ost/include/ost/frontend.h
--- DVB/ost/include/ost/frontend.h	Wed Apr 25 01:35:25 2001
+++ DVBmod/ost/include/ost/frontend.h	Tue Aug 21 11:08:04 2001
@@ -175,5 +175,12 @@
 #define QAM_READ_REGISTER              _IOR('o',85,struct qamRegister *)
 #define QAM_GET_STATUS                 _IOR('o',86,struct qamParameters *)

+#define IR_GET_COMMAND                 _IOR('o', 170,uint32_t *)
+#define IR_GET_COMMAND_NB              _IOR('o', 171,uint32_t *)
+#define IR_FLUSH                       _IO('o',  172)
+#define IR_READY                       _IOR('o', 173,uint32_t *)
+#define IR_SET_REPEATDELAY             _IOR('o', 174,uint32_t *)
+#define IR_SET_REPEATLIMIT             _IOR('o', 175,uint32_t *)
+
 #endif /*_OST_FRONTEND_H_*/

----------------------------cut------------------------------------
vdr.patch:
----------------------------cut------------------------------------
diff -r -u VDR/Makefile VDRmod/Makefile
--- VDR/Makefile	Wed Aug 15 15:56:11 2001
+++ VDRmod/Makefile	Tue Aug 21 13:48:12 2001
@@ -32,7 +32,7 @@

 OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
 FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
-
+REMOTE = REV21
 ifndef REMOTE
 REMOTE = KBD
 endif
@@ -55,7 +55,7 @@
 # Implicit rules:

 %.o: %.c
-	g++ -g -O2 -Wall -Woverloaded-virtual -m486 -c $(DEFINES)
$(INCLUDES) $<
+	g++ -g3 -Wall -Woverloaded-virtual -m486 -c $(DEFINES) $(INCLUDES)
$<

 # Dependencies:

diff -r -u VDR/dvbapi.c VDRmod/dvbapi.c
--- VDR/dvbapi.c	Sun Aug 19 17:09:48 2001
+++ VDRmod/dvbapi.c	Tue Aug 21 11:08:12 2001
@@ -3464,6 +3464,41 @@
   audioCommand = strdup(Command);
 }

+// IRCHANGE
+
+unsigned int cDvbApi::GetIRCommand() {
+  unsigned int command;
+	CHECK(ioctl(fd_qpskfe, IR_GET_COMMAND, &command));
+	return command;//wenn fehler return -1
+}
+
+unsigned int cDvbApi::GetIRCommandNB() {
+  unsigned int command;
+	CHECK(ioctl(fd_qpskfe, IR_GET_COMMAND_NB, &command));
+	return command;//wenn fehler return -1
+}
+
+void cDvbApi::SetIRRepeatDelay(int delay) {
+	CHECK(ioctl(fd_qpskfe, IR_SET_REPEATDELAY, &delay));
+}
+
+
+void cDvbApi::SetIRRepeatLimit(int limit) {
+	CHECK(ioctl(fd_qpskfe, IR_SET_REPEATLIMIT, &limit));
+}
+
+bool cDvbApi::IRReady() {
+	int ready = -1;
+	CHECK(ioctl(fd_qpskfe, IR_READY, &ready));
+	return ready;
+}
+
+
+void cDvbApi::FlushIR() {
+	CHECK(ioctl(fd_qpskfe, IR_FLUSH));
+}
+
+
 // --- cEITScanner
-----------------------------------------------------------

 cEITScanner::cEITScanner(void)
diff -r -u VDR/dvbapi.h VDRmod/dvbapi.h
--- VDR/dvbapi.h	Sat Aug 11 14:22:01 2001
+++ VDRmod/dvbapi.h	Tue Aug 21 11:08:12 2001
@@ -290,7 +290,13 @@
        // audio tracks, or if the current channel has two audio PIDs.
   bool ToggleAudioTrack(void);
        // Toggles the audio track if possible.
-
+  // Infrared Control
+  unsigned int GetIRCommandNB();
+  unsigned int GetIRCommand();
+  void FlushIR();
+  void SetIRRepeatDelay(int delay);
+  void SetIRRepeatLimit(int limit);
+  bool IRReady();
   // Dolby Digital audio facilities

 private:
@@ -298,6 +304,7 @@
 public:
   static void SetAudioCommand(const char *Command);
   static const char *AudioCommand(void) { return audioCommand; }
+
   };

 class cEITScanner {
diff -r -u VDR/interface.c VDRmod/interface.c
--- VDR/interface.c	Tue Aug  7 18:23:28 2001
+++ VDRmod/interface.c	Wed Aug 22 13:52:39 2001
@@ -28,6 +28,8 @@
   rcIo = new cRcIoLIRC("/dev/lircd");
 #elif defined(REMOTE_KBD)
   rcIo = new cRcIoKBD;
+#elif defined(REMOTE_REV21)
+  rcIo = new cRcIoREV21();
 #else
   rcIo = new cRcIoBase; // acts as a dummy device
 #endif
@@ -67,7 +69,7 @@
 {
   Flush();
   if (!rcIo->InputAvailable())
-     cFile::AnyFileReady(-1, Wait ? 1000 : 0);
+	cFile::AnyFileReady(-1,Wait?0: 0); //always fast response :-)
   unsigned int Command;
   return rcIo->GetCommand(&Command, Repeat, Release) ? Command : 0;
 }
diff -r -u VDR/remote.c VDRmod/remote.c
--- VDR/remote.c	Sun Aug 12 17:07:26 2001
+++ VDRmod/remote.c	Wed Aug 22 15:18:10 2001
@@ -495,5 +495,90 @@
   return false;
 }

+#elif defined REMOTE_REV21
+
+#define IR_INC(x) x = (x + 1) % IR_BUF_LENGTH
+
+//buffer handling
+inline void cRcIoREV21::irb_enqueue(unsigned int value) {
+  irbuf[irend] = value;
+  IR_INC(irend);
+  if (irend == irbeg)
+	IR_INC(irbeg);
+}
+
+inline unsigned int cRcIoREV21::irb_dequeue() {
+  unsigned int value;
+  if (irend == irbeg) return 0xffffffff; //queue empty
+  value = irbuf[irbeg];
+  IR_INC(irbeg);
+  return value;
+}
+
+
+// Konstruktor
+cRcIoREV21::cRcIoREV21()
+{
+  cDvbApi::PrimaryDvbApi->SetIRRepeatDelay(110);
+  cDvbApi::PrimaryDvbApi->SetIRRepeatLimit(35);
+  irbeg= irend = 0;
+  Start();
+}
+
+cRcIoREV21::~cRcIoREV21()
+{
+  Cancel();
+}
+
+//Thread
+void cRcIoREV21::Action(void)
+{
+  dsyslog(LOG_INFO, "REV21 remote control thread started (pid=%d)",
getpid());
+  unsigned int ircommand;
+  while (true) {
+	ircommand = cDvbApi::PrimaryDvbApi->GetIRCommand(); //blocking
+	//workaround: pressed events get release, ignore release events
+	if (ircommand & (1<<31)) {
+	  mutex.Lock();
+	  irb_enqueue(ircommand & 0x7fffffff);
+	  mutex.Unlock();
+	}
+  }
+}
+
+// Interface
+void cRcIoREV21::Flush(int WaitMs)
+{
+  cDvbApi::PrimaryDvbApi->FlushIR();
+  irbeg = irend = 0; //reset buffer
+  //delay_ms(WaitMs);
+}
+
+bool cRcIoREV21::InputAvailable(void)
+{
+  return irbeg != irend;
+}
+
+bool cRcIoREV21::GetCommand(unsigned int *Command, bool *Repeat, bool *Release)
+{
+  unsigned int ircommand;
+  if (Command) {
+	mutex.Lock();
+	ircommand = irb_dequeue();
+	mutex.Unlock();
+	*Command = (ircommand+1) & 0x3fffffff;
+	/*if (Repeat)
+	 *Repeat = ircommand & (1 << 30);*/
+	/*if (Release)
+	 *Release = !(ircommand & (1 << 31));*/
+	return true;
+	if (*Command == 0)
+	  return false;
+	else
+	return true;
+  }
+  return false;
+}
+
 #endif

diff -r -u VDR/remote.h VDRmod/remote.h
--- VDR/remote.h	Sun Jul 22 16:42:59 2001
+++ VDRmod/remote.h	Tue Aug 21 12:50:06 2001
@@ -14,6 +14,9 @@
 #include <time.h>
 #include "thread.h"
 #include "tools.h"
+#if defined REMOTE_REV21
+#include "dvbapi.h"
+#endif

 class cRcIoBase {
 protected:
@@ -92,6 +95,29 @@
   virtual bool InputAvailable(void) { return receivedData; }
   virtual bool GetCommand(unsigned int *Command = NULL, bool *Repeat = NULL, bool *Release = NULL);
   };
+#elif defined REMOTE_REV21
+
+#define IR_BUF_LENGTH 10
+class cRcIoREV21 : public cRcIoBase, private cThread {
+private:
+  unsigned int irbuf[IR_BUF_LENGTH];
+  int irbeg, irend;
+  int key;
+  bool repeat;
+  bool release;
+  cMutex mutex;
+  virtual void Action(void);
+  inline void irb_enqueue(unsigned int value);
+  inline unsigned int irb_dequeue();
+
+public:
+  cRcIoREV21();
+  virtual ~cRcIoREV21();
+  virtual void Flush(int WaitMs = 0);
+  virtual bool InputAvailable(void);
+  virtual bool GetCommand(unsigned int *Command = NULL, bool *Repeat = NULL, bool *Release = NULL);
+};
+

 #elif !defined REMOTE_NONE

diff -r -u VDR/tools.c VDRmod/tools.c
--- VDR/tools.c	Fri Aug 17 14:45:42 2001
+++ VDRmod/tools.c	Wed Aug 22 13:07:59 2001
@@ -146,12 +146,13 @@
   return 0;
 }

-void delay_ms(int ms)
+/*void delay_ms(int ms)
 {
-  int t0 = time_ms();
-  while (time_ms() - t0 < ms)
-        ;
-}
+  usleep(ms);
+//int t0 = time_ms();
+//while (time_ms() - t0 < ms)
+//;
+}*/

 bool isnumber(const char *s)
 {
diff -r -u VDR/tools.h VDRmod/tools.h
--- VDR/tools.h	Fri Aug 17 14:44:39 2001
+++ VDRmod/tools.h	Wed Aug 22 12:38:33 2001
@@ -45,7 +45,7 @@
 bool startswith(const char *s, const char *p);
 bool isempty(const char *s);
 int time_ms(void);
-void delay_ms(int ms);
+#define delay_ms(x) usleep(x)
 bool isnumber(const char *s);
 const char *AddDirectory(const char *DirName, const char *FileName);
 uint FreeDiskSpaceMB(const char *Directory);
----------------------------------------end-------------------------




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


Home | Main Index | Thread Index