Skip to contentSkip to conversation

mantis infrared remote patch (Cinergy C)

linux-dvb Roland Scheidegger 1 participant 1 message May 16, 2008 Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

Hi,

following earlier patches [1], [2], here's another version. I've added the remote for the Cinergy C card, and simplified it even a bit.

The remote of the Cinergy C appears to be the same physically as the one of the Cinergy DT USB XS Diversity. If you compare the key definitions to the one in dib0700_devices.c you can see some differences:
1) I've mapped one button differently since the dib driver has two physical keys mapped to the same keycode...
2) the codes received in the dib driver are the same, except they are bit-inverted (the first 6 bits) and then the dib driver will always use the seventh bit instead of the sixth. I don't know if that's because the remote is actually different or if one of the drivers interprets the values a bit wrong...

As for simplification, the driver got out of the non-working auto-repeat business... So no longer any worker thread when we know there's no work to do (actually should probably use work_struct instead of delayed_work now). The trouble with the previous auto-repeat code was that at least for the Cinergy C remote it can't work. This remote has an initial delay (initial button to first repeat) of ~270ms, and time between further repeats is ~220ms. So the code using polling 10 times per second didn't work and always registered single keypresses anyway. It couldn't be easily fixed, since the remote's repeat delay is larger than the fixed delay for repeats of the input layer (250ms) - meaning you wouldn't be able to do single key presses any longer... (I don't know if this really worked for the vp-2033 remote - the driver will now print out the time between irqs if the verbose option is set).
So repeats are a bit slow (in fact annoyingly slow imho, with not even 5 per seconds here), but even a proper auto-repeat solution can't really fix this - if you'd emulate more repeats per second you obviously would not be able to stop pressing a key precisely, which is just as annoying.

btw enabling verbose is a bit annoying due to the cam slot polling code filling up your log file even when the driver is just sitting idle - are people really expected to be able to insert/remove smartcards 10 times a second?

Roland

[1] http://www.linuxtv.org/pipermail/linux-dvb/2007-April/017403.html
[2] http://www.linuxtv.org/pipermail/linux-dvb/2008-March/024301.html

linux/drivers/media/dvb/mantis/Makefile +2 -1
diff -r cd1fc4c7f1d8 linux/drivers/media/dvb/mantis/Makefile
@@ -12,7 +12,8 @@ mantis-objs = 	mantis_core.o	\
 		mantis_vp1041.o	\
 		mantis_vp2033.o	\
 		mantis_vp2040.o	\
-		mantis_vp3030.o
+		mantis_vp3030.o \
+		mantis_rc.o
 
 obj-$(CONFIG_DVB_MANTIS) += mantis.o
 
linux/drivers/media/dvb/mantis/mantis_common.h +20 -0
diff -r cd1fc4c7f1d8 linux/drivers/media/dvb/mantis/mantis_common.h
@@ -26,6 +26,8 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/mutex.h>
+#include <linux/input.h>
+#include <media/ir-common.h>
 
 #include "dvbdev.h"
 #include "dvb_demux.h"
@@ -74,6 +76,21 @@ struct mantis_hwconfig {
 	char			*model_name;
 	char			*dev_type;
 	u32			ts_size;
+	IR_KEYTAB_TYPE		*ir_codes;
+};
+
+struct mantis_ir {
+	struct input_dev	*rc_dev;
+	char			rc_name[80];
+	char			rc_phys[80];
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	struct work_struct	rc_query_work;
+#else
+	struct delayed_work	rc_query_work;
+#endif
+	u32			ir_last_code;
+	u32			ir_last_irq;
+	struct ir_input_state	ir;
 };
 
 struct mantis_pci {
@@ -139,6 +156,9 @@ struct mantis_pci {
 	 /*	A12 A13 A14		*/
 	int			gpio_status;
 
+        /*       RC                     */
+	struct mantis_ir	ir;
+
 	struct mantis_ca	*mantis_ca;
 };
 
linux/drivers/media/dvb/mantis/mantis_core.c +4 -0
diff -r cd1fc4c7f1d8 linux/drivers/media/dvb/mantis/mantis_core.c
@@ -164,6 +164,10 @@ int mantis_core_init(struct mantis_pci *
 		dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");
 		return err;
 	}
+	if ((err = mantis_rc_init(mantis)) < 0) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "mantis RC init failed");
+		return err;
+	}
 
 	return 0;
 }
linux/drivers/media/dvb/mantis/mantis_core.h +2 -0
diff -r cd1fc4c7f1d8 linux/drivers/media/dvb/mantis/mantis_core.h
@@ -53,6 +53,8 @@ extern int mantis_i2c_exit(struct mantis
 extern int mantis_i2c_exit(struct mantis_pci *mantis);
 extern int mantis_core_init(struct mantis_pci *mantis);
 extern int mantis_core_exit(struct mantis_pci *mantis);
+extern int mantis_rc_init(struct mantis_pci *mantis);
+extern int mantis_rc_exit(struct mantis_pci *mantis);
 //extern void mantis_fe_powerup(struct mantis_pci *mantis);
 //extern void mantis_fe_powerdown(struct mantis_pci *mantis);
 //extern void mantis_fe_reset(struct dvb_frontend *fe);
linux/drivers/media/dvb/mantis/mantis_pci.c +8 -0
diff -r cd1fc4c7f1d8 linux/drivers/media/dvb/mantis/mantis_pci.c
@@ -65,6 +65,7 @@ static irqreturn_t mantis_pci_irq(int ir
 
 	stat = mmread(MANTIS_INT_STAT);
 	mask = mmread(MANTIS_INT_MASK);
+
 	mstat = lstat = stat & ~MANTIS_INT_RISCSTAT;
 	if (!(stat & mask))
 		return IRQ_NONE;
@@ -72,6 +73,7 @@ static irqreturn_t mantis_pci_irq(int ir
 	mantis->mantis_int_stat = stat;
 	mantis->mantis_int_mask = mask;
 	dprintk(verbose, MANTIS_DEBUG, 0, "=== Interrupts[%04x/%04x]= [", stat, mask);
+
 	if (stat & MANTIS_INT_RISCEN) {
 		dprintk(verbose, MANTIS_DEBUG, 0, "* DMA enabl *");
 	}
@@ -81,6 +83,11 @@ static irqreturn_t mantis_pci_irq(int ir
 	}
 	if (stat & MANTIS_INT_IRQ1) {
 		dprintk(verbose, MANTIS_DEBUG, 0, "* INT IRQ-1 *");
+		dprintk(verbose, MANTIS_DEBUG, 0, "ir repeat msec %u", jiffies_to_msecs(jiffies - mantis->ir.ir_last_irq));
+		mantis->ir.ir_last_irq = jiffies;
+		/* note value must be read here or we'll get irq storm */
+		mantis->ir.ir_last_code = mmread(0xe8);
+		schedule_delayed_work(&mantis->ir.rc_query_work, 0);
 	}
 	if (stat & MANTIS_INT_OCERR) {
 		dprintk(verbose, MANTIS_DEBUG, 0, "* INT OCERR *");
@@ -243,6 +250,7 @@ static void __devexit mantis_pci_remove(
 		dprintk(verbose, MANTIS_ERROR, 1, "Aeio, Mantis NULL ptr");
 		return;
 	}
+	mantis_rc_exit(mantis);
 	mantis_core_exit(mantis);
 	dprintk(verbose, MANTIS_ERROR, 1, "Removing -->Mantis irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p",
 		pdev->irq, mantis->latency, mantis->mantis_addr,
linux/drivers/media/dvb/mantis/mantis_vp2033.c +2 -0
diff -r cd1fc4c7f1d8 linux/drivers/media/dvb/mantis/mantis_vp2033.c
@@ -20,6 +20,7 @@
 
 #include "mantis_common.h"
 #include "mantis_vp2033.h"
+#include "mantis_rc.h"
 
 #define MANTIS_MODEL_NAME	"VP-2033"
 #define MANTIS_DEV_TYPE		"DVB-C"
@@ -28,6 +29,7 @@ struct mantis_hwconfig vp2033_mantis_con
 	.model_name	= MANTIS_MODEL_NAME,
 	.dev_type	= MANTIS_DEV_TYPE,
 	.ts_size	= MANTIS_TS_204,
+	.ir_codes       = ir_codes_mantis_vp2033,
 };
 
 struct tda1002x_config philips_cu1216_config = {
linux/drivers/media/dvb/mantis/mantis_vp2040.c +2 -0
diff -r cd1fc4c7f1d8 linux/drivers/media/dvb/mantis/mantis_vp2040.c
@@ -20,6 +20,7 @@
 
 #include "mantis_common.h"
 #include "mantis_vp2040.h"
+#include "mantis_rc.h"
 
 #define MANTIS_MODEL_NAME	"VP-2040"
 #define MANTIS_DEV_TYPE		"DVB-C"
@@ -28,6 +29,7 @@ struct mantis_hwconfig vp2040_mantis_con
 	.model_name	= MANTIS_MODEL_NAME,
 	.dev_type	= MANTIS_DEV_TYPE,
 	.ts_size	= MANTIS_TS_204,
+	.ir_codes	= ir_codes_mantis_vp2040,
 };
 
 struct tda1002x_config tda10023_cu1216_config = {
linux/drivers/media/dvb/mantis/mantis_rc.c new file +204 -0

204 lines not on this page · raw message

linux/drivers/media/dvb/mantis/mantis_rc.h new file +2 -0
diff -r cd1fc4c7f1d8 linux/drivers/media/dvb/mantis/mantis_rc.h
@@ -0,0 +1,2 @@
+extern IR_KEYTAB_TYPE ir_codes_mantis_vp2033[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_mantis_vp2040[IR_KEYTAB_SIZE];

_______________________________________________
linux-dvb mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb