[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