[vdr] Hauppauge LIRC remote, FC3, buttons
Darren Salt
linux at youmustbejoking.demon.co.uk
Fri Feb 25 03:10:48 CET 2005
I demand that Simon Baxter may or may not have written...
> I'm having some strange problems with my VDR keymaps on Xine (running FC3
> with a DVB Nova-T). I use the xine keymap editor to 'grab' keystrokes for
> the VDR buttons, but none of the coloured buttons (green, red, blue) are
> recognised?
I can't help with LIRC, but you *can* get this working with the remote plugin
and my patches (attached).
The -kernel patch is applicable to 2.6.x kernel source and the LinuxTV DVB
driver tarballs (1.1.0, 1.1.1 and possibly some older versions); the -linuxtv
patch is for DVB CVS (and *should* still be applicable; I've not checked
recently). For the record, these are based on the IR keymap interface in the
av7110 code.
The third patch is for the DVB utilities - you'll get an extra binary,
budget_ci_loadkeys, which you can use as follows (once you've loaded the
patched budget_ci module):
# budget_ci_loadkeys hauppauge_grey.rc5 >/proc/budget_ci_ir
For those who are already using these patches: no need to update - the
patches are unchanged.
Debian testing/unstable users: these patches are present in dvb-utils 1.1.0-3
and dvb-driver-source 1.1.1-4 and later versions.
(BTW, you need to switch on text wrapping or to stop using OE.)
--
| Darren Salt | nr. Ashington, | d youmustbejoking,demon,co,uk
| Debian, | Northumberland | s zap,tartarus,org
| RISC OS | Toon Army | @
| Retrocomputing: a PC card in a Risc PC
Anything worth doing is worth overdoing.
-------------- next part --------------
--- linux/drivers/media/dvb/ttpci/budget-ci.c.orig 2003-11-20 10:50:15.000000000 +0000
+++ linux/drivers/media/dvb/ttpci/budget-ci.c 2004-09-27 22:16:19.000000000 +0100
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
+#include <linux/proc_fs.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "input_fake.h"
@@ -181,10 +182,48 @@
}
+static int budget_ci_ir_write_proc (struct file *file,
+ const char __user *buffer,
+ unsigned long count, void *data)
+{
+ /* adapted from av7110_ir.c */
+ char *page;
+ int i;
+ struct input_dev *input = (struct input_dev *)data;
+
+ if (count < sizeof (key_map))
+ return -EINVAL;
+
+ page = (char *)vmalloc(sizeof (key_map));
+ if (!page)
+ return -ENOMEM;
+
+ if (copy_from_user(page, buffer, sizeof (key_map))) {
+ vfree(page);
+ return -EFAULT;
+ }
+
+ memcpy (&key_map, page, sizeof (key_map));
+ vfree(page);
+
+ memset (input->keybit, 0, sizeof(input->keybit));
+
+ for (i=0; i<sizeof(key_map)/sizeof(key_map[0]); i++) {
+ if (key_map[i] > KEY_MAX)
+ key_map[i] = 0;
+ else if (key_map[i] > KEY_RESERVED)
+ set_bit (key_map[i], input->keybit);
+ }
+
+ return count;
+}
+
+
static int msp430_ir_init (struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
int i;
+ static struct proc_dir_entry *e;
memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
@@ -204,6 +243,13 @@
saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
+ e = create_proc_entry ("budget_ci_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
+ if (e) {
+ e->write_proc = budget_ci_ir_write_proc;
+ e->data = &budget_ci->input_dev;
+ e->size = sizeof (key_map);
+ }
+
return 0;
}
@@ -213,6 +259,8 @@
struct saa7146_dev *saa = budget_ci->budget.dev;
struct input_dev *dev = &budget_ci->input_dev;
+ remove_proc_entry ("budget_ci_ir", NULL);
+
saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
-------------- next part --------------
--- linux/drivers/media/dvb/ttpci/budget-ci.c.orig 2004-09-20 17:37:46.000000000 +0100
+++ linux/drivers/media/dvb/ttpci/budget-ci.c 2004-10-17 22:02:12.000000000 +0100
@@ -36,6 +36,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
+#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include "dvb_ca_en50221.h"
@@ -234,10 +235,48 @@ static void msp430_ir_interrupt (unsigne
}
}
+static int budget_ci_ir_write_proc (struct file *file,
+ const char __user *buffer,
+ unsigned long count, void *data)
+{
+ /* adapted from av7110_ir.c */
+ char *page;
+ int i;
+ struct input_dev *input = (struct input_dev *)data;
+
+ if (count < sizeof (key_map))
+ return -EINVAL;
+
+ page = (char *)vmalloc(sizeof (key_map));
+ if (!page)
+ return -ENOMEM;
+
+ if (copy_from_user(page, buffer, sizeof (key_map))) {
+ vfree(page);
+ return -EFAULT;
+ }
+
+ memcpy (&key_map, page, sizeof (key_map));
+ vfree(page);
+
+ memset (input->keybit, 0, sizeof(input->keybit));
+
+ for (i=0; i<sizeof(key_map)/sizeof(key_map[0]); i++) {
+ if (key_map[i] > KEY_MAX)
+ key_map[i] = 0;
+ else if (key_map[i] > KEY_RESERVED)
+ set_bit (key_map[i], input->keybit);
+ }
+
+ return count;
+}
+
+
static int msp430_ir_init (struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
int i;
+ static struct proc_dir_entry *e;
memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
@@ -258,6 +297,13 @@ static int msp430_ir_init (struct budget
saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
+ e = create_proc_entry ("budget_ci_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
+ if (e) {
+ e->write_proc = budget_ci_ir_write_proc;
+ e->data = &budget_ci->input_dev;
+ e->size = sizeof (key_map);
+ }
+
return 0;
}
@@ -266,6 +312,8 @@ static void msp430_ir_deinit (struct bud
struct saa7146_dev *saa = budget_ci->budget.dev;
struct input_dev *dev = &budget_ci->input_dev;
+ remove_proc_entry ("budget_ci_ir", NULL);
+
saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
-------------- next part --------------
diff -urNad linuxtv-dvb-apps-1.1.0/util/av7110_loadkeys/Makefile linuxtv-dvb-apps-1.1.0/util/av7110_loadkeys/Makefile
--- linuxtv-dvb-apps-1.1.0/util/av7110_loadkeys/Makefile 2004-09-27 20:48:23.000000000 +0100
+++ linuxtv-dvb-apps-1.1.0/util/av7110_loadkeys/Makefile 2004-09-27 20:48:39.000000000 +0100
@@ -1,14 +1,23 @@
CC = gcc
-CFLAGS = -g -Wall -O2
+CFLAGS = -g -Wall -O2 -D_GNU_SOURCE
-all: av7110_loadkeys evtest
+all: av7110_loadkeys budget_ci_loadkeys evtest
av7110_loadkeys: av7110_loadkeys.o
+budget_ci_loadkeys: budget_ci_loadkeys.o
+
evtest: evtest.o
+av7110_loadkeys.o: CFLAGS += -UHW_MSP430
av7110_loadkeys.o: av7110_loadkeys.c input_keynames.h
+budget_ci_loadkeys.c: av7110_loadkeys.c
+ ln av7110_loadkeys.c budget_ci_loadkeys.c
+
+budget_ci_loadkeys.o: CFLAGS += -DHW_MSP430
+budget_ci_loadkeys.o: budget_ci_loadkeys.c input_keynames.h
+
evtest.o: evtest.c input_keynames.h
@@ -53,5 +62,6 @@
clean:
- $(RM) core* *.o input_keynames.h av7110_loadkeys evtest
+ $(RM) core* *.o input_keynames.h av7110_loadkeys budget_ci_loadkeys \
+ budget_ci_loadkeys.c evtest
diff -urNad linuxtv-dvb-apps-1.1.0/util/av7110_loadkeys/av7110_loadkeys.c linuxtv-dvb-apps-1.1.0/util/av7110_loadkeys/av7110_loadkeys.c
--- linuxtv-dvb-apps-1.1.0/util/av7110_loadkeys/av7110_loadkeys.c 2004-09-27 20:48:23.000000000 +0100
+++ linuxtv-dvb-apps-1.1.0/util/av7110_loadkeys/av7110_loadkeys.c 2004-09-27 20:48:23.000000000 +0100
@@ -1,5 +1,6 @@
#include <asm/types.h>
#include <stdlib.h>
+#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
@@ -111,12 +112,20 @@
+#ifdef HW_MSP430
+const char usage [] = "\n\tusage: budget_ci_loadkeys keymap_filename.rc5\n\n";
+#else
const char usage [] = "\n\tusage: av7110_loadkeys [-i|--invert] [-a|--address <num>] keymap_filename.(rc5|rcmm)\n\n";
-
+#endif
struct ir_setup {
+#ifdef HW_MSP430
+#define KEYTAB_SIZE 64
+#else
+#define KEYTAB_SIZE 256
__u32 ir_config;
- __u16 keytab [256];
+#endif
+ __u16 keytab [KEYTAB_SIZE];
} __attribute__ ((packed));
@@ -128,7 +137,10 @@
char *buf, *pos, *fname = NULL;
for (i=1; i<argc; i++) {
+#ifndef HW_MSP430
+ /* AV7110 only; not MSP430 */
if (!strcmp("-i", argv[i]) || !strcmp("--invert", argv[i]))
+
setup.ir_config |= 0x8000;
else if (!strcmp("-a", argv[i]) || !strcmp("--address", argv[i])) {
if (++i < argc) {
@@ -136,6 +148,7 @@
setup.ir_config |= 0x4000;
}
} else
+#endif
fname = argv[i];
}
@@ -144,6 +157,14 @@
exit (-1);
}
+#ifdef HW_MSP430
+ if (strncmp(".rc5", fname + strlen(fname) - 4, 4) != 0) {
+ const char msg [] = "\nERROR: "
+ "input filename must have suffix .rc5\n";
+ write (0, msg, strlen(msg));
+ exit (-1);
+ }
+#else
if (strncmp(".rcmm", fname + strlen(fname) - 5, 5) == 0)
setup.ir_config |= 0x0001;
else if (strncmp(".rc5", fname + strlen(fname) - 4, 4) != 0) {
@@ -152,6 +173,7 @@
write (0, msg, strlen(msg));
exit (-1);
}
+#endif
if ((fd = open (fname, O_RDONLY)) < 0)
print_error ("open", fname);
@@ -173,9 +195,11 @@
key = strtol (pos, &pos, 0);
keycode = parse_keyname (pos, &pos, buf + len - pos);
- if (key < 0 || key > 0xff) {
- const char msg [] =
- "\nERROR: key must be in range 0 ... 0xff!\n\n";
+ if (key < 0 || key >= KEYTAB_SIZE) {
+ char *msg;
+ asprintf (&msg,
+ "\nERROR: key must be in range 0 ... 0x%02x!\n\n",
+ KEYTAB_SIZE);
write (0, msg, strlen(msg));
exit (-1);
@@ -190,7 +214,7 @@
munmap (buf, len);
close (fd);
- write (1, &setup, 4 + 256 * sizeof(__u16));
+ write (1, &setup, sizeof (setup));
return 0;
}
More information about the vdr
mailing list