diff options
Diffstat (limited to 'linux/drivers/media/dvb/dibusb/dvb-dibusb-remote.c')
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb-remote.c | 150 |
1 files changed, 122 insertions, 28 deletions
diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb-remote.c b/linux/drivers/media/dvb/dibusb/dvb-dibusb-remote.c index b3b6f2413..c73b3f9c6 100644 --- a/linux/drivers/media/dvb/dibusb/dvb-dibusb-remote.c +++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb-remote.c @@ -13,7 +13,7 @@ /* Table to map raw key codes to key events. This should not be hard-wired into the kernel. */ -static const struct { u8 c0, c1, c2; uint32_t key; } rc_keys [] = +static const struct { u8 c0, c1, c2; uint32_t key; } nec_rc_keys [] = { /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ { 0x00, 0xff, 0x16, KEY_POWER }, @@ -83,18 +83,58 @@ static const struct { u8 c0, c1, c2; uint32_t key; } rc_keys [] = { 0x86, 0x6b, 0x1b, KEY_RIGHT }, }; -/* - * Read the remote control and feed the appropriate event. - * NEC protocol is used for remote controls - */ -static int dibusb_read_remote_control(struct usb_dibusb *dib) +/* Hauppauge NOVA-T USB2 keys */ +static const struct { u16 raw; uint32_t key; } haupp_rc_keys [] = { + { 0xddf, KEY_GOTO }, + { 0xdef, KEY_POWER }, + { 0xce7, KEY_TV }, + { 0xcc7, KEY_VIDEO }, + { 0xccf, KEY_AUDIO }, + { 0x32f, KEY_MEDIA }, + { 0xcdf, KEY_EPG }, + { 0xca7, KEY_UP }, + { 0xc67, KEY_RADIO }, + { 0xcb7, KEY_LEFT }, + { 0xd2f, KEY_OK }, + { 0xcbf, KEY_RIGHT }, + { 0xcff, KEY_BACK }, + { 0xcaf, KEY_DOWN }, + { 0xc67, KEY_MENU }, + { 0xc87, KEY_VOLUMEUP }, + { 0xc8f, KEY_VOLUMEDOWN }, + { 0xc97, KEY_CHANNEL }, + { 0xc7f, KEY_MUTE }, + { 0xd07, KEY_CHANNELUP }, + { 0xd0f, KEY_CHANNELDOWN }, + { 0xdbf, KEY_RECORD }, + { 0xdb7, KEY_STOP }, + { 0xd97, KEY_REWIND }, + { 0xdaf, KEY_PLAY }, + { 0xda7, KEY_FASTFORWARD }, + { 0xd27, KEY_LAST }, /* Skip backwards */ + { 0xd87, KEY_PAUSE }, + { 0xcf7, KEY_NEXT }, + { 0xc07, KEY_0 }, + { 0xc0f, KEY_1 }, + { 0xc17, KEY_2 }, + { 0xc1f, KEY_3 }, + { 0xc27, KEY_4 }, + { 0xc2f, KEY_5 }, + { 0xc37, KEY_6 }, + { 0xc3f, KEY_7 }, + { 0xc47, KEY_8 }, + { 0xc4f, KEY_9 }, + { 0xc57, KEY_KPASTERISK }, + { 0xc77, KEY_GRAVE }, /* # */ + { 0xc5f, KEY_RED }, + { 0xd77, KEY_GREEN }, + { 0xdc7, KEY_YELLOW }, + { 0xd4f, KEY_BLUE}, +}; + +static int dibusb_key2event_nec(struct usb_dibusb *dib,u8 rb[5]) { - u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5]; - int ret; int i; - if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5))) - return ret; - switch (rb[0]) { case DIBUSB_RC_NEC_KEY_PRESSED: /* rb[1-3] is the actual key, rb[4] is a checksum */ @@ -107,33 +147,86 @@ static int dibusb_read_remote_control(struct usb_dibusb *dib) } /* See if we can match the raw key code. */ - for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++) { - if (rc_keys[i].c0 == rb[1] && - rc_keys[i].c1 == rb[2] && - rc_keys[i].c2 == rb[3]) { - dib->rc_input_event = rc_keys[i].key; - deb_rc("Translated key 0x%04x\n", dib->rc_input_event); - /* Signal down and up events for this key. */ - input_report_key(&dib->rc_input_dev, dib->rc_input_event, 1); - input_report_key(&dib->rc_input_dev, dib->rc_input_event, 0); - input_sync(&dib->rc_input_dev); - break; + for (i = 0; i < sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) { + if (nec_rc_keys[i].c0 == rb[1] && + nec_rc_keys[i].c1 == rb[2] && + nec_rc_keys[i].c2 == rb[3]) { + return nec_rc_keys[i].key; } } break; - case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */ - break; case DIBUSB_RC_NEC_KEY_REPEATED: /* rb[1]..rb[4] are always zero.*/ /* Repeats often seem to occur so for the moment just ignore this. */ deb_rc("Key repeat\n"); break; + case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */ default: break; } return 0; } +static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[4]) +{ + u16 raw; + int i; + switch (rb[0]) { + case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED: + raw = ((rb[1] & 0x0f) << 8) | rb[2]; + +/* if (rb[1] & 0x40) + deb_rc("first key press\n"); + else + deb_rc("key repeat\n");*/ + + deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x\n",rb[1],rb[2],rb[3],raw); + for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) { + if (haupp_rc_keys[i].raw == raw) + return haupp_rc_keys[i].key; + } + + break; + case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY: + default: + break; + } + return 0; +} + +/* + * Read the remote control and feed the appropriate event. + * NEC protocol is used for remote controls + */ +static int dibusb_read_remote_control(struct usb_dibusb *dib) +{ + u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5]; + int ret,event = 0; + + if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5))) + return ret; + + switch (dib->dibdev->dev_cl->remote_type) { + case DIBUSB_RC_NEC_PROTOCOL: + event = dibusb_key2event_nec(dib,rb); + break; + case DIBUSB_RC_HAUPPAUGE_PROTO: + event = dibusb_key2event_hauppauge(dib,rb); + default: + break; + } + + if (event > 0) { + deb_rc("Translated key 0x%04x\n",event); + + /* Signal down and up events for this key. */ + input_report_key(&dib->rc_input_dev, event, 1); + input_report_key(&dib->rc_input_dev, event, 0); + input_sync(&dib->rc_input_dev); + } + return 0; +} + /* Remote-control poll function - called every dib->rc_query_interval ms to see whether the remote control has received anything. */ static void dibusb_remote_query(void *data) @@ -161,13 +254,14 @@ int dibusb_remote_init(struct usb_dibusb *dib) dib->rc_input_dev.keycodemax = KEY_MAX; dib->rc_input_dev.name = DRIVER_DESC " remote control"; - for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i++) - set_bit(rc_keys[i].key, dib->rc_input_dev.keybit); + for (i=0; i<sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) + set_bit(haupp_rc_keys[i].key, dib->rc_input_dev.keybit); + + for (i=0; i<sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) + set_bit(haupp_rc_keys[i].key, dib->rc_input_dev.keybit); input_register_device(&dib->rc_input_dev); - dib->rc_input_event = KEY_MAX; - INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib); /* Start the remote-control polling. */ |