
From: Johannes Stezenbach <js@linuxtv.org>

o added support for KWorld/ADSTech Instant DVB-T USB2.0 (DiB3000M-B)
o added deactivation option of the pid parser for the DiB3000M-B (since there
  are USB2.0 devices and which now have the ability to deliver the complete
  Transport Stream)
(Patrick Boettcher)

Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/Documentation/dvb/README.dibusb            |   14 ++-
 25-akpm/drivers/media/dvb/dibusb/Kconfig           |    3 
 25-akpm/drivers/media/dvb/dibusb/dvb-dibusb-core.c |   78 +++++++++++++++++----
 25-akpm/drivers/media/dvb/dibusb/dvb-dibusb-usb.c  |    4 -
 25-akpm/drivers/media/dvb/dibusb/dvb-dibusb.h      |    1 
 25-akpm/drivers/media/dvb/frontends/dib3000mb.c    |    5 -
 25-akpm/drivers/media/dvb/frontends/dib3000mc.c    |    2 
 7 files changed, 83 insertions(+), 24 deletions(-)

diff -puN Documentation/dvb/README.dibusb~dvb-support-kworld-adstech-instant-dvb-t-usb20 Documentation/dvb/README.dibusb
--- 25/Documentation/dvb/README.dibusb~dvb-support-kworld-adstech-instant-dvb-t-usb20	2005-03-21 20:57:50.000000000 -0800
+++ 25-akpm/Documentation/dvb/README.dibusb	2005-03-21 20:57:50.000000000 -0800
@@ -77,6 +77,8 @@ Supported devices USB2.0
 - Hauppauge WinTV NOVA-T USB2
 	http://www.hauppauge.com/
 
+- KWorld/ADSTech Instant DVB-T USB2.0 (DiB3000M-B)
+
 - DiBcom USB2.0 DVB-T reference device (non-public)
 
 1) It is working almost.
@@ -84,12 +86,13 @@ Supported devices USB2.0
 
 
 0. NEWS:
-  2004-02-02 - added support for the Hauppauge Win-TV Nova-T USB2
-  2004-01-31 - distorted streaming is finally gone for USB1.1 devices
-  2004-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
+  2005-02-11 - added support for the KWorld/ADSTech Instant DVB-T USB2.0. Thanks a lot to Joachim von Caron
+  2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2
+  2005-01-31 - distorted streaming is finally gone for USB1.1 devices
+  2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
              - first almost working version for HanfTek UMT-010
              - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010
-  2004-01-10 - refactoring completed, now everything is very delightful
+  2005-01-10 - refactoring completed, now everything is very delightful
              - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
                Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich.
   2004-12-29 - after several days of struggling around bug of no returning URBs fixed.
@@ -260,6 +263,9 @@ Patches, comments and suggestions are ve
 
    Bernd Wagner for helping with huge bug reports and discussions.
 
+   Gunnar Wittich and Joachim von Caron for their trust for giving me
+    root-shells on their machines to implement support for new devices.
+
    Some guys on the linux-dvb mailing list for encouraging me
 
    Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
