I've been trying to do exactly the same thing and wrote a big long e-mail at work about it, but I lost it :-(.
Attached is a patch of as far as I got with it. I kindof gave up because I don't have the confidence to continue really. *Don't* apply the patch unless you know what you're doing. I wouldn't want to crash your system.
Please keep in mind I'm a complete linux kernel newbie - & programming C isn't my forte (& I'm lazy). I'm trying to get out of not statically allocating my swap_table array because I wanted to see all my changes on the same page.
I'm using debug=49 which gives loads of info.
There are a few issues.
- I tried my freecom USB stick with a JVC DVD remote similar to http://lirc.sourceforge.net/remotes/jvc/RM-SXVS40A I worked out that the 2 bytes received by the stick had their nibbles swapped and the bits reversed in comparison with the LIRC definition of things. The patch muddles the bits around to fix it. There's probably some macro somewhere in the kernel code to fix this by magic, but I never know how to find those things.
- The freecom remote seems to transmit 4 bytes, 1 byte identifier (0x80), 1 byte code, and 2 checksum (same but NOTed I think).
- The JVC remote transmits 2 bytes: an identifier (0xf7) and 1 byte code.
- The freeecom stick seems to have a 5 byte buffer. THe first byte is always 1 if there something new (I think), and the remaining 4 bytes
- If the freecom remote transmits, all 4 bytes are written over. However, if the JVC remote transmits, only the first 2 are written over & the remaining 2 bytes aren't. So here's the first problem: If you want to do the checksum, then the JVC remote will always fail the checksum. I put a workaround for this by checking whether the first byte was the freecom remote first byte (0x80) & if it was, then do the checksum. This probably isn't a valid solution for all remotes, but it got me around it.
- Having worked this out, the problem is, how to get the key-code to lirc. I thought at first of looking at /proc/dev/input/devices to see where the output is going. Mine looks like this:
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="IR-receiver inside an USB DVB receiver"
P: Phys=/ir0
H: Handlers=kbd event3
B: EV=3
B: KEY=c0000 100002 0 0 0 0 0 0 0 1e0000 0 0 ffc
Which suggests I should look at /dev/input/event3
But when I cat /dev/input/event3 & try my JVC remote nothign happens. I think this is because, when you setup the input device (in dvb_usb_remote_init()) you have to tell the kernel which key-codes you will generate by setting some mask values with set_bit(). That got a little complicated for me.
At this point I decided I was way out of my depth because really these aren't valid key codes being generated by the remote (i.e. it isn't KEY_1) when I hit the JVC remote 1 key. In fact, I want to let lirc do the key decoding. So perhaps to get key-codes out to lirc we need to create a completely separate char device that has nothing to do with the linux input subsystem. I dunno.
Phew, that's tiring.
I'd help out for fun if you need. Let me know if I've gone completely down the wrong track.
Cheers!
Keith
BEGIN PATCH
Index: dtt200u.c
==============================
=====================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/dvb-usb/dtt200u.c,v
retrieving revision 1.20
diff -r1.20 dtt200u.c
83d82
< dvb_usb_nec_rc_key_to_event(d,key,event,state);
85a85,120
> if (key[1] == 0x80) {
> dvb_usb_nec_rc_key_to_event(d,key,event,state);
> } else {
> u8 swapped_keys[5];
> u8 swap_table[] = {0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
> u8 nibl, nibh;
> *event = 0;
> *state = REMOTE_NO_KEY_PRESSED;
>
> switch(key[0]) {
> case 0x00:
> break;
> case 0x01:
> swapped_keys[0] = key[0];
> nibl = key[1] & 0xf;
> nibh = (key[1] >> 4) & 0xf;
> swapped_keys[1] = (swap_table[nibl] << 4) | swap_table[nibh];
> nibl = key[2] & 0xf;
> nibh = (key[2] >> 4) & 0xf;
> swapped_keys[2] = (swap_table[nibl] << 4) | swap_table[nibh];
> swapped_keys[3] = key[3];
> swapped_keys[4] = key[4];
> *event = (swapped_keys[1] << 8) + (swapped_keys[2]);
> *state = REMOTE_KEY_PRESSED;
> deb_info("swapped_key: %x %x %x %x %x event:%d\n",swapped_keys[0],
> swapped_keys[1],swapped_keys[2],swapped_keys[3],swapped_keys[4], *event);
> break;
>
> case 0x02:
> *state = REMOTE_KEY_REPEAT;
> break;
> default:
> deb_info("KB: unkown type of remote status: %d\n",key[0]);
> break;
> }
> }
Index: dvb-usb-remote.c
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c,v
retrieving revision 1.11
diff -r1.11 dvb-usb-remote.c
106,107c106,107
< d->rc_input_dev->keycodesize = sizeof(unsigned char);
< d->rc_input_dev->keycodemax = KEY_MAX;
---
> d->rc_input_dev->keycodesize = sizeof(unsigned short);
> d->rc_input_dev->keycodemax = 0xffff; //KEY_MAX;
113,114c113,117
< for (i = 0; i < d->props.rc_key_map_size; i++) {
< deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
---
> // for (i = 0; i < d->props.rc_key_map_size; i++) {
> // deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
> // set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit);
> // }
> for (i = 0; i < 512; i++)
116d118
< }
-- RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/dvb-usb/dtt200u.c,v
retrieving revision 1.20
diff -r1.20 dtt200u.c
83d82
< dvb_usb_nec_rc_key_to_event(d,key,event,state);
85a85,120
> if (key[1] == 0x80) {
> dvb_usb_nec_rc_key_to_event(d,key,event,state);
> } else {
> u8 swapped_keys[5];
> u8 swap_table[] = {0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
> u8 nibl, nibh;
> *event = 0;
> *state = REMOTE_NO_KEY_PRESSED;
>
> switch(key[0]) {
> case 0x00:
> break;
> case 0x01:
> swapped_keys[0] = key[0];
> nibl = key[1] & 0xf;
> nibh = (key[1] >> 4) & 0xf;
> swapped_keys[1] = (swap_table[nibl] << 4) | swap_table[nibh];
> nibl = key[2] & 0xf;
> nibh = (key[2] >> 4) & 0xf;
> swapped_keys[2] = (swap_table[nibl] << 4) | swap_table[nibh];
> swapped_keys[3] = key[3];
> swapped_keys[4] = key[4];
> *event = (swapped_keys[1] << 8) + (swapped_keys[2]);
> *state = REMOTE_KEY_PRESSED;
> deb_info("swapped_key: %x %x %x %x %x event:%d\n",swapped_keys[0],
> swapped_keys[1],swapped_keys[2],swapped_keys[3],swapped_keys[4], *event);
> break;
>
> case 0x02:
> *state = REMOTE_KEY_REPEAT;
> break;
> default:
> deb_info("KB: unkown type of remote status: %d\n",key[0]);
> break;
> }
> }
Index: dvb-usb-remote.c
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c,v
retrieving revision 1.11
diff -r1.11 dvb-usb-remote.c
106,107c106,107
< d->rc_input_dev->keycodesize = sizeof(unsigned char);
< d->rc_input_dev->keycodemax = KEY_MAX;
---
> d->rc_input_dev->keycodesize = sizeof(unsigned short);
> d->rc_input_dev->keycodemax = 0xffff; //KEY_MAX;
113,114c113,117
< for (i = 0; i < d->props.rc_key_map_size; i++) {
< deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
---
> // for (i = 0; i < d->props.rc_key_map_size; i++) {
> // deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
> // set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit);
> // }
> for (i = 0; i < 512; i++)
116d118
< }
Keith Bannister
_______________________________________________ linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb