Hi!

I managed to get the remote working now in both in Ubuntu 9.04 (kernel
2.6.28-16) and Ubuntu 9.10 (kernel 2.6.31-14).

There is one difference tho, in the 2.6.28-16 kernel the remote
doesn't do anything without configuring lirc.
In 2.6.31-14 I can for example adjust volume in X and use the numeric
keys to change channels in tvtime without lirc.
Don't know why, it just works like that.

I've added 3 different examples for a patch as attachment, since the
remote can be enabled different ways.
(They also changes the basic config for my board.)

ex1.patch only works for kernel 2.6.31.

ex2.patch works for both 2.6.31 and 2.6.28 but can in the future cause
problems for boards that would like to use adress 0x1f (0x3e) for IR.
(Because of the "case 0x1f" for my board.)

ex3.patch is a combination of ex1 and ex2. where it is depending on if
kernel version is higher or lower than 2.6.30.

Dunno which one that would be most suitable.

Another thing is that my board finds an IR device at 0x18 (0x30), but
ir-polling doesn't work at that address, so if any board in the future
needs that added
0x1f needs to stand before 0x18.
This is for the funtion in em28xx-cards if kernel higher than 2.6.30:

        const unsigned short addr_list[] = {
                 0x1f, 0x30, 0x47, I2C_CLIENT_END                       
        };

or in  ir-kbd-i2c for kernel lower than 2.6.30:

static const int probe_em28XX[] = { 0x1f, 0x30, 0x47, -1 };


I guess you also might have objections in how I'm naming stuff like
"get_key_lwtu2d", maybe it's a bit obscure...


/Magnus Alm
--- org/v4l-dvb/linux/include/media/ir-common.h	2009-10-29 13:03:42.515061680 +0100
+++ ex1/v4l-dvb/linux/include/media/ir-common.h	2009-10-26 12:00:00.000000000 +0100
@@ -179,4 +179,5 @@
 extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table;
 extern struct ir_scancode_table ir_codes_videomate_s350_table;
 extern struct ir_scancode_table ir_codes_gadmei_rm008z_table;
+extern struct ir_scancode_table ir_codes_lwtu2d_table;
 #endif
--- org/v4l-dvb/linux/drivers/media/common/ir-keymaps.c	2009-10-29 13:03:41.525062396 +0100
+++ ex1/v4l-dvb/linux/drivers/media/common/ir-keymaps.c	2009-10-27 16:51:08.267566000 +0100
@@ -3302,3 +3302,42 @@
 	.size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
 };
 EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
+
+static struct ir_scancode ir_codes_lwtu2d[] = {
+	{ 0x70, KEY_POWER2},		/* POWER OFF*/
+	{ 0x72, KEY_MODE}, 		/* TV/FM */
+	{ 0x21, KEY_CHANNEL},		/* CHANNEL SURF */
+	{ 0x73, KEY_ZOOM},		/* FULLSECREEN */
+	{ 0x39, KEY_CLOSE},		/* MINIMIZE */
+	{ 0x66, KEY_INFO},		/* DISPLAY */
+	{ 0x61, KEY_PREVIOUS},		/* RECALL */
+	{ 0x64, KEY_MUTE},		/* MUTE */
+	
+	{ 0x75, KEY_1},
+	{ 0x76, KEY_2},
+	{ 0x77, KEY_3},
+	{ 0x79, KEY_4},
+	{ 0x7a, KEY_5},
+	{ 0x7b, KEY_6},
+	{ 0x7d, KEY_7},
+	{ 0x7e, KEY_8},
+	{ 0x7f, KEY_9},
+	{ 0x62, KEY_0},
+	{ 0x31, KEY_DOT},		/* '.' */
+	{ 0x63, KEY_ENTER},		/* ENTER */
+
+	{ 0x35, KEY_TIME},		/* TIMESHIFT */
+	{ 0x38, KEY_CAMERA},		/* SNAPSHOT */
+	{ 0x37, KEY_RECORD},		/* RECORD */
+	{ 0x3a, KEY_TV2},		/* PIP */
+
+	{ 0x74, KEY_VOLUMEUP},		/* VOLUMEUP */
+	{ 0x78, KEY_VOLUMEDOWN},	/* VOLUMEDOWN */
+	{ 0x7c, KEY_CHANNELUP},		/* CHANNELUP */
+	{ 0x60, KEY_CHANNELDOWN},	/* CHANNELDOWN */
+};
+struct ir_scancode_table ir_codes_lwtu2d_table = {
+	.scan = ir_codes_lwtu2d,
+	.size = ARRAY_SIZE(ir_codes_lwtu2d),
+};
+EXPORT_SYMBOL_GPL(ir_codes_lwtu2d_table);
--- org/v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c	2009-10-29 13:03:42.155062472 +0100
+++ ex1/v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c	2009-10-29 13:28:02.705063253 +0100
@@ -416,6 +416,7 @@
 		ir_codes    = &ir_codes_pv951_table;
 		break;
 	case 0x18:
+	case 0x1f:
 	case 0x1a:
 		name        = "Hauppauge";
 		ir->get_key = get_key_haup;
--- org/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-10-29 13:03:42.045061311 +0100
+++ ex1/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-10-29 13:48:43.285519588 +0100
@@ -466,22 +466,31 @@
 		.name         = "Leadtek Winfast USB II Deluxe",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
 		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
-		.tda9887_conf = TDA9887_PRESENT,
+		.has_ir_i2c   = 1,
+		.tvaudio_addr = 0x58,					
+		.tda9887_conf = TDA9887_PRESENT |
+				TDA9887_PORT2_ACTIVE |
+				TDA9887_QSS,
 		.decoder      = EM28XX_SAA711X,
-		.input        = { {
+		.adecoder     = EM28XX_TVAUDIO,
+      		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
-			.vmux     = SAA7115_COMPOSITE2,
-			.amux     = EM28XX_AMUX_VIDEO,
-		}, {
+			.vmux     = SAA7115_COMPOSITE4,
+			.amux     = EM28XX_AMUX_AUX,
+      		}, {
 			.type     = EM28XX_VMUX_COMPOSITE1,
-			.vmux     = SAA7115_COMPOSITE0,
+			.vmux     = SAA7115_COMPOSITE5,
 			.amux     = EM28XX_AMUX_LINE_IN,
-		}, {
+      		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
-			.vmux     = SAA7115_COMPOSITE0,
+			.vmux     = SAA7115_SVIDEO3,
 			.amux     = EM28XX_AMUX_LINE_IN,
-		} },
-	},
+      		} },
+			.radio	  = {
+			.type     = EM28XX_RADIO,
+			.amux     = EM28XX_AMUX_AUX,
+                      }
+        },
 	[EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
 		.name         = "Videology 20K14XUSB USB2.0",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
@@ -2310,9 +2319,9 @@
 	}
 #else
 	const unsigned short addr_list[] = {
-		 0x30, 0x47, I2C_CLIENT_END
-	};
-
+		 0x1f, 0x30, 0x47, I2C_CLIENT_END			
+	};							
+        
 	if (disable_ir)
 		return;
 
@@ -2360,6 +2369,18 @@
 		dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
 #endif
 		break;
+	case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+		ir->ir_codes = &ir_codes_lwtu2d_table;			
+		ir->get_key = em28xx_get_key_lwtu2d;			
+		snprintf(ir->name, sizeof(ir->name),			
+			 "i2c IR (EM2820 Winfast tvu2d)");
+#else
+		dev->init_data.ir_codes = &ir_codes_lwtu2d_table;		
+		dev->init_data.get_key = em28xx_get_key_lwtu2d;		
+               	dev->init_data.name = "i2c IR (EM2820 Winfast tvu2d)";
+#endif
+		break;
 	}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
 
--- org/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-input.c	2009-10-29 13:03:42.055064820 +0100
+++ ex1/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-input.c	2009-10-29 14:05:54.255827258 +0100
@@ -179,6 +179,51 @@
 
 	return 1;
 }
+int em28xx_get_key_lwtu2d(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+	unsigned char subaddr, keydetect, key;
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+	struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, .buf = &subaddr, .len = 1},
+#else
+	struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1},
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+				 { .addr = ir->c.addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} };
+#else
+				 { .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} };
+#endif
+				  
+	subaddr = 0x10;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+#else
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
+#endif
+		i2cdprintk("read error\n");
+		return -EIO;
+	}
+	if (keydetect == 0x00)
+		return 0;
+
+	subaddr = 0x00;
+	msg[1].buf = &key;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+#else
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
+#endif
+		i2cdprintk("read error\n");
+		return -EIO;
+	}
+	if (key == 0x00)
+		return 0;
+	
+	*ir_key = key;
+	*ir_raw = key;
+	return 1;
+}
 
 /**********************************************************
  Poll based get keycode functions
--- org/v4l-dvb/linux/drivers/media/video/em28xx/em28xx.h	2009-10-29 13:03:42.065061345 +0100
+++ ex1/v4l-dvb/linux/drivers/media/video/em28xx/em28xx.h	2009-10-27 16:51:08.237565000 +0100
@@ -708,6 +708,8 @@
 int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
 				     u32 *ir_raw);
+int em28xx_get_key_lwtu2d(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 void em28xx_register_snapshot_button(struct em28xx *dev);
 void em28xx_deregister_snapshot_button(struct em28xx *dev);
 
--- org/v4l-dvb/linux/include/media/ir-common.h	2009-10-29 13:03:42.515061680 +0100
+++ ex2/v4l-dvb/linux/include/media/ir-common.h	2009-10-26 12:00:00.000000000 +0100
@@ -179,4 +179,5 @@
 extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table;
 extern struct ir_scancode_table ir_codes_videomate_s350_table;
 extern struct ir_scancode_table ir_codes_gadmei_rm008z_table;
+extern struct ir_scancode_table ir_codes_lwtu2d_table;
 #endif
--- org/v4l-dvb/linux/drivers/media/common/ir-keymaps.c	2009-10-29 13:03:41.525062396 +0100
+++ ex2/v4l-dvb/linux/drivers/media/common/ir-keymaps.c	2009-10-27 16:51:08.267566000 +0100
@@ -3302,3 +3302,42 @@
 	.size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
 };
 EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
+
+static struct ir_scancode ir_codes_lwtu2d[] = {
+	{ 0x70, KEY_POWER2},		/* POWER OFF*/
+	{ 0x72, KEY_MODE}, 		/* TV/FM */
+	{ 0x21, KEY_CHANNEL},		/* CHANNEL SURF */
+	{ 0x73, KEY_ZOOM},		/* FULLSECREEN */
+	{ 0x39, KEY_CLOSE},		/* MINIMIZE */
+	{ 0x66, KEY_INFO},		/* DISPLAY */
+	{ 0x61, KEY_PREVIOUS},		/* RECALL */
+	{ 0x64, KEY_MUTE},		/* MUTE */
+	
+	{ 0x75, KEY_1},
+	{ 0x76, KEY_2},
+	{ 0x77, KEY_3},
+	{ 0x79, KEY_4},
+	{ 0x7a, KEY_5},
+	{ 0x7b, KEY_6},
+	{ 0x7d, KEY_7},
+	{ 0x7e, KEY_8},
+	{ 0x7f, KEY_9},
+	{ 0x62, KEY_0},
+	{ 0x31, KEY_DOT},		/* '.' */
+	{ 0x63, KEY_ENTER},		/* ENTER */
+
+	{ 0x35, KEY_TIME},		/* TIMESHIFT */
+	{ 0x38, KEY_CAMERA},		/* SNAPSHOT */
+	{ 0x37, KEY_RECORD},		/* RECORD */
+	{ 0x3a, KEY_TV2},		/* PIP */
+
+	{ 0x74, KEY_VOLUMEUP},		/* VOLUMEUP */
+	{ 0x78, KEY_VOLUMEDOWN},	/* VOLUMEDOWN */
+	{ 0x7c, KEY_CHANNELUP},		/* CHANNELUP */
+	{ 0x60, KEY_CHANNELDOWN},	/* CHANNELDOWN */
+};
+struct ir_scancode_table ir_codes_lwtu2d_table = {
+	.scan = ir_codes_lwtu2d,
+	.size = ARRAY_SIZE(ir_codes_lwtu2d),
+};
+EXPORT_SYMBOL_GPL(ir_codes_lwtu2d_table);
--- org/v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c	2009-10-29 13:03:42.155062472 +0100
+++ ex2/v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c	2009-10-29 14:05:09.095381128 +0100
@@ -295,6 +295,52 @@
 	return 1;
 }
 
+static int get_key_lwtu2d(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+	unsigned char subaddr, keydetect, key;
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+	struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, 
+#else
+	struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, 
+#endif
+				   .buf = &subaddr, .len = 1},
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+				 { .addr = ir->c.addr, .flags = I2C_M_RD, 
+#else
+				 { .addr = ir->c->addr, .flags = I2C_M_RD, 
+#endif
+				   .buf = &keydetect, .len = 1} };
+	subaddr = 0x10;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+#else
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
+#endif
+		dprintk(1, "read error\n");
+		return -EIO;
+	}
+	if (keydetect == 0x00)
+		return 0;
+
+	subaddr = 0x00;
+	msg[1].buf = &key;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+#else
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
+#endif
+		dprintk(1, "read error\n");
+		return -EIO;
+	}
+	if (key == 0x00)
+		return 0;
+	
+	*ir_key = key;
+	*ir_raw = key;
+	return 1;
+}
 /* ----------------------------------------------------------------------- */
 
 static void ir_key_poll(struct IR_i2c *ir)
@@ -416,6 +462,12 @@
 		ir_codes    = &ir_codes_pv951_table;
 		break;
 	case 0x18:
+	case 0x1f:
+		name        = "Leadtek Winfast TV USB II Deluxe remote";
+		ir->get_key = get_key_lwtu2d;
+		ir_type     = IR_TYPE_OTHER;
+		ir_codes    = &ir_codes_lwtu2d_table;
+		break;
 	case 0x1a:
 		name        = "Hauppauge";
 		ir->get_key = get_key_haup;
@@ -633,7 +685,7 @@
 
 	static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
 	static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 };
-	static const int probe_em28XX[] = { 0x30, 0x47, -1 };
+	static const int probe_em28XX[] = { 0x1f, 0x30, 0x47, -1 };
 	static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
 	static const int probe_cx23885[] = { 0x6b, -1 };
 	const int *probe;
--- org/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-10-29 13:03:42.045061311 +0100
+++ ex2/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-10-29 13:43:36.685061264 +0100
@@ -466,22 +466,31 @@
 		.name         = "Leadtek Winfast USB II Deluxe",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
 		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
-		.tda9887_conf = TDA9887_PRESENT,
+		.has_ir_i2c   = 1,
+		.tvaudio_addr = 0x58,
+		.tda9887_conf = TDA9887_PRESENT |
+				TDA9887_PORT2_ACTIVE |
+				TDA9887_QSS,
 		.decoder      = EM28XX_SAA711X,
+		.adecoder     = EM28XX_TVAUDIO,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
-			.vmux     = SAA7115_COMPOSITE2,
-			.amux     = EM28XX_AMUX_VIDEO,
-		}, {
+			.vmux     = SAA7115_COMPOSITE4,
+			.amux     = EM28XX_AMUX_AUX,
+      		}, {
 			.type     = EM28XX_VMUX_COMPOSITE1,
-			.vmux     = SAA7115_COMPOSITE0,
+			.vmux     = SAA7115_COMPOSITE5,
 			.amux     = EM28XX_AMUX_LINE_IN,
-		}, {
+      		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
-			.vmux     = SAA7115_COMPOSITE0,
+			.vmux     = SAA7115_SVIDEO3,
 			.amux     = EM28XX_AMUX_LINE_IN,
-		} },
-	},
+      		} },
+			.radio	  = {
+			.type     = EM28XX_RADIO,
+			.amux     = EM28XX_AMUX_AUX,
+                      }
+        },
 	[EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
 		.name         = "Videology 20K14XUSB USB2.0",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
@@ -2310,9 +2319,9 @@
 	}
 #else
 	const unsigned short addr_list[] = {
-		 0x30, 0x47, I2C_CLIENT_END
-	};
-
+		 0x1f, 0x30, 0x47, I2C_CLIENT_END			
+	};							
+        
 	if (disable_ir)
 		return;
 
--- org/v4l-dvb/linux/include/media/ir-common.h	2009-10-29 13:03:42.515061680 +0100
+++ ex3/v4l-dvb/linux/include/media/ir-common.h	2009-10-26 12:00:00.000000000 +0100
@@ -179,4 +179,5 @@
 extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table;
 extern struct ir_scancode_table ir_codes_videomate_s350_table;
 extern struct ir_scancode_table ir_codes_gadmei_rm008z_table;
+extern struct ir_scancode_table ir_codes_lwtu2d_table;
 #endif
--- org/v4l-dvb/linux/drivers/media/common/ir-keymaps.c	2009-10-29 13:03:41.525062396 +0100
+++ ex3/v4l-dvb/linux/drivers/media/common/ir-keymaps.c	2009-10-27 16:51:08.267566000 +0100
@@ -3302,3 +3302,42 @@
 	.size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
 };
 EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
+
+static struct ir_scancode ir_codes_lwtu2d[] = {
+	{ 0x70, KEY_POWER2},		/* POWER OFF*/
+	{ 0x72, KEY_MODE}, 		/* TV/FM */
+	{ 0x21, KEY_CHANNEL},		/* CHANNEL SURF */
+	{ 0x73, KEY_ZOOM},		/* FULLSECREEN */
+	{ 0x39, KEY_CLOSE},		/* MINIMIZE */
+	{ 0x66, KEY_INFO},		/* DISPLAY */
+	{ 0x61, KEY_PREVIOUS},		/* RECALL */
+	{ 0x64, KEY_MUTE},		/* MUTE */
+	
+	{ 0x75, KEY_1},
+	{ 0x76, KEY_2},
+	{ 0x77, KEY_3},
+	{ 0x79, KEY_4},
+	{ 0x7a, KEY_5},
+	{ 0x7b, KEY_6},
+	{ 0x7d, KEY_7},
+	{ 0x7e, KEY_8},
+	{ 0x7f, KEY_9},
+	{ 0x62, KEY_0},
+	{ 0x31, KEY_DOT},		/* '.' */
+	{ 0x63, KEY_ENTER},		/* ENTER */
+
+	{ 0x35, KEY_TIME},		/* TIMESHIFT */
+	{ 0x38, KEY_CAMERA},		/* SNAPSHOT */
+	{ 0x37, KEY_RECORD},		/* RECORD */
+	{ 0x3a, KEY_TV2},		/* PIP */
+
+	{ 0x74, KEY_VOLUMEUP},		/* VOLUMEUP */
+	{ 0x78, KEY_VOLUMEDOWN},	/* VOLUMEDOWN */
+	{ 0x7c, KEY_CHANNELUP},		/* CHANNELUP */
+	{ 0x60, KEY_CHANNELDOWN},	/* CHANNELDOWN */
+};
+struct ir_scancode_table ir_codes_lwtu2d_table = {
+	.scan = ir_codes_lwtu2d,
+	.size = ARRAY_SIZE(ir_codes_lwtu2d),
+};
+EXPORT_SYMBOL_GPL(ir_codes_lwtu2d_table);
--- org/v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c	2009-10-29 13:03:42.155062472 +0100
+++ ex3/v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c	2009-10-29 14:04:43.395136347 +0100
@@ -295,6 +295,37 @@
 	return 1;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+static int get_key_lwtu2d(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+	unsigned char subaddr, keydetect, key;
+	
+	struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, 
+				   .buf = &subaddr, .len = 1},
+				 { .addr = ir->c.addr, .flags = I2C_M_RD, 
+				   .buf = &keydetect, .len = 1} };
+	subaddr = 0x10;
+	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+		dprintk(1, "read error\n");
+		return -EIO;
+	}
+	if (keydetect == 0x00)
+		return 0;
+
+	subaddr = 0x00;
+	msg[1].buf = &key;
+	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+		dprintk(1, "read error\n");
+		return -EIO;
+	}
+	if (key == 0x00)
+		return 0;
+	
+	*ir_key = key;
+	*ir_raw = key;
+	return 1;
+}
+#endif
 /* ----------------------------------------------------------------------- */
 
 static void ir_key_poll(struct IR_i2c *ir)
@@ -416,6 +447,14 @@
 		ir_codes    = &ir_codes_pv951_table;
 		break;
 	case 0x18:
+	case 0x1f:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
+		name        = "Leadtek Winfast TV USB II Deluxe remote";
+		ir->get_key = get_key_lwtu2d;
+		ir_type     = IR_TYPE_OTHER;
+		ir_codes    = &ir_codes_lwtu2d_table;
+		break;
+#endif
 	case 0x1a:
 		name        = "Hauppauge";
 		ir->get_key = get_key_haup;
@@ -633,7 +672,7 @@
 
 	static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
 	static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 };
-	static const int probe_em28XX[] = { 0x30, 0x47, -1 };
+	static const int probe_em28XX[] = { 0x1f, 0x30, 0x47, -1 };
 	static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
 	static const int probe_cx23885[] = { 0x6b, -1 };
 	const int *probe;
--- org/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-10-29 13:03:42.045061311 +0100
+++ ex3/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-10-29 14:04:38.935064618 +0100
@@ -466,22 +466,31 @@
 		.name         = "Leadtek Winfast USB II Deluxe",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
 		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
-		.tda9887_conf = TDA9887_PRESENT,
+		.has_ir_i2c   = 1,
+		.tvaudio_addr = 0x58,
+		.tda9887_conf = TDA9887_PRESENT |
+				TDA9887_PORT2_ACTIVE |
+				TDA9887_QSS,
 		.decoder      = EM28XX_SAA711X,
+		.adecoder     = EM28XX_TVAUDIO,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
-			.vmux     = SAA7115_COMPOSITE2,
-			.amux     = EM28XX_AMUX_VIDEO,
-		}, {
+			.vmux     = SAA7115_COMPOSITE4,
+			.amux     = EM28XX_AMUX_AUX,
+      		}, {
 			.type     = EM28XX_VMUX_COMPOSITE1,
-			.vmux     = SAA7115_COMPOSITE0,
+			.vmux     = SAA7115_COMPOSITE5,
 			.amux     = EM28XX_AMUX_LINE_IN,
-		}, {
+      		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
-			.vmux     = SAA7115_COMPOSITE0,
+			.vmux     = SAA7115_SVIDEO3,
 			.amux     = EM28XX_AMUX_LINE_IN,
-		} },
-	},
+      		} },
+			.radio	  = {
+			.type     = EM28XX_RADIO,
+			.amux     = EM28XX_AMUX_AUX,
+                      }
+        },
 	[EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
 		.name         = "Videology 20K14XUSB USB2.0",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
@@ -2310,9 +2319,9 @@
 	}
 #else
 	const unsigned short addr_list[] = {
-		 0x30, 0x47, I2C_CLIENT_END
-	};
-
+		 0x1f, 0x30, 0x47, I2C_CLIENT_END			
+	};							
+        
 	if (disable_ir)
 		return;
 
@@ -2360,6 +2369,13 @@
 		dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
 #endif
 		break;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+	case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
+		dev->init_data.ir_codes = &ir_codes_lwtu2d_table;
+		dev->init_data.get_key = em28xx_get_key_lwtu2d;
+               	dev->init_data.name = "i2c IR (EM2820 Winfast tvu2d)";
+		break;
+#endif
 	}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
 
--- org/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-input.c	2009-10-29 13:03:42.055064820 +0100
+++ ex3/v4l-dvb/linux/drivers/media/video/em28xx/em28xx-input.c	2009-10-29 14:04:41.545837108 +0100
@@ -179,7 +179,36 @@
 
 	return 1;
 }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+int em28xx_get_key_lwtu2d(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+	unsigned char subaddr, keydetect, key;
+
+	struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1},
+				 { .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} };
+				  
+	subaddr = 0x10;
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
+		i2cdprintk("read error\n");
+		return -EIO;
+	}
+	if (keydetect == 0x00)
+		return 0;
+
+	subaddr = 0x00;
+	msg[1].buf = &key;
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
+		i2cdprintk("read error\n");
+		return -EIO;
+	}
+	if (key == 0x00)
+		return 0;
+	
+	*ir_key = key;
+	*ir_raw = key;
+	return 1;
+}
+#endif
 /**********************************************************
  Poll based get keycode functions
  **********************************************************/
--- org/v4l-dvb/linux/drivers/media/video/em28xx/em28xx.h	2009-10-29 13:03:42.065061345 +0100
+++ ex3/v4l-dvb/linux/drivers/media/video/em28xx/em28xx.h	2009-10-29 13:53:42.515396360 +0100
@@ -708,6 +708,9 @@
 int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
 				     u32 *ir_raw);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 30)
+int em28xx_get_key_lwtu2d(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
+#endif
 void em28xx_register_snapshot_button(struct em28xx *dev);
 void em28xx_deregister_snapshot_button(struct em28xx *dev);
 

Reply via email to