[linux-dvb] Re: Using the Freecom DVB-T stick remote control

Keith Bannister keith.bannister at gmail.com
Wed Feb 8 20:47:10 CET 2006


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.




Index: dtt200u.c
============================== =====================================
RCS file:
retrieving revision 1.20
diff -r1.20 dtt200u.c
<       dvb_usb_nec_rc_key_to_event(d,key,event,state);
>       if (key[1] == 0x80) {
>               dvb_usb_nec_rc_key_to_event(d,key,event,state);
>       } else {
>               u8 swapped_keys[5];
>               u8 swap_table[] =
>               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) |
>                       nibl = key[2] & 0xf;
>                       nibh = (key[2] >> 4) & 0xf;
>                       swapped_keys[2] = (swap_table[nibl] << 4) |
>                       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
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:
>                       break;
>               }
>       }
Index: dvb-usb-remote.c
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/dvb-usb/dvb-
retrieving revision 1.11
diff -r1.11 dvb-usb-remote.c
<       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;
<       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,
>       //      }
>       for (i = 0; i < 512; i++)
<       }

Keith Bannister
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.linuxtv.org/pipermail/linux-dvb/attachments/20060208/0146cd4f/attachment-0001.htm

More information about the linux-dvb mailing list