diff -puN drivers/media/dvb/dibusb/dvb-dibusb-core.c~dvb-support-kworld-adstech-instant-dvb-t-usb20 drivers/media/dvb/dibusb/dvb-dibusb-core.c
--- 25/drivers/media/dvb/dibusb/dvb-dibusb-core.c~dvb-support-kworld-adstech-instant-dvb-t-usb20	2005-03-21 20:57:50.000000000 -0800
+++ 25-akpm/drivers/media/dvb/dibusb/dvb-dibusb-core.c	2005-03-21 20:57:50.000000000 -0800
@@ -47,6 +47,7 @@ module_param(rc_query_interval, int, 064
 MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
 
 /* Vendor IDs */
+#define USB_VID_ADSTECH						0x06e1
 #define USB_VID_ANCHOR						0x0547
 #define USB_VID_AVERMEDIA					0x14aa
 #define USB_VID_COMPRO						0x185b
@@ -63,6 +64,8 @@ MODULE_PARM_DESC(rc_query_interval, "int
 #define USB_VID_ULTIMA_ELECTRONIC			0x05d8
 
 /* Product IDs */
+#define USB_PID_ADSTECH_USB2_COLD			0xa333
+#define USB_PID_ADSTECH_USB2_WARM			0xa334
 #define USB_PID_AVERMEDIA_DVBT_USB_COLD		0x0001
 #define USB_PID_AVERMEDIA_DVBT_USB_WARM		0x0002
 #define USB_PID_COMPRO_DVBU2000_COLD		0xd000
@@ -148,16 +151,18 @@ static struct usb_device_id dib_table []
 
 /* 30 */	{ USB_DEVICE(USB_VID_HAUPPAUGE,		USB_PID_WINTV_NOVA_T_USB2_COLD) },
 /* 31 */	{ USB_DEVICE(USB_VID_HAUPPAUGE,		USB_PID_WINTV_NOVA_T_USB2_WARM) },
+/* 32 */	{ USB_DEVICE(USB_VID_ADSTECH,		USB_PID_ADSTECH_USB2_COLD) },
+/* 33 */	{ USB_DEVICE(USB_VID_ADSTECH,		USB_PID_ADSTECH_USB2_WARM) },
 /* 
  * activate the following define when you have one of the devices and want to 
  * build it from build-2.6 in dvb-kernel
  */
 // #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES 
 #ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
-/* 32 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
-/* 33 */	{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
-/* 34 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
-/* 35 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_DIBCOM_ANCHOR_2135_COLD) },
+/* 34 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+/* 35 */	{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
+/* 36 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
+/* 37 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_DIBCOM_ANCHOR_2135_COLD) },
 #endif
 			{ }		/* Terminating entry */
 };
@@ -204,7 +209,7 @@ static struct dibusb_device_class dibusb
 	{ .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0],
 	  .firmware = "dvb-dibusb-5.0.0.11.fw",
 	  .pipe_cmd = 0x01, .pipe_data = 0x02, 
-	  .urb_count = 5, .urb_buffer_size = 4096,
+	  .urb_count = 7, .urb_buffer_size = 4096,
 	  DIBUSB_RC_NEC_PROTOCOL,
 	  &dibusb_demod[DIBUSB_DIB3000MB],
 	  &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
@@ -212,7 +217,7 @@ static struct dibusb_device_class dibusb
 	{ DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
 	  "dvb-dibusb-an2235-1.fw",
 	  0x01, 0x02, 
-	  5, 4096,
+	  7, 4096,
 	  DIBUSB_RC_NEC_PROTOCOL,
 	  &dibusb_demod[DIBUSB_DIB3000MB],
 	  &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
@@ -228,11 +233,19 @@ static struct dibusb_device_class dibusb
 	{ UMT2_0, &dibusb_usb_ctrl[2],
 	  "dvb-dibusb-umt-1.fw",
 	  0x01, 0x02, 
-	  15, 188*21,
+	  7, 188*21,
 	  DIBUSB_RC_NO,
 	  &dibusb_demod[DIBUSB_MT352],
 	  &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
 	},
+	{ DIBUSB2_0B,&dibusb_usb_ctrl[2],
+	  "dvb-dibusb-adstech-usb2-1.fw",
+	  0x01, 0x06,
+	  7, 4096,
+	  DIBUSB_RC_NEC_PROTOCOL,
+	  &dibusb_demod[DIBUSB_DIB3000MB],
+	  &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
+	},
 };
 
 static struct dibusb_usb_device dibusb_devices[] = {
@@ -306,20 +319,25 @@ static struct dibusb_usb_device dibusb_d
 		{ &dib_table[28], NULL },
 		{ &dib_table[29], NULL },
 	},	
+	{	"KWorld/ADSTech Instant DVB-T USB 2.0",
+		&dibusb_device_classes[DIBUSB2_0B],
+		{ &dib_table[32], NULL },
+		{ &dib_table[33], NULL }, /* device ID with default DIBUSB2_0-firmware */
+	},
 #ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
 	{	"Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
 		&dibusb_device_classes[DIBUSB1_1_AN2235],
-		{ &dib_table[32], NULL },
+		{ &dib_table[34], NULL },
 		{ NULL },
 	},
 	{	"Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
 		&dibusb_device_classes[DIBUSB2_0],
-		{ &dib_table[33], NULL },
-		{ &dib_table[34], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
+		{ &dib_table[35], NULL },
+		{ &dib_table[36], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
 	},
 	{	"DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
 		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[35], NULL },
+		{ &dib_table[37], NULL },
 		{ NULL },
 	},
 #endif
@@ -365,30 +383,62 @@ static int dibusb_init(struct usb_dibusb
 	return 0;
 }
 
+static struct dibusb_usb_device * dibusb_device_class_quirk(struct usb_device *udev, struct dibusb_usb_device *dev)
+{
+	int i;
+
+	/* Quirk for the Kworld/ADSTech Instant USB2.0 device. It has the same USB
+	 * IDs like the USB1.1 KWorld after loading the firmware. Which is a bad
+	 * idea and make this quirk necessary.
+	 */
+	if (dev->dev_cl->id == DIBUSB1_1 && udev->speed == USB_SPEED_HIGH) {
+		info("this seems to be the Kworld/ADSTech Instant USB2.0 device or equal.");
+		for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
+			if (dibusb_devices[i].dev_cl->id == DIBUSB2_0B) {
+				dev = &dibusb_devices[i];
+				break;
+			}
+		}
+	}
+
+	return dev;
+}
+
 static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
 {
 	int i,j;
 	*cold = -1;
+	struct dibusb_usb_device *dev = NULL;
+
 	for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
 		for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) {
 			deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct);
 			if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
 				dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
 				*cold = 1;
-				return &dibusb_devices[i];
+				dev = &dibusb_devices[i];
+				break;
 			}
 		}
 
+		if (dev != NULL)
+			break;
+
 		for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) {
 			deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct);
 			if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
 				dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
 				*cold = 0;
