diff options
author | Patrick Boettcher <devnull@localhost> | 2005-04-17 18:08:14 +0000 |
---|---|---|
committer | Patrick Boettcher <devnull@localhost> | 2005-04-17 18:08:14 +0000 |
commit | 257c0fe84d1f6bb41efff21aec43f4153f9d26cb (patch) | |
tree | 198b003e0e46f6a43effe8ed6f8375a7a07d1c6c /linux/drivers | |
parent | 4e4da24aa36487071bd874fc63d387258299ceb0 (diff) | |
download | mediapointer-dvb-s2-257c0fe84d1f6bb41efff21aec43f4153f9d26cb.tar.gz mediapointer-dvb-s2-257c0fe84d1f6bb41efff21aec43f4153f9d26cb.tar.bz2 |
enabled remote controls again
nova-t has now real RC5 keys :)
Diffstat (limited to 'linux/drivers')
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dibusb-common.c | 114 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dibusb-mb.c | 12 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dibusb-mc.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dibusb.h | 13 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dtt200u.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 17 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c | 119 |
7 files changed, 248 insertions, 33 deletions
diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb-common.c b/linux/drivers/media/dvb/dvb-usb/dibusb-common.c index fdec9e459..486548a82 100644 --- a/linux/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/linux/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -86,24 +86,6 @@ int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff) } EXPORT_SYMBOL(dibusb2_0_power_ctrl); -int dibusb_rc_init(struct dvb_usb_device *d) -{ - return 0; -} -EXPORT_SYMBOL(dibusb_rc_init); - -int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE; - dvb_usb_generic_rw(d,&cmd,1,key,5); -/* dvb_usb_nec_rc_key_to_event(d,dtt200u_rc_keys,sizeof(dtt200u_rc_keys)/sizeof(struct dvb_usb_nec_rc_key), - key,event,state);*/ - if (key[0] != 0) - deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); - return 0; -} -EXPORT_SYMBOL(dibusb_rc_query); - static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { @@ -250,3 +232,99 @@ int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) return 0; } EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); + +/* + * common remote control stuff + */ + +static struct dvb_usb_nec_rc_key dibusb_rc_keys[] = { + /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ + { 0x00, 0xff, 0x16, KEY_POWER }, + { 0x00, 0xff, 0x10, KEY_MUTE }, + { 0x00, 0xff, 0x03, KEY_1 }, + { 0x00, 0xff, 0x01, KEY_2 }, + { 0x00, 0xff, 0x06, KEY_3 }, + { 0x00, 0xff, 0x09, KEY_4 }, + { 0x00, 0xff, 0x1d, KEY_5 }, + { 0x00, 0xff, 0x1f, KEY_6 }, + { 0x00, 0xff, 0x0d, KEY_7 }, + { 0x00, 0xff, 0x19, KEY_8 }, + { 0x00, 0xff, 0x1b, KEY_9 }, + { 0x00, 0xff, 0x15, KEY_0 }, + { 0x00, 0xff, 0x05, KEY_CHANNELUP }, + { 0x00, 0xff, 0x02, KEY_CHANNELDOWN }, + { 0x00, 0xff, 0x1e, KEY_VOLUMEUP }, + { 0x00, 0xff, 0x0a, KEY_VOLUMEDOWN }, + { 0x00, 0xff, 0x11, KEY_RECORD }, + { 0x00, 0xff, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */ + { 0x00, 0xff, 0x14, KEY_PLAY }, + { 0x00, 0xff, 0x1a, KEY_STOP }, + { 0x00, 0xff, 0x40, KEY_REWIND }, + { 0x00, 0xff, 0x12, KEY_FASTFORWARD }, + { 0x00, 0xff, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */ + { 0x00, 0xff, 0x4c, KEY_PAUSE }, + { 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */ + { 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ + /* additional keys TwinHan VisionPlus, the Artec seemingly not have */ + { 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */ + { 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */ + { 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */ + { 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */ + { 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */ + { 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */ + /* Key codes for the KWorld/ADSTech/JetWay remote. */ + { 0x86, 0x6b, 0x12, KEY_POWER }, + { 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */ + { 0x86, 0x6b, 0x0c, KEY_UNKNOWN }, /* scan */ + { 0x86, 0x6b, 0x0b, KEY_EPG }, + { 0x86, 0x6b, 0x10, KEY_MUTE }, + { 0x86, 0x6b, 0x01, KEY_1 }, + { 0x86, 0x6b, 0x02, KEY_2 }, + { 0x86, 0x6b, 0x03, KEY_3 }, + { 0x86, 0x6b, 0x04, KEY_4 }, + { 0x86, 0x6b, 0x05, KEY_5 }, + { 0x86, 0x6b, 0x06, KEY_6 }, + { 0x86, 0x6b, 0x07, KEY_7 }, + { 0x86, 0x6b, 0x08, KEY_8 }, + { 0x86, 0x6b, 0x09, KEY_9 }, + { 0x86, 0x6b, 0x0a, KEY_0 }, + { 0x86, 0x6b, 0x18, KEY_ZOOM }, + { 0x86, 0x6b, 0x1c, KEY_UNKNOWN }, /* preview */ + { 0x86, 0x6b, 0x13, KEY_UNKNOWN }, /* snap */ + { 0x86, 0x6b, 0x00, KEY_UNDO }, + { 0x86, 0x6b, 0x1d, KEY_RECORD }, + { 0x86, 0x6b, 0x0d, KEY_STOP }, + { 0x86, 0x6b, 0x0e, KEY_PAUSE }, + { 0x86, 0x6b, 0x16, KEY_PLAY }, + { 0x86, 0x6b, 0x11, KEY_BACK }, + { 0x86, 0x6b, 0x19, KEY_FORWARD }, + { 0x86, 0x6b, 0x14, KEY_UNKNOWN }, /* pip */ + { 0x86, 0x6b, 0x15, KEY_ESC }, + { 0x86, 0x6b, 0x1a, KEY_UP }, + { 0x86, 0x6b, 0x1e, KEY_DOWN }, + { 0x86, 0x6b, 0x1f, KEY_LEFT }, + { 0x86, 0x6b, 0x1b, KEY_RIGHT }, +}; + + +int dibusb_rc_init(struct dvb_usb_device *d) +{ + int i; + for (i = 0; i < sizeof(dibusb_rc_keys)/sizeof(struct dvb_usb_nec_rc_key); i++) + set_bit(dibusb_rc_keys[i].key, d->rc_input_dev.keybit); + return 0; +} +EXPORT_SYMBOL(dibusb_rc_init); + +int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE; + dvb_usb_generic_rw(d,&cmd,1,key,5); + dvb_usb_nec_rc_key_to_event(d,dibusb_rc_keys,sizeof(dibusb_rc_keys)/sizeof(struct dvb_usb_nec_rc_key), + key,event,state); + if (key[0] != 0) + deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); + return 0; +} +EXPORT_SYMBOL(dibusb_rc_query); + diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb-mb.c b/linux/drivers/media/dvb/dvb-usb/dibusb-mb.c index b7499cb76..135f4cd72 100644 --- a/linux/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/linux/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -133,8 +133,8 @@ static struct dvb_usb_properties dibusb1_1_properties = { .read_mac_address = NULL, .rc_interval = DEFAULT_RC_INTERVAL, - .init_rc = NULL, //dibusb_rc_init, - .query_rc = NULL, //dibusb_rc_query, + .init_rc = dibusb_rc_init, + .query_rc = dibusb_rc_query, .i2c_algo = &dibusb_i2c_algo, @@ -205,8 +205,8 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { .read_mac_address = NULL, .rc_interval = DEFAULT_RC_INTERVAL, - .init_rc = NULL, //dibusb_rc_init, - .query_rc = NULL, //dibusb_rc_query, + .init_rc = dibusb_rc_init, + .query_rc = dibusb_rc_query, .i2c_algo = &dibusb_i2c_algo, @@ -249,8 +249,8 @@ static struct dvb_usb_properties dibusb2_0b_properties = { .read_mac_address = NULL, .rc_interval = DEFAULT_RC_INTERVAL, - .init_rc = NULL, //dibusb_rc_init, - .query_rc = NULL, // dibusb_rc_query, + .init_rc = dibusb_rc_init, + .query_rc = dibusb_rc_query, .i2c_algo = &dibusb_i2c_algo, diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb-mc.c b/linux/drivers/media/dvb/dvb-usb/dibusb-mc.c index a4fc01557..fbf22cca5 100644 --- a/linux/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ b/linux/drivers/media/dvb/dvb-usb/dibusb-mc.c @@ -49,8 +49,8 @@ static struct dvb_usb_properties dibusb_mc_properties = { .read_mac_address = NULL, .rc_interval = DEFAULT_RC_INTERVAL, - .init_rc = NULL, //dibusb_rc_init, - .query_rc = NULL, //dibusb_rc_query, + .init_rc = dibusb_rc_init, + .query_rc = dibusb_rc_query, .i2c_algo = &dibusb_i2c_algo, diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb.h b/linux/drivers/media/dvb/dvb-usb/dibusb.h index f3ee7285c..40a36e2e5 100644 --- a/linux/drivers/media/dvb/dvb-usb/dibusb.h +++ b/linux/drivers/media/dvb/dvb-usb/dibusb.h @@ -94,13 +94,14 @@ #define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01 #define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02 -// #define DEFAULT_RC_INTERVAL 100 -#define DEFAULT_RC_INTERVAL 100000 - struct dibusb_state { struct dib_fe_xfer_ops ops; struct dvb_pll_desc *pll_desc; u8 pll_addr; + + /* for RC5 remote control */ + int old_toggle; + int last_repeat_count; }; extern struct i2c_algorithm dibusb_i2c_algo; @@ -119,4 +120,10 @@ extern int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff); extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff); extern int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff); +#define DEFAULT_RC_INTERVAL 150 +//#define DEFAULT_RC_INTERVAL 100000 + +extern int dibusb_rc_init(struct dvb_usb_device *d); +extern int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state); + #endif diff --git a/linux/drivers/media/dvb/dvb-usb/dtt200u.c b/linux/drivers/media/dvb/dvb-usb/dtt200u.c index 8827ddb40..ebe6b4ea8 100644 --- a/linux/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/linux/drivers/media/dvb/dvb-usb/dtt200u.c @@ -43,7 +43,7 @@ static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int /* remote control */ /* key list for the tiny remote control (Yakumo, don't know about the others) */ -struct dvb_usb_nec_rc_key dtt200u_rc_keys[] = { +static struct dvb_usb_nec_rc_key dtt200u_rc_keys[] = { { 0x80, 0x7f, 0x01, KEY_MUTE }, { 0x80, 0x7f, 0x02, KEY_CHANNELDOWN }, { 0x80, 0x7f, 0x03, KEY_VOLUMEDOWN }, diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 811af315e..7908b4de6 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -26,6 +26,22 @@ static void dvb_usb_read_remote_control(void *data) goto schedule; } + + switch (state) { + case REMOTE_NO_KEY_PRESSED: + break; + case REMOTE_KEY_PRESSED: + d->last_event = event; + case REMOTE_KEY_REPEAT: + input_event(&d->rc_input_dev, EV_KEY, event, 1); + input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); + input_sync(&d->rc_input_dev); + break; + default: + break; + } + +/* improved repeat handling ??? switch (state) { case REMOTE_NO_KEY_PRESSED: deb_rc("NO KEY PRESSED\n"); @@ -58,6 +74,7 @@ static void dvb_usb_read_remote_control(void *data) default: break; } +*/ schedule: schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); diff --git a/linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c index 7e15ab82a..62355e714 100644 --- a/linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -11,6 +11,119 @@ */ #include "dibusb.h" +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (|-able))." DVB_USB_DEBUG_STATUS); + +#define deb_rc(args...) dprintk(debug,0x01,args) + + +/* Hauppauge NOVA-T USB2 keys */ +static const struct { u8 raw; uint32_t key; } haupp_rc_keys [] = { + { 0x00, KEY_0 }, + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + { 0x0a, KEY_KPASTERISK }, + { 0x0b, KEY_RED }, + { 0x0c, KEY_RADIO }, + { 0x0d, KEY_MENU }, + { 0x0e, KEY_GRAVE }, /* # */ + { 0x0f, KEY_MUTE }, + { 0x10, KEY_VOLUMEUP }, + { 0x11, KEY_VOLUMEDOWN }, + { 0x12, KEY_CHANNEL }, + { 0x14, KEY_UP }, + { 0x15, KEY_DOWN }, + { 0x16, KEY_LEFT }, + { 0x17, KEY_RIGHT }, + { 0x18, KEY_VIDEO }, + { 0x19, KEY_AUDIO }, + { 0x1a, KEY_MEDIA }, + { 0x1b, KEY_EPG }, + { 0x1c, KEY_TV }, + { 0x1e, KEY_NEXT }, + { 0x1f, KEY_BACK }, + { 0x20, KEY_CHANNELUP }, + { 0x21, KEY_CHANNELDOWN }, + { 0x24, KEY_LAST }, /* Skip backwards */ + { 0x25, KEY_OK }, + { 0x29, KEY_BLUE}, + { 0x2e, KEY_GREEN }, + { 0x30, KEY_PAUSE }, + { 0x32, KEY_REWIND }, + { 0x34, KEY_FASTFORWARD }, + { 0x35, KEY_PLAY }, + { 0x36, KEY_STOP }, + { 0x37, KEY_RECORD }, + { 0x38, KEY_YELLOW }, + { 0x3b, KEY_GOTO }, + { 0x3d, KEY_POWER }, +}; + +static int count; +static int nova_t_rc_init(struct dvb_usb_device *d) +{ + int i; + for (i=0; i<sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) + set_bit(haupp_rc_keys[i].key, d->rc_input_dev.keybit); + return 0; +} + + +/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key + * is delivered. No workaround yet. + */ +static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle; + u16 raw; + int i; + struct dibusb_state *st = d->priv; + + dvb_usb_generic_rw(d,cmd,2,key,5); + + *state = REMOTE_NO_KEY_PRESSED; + switch (key[0]) { + case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED: + raw = ((key[1] << 8) | key[2]) >> 3; + toggle = !!(raw & 0x800); + data = raw & 0x3f; + + deb_rc("%8d: raw key code 0x%02x, 0x%02x, 0x%02x to %02x toggle: %d\n",count++,key[1],key[2],key[3],data,toggle); + + for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) { + if (haupp_rc_keys[i].raw == data) { + *event = haupp_rc_keys[i].key; + *state = REMOTE_KEY_PRESSED; + if (st->old_toggle == toggle) { + if (st->last_repeat_count++ < 2) + *state = REMOTE_NO_KEY_PRESSED; + } else { + st->last_repeat_count = 0; + st->old_toggle = toggle; + } + + break; + } + } + + break; + case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY: + default: + break; + } + + + return 0; +} + /* USB Driver stuff */ static struct dvb_usb_properties nova_t_properties; @@ -44,9 +157,9 @@ static struct dvb_usb_properties nova_t_properties = { .tuner_attach = dibusb_dib3000mc_tuner_attach, .read_mac_address = NULL, - .rc_interval = DEFAULT_RC_INTERVAL, - .init_rc = NULL, /* TODO */ - .query_rc = NULL, + .rc_interval = 100, + .init_rc = nova_t_rc_init, + .query_rc = nova_t_rc_query, .i2c_algo = &dibusb_i2c_algo, |