[linux-dvb] [PATCH] Keymap loading support for budget-ci

Darren Salt linux at youmustbejoking.demon.co.uk
Thu Dec 15 23:43:26 CET 2005


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 at youmustbejoking.demon.co.uk>

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 at youmustbejoking.demon.co.uk>

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;
 }


More information about the linux-dvb mailing list