New Leadtek Winfast DTV Dongle support investigation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Here is the state of my investigation to get the second revision of the Leadtek
Winfast DTV Dongle (usb id 6f01) supported.

The tuner can receive streams as the first revision did. The driver just needs
to know the new usb id.

The current problem is about the remote controller, several previous posts
report that the driver can only handle the first keypress, then you have to
unplug/replug the dongle if you want to handle one more key press.

A previous post
(http://www.linuxtv.org/pipermail/linux-dvb/2007-November/021836.html) tells
that this remote controller uses the NEC ir protocol. There is a patch for this
but it is not in the main sources (http://www.grunau.be/dib0700_rc_query.diff).

If you use this patch and modprobe with the dvb_usb_dib0700_ir_proto=0 param (is
there any way to use this option by default for this card ?), you can see in
dmesg that several keypressed can be handled. I had the keycodes in
dib0700_devices.c to stop the logs in dmesg and transmits the events to the
kernel.

But there is still one problem : once you pressed a key, the driver continiously
receive a remote control query (a call to the function dib0700_rc_query). In
this function, the NEC ir protocol patch specify that the key[3-0] state of the
query (filled with a call to the function dib0700_ctrl_rd) have to change (which
i suppose means that a key is pressed) to transmit the event to the kernel. But
for me, most of the time, this state never change and stay at Oxff (some times
and for some keys, it turns to 0x00 and the event is transmitted to the kernel.
Can someone confirm this behaviour ?)

The only solution i found is to had a variable that store the last pressed key
and allow to transmit the event to the kernel only if the pressed key has
changed. So the event will not be transmitted if the same key is pressed several
time.

So for now, the driver can handle several key press, but most of the time not
the same key consecutively.

I attach the patch i use that includes all the modifications (usb id
recognition, nec ir protocol patch, and the "last pressed key" stuff).


Simfu
diff -r 2367f40bc1c6 linux/drivers/media/dvb/dvb-usb/dib0700.h
--- a/linux/drivers/media/dvb/dvb-usb/dib0700.h	Sat Dec 22 01:33:36 2007 +0100
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700.h	Wed Dec 26 16:15:36 2007 +0100
@@ -33,10 +33,21 @@ extern int dvb_usb_dib0700_debug;
 #define REQUEST_SET_RC       0x11
 #define REQUEST_GET_VERSION  0x15
 
+ 
+enum dib0700_ir_protocol {
+	IR_PROTO_NEC = 0,
+	IR_PROTO_RC5,
+	IR_PROTO_RC6,
+};
+
+
 struct dib0700_state {
 	u8 channel_state;
 	u16 mt2060_if1[2];
+	u8 rc_protocol;
 	u8 rc_toggle;
+	u8 rc_state[2];
+	u8 rc_toggle3;   /* For the last pressed key */
 	u8 is_dib7000pc;
 };
 
diff -r 2367f40bc1c6 linux/drivers/media/dvb/dvb-usb/dib0700_core.c
--- a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c	Sat Dec 22 01:33:36 2007 +0100
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c	Wed Dec 26 16:15:36 2007 +0100
@@ -267,11 +267,13 @@ static int dib0700_rc_setup(struct dvb_u
 static int dib0700_rc_setup(struct dvb_usb_device *d)
 {
 	u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
+	struct dib0700_state *st = d->priv;
 	int i = dib0700_ctrl_wr(d, rc_setup, 3);
 	if (i<0) {
 		err("ir protocol setup failed");
 		return -1;
 	}
+	st->rc_protocol = dvb_usb_dib0700_ir_proto;
 	return 0;
 }
 
diff -r 2367f40bc1c6 linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
--- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c	Sat Dec 22 01:33:36 2007 +0100
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c	Wed Dec 26 16:15:36 2007 +0100
@@ -278,7 +278,30 @@ static int dib0700_rc_query(struct dvb_u
 		return -1;
 	}
 	if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
-	if (key[3-1]!=st->rc_toggle) {
+	//err("Got remote controller key : %2X %2X %2X %2X",(int)key[3-0],(int)key[3-1],(int)key[3-2],(int)key[3-3]);
+	if (st->rc_protocol == IR_PROTO_NEC) {
+		if ( (key[3-0]!=st->rc_toggle || key[3-3]!=st->rc_toggle3 /* If pressed key has changed */) && key[3-0] == 0xff) {			
+			for (i=0;i<d->props.rc_key_map_size; i++) {
+                        	if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
+                                	*event = keymap[i].event;
+                                	*state = REMOTE_KEY_PRESSED;
+                                	//err("Register key : %d",(int)keymap[i].event);
+                                	st->rc_toggle=key[3-0];
+									st->rc_toggle3=key[3-3];  /* Update last pressed key */
+                                	return 0;
+                        	}
+			}
+			err("Unknown remote controller key : %2X %2X",(int)key[3-2],(int)key[3-3]);
+			st->rc_toggle=key[3-0];
+			st->rc_toggle3=key[3-3];
+			return 0;
+                }
+		else
+			st->rc_toggle=key[3-0];
+			st->rc_toggle3=key[3-3];
+	}
+	else if (st->rc_protocol == IR_PROTO_RC5) {
+		if (key[3-1]!=st->rc_toggle) {	
 		for (i=0;i<d->props.rc_key_map_size; i++) {
 			if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
 				*event = keymap[i].event;
@@ -287,7 +310,12 @@ static int dib0700_rc_query(struct dvb_u
 				return 0;
 			}
 		}
+		st->rc_toggle=key[3-1];
 		err("Unknown remote controller key : %2X %2X",(int)key[3-2],(int)key[3-3]);
+		}
+	}
+	else if (st->rc_protocol == IR_PROTO_RC6) {
+		err("IR protocol RC6 not supported.");
 	}
 	return 0;
 }
@@ -444,6 +472,36 @@ static struct dvb_usb_rc_key dib0700_rc_
 	{ 0x01, 0x7d, KEY_VOLUMEDOWN },
 	{ 0x02, 0x42, KEY_CHANNELUP },
 	{ 0x00, 0x7d, KEY_CHANNELDOWN },
+
+    /* Key codes for the Leadtek Winfast DTV Dongle revision 2 (0x6f01) */
+	{ 0xfc, 0x00, KEY_POWER },
+	{ 0xfc, 0x02, KEY_TUNER },
+	{ 0xfc, 0x51, KEY_PRINT },
+	{ 0xfc, 0x03, KEY_SCREEN }, /* full screen toggle*/
+	{ 0xfc, 0x12, KEY_0 },
+	{ 0xfc, 0x05, KEY_1 },
+	{ 0xfc, 0x06, KEY_2 },
+	{ 0xfc, 0x07, KEY_3 },
+	{ 0xfc, 0x09, KEY_4 },
+	{ 0xfc, 0x0A, KEY_5 },
+	{ 0xfc, 0x0B, KEY_6 },
+	{ 0xfc, 0x0D, KEY_7 },
+	{ 0xfc, 0x0E, KEY_8 },
+	{ 0xfc, 0x0F, KEY_9 },
+	{ 0xfc, 0x49, KEY_CLEAR }, /*boss*/
+	{ 0xfc, 0x16, KEY_INFO }, /* 123 */
+	{ 0xfc, 0x11, KEY_PREVIOUS }, /* recall */
+	{ 0xfc, 0x41, KEY_DOT }, 
+	{ 0xfc, 0x13, KEY_OK }, 
+	{ 0xfc, 0x14, KEY_MUTE },
+	{ 0xfc, 0x4a, KEY_TV2 }, /* pip */
+	{ 0xfc, 0x48, KEY_CAMERA }, 
+	{ 0xfc, 0x45, KEY_TIME },
+	{ 0xfc, 0x47, KEY_RECORD }, 
+	{ 0xfc, 0x04, KEY_VOLUMEUP },
+	{ 0xfc, 0x08, KEY_VOLUMEDOWN },
+	{ 0xfc, 0x0C, KEY_CHANNELUP },
+	{ 0xfc, 0x10, KEY_CHANNELDOWN },
 };
 
 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
@@ -851,6 +909,7 @@ struct usb_device_id dib0700_usb_id_tabl
 		{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
 /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
 /* 21 */{ USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
+		{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
 		{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -892,7 +951,7 @@ struct dvb_usb_device_properties dib0700
 			},
 		},
 
-		.num_device_descs = 8,
+		.num_device_descs = 9,
 		.devices = {
 			{   "DiBcom STK7700P reference design",
 				{ &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
@@ -925,6 +984,10 @@ struct dvb_usb_device_properties dib0700
 			/* dom : pour Gigabyte U7000 */
 			{   "Gigabyte U7000",
 				{ &dib0700_usb_id_table[21], NULL },
+				{ NULL },
+			},
+			{   "Leadtek Winfast DTV Dongle (STK7700P based, rev 2)",
+				{ &dib0700_usb_id_table[22], NULL },
 				{ NULL },
 			}
 		},
diff -r 2367f40bc1c6 linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	Sat Dec 22 01:33:36 2007 +0100
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	Wed Dec 26 16:15:36 2007 +0100
@@ -179,5 +179,6 @@
 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM		0x0513
 /* dom pour gigabyte u7000 */
 #define USB_PID_GIGABYTE_U7000				0x7001
+#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2	0x6f01
 
 #endif
_______________________________________________
linux-dvb mailing list
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux