This message contains two patches which I've had floating around for some time now. Taken together, they implement kernel and user-space components for keymap-loading support for budget-ci cards such as my Nova-T (PCI ID 1131:7146 subsystem 13C2:1011). These patches are updated versions of those which can be found in Debian's liuxtv-dvb-apps and linuxtv-dvb source packages. They provide /proc/budget_ci_ir and /usr/bin/budget_ci_loadkeys. /proc/budget_ci_ir takes an array of 64 key codes (unsigned short, native endianness). The code which handles this is derived from av7110_ir.c. hauppauge_grey.rc5 is the correct keymap for my remote control (although I prefer BTN_<digit> to KEY_<digit>). -- | Darren Salt | nr. Ashington, | d youmustbejoking,demon,co,uk | Debian, | Northumberland | s zap,tartarus,org | RISC OS | Toon Army | @ | Kill all extremists! He who cooks carrots and peas in same pot unsanitary. -------------- next part -------------- Implement keymap loading support for budget_ci cards. This is the kernel part, creating /proc/budget_ci_ir. The implementation is derived from the av7110 keymap code. (An older version of this patch has been in the Debian dvb-driver-source package since October 2004.) Signed-off-by: Darren Salt <linux@xxxxxxxxxxxxxxxxxxxxxxxxxxx> Index: drivers/media/dvb/ttpci/budget-ci.c =================================================================== RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/ttpci/budget-ci.c,v retrieving revision 1.46 diff -u -p -r1.46 budget-ci.c --- v4l-dvb/linux/drivers/media/dvb/ttpci/budget-ci.c 4 Dec 2005 01:12:43 -0000 1.46 +++ v4l-dvb/linux/drivers/media/dvb/ttpci/budget-ci.c 15 Dec 2005 21:15:18 -0000 @@ -37,6 +37,7 @@ #include <linux/interrupt.h> #include <linux/input.h> #include <linux/spinlock.h> +#include <linux/proc_fs.h> #include "dvb_ca_en50221.h" #include "stv0299.h" @@ -178,11 +179,48 @@ static void msp430_ir_interrupt(unsigned } } +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; struct input_dev *input_dev; int i; + static struct proc_dir_entry *e; budget_ci->input_dev = input_dev = input_allocate_device(); if (!input_dev) @@ -204,6 +242,13 @@ static int msp430_ir_init(struct budget_ saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06); 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; } @@ -212,6 +257,8 @@ static void msp430_ir_deinit(struct budg 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 -------------- Implement keymap loading support for budget_ci cards. This is the user-space part. Build and install budget_ci_loadkeys. Usage is: budget_ci_loadkeys keymap.rc5 >/proc/budget_ci_ir Signed-off-by: Darren Salt <linux@xxxxxxxxxxxxxxxxxxxxxxxxxxx> Index: util/av7110_loadkeys/Makefile =================================================================== RCS file: /cvs/linuxtv/dvb-apps/util/av7110_loadkeys/Makefile,v retrieving revision 1.6 diff -u -p -r1.6 Makefile --- dvb-apps/util/av7110_loadkeys/Makefile 4 Jul 2005 20:26:13 -0000 1.6 +++ dvb-apps/util/av7110_loadkeys/Makefile 15 Dec 2005 21:26:16 -0000 @@ -1,19 +1,28 @@ CC = gcc -CFLAGS ?= -g -Wall -O2 +CFLAGS ?= -g -Wall -O2 -D_GNU_SOURCE CFLAGS += $(ARCH) CPPFLAGS += $(DEFS) DEFS = '-DDATADIR="$(datadir)"' bindir = /usr/local/bin datadir = /usr/local/share -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: av7110_loadkeys.c input_keynames.h + evtest.o: evtest.c input_keynames.h @@ -58,11 +67,13 @@ input_keynames.h: /usr/include/linux/inp 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 install: install-bin install-data -install-bin: av7110_loadkeys - install -m 755 av7110_loadkeys $(DESTDIR)$(bindir) +install-bin: av7110_loadkeys budget_ci_loadkeys + install -m 755 av7110_loadkeys budget_ci_loadkeys $(DESTDIR)$(bindir) install-data: mkdir -p $(DESTDIR)$(datadir)/dvb/av7110_loadkeys + ln -s av7110_loadkeys $(DESTDIR)$(datadir)/dvb/budget_ci_loadkeys cp *.rc5 *.rcmm $(DESTDIR)$(datadir)/dvb/av7110_loadkeys/ Index: util/av7110_loadkeys/av7110_loadkeys.c =================================================================== RCS file: /cvs/linuxtv/dvb-apps/util/av7110_loadkeys/av7110_loadkeys.c,v retrieving revision 1.2 diff -u -p -r1.2 av7110_loadkeys.c --- dvb-apps/util/av7110_loadkeys/av7110_loadkeys.c 23 Apr 2005 21:57:54 -0000 1.2 +++ dvb-apps/util/av7110_loadkeys/av7110_loadkeys.c 15 Dec 2005 21:26:17 -0000 @@ -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 @@ int parse_keyname (char *pos, char **nen +#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 @@ int main (int argc, char **argv) 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 @@ int main (int argc, char **argv) setup.ir_config |= 0x4000; } } else +#endif fname = argv[i]; } @@ -144,6 +157,14 @@ int main (int argc, char **argv) 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 @@ int main (int argc, char **argv) write (0, msg, strlen(msg)); exit (-1); } +#endif if ((fd = open (fname, O_RDONLY)) < 0) print_error ("open", fname); @@ -173,9 +195,11 @@ int main (int argc, char **argv) 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 @@ int main (int argc, char **argv) munmap (buf, len); close (fd); - write (1, &setup, 4 + 256 * sizeof(__u16)); + write (1, &setup, sizeof (setup)); return 0; }