summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
authorPatrick Boettcher <devnull@localhost>2005-04-02 14:42:56 +0000
committerPatrick Boettcher <devnull@localhost>2005-04-02 14:42:56 +0000
commit861784e76607eafbfb13c6ce1e3b87204b3978da (patch)
tree892e736a8c25848d2ccb0a3a8a46f6b92693ec56 /linux/drivers/media
parent302481a5ffb8737f5fcb821ee79576637aa85055 (diff)
downloadmediapointer-dvb-s2-861784e76607eafbfb13c6ce1e3b87204b3978da.tar.gz
mediapointer-dvb-s2-861784e76607eafbfb13c6ce1e3b87204b3978da.tar.bz2
re-enabled and improved commonly used remote control code for dvb-usb
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Makefile2
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dtt200u.c30
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h15
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c6
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c374
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb.h36
-rw-r--r--linux/drivers/media/dvb/dvb-usb/vp7045.c56
-rw-r--r--linux/drivers/media/dvb/dvb-usb/vp7045.h1
8 files changed, 206 insertions, 314 deletions
diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile
index 76df16795..15c63d4f2 100644
--- a/linux/drivers/media/dvb/dvb-usb/Makefile
+++ b/linux/drivers/media/dvb/dvb-usb/Makefile
@@ -1,4 +1,4 @@
-dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o
+dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o
obj-$(CONFIG_DVB_USB) += dvb-usb.o
dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
diff --git a/linux/drivers/media/dvb/dvb-usb/dtt200u.c b/linux/drivers/media/dvb/dvb-usb/dtt200u.c
index 28cb6863b..12abff048 100644
--- a/linux/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/linux/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -41,11 +41,29 @@ static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int
return dvb_usb_generic_write(d,b_pid,4);
}
-static int dtt200u_rc_query(struct dvb_usb_device *d, u8 *key_buf, int *state)
+/* remote control */
+
+struct dvb_usb_nec_rc_key dtt200u_rc_keys[] = {
+ { 0x00, 0xff, 0x03, KEY_1 },
+ { 0x00, 0xff, 0x01, KEY_2 },
+ { 0x00, 0xff, 0x06, KEY_3 },
+};
+
+static int dtt200u_rc_init(struct dvb_usb_device *d)
+{
+ int i;
+ for (i = 0; i < sizeof(dtt200u_rc_keys)/sizeof(struct dvb_usb_nec_rc_key); i++)
+ set_bit(dtt200u_rc_keys[i].key, d->rc_input_dev.keybit);
+ return 0;
+}
+
+static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
- deb_info("remote query\n");
- *state = REMOTE_KEY_NO;
- return 0; //dtt200u_usb_op(d,RC_VAL_READ,&v,1,NULL,0,20);
+ u8 key[5],cmd = GET_RC_KEY;
+ 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);
+ return 0;
}
static int dtt200u_frontend_attach(struct dvb_usb_device *d)
@@ -81,9 +99,9 @@ static struct dvb_usb_properties dtt200u_properties = {
.power_ctrl = NULL,
.frontend_attach = dtt200u_frontend_attach,
- .rc_interval = 400,
- .remote_protocol = USB_REMOTE_PROTO_NEC,
+ .rc_interval = 200,
.query_rc = dtt200u_rc_query,
+ .init_rc = dtt200u_rc_init,
.generic_bulk_ctrl_endpoint = 0x01,
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h
index e6e304851..2ea1f6ef7 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -28,13 +28,16 @@ extern int dvb_usb_urb_kill(struct dvb_usb_device *);
extern int dvb_usb_urb_init(struct dvb_usb_device *);
extern int dvb_usb_urb_exit(struct dvb_usb_device *);
-extern int dvb_usb_i2c_init(struct dvb_usb_device *d);
-extern int dvb_usb_i2c_exit(struct dvb_usb_device *d);
+extern int dvb_usb_i2c_init(struct dvb_usb_device *);
+extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
-extern int dvb_usb_dvb_init(struct dvb_usb_device *d);
-extern int dvb_usb_dvb_exit(struct dvb_usb_device *d);
+extern int dvb_usb_dvb_init(struct dvb_usb_device *);
+extern int dvb_usb_dvb_exit(struct dvb_usb_device *);
-extern int dvb_usb_fe_init(struct dvb_usb_device *d);
-extern int dvb_usb_fe_exit(struct dvb_usb_device *d);
+extern int dvb_usb_fe_init(struct dvb_usb_device *);
+extern int dvb_usb_fe_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_remote_init(struct dvb_usb_device *);
+extern int dvb_usb_remote_exit(struct dvb_usb_device *);
#endif
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 204b591d3..d4cea6e30 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -22,7 +22,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,alot=4,ts=8,err=16,r
int dvb_usb_exit(struct dvb_usb_device *d)
{
deb_info("init_state before exiting everything: %x\n",d->init_state);
-// dvb_usb_remote_exit(d);
+ dvb_usb_remote_exit(d);
dvb_usb_fe_exit(d);
dvb_usb_i2c_exit(d);
dvb_usb_dvb_exit(d);
@@ -62,8 +62,8 @@ static int dvb_usb_init(struct dvb_usb_device *d)
return ret;
}
-/* if ((ret = dvb_usb_remote_init(d)))
- err("could not initialize remote control.");*/
+ if ((ret = dvb_usb_remote_init(d)))
+ err("could not initialize remote control.");
return 0;
}
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 f461c30f1..811af315e 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -4,316 +4,146 @@
* see dvb-usb-init.c for copyright information.
*
* This file contains functions for initializing the the input-device and for handling remote-control-queries.
- *
- * TODO: this part is not compiling yet, some adaptions will be necessary.
*/
-#include "dvb-usb.h"
+#include "dvb-usb-common.h"
-/* 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; } nec_rc_keys [] =
+/* Remote-control poll function - called every dib->rc_query_interval ms to see
+ * whether the remote control has received anything.
+ *
+ * TODO: Fix the repeat rate of the input device.
+ */
+static void dvb_usb_read_remote_control(void *data)
{
- /* 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 appearantly not has */
- { 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 },
-};
+ struct dvb_usb_device *d = data;
+ u32 event;
+ int state;
-/* 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 },
- { 0xcd7, 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 },
- { 0xc6f, 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},
-};
+ /* TODO: need a lock here. We can simply skip checking for the remote control
+ if we're busy. */
-#define DIBUSB_RC_NEC_EMPTY 0x00
-#define DIBUSB_RC_NEC_KEY_PRESSED 0x01
-#define DIBUSB_RC_NEC_KEY_REPEATED 0x02
-static int dvb_usb_key2event_dibusb_nec(struct dvb_usb *d,u8 rb[5])
-{
- int i;
- switch (rb[0]) {
- case DIBUSB_RC_NEC_KEY_PRESSED:
- /* rb[1-3] is the actual key, rb[4] is a checksum */
- deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
- rb[1], rb[2], rb[3], rb[4]);
+ if (d->props.query_rc(d,&event,&state)) {
+ err("error while querying for an remote control event.");
+ goto schedule;
+ }
- if ((0xff - rb[3]) != rb[4]) {
- deb_rc("remote control checksum failed.\n");
- break;
+ switch (state) {
+ case REMOTE_NO_KEY_PRESSED:
+ deb_rc("NO KEY PRESSED\n");
+ if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+ deb_rc("releasing event %d\n",d->last_event);
+ input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
+ input_sync(&d->rc_input_dev);
}
+ d->last_state = REMOTE_NO_KEY_PRESSED;
+ d->last_event = 0;
+ break;
+ case REMOTE_KEY_PRESSED:
+ deb_rc("KEY PRESSED\n");
+ deb_rc("pressing event %d\n",event);
- /* See if we can match the raw key code. */
- 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]) {
+ input_event(&d->rc_input_dev, EV_KEY, event, 1);
+ input_sync(&d->rc_input_dev);
- dib->last_event = nec_rc_keys[i].key;
- return 1;
- }
- }
+ d->last_event = event;
+ d->last_state = REMOTE_KEY_PRESSED;
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. */
- return 0;
- case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
+ case REMOTE_KEY_REPEAT:
+ deb_rc("KEY_REPEAT\n");
+ if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+ deb_rc("repeating event %d\n",d->last_event);
+ input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
+ input_sync(&d->rc_input_dev);
+ d->last_state = REMOTE_KEY_REPEAT;
+ }
default:
break;
}
- return -1;
+
+schedule:
+ schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
}
-/* additional status values for Hauppauge Remote Control Protocol */
-#define HAUPPAUGE_RC_KEY_PRESSED 0x01
-#define HAUPPAUGE_RC_KEY_EMPTY 0x03
-static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[3])
+int dvb_usb_remote_init(struct dvb_usb_device *d)
{
- u16 raw;
- int i,state;
- switch (rb[0]) {
- case HAUPPAUGE_RC_KEY_PRESSED:
- raw = ((rb[1] & 0x0f) << 8) | rb[2];
+ if (d->props.query_rc == NULL)
+ return 0;
- state = !!(rb[1] & 0x40);
+ /* Initialise the remote-control structures.*/
+ init_input_dev(&d->rc_input_dev);
- deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x state: %d\n",rb[1],rb[2],rb[3],raw,state);
- for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) {
- if (haupp_rc_keys[i].raw == raw) {
- if (dib->last_event == haupp_rc_keys[i].key &&
- dib->last_state == state) {
- deb_rc("key repeat\n");
- return 0;
- } else {
- dib->last_event = haupp_rc_keys[i].key;
- dib->last_state = state;
- return 1;
- }
- }
- }
+ d->rc_input_dev.evbit[0] = BIT(EV_KEY);
+ d->rc_input_dev.keycodesize = sizeof(unsigned char);
+ d->rc_input_dev.keycodemax = KEY_MAX;
+ d->rc_input_dev.name = "Remote control inside an USB DVB receiver";
- break;
- case HAUPPAUGE_RC_KEY_EMPTY:
- default:
- break;
- }
- return -1;
-}
+ /* set the bits for the keys */
+ d->props.init_rc(d);
-/* Read the remote control and feed the appropriate event.
- * NEC protocol is used for remote controls
- */
-static int dvb_usb_read_remote_control(struct usb_dibusb *dib)
-{
- u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5];
- int ret,event = 0;
+ /* Start the remote-control polling. */
+ if (d->props.rc_interval < 40)
+ d->props.rc_interval = 100; /* default */
- if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
- return ret;
+ /* setting these two values to non-zero, we have to manage key repeats */
+ d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
+ d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150;
- 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;
- }
+ input_register_device(&d->rc_input_dev);
- /* key repeat */
- if (event == 0)
- if (++dib->repeat_key_count < dib->rc_key_repeat_count) {
- deb_rc("key repeat dropped. (%d)\n",dib->repeat_key_count);
- event = -1; /* skip this key repeat */
- }
+ INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
- if (event == 1 || event == 0) {
- deb_rc("Translated key 0x%04x\n",event);
+ info("schedule remote query interval to %d msecs.",d->props.rc_interval);
+ schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
- /* Signal down and up events for this key. */
- input_report_key(&dib->rc_input_dev, dib->last_event, 1);
- input_report_key(&dib->rc_input_dev, dib->last_event, 0);
- input_sync(&dib->rc_input_dev);
+ d->init_state |= DVB_USB_STATE_REMOTE;
- if (event == 1)
- dib->repeat_key_count = 0;
- }
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)
+int dvb_usb_remote_exit(struct dvb_usb_device *d)
{
- struct usb_dibusb *dib = (struct usb_dibusb *) data;
- /* TODO: need a lock here. We can simply skip checking for the remote control
- if we're busy. */
- dibusb_read_remote_control(dib);
- schedule_delayed_work(&dib->rc_query_work,
- msecs_to_jiffies(dib->rc_query_interval));
+ if (d->init_state & DVB_USB_STATE_REMOTE) {
+ cancel_delayed_work(&d->rc_query_work);
+ flush_scheduled_work();
+ input_unregister_device(&d->rc_input_dev);
+ }
+ d->init_state &= ~DVB_USB_STATE_REMOTE;
+ return 0;
}
-int dibusb_remote_init(struct usb_dibusb *dib)
+#define DVB_USB_RC_NEC_EMPTY 0x00
+#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
+#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
+int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, struct dvb_usb_nec_rc_key keymap[],int key_count, u8 keybuf[5], u32 *event, int *state)
{
int i;
-
- if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
- return 0;
-
- /* Initialise the remote-control structures.*/
- init_input_dev(&dib->rc_input_dev);
-
- dib->rc_input_dev.evbit[0] = BIT(EV_KEY);
- dib->rc_input_dev.keycodesize = sizeof(unsigned char);
- dib->rc_input_dev.keycodemax = KEY_MAX;
- dib->rc_input_dev.name = DRIVER_DESC " remote control";
-
- switch (dib->dibdev->dev_cl->remote_type) {
- case DIBUSB_RC_NEC_PROTOCOL:
- for (i=0; i<sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++)
- set_bit(nec_rc_keys[i].key, dib->rc_input_dev.keybit);
+ *event = 0;
+ *state = REMOTE_NO_KEY_PRESSED;
+ switch (keybuf[0]) {
+ case DVB_USB_RC_NEC_EMPTY:
+ break;
+ case DVB_USB_RC_NEC_KEY_PRESSED:
+ if ((0xff - keybuf[3]) != keybuf[4]) {
+ deb_err("remote control checksum failed.\n");
+ break;
+ }
+ /* See if we can match the raw key code. */
+ for (i = 0; i < key_count; i++)
+ if (keymap[i].c0 == keybuf[1] &&
+ keymap[i].c1 == keybuf[2] &&
+ keymap[i].c2 == keybuf[3]) {
+ *event = keymap[i].key;
+ *state = REMOTE_KEY_PRESSED;
+ break;
+ }
+ deb_err("key mapping failed - no appropriate key found in keymapping\n");
break;
- case DIBUSB_RC_HAUPPAUGE_PROTO:
- 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);
+ case DVB_USB_RC_NEC_KEY_REPEATED:
+ *state = REMOTE_KEY_REPEAT;
break;
default:
+ deb_err("unkown type of remote status: %d\n",keybuf[0]);
break;
}
-
-
- input_register_device(&dib->rc_input_dev);
-
- INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib);
-
- /* Start the remote-control polling. */
- if (dib->rc_query_interval < 40)
- dib->rc_query_interval = 100; /* default */
-
- info("schedule remote query interval to %d msecs.",dib->rc_query_interval);
- schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(dib->rc_query_interval));
-
- dib->init_state |= DIBUSB_STATE_REMOTE;
-
- return 0;
-}
-
-int dibusb_remote_exit(struct usb_dibusb *dib)
-{
- if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
- return 0;
-
- if (dib->init_state & DIBUSB_STATE_REMOTE) {
- cancel_delayed_work(&dib->rc_query_work);
- flush_scheduled_work();
- input_unregister_device(&dib->rc_input_dev);
- }
- dib->init_state &= ~DIBUSB_STATE_REMOTE;
return 0;
}
+EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
index 7f08936ce..8fdafd2b3 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -88,17 +88,13 @@ struct dvb_usb_properties {
struct dvb_usb_device_description * (*identify_desc_quirk) (void); /* the device is not distinuishable just by its USB IDs */
-#define USB_REMOTE_PROTO_NO 1
-#define USB_REMOTE_PROTO_NEC 2
-#define USB_REMOTE_PROTO_HAUPPAUGE 3
- int remote_protocol; /* does this device have an ir-receiver */
+#define REMOTE_NO_KEY_PRESSED 0x00
+#define REMOTE_KEY_PRESSED 0x01
+#define REMOTE_KEY_REPEAT 0x02
+ int (*init_rc) (struct dvb_usb_device *); /* remote query callback - NULL no ir-receiver */
+ int (*query_rc) (struct dvb_usb_device *, u32 *, int *); /* remote query callback - NULL no ir-receiver */
int rc_interval;
-#define REMOTE_KEY_NO 0x01
-#define REMOTE_KEY_REPEAT 0x02
-#define REMOTE_KEY_PRESSED 0x03
- int (*query_rc) (struct dvb_usb_device *, u8 *, int *); /* remote query callback */
-
/* i2c algorithm, if any */
struct i2c_algorithm i2c_algo;
@@ -151,6 +147,7 @@ struct dvb_usb_device {
int urbs_submitted;
int feedcount;
+ int pid_filtering;
/* locking */
struct semaphore usb_sem;
@@ -170,15 +167,10 @@ struct dvb_usb_device {
int (*fe_init) (struct dvb_frontend *);
/* remote control */
-// struct input_dev rc_input_dev;
-// struct work_struct rc_query_work;
-// int last_event;
-// int last_state; /* for Hauppauge RC protocol */
-// int repeat_key_count;
-// int rc_key_repeat_count; /* module parameter */
-
- int pid_filtering;
-// int rc_query_interval;
+ struct input_dev rc_input_dev;
+ struct work_struct rc_query_work;
+ u32 last_event;
+ int last_state;
void *priv;
};
@@ -190,4 +182,12 @@ extern void dvb_usb_device_exit(struct usb_interface *);
extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16);
extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
+/* common used remote control parsing */
+struct dvb_usb_nec_rc_key {
+ u8 c0,c1,c2;
+ u32 key;
+};
+
+extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, struct dvb_usb_nec_rc_key[],int, u8[], u32 *, int *);
+
#endif
diff --git a/linux/drivers/media/dvb/dvb-usb/vp7045.c b/linux/drivers/media/dvb/dvb-usb/vp7045.c
index 10945591b..d3d0b267d 100644
--- a/linux/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/linux/drivers/media/dvb/dvb-usb/vp7045.c
@@ -16,7 +16,7 @@
/* debug */
int dvb_usb_vp7045_debug;
module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
{
@@ -85,16 +85,56 @@ u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 v = onoff;
- deb_info("power control: %s\n",onoff ? "on" : "off");
-
return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
}
-static int vp7045_rc_query(struct dvb_usb_device *d, u8 *key_buf, int *state)
+/* remote control stuff */
+
+/* The keymapping struct. Somehow this should be loaded to the driver, but
+ * currently it is hardcoded. */
+struct {
+ u8 raw;
+ u32 key;
+} vp7045_rc_key_mapping[] = {
+
+ /* insert the keys like this. to make the raw keys visible, enable
+ * debug=0x04 when loading dvb-usb-vp7045. */
+
+ /* these keys are probably wrong. I don't have a working IR-receiver on my
+ * vp7045, so I can't test it. Patches are welcome. */
+ { 0x01, KEY_1 },
+ { 0x02, KEY_2 },
+};
+
+static int vp7045_rc_init(struct dvb_usb_device *d)
{
- deb_info("remote query\n");
- *state = REMOTE_KEY_NO;
- return 0; //vp7045_usb_op(d,RC_VAL_READ,NULL,0,&v,1,20);
+ int i;
+ for (i = 0; i < sizeof(vp7045_rc_key_mapping)/sizeof(vp7045_rc_key_mapping[0]); i++)
+ set_bit(vp7045_rc_key_mapping[i].key, d->rc_input_dev.keybit);
+
+ return 0;
+}
+
+static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state)
+{
+ u8 key;
+ int i;
+ vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
+
+ deb_rc("remote query key: %x %d\n",key,key);
+
+ if (key == 0x44) {
+ *state = REMOTE_NO_KEY_PRESSED;
+ return 0;
+ }
+
+ for (i = 0; i < sizeof(vp7045_rc_key_mapping)/sizeof(vp7045_rc_key_mapping); i++)
+ if (vp7045_rc_key_mapping[i].raw == key) {
+ *state = REMOTE_KEY_PRESSED;
+ *key_buf = vp7045_rc_key_mapping[i].key;
+ break;
+ }
+ return 0;
}
static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
@@ -169,7 +209,7 @@ static struct dvb_usb_properties vp7045_properties = {
.read_mac_address = vp7045_read_mac_addr,
.rc_interval = 400,
- .remote_protocol = USB_REMOTE_PROTO_NEC,
+ .init_rc = vp7045_rc_init,
.query_rc = vp7045_rc_query,
/* parameter for the MPEG2-data transfer */
diff --git a/linux/drivers/media/dvb/dvb-usb/vp7045.h b/linux/drivers/media/dvb/dvb-usb/vp7045.h
index 0ff5e5dc6..9ce21a20f 100644
--- a/linux/drivers/media/dvb/dvb-usb/vp7045.h
+++ b/linux/drivers/media/dvb/dvb-usb/vp7045.h
@@ -20,6 +20,7 @@
extern int dvb_usb_vp7045_debug;
#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
+#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
/* vp7045 commands */