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