-				return &dibusb_devices[i];
+				dev = &dibusb_devices[i];
+				break;
 			}
 		}
 	}
-	return NULL;
+
+	if (dev != NULL)
+		dev = dibusb_device_class_quirk(udev,dev);
+
+	return dev;
 }
 
 /*
diff -puN drivers/media/dvb/dibusb/dvb-dibusb.h~dvb-support-kworld-adstech-instant-dvb-t-usb20 drivers/media/dvb/dibusb/dvb-dibusb.h
--- 25/drivers/media/dvb/dibusb/dvb-dibusb.h~dvb-support-kworld-adstech-instant-dvb-t-usb20	2005-03-21 20:57:50.000000000 -0800
+++ 25-akpm/drivers/media/dvb/dibusb/dvb-dibusb.h	2005-03-21 20:57:50.000000000 -0800
@@ -72,6 +72,7 @@ typedef enum {
 	DIBUSB1_1_AN2235,
 	DIBUSB2_0,
 	UMT2_0,
+	DIBUSB2_0B,
 } dibusb_class_t;
 
 typedef enum {
diff -puN drivers/media/dvb/dibusb/dvb-dibusb-usb.c~dvb-support-kworld-adstech-instant-dvb-t-usb20 drivers/media/dvb/dibusb/dvb-dibusb-usb.c
--- 25/drivers/media/dvb/dibusb/dvb-dibusb-usb.c~dvb-support-kworld-adstech-instant-dvb-t-usb20	2005-03-21 20:57:50.000000000 -0800
+++ 25-akpm/drivers/media/dvb/dibusb/dvb-dibusb-usb.c	2005-03-21 20:57:50.000000000 -0800
@@ -136,6 +136,7 @@ int dibusb_streaming(struct usb_dibusb *
 {
 	switch (dib->dibdev->dev_cl->id) {
 		case DIBUSB2_0:
+		case DIBUSB2_0B:
 			if (onoff)
 				return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0);
 			else
@@ -206,10 +207,11 @@ int dibusb_urb_init(struct usb_dibusb *d
 
 	/* dib->pid_parse here contains the value of the module parameter */
 	/* decide if pid parsing can be deactivated:
-	 * is possible (by speed) and wanted (by user)
+	 * is possible (by device type) and wanted (by user)
 	 */
 	switch (dib->dibdev->dev_cl->id) {
 		case DIBUSB2_0:
+		case DIBUSB2_0B:
 			if (dib->udev->speed == USB_SPEED_HIGH && !dib->pid_parse) {
 				def_pid_parse = 0;
 				info("running at HIGH speed, will deliver the complete TS.");
diff -puN drivers/media/dvb/dibusb/Kconfig~dvb-support-kworld-adstech-instant-dvb-t-usb20 drivers/media/dvb/dibusb/Kconfig
--- 25/drivers/media/dvb/dibusb/Kconfig~dvb-support-kworld-adstech-instant-dvb-t-usb20	2005-03-21 20:57:50.000000000 -0800
+++ 25-akpm/drivers/media/dvb/dibusb/Kconfig	2005-03-21 20:57:50.000000000 -0800
@@ -13,7 +13,7 @@ config DVB_DIBUSB
 
 	    TwinhanDTV USB-Ter (VP7041)
 		TwinhanDTV Magic Box (VP7041e)
-	    KWorld V-Stream XPERT DTV - DVB-T USB
+	    KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
 	    Hama DVB-T USB-Box
 	    DiBcom reference devices (non-public)
 	    Ultima Electronic/Artec T1 USB TVBOX
@@ -23,6 +23,7 @@ config DVB_DIBUSB
 	    Artec T1 USB1.1 and USB2.0 boxes
 	    Yakumo/Typhoon DVB-T USB2.0
 	    Hanftek UMT-010 USB2.0
+	    Hauppauge WinTV NOVA-T USB2
 
 	  The VP7041 seems to be identical to "CTS Portable" (Chinese
 	  Television System).
diff -puN drivers/media/dvb/frontends/dib3000mb.c~dvb-support-kworld-adstech-instant-dvb-t-usb20 drivers/media/dvb/frontends/dib3000mb.c
--- 25/drivers/media/dvb/frontends/dib3000mb.c~dvb-support-kworld-adstech-instant-dvb-t-usb20	2005-03-21 20:57:50.000000000 -0800
+++ 25-akpm/drivers/media/dvb/frontends/dib3000mb.c	2005-03-21 20:57:50.000000000 -0800
@@ -684,8 +684,9 @@ static int dib3000mb_fifo_control(struct
 
 static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
 {
-	//struct dib3000_state *state = fe->demodulator_priv;
-	/* switch it off and on */
+	struct dib3000_state *state = fe->demodulator_priv;
+	deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
+	wr(DIB3000MB_REG_PID_PARSE,onoff);
 	return 0;
 }
 
diff -puN drivers/media/dvb/frontends/dib3000mc.c~dvb-support-kworld-adstech-instant-dvb-t-usb20 drivers/media/dvb/frontends/dib3000mc.c
--- 25/drivers/media/dvb/frontends/dib3000mc.c~dvb-support-kworld-adstech-instant-dvb-t-usb20	2005-03-21 20:57:50.000000000 -0800
+++ 25-akpm/drivers/media/dvb/frontends/dib3000mc.c	2005-03-21 20:57:50.000000000 -0800
@@ -794,10 +794,8 @@ static int dib3000mc_pid_parse(struct dv
 	deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
 
 	if (onoff) {
-		deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_PID_PARSE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
 		wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
 	} else {
-		deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
 		wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
 	}
 	return 0;
_
