diff options
author | Patrick Boettcher <devnull@localhost> | 2005-02-19 09:13:58 +0000 |
---|---|---|
committer | Patrick Boettcher <devnull@localhost> | 2005-02-19 09:13:58 +0000 |
commit | fa6b156a6e41359640346fb80ac0a7119052a32c (patch) | |
tree | 7a97f9eeb2c4d64240074a30d8e4c77b9639bb77 /linux/drivers/media/dvb | |
parent | 2e6008d1229ef6fd097931b3377f4e14ed21b773 (diff) | |
download | mediapointer-dvb-s2-fa6b156a6e41359640346fb80ac0a7119052a32c.tar.gz mediapointer-dvb-s2-fa6b156a6e41359640346fb80ac0a7119052a32c.tar.bz2 |
- added native nova-t support, since only the nova-t firmware works with the nova-t remote control
- added keys statically (maybe we should find something to sort this out... cinergyt2 is doing the same)
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb-core.c | 10 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb-remote.c | 150 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb-usb.c | 12 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb.h | 9 |
5 files changed, 150 insertions, 35 deletions
diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb-core.c b/linux/drivers/media/dvb/dibusb/dvb-dibusb-core.c index d53270003..9e0d3e6e4 100644 --- a/linux/drivers/media/dvb/dibusb/dvb-dibusb-core.c +++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb-core.c @@ -245,6 +245,14 @@ static struct dibusb_device_class dibusb_device_classes[] = { &dibusb_demod[DIBUSB_DIB3000MB], &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON], }, + { NOVAT_USB2,&dibusb_usb_ctrl[2], + "dvb-dibusb-nova-t-1.fw", + 0x01, 0x06, + 7, 4096, + DIBUSB_RC_HAUPPAUGE_PROTO, + &dibusb_demod[DIBUSB_DIB3000MC], + &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5], + }, }; static struct dibusb_usb_device dibusb_devices[] = { @@ -304,7 +312,7 @@ static struct dibusb_usb_device dibusb_devices[] = { { NULL }, }, { "Hauppauge WinTV NOVA-T USB2", - &dibusb_device_classes[DIBUSB2_0], + &dibusb_device_classes[NOVAT_USB2], { &dib_table[30], NULL }, { &dib_table[31], NULL }, }, diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c b/linux/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c index 972548a0c..c8a0efaf4 100644 --- a/linux/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c +++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c @@ -30,11 +30,13 @@ int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibde int ret = 0,i; if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) { - err("did not find a valid firmware file. (%s) " + err("did not find the firmware file. (%s) " "Please see linux/Documentation/dvb/ for more details on firmware-problems.", dibdev->dev_cl->firmware); return ret; } + + info("downloading firmware from file '%s'.",dibdev->dev_cl->firmware); p = kmalloc(fw->size,GFP_KERNEL); if (p != NULL) { 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. */ diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/linux/drivers/media/dvb/dibusb/dvb-dibusb-usb.c index 1cdc596f3..a2f4c3172 100644 --- a/linux/drivers/media/dvb/dibusb/dvb-dibusb-usb.c +++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb-usb.c @@ -117,9 +117,14 @@ int dibusb_hw_sleep(struct dvb_frontend *fe) u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP }; deb_info("dibusb-device is going to bed.\n"); /* workaround, something is wrong, when dibusb 1.1 device are going to bed too late */ - if (dib->dibdev->dev_cl->id != DIBUSB1_1) - dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1); - + switch (dib->dibdev->dev_cl->id) { + case DIBUSB1_1: + case NOVAT_USB2: + break; + default: + dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1); + break; + } if (dib->fe_sleep) return dib->fe_sleep(fe); @@ -137,6 +142,7 @@ int dibusb_streaming(struct usb_dibusb *dib,int onoff) switch (dib->dibdev->dev_cl->id) { case DIBUSB2_0: case DIBUSB2_0B: + case NOVAT_USB2: if (onoff) return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0); else diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb.h b/linux/drivers/media/dvb/dibusb/dvb-dibusb.h index 102d5a5b4..8c01bc785 100644 --- a/linux/drivers/media/dvb/dibusb/dvb-dibusb.h +++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb.h @@ -73,6 +73,7 @@ typedef enum { DIBUSB2_0, UMT2_0, DIBUSB2_0B, + NOVAT_USB2, } dibusb_class_t; typedef enum { @@ -90,7 +91,8 @@ typedef enum { typedef enum { DIBUSB_RC_NO = 0, - DIBUSB_RC_NEC_PROTOCOL = 1, + DIBUSB_RC_NEC_PROTOCOL, + DIBUSB_RC_HAUPPAUGE_PROTO, } dibusb_remote_t; struct dibusb_tuner { @@ -188,7 +190,6 @@ struct usb_dibusb { /* remote control */ struct input_dev rc_input_dev; struct work_struct rc_query_work; - int rc_input_event; /* module parameters */ int pid_parse; @@ -270,6 +271,10 @@ int dibusb_urb_exit(struct usb_dibusb *); #define DIBUSB_RC_NEC_KEY_PRESSED 0x01 #define DIBUSB_RC_NEC_KEY_REPEATED 0x02 +/* additional status values for Hauppauge Remote Control Protocol */ +#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01 +#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03 + /* streaming mode: * bulk write: 0x05 mode_byte * |