All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johannes Stezenbach <js@linuxtv.org>
To: Linus Torvalds <torvalds@osdl.org>
Cc: linux-kernel@vger.kernel.org, js@linuxtv.org
Subject: [PATCH 3/9] refactoring, support Yakumo/HAMA/Typhoon/HanfTek clones
Date: Sat, 22 Jan 2005 18:34:28 +0100	[thread overview]
Message-ID: <11064152683716@linuxtv.org> (raw)
In-Reply-To: <1106415266247@linuxtv.org>

- [DVB] dvb-dibusb: refactoring of the dibusb driver, support for device clones
        from Yakumo/HAMA/Typhoon/HanfTek, update the documentation

Signed-off-by: Michael Hunold <hunold@linuxtv.org>
Signed-off-by: Johannes Stezenbach <js@linuxtv.org>

diff -uraNwB linux-2.6.11-rc2/Documentation/dvb/README.dibusb linux-2.6.11-rc2-dvb/Documentation/dvb/README.dibusb
--- linux-2.6.11-rc2/Documentation/dvb/README.dibusb	2005-01-20 19:55:06.000000000 +0100
+++ linux-2.6.11-rc2-dvb/Documentation/dvb/README.dibusb	2005-01-20 19:56:37.000000000 +0100
@@ -26,7 +26,7 @@
 - HAMA DVB-T USB device
 	http://www.hama.de/portal/articleId*110620/action*2598
 
-- CTS Portable (Chinese Television System)
+- CTS Portable (Chinese Television System) (2)
 	http://www.2cts.tv/ctsportable/
 
 - Unknown USB DVB-T device with vendor ID Hyper-Paltek
@@ -46,16 +46,16 @@
 
 Others:
 -------
-- Ultima Electronic/Artec T1 USB TVBOX (AN2135 and AN2235)
+- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner) 
 	http://82.161.246.249/products-tvbox.html
 
-- Compro Videomate DVB-U2000 - DVB-T USB
+- Compro Videomate DVB-U2000 - DVB-T USB (2)
 	http://www.comprousa.com/products/vmu2000.htm
 
 - Grandtec USB DVB-T
 	http://www.grand.com.tw/
 
-- Avermedia AverTV DVBT USB
+- Avermedia AverTV DVBT USB (2)
 	http://www.avermedia.com/
 
 - DiBcom USB DVB-T reference device (non-public)
@@ -63,16 +63,33 @@
 
 Supported devices USB2.0
 ========================
-- Twinhan MagicBox II
+- Twinhan MagicBox II (2)
 	http://www.twinhan.com/product_terrestrial_7.asp
 
-- Yakumo DVB-T mobile
+- Hanftek UMT-010 (1)
+	http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529
+
+- Typhoon/Yakumo/HAMA DVB-T mobile USB2.0 (1)
 	http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T
 
+- Artec T1 USB TVBOX (FX2) (2)
+
 - DiBcom USB2.0 DVB-T reference device (non-public)
 
+1) It is working almost.
+2) No test reports received yet. 
+
 
 0. NEWS:
+  2004-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
+  2004-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.
+  2004-12-26 - refactored the dibusb-driver, splitted into separate files
+             - i2c-probing enabled
   2004-12-06 - possibility for demod i2c-address probing
              - new usb IDs (Compro,Artec)
   2004-11-23 - merged changes from DiB3000MC_ver2.1
@@ -115,13 +132,15 @@
 
 1. How to use?
 NOTE: This driver was developed using Linux 2.6.6.,
-it is working with 2.6.7, 2.6.8.1, 2.6.9 .
+it is working with 2.6.7 and above.
 
 Linux 2.4.x support is not planned, but patches are very welcome.
 
 NOTE: I'm using Debian testing, so the following explaination (especially
 the hotplug-path) needn't match your system, but probably it will :).
 
+The driver is included in the kernel since Linux 2.6.10.
+
 1.1. Firmware
 
 The USB driver needs to download a firmware to start working.
@@ -155,9 +174,13 @@
 first have a look, which debug level are available:
 
 modinfo dib3000mb
+modinfo dib3000-common
+modinfo dib3000mc
 modinfo dvb-dibusb
 
+modprobe dib3000-common debug=<level>
 modprobe dib3000mb debug=<level>
+modprobe dib3000mc debug=<level>
 modprobe dvb-dibusb debug=<level>
 
 should do the trick.
@@ -168,13 +191,11 @@
 
 At this point you should be able to start a dvb-capable application. For myself
 I used mplayer, dvbscan, tzap and kaxtv, they are working. Using the device
-as a slave device in vdr, was not working for me. Some work has to be done
-(patches and comments are very welcome).
+in vdr (at least the USB2.0 one) is working. 
 
 2. Known problems and bugs
 
-TODO:
-- signal-quality and strength calculations
+- none this time
 
 2.1. Adding support for devices 
 
@@ -202,9 +223,10 @@
 maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
 This is not enough for receiving the complete transport stream of a
 DVB-T channel (which can be about 16 MBit/s). Normally this is not a
-problem, if you only want to watch TV, but watching a channel while
-recording another channel on the same frequency simply does not work.
-This applies to all USB1.1 DVB-T devices.
+problem, if you only want to watch TV (this does not apply for HDTV),
+but watching a channel while recording another channel on the same 
+frequency simply does not work. This applies to all USB1.1 DVB-T 
+devices, not only dibusb)
 
 A special problem of the dibusb for the USB1.1 is, that the USB control
 IC has a problem with write accesses while having MPEG2-streaming
@@ -218,14 +240,20 @@
 these features is maybe a solution. Additionally this behaviour of VDR exceeds
 the USB1.1 bandwidth.
 
+Update:
+For the USB1.1 and VDR some work has been done (patches and comments are still 
+very welcome). Maybe the problem is solved in the meantime because I now use
+the dmx_sw_filter function instead of dmx_sw_filter_packet. I hope the
+linux-dvb software filter is able to get the best of the garbled TS.
+
 2.3. Comments
 
 Patches, comments and suggestions are very very welcome
 
 3. Acknowledgements
 	Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for
-	providing specs, code and help, on which the dvb-dibusb and dib3000mb are
-	based.
+    providing specs, code and help, on which the dvb-dibusb, dib3000mb and 
+    dib3000mc are based.
 
    David Matthews for identifying a new device type (Artec T1 with AN2235)
     and for extending dibusb with remote control event handling. Thank you.
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-core.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-core.c
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-core.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-core.c	2005-01-13 14:24:12.000000000 +0100
@@ -0,0 +1,471 @@
+/*
+ * Driver for mobile USB Budget DVB-T devices based on reference 
+ * design made by DiBcom (http://www.dibcom.fr/)
+ * 
+ * dvb-dibusb-core.c
+ * 
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * 
+ * based on GPL code from DiBcom, which has
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ * Remote control code added by David Matthews (dm@prolingua.co.uk)
+ * 
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation, version 2.
+ *
+ * Acknowledgements
+ * 
+ *  Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
+ *  sources, on which this driver (and the dib3000mb/mc/p frontends) are based.
+ * 
+ * see Documentation/dvb/README.dibusb for more information
+ */
+#include "dvb-dibusb.h"
+
+#include <linux/moduleparam.h>
+
+/* debug */
+#ifdef CONFIG_DVB_DIBCOM_DEBUG
+int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able)).");
+#endif
+
+int pid_parse;
+module_param(pid_parse, int, 0644);
+MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
+
+int rc_query_interval;
+module_param(rc_query_interval, int, 0644);
+MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
+
+/* Vendor IDs */
+#define USB_VID_ANCHOR						0x0547
+#define USB_VID_AVERMEDIA					0x14aa
+#define USB_VID_COMPRO						0x185b
+#define USB_VID_COMPRO_UNK					0x145f
+#define USB_VID_CYPRESS						0x04b4
+#define USB_VID_DIBCOM						0x10b8
+#define USB_VID_EMPIA						0xeb1a
+#define USB_VID_GRANDTEC					0x5032
+#define USB_VID_HYPER_PALTEK				0x1025
+#define USB_VID_HANFTEK						0x15f4
+#define USB_VID_IMC_NETWORKS				0x13d3
+#define USB_VID_TWINHAN						0x1822
+#define USB_VID_ULTIMA_ELECTRONIC			0x05d8
+
+/* Product IDs */
+#define USB_PID_AVERMEDIA_DVBT_USB_COLD		0x0001
+#define USB_PID_AVERMEDIA_DVBT_USB_WARM		0x0002
+#define USB_PID_COMPRO_DVBU2000_COLD		0xd000
+#define USB_PID_COMPRO_DVBU2000_WARM		0xd001
+#define USB_PID_COMPRO_DVBU2000_UNK_COLD	0x010c
+#define USB_PID_COMPRO_DVBU2000_UNK_WARM	0x010d
+#define USB_PID_DIBCOM_MOD3000_COLD			0x0bb8
+#define USB_PID_DIBCOM_MOD3000_WARM			0x0bb9
+#define USB_PID_DIBCOM_MOD3001_COLD			0x0bc6
+#define USB_PID_DIBCOM_MOD3001_WARM			0x0bc7
+#define USB_PID_DIBCOM_ANCHOR_2135_COLD		0x2131
+#define USB_PID_GRANDTEC_DVBT_USB_COLD		0x0fa0
+#define USB_PID_GRANDTEC_DVBT_USB_WARM		0x0fa1
+#define USB_PID_KWORLD_VSTREAM_COLD			0x17de
+#define USB_PID_KWORLD_VSTREAM_WARM			0x17df
+#define USB_PID_TWINHAN_VP7041_COLD			0x3201
+#define USB_PID_TWINHAN_VP7041_WARM			0x3202
+#define USB_PID_ULTIMA_TVBOX_COLD			0x8105
+#define USB_PID_ULTIMA_TVBOX_WARM			0x8106
+#define USB_PID_ULTIMA_TVBOX_AN2235_COLD	0x8107
+#define USB_PID_ULTIMA_TVBOX_AN2235_WARM	0x8108
+#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD	0x2235
+#define USB_PID_ULTIMA_TVBOX_USB2_COLD		0x8109
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD	0x8613
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM	0x1002
+#define USB_PID_UNK_HYPER_PALTEK_COLD		0x005e
+#define USB_PID_UNK_HYPER_PALTEK_WARM		0x005f
+#define USB_PID_HANFTEK_UMT_010_COLD		0x0001
+#define USB_PID_HANFTEK_UMT_010_WARM		0x0025
+#define USB_PID_YAKUMO_DTT200U_COLD			0x0201
+#define USB_PID_YAKUMO_DTT200U_WARM			0x0301
+
+/* USB Driver stuff
+ * table of devices that this driver is working with
+ *
+ * ATTENTION: Never ever change the order of this table, the particular 
+ * devices depend on this order 
+ *
+ * Each entry is used as a reference in the device_struct. Currently this is 
+ * the only non-redundant way of assigning USB ids to actual devices I'm aware 
+ * of, because there is only one place in the code where the assignment of 
+ * vendor and product id is done, here.
+ */
+static struct usb_device_id dib_table [] = {
+/* 00 */	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_AVERMEDIA_DVBT_USB_COLD)},
+/* 01 */	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_AVERMEDIA_DVBT_USB_WARM)},
+/* 02 */	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_YAKUMO_DTT200U_COLD) },
+
+/* the following device is actually not supported, but when loading the 
+ * correct firmware (ie. its usb ids will change) everything works fine then 
+ */
+/* 03 */	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_YAKUMO_DTT200U_WARM) },
+
+/* 04 */	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_COLD) },
+/* 05 */	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_WARM) },
+/* 06 */	{ USB_DEVICE(USB_VID_COMPRO_UNK,	USB_PID_COMPRO_DVBU2000_UNK_COLD) },
+/* 07 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_COLD) },
+/* 08 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_WARM) },
+/* 09 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_COLD) },
+/* 10 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_WARM) },
+/* 11 */	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_COLD) },
+/* 12 */	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_WARM) },
+/* 13 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_COLD) },
+/* 14 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_WARM) },
+/* 15 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_COLD) },
+/* 16 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_WARM) },
+/* 17 */	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_COLD) },
+/* 18 */	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_WARM) },
+/* 19 */	{ USB_DEVICE(USB_VID_IMC_NETWORKS,	USB_PID_TWINHAN_VP7041_COLD) },
+/* 20 */	{ USB_DEVICE(USB_VID_IMC_NETWORKS,	USB_PID_TWINHAN_VP7041_WARM) },
+/* 21 */	{ USB_DEVICE(USB_VID_TWINHAN, 		USB_PID_TWINHAN_VP7041_COLD) },
+/* 22 */	{ USB_DEVICE(USB_VID_TWINHAN, 		USB_PID_TWINHAN_VP7041_WARM) },
+/* 23 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
+/* 24 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
+/* 25 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
+/* 26 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
+/* 27 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+	
+/* 28 */	{ USB_DEVICE(USB_VID_HANFTEK,		USB_PID_HANFTEK_UMT_010_COLD) },
+/* 29 */	{ USB_DEVICE(USB_VID_HANFTEK,		USB_PID_HANFTEK_UMT_010_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
+/* 30 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+/* 31 */	{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
+/* 32 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
+/* 33 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_DIBCOM_ANCHOR_2135_COLD) },
+#endif
+			{ }		/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, dib_table);
+
+static struct dibusb_usb_controller dibusb_usb_ctrl[] = {
+	{ .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
+	{ .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
+	{ .name = "Cypress FX2",    .cpu_cs_register = 0xe600 },
+};
+
+struct dibusb_tuner dibusb_tuner[] = {
+	{ DIBUSB_TUNER_CABLE_THOMSON, 
+	  0x61 
+	},
+	{ DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
+	  0x60 
+	},
+	{ DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
+	  0x61
+	},
+	{ DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
+	  0x60
+	},
+};
+
+static struct dibusb_demod dibusb_demod[] = {
+	{ DIBUSB_DIB3000MB,
+	  16,
+	  { 0x8, 0 },
+	},
+	{ DIBUSB_DIB3000MC,
+	  32,
+	  { 0x9, 0xa, 0xb, 0xc }, 
+	},
+	{ DIBUSB_MT352,
+	  254,
+	  { 0xf, 0 }, 
+	},
+};
+
+static struct dibusb_device_class dibusb_device_classes[] = {
+	{ .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 = 3, .urb_buffer_size = 4096,
+	  DIBUSB_RC_NEC_PROTOCOL,
+	  &dibusb_demod[DIBUSB_DIB3000MB],
+	  &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
+	},
+	{ DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
+	  "dvb-dibusb-an2235-1.fw",
+	  0x01, 0x02, 
+	  3, 4096,
+	  DIBUSB_RC_NEC_PROTOCOL,
+	  &dibusb_demod[DIBUSB_DIB3000MB],
+	  &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
+	},
+	{ DIBUSB2_0,&dibusb_usb_ctrl[2],
+	  "dvb-dibusb-6.0.0.5.fw",
+	  0x01, 0x06, 
+	  3, 188*210,
+	  DIBUSB_RC_NEC_PROTOCOL,
+	  &dibusb_demod[DIBUSB_DIB3000MC],
+	  &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
+	},
+	{ UMT2_0, &dibusb_usb_ctrl[2],
+	  "dvb-dibusb-umt-1.fw",
+	  0x01, 0x02, 
+	  15, 188*21,
+	  DIBUSB_RC_NO,
+	  &dibusb_demod[DIBUSB_MT352],
+//	  &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5],
+	  &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
+	},
+};
+
+static struct dibusb_usb_device dibusb_devices[] = {
+	{	"TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
+		&dibusb_device_classes[DIBUSB1_1],
+		{ &dib_table[19], &dib_table[21], NULL},
+		{ &dib_table[20], &dib_table[22], NULL},
+	},
+	{	"KWorld V-Stream XPERT DTV - DVB-T USB1.1",
+		&dibusb_device_classes[DIBUSB1_1],
+		{ &dib_table[11], NULL },
+		{ &dib_table[12], NULL },
+	},
+	{	"Grandtec USB1.1 DVB-T",
+		&dibusb_device_classes[DIBUSB1_1],
+		{ &dib_table[13], &dib_table[15], NULL },
+		{ &dib_table[14], &dib_table[16], NULL },
+	},
+	{	"DiBcom USB1.1 DVB-T reference design (MOD3000)",
+		&dibusb_device_classes[DIBUSB1_1],
+		{ &dib_table[7],  NULL },
+		{ &dib_table[8],  NULL },
+	},
+	{	"Artec T1 USB1.1 TVBOX with AN2135",
+		&dibusb_device_classes[DIBUSB1_1],
+		{ &dib_table[23], NULL },
+		{ &dib_table[24], NULL },
+	},
+	{	"Artec T1 USB1.1 TVBOX with AN2235",
+		&dibusb_device_classes[DIBUSB1_1_AN2235],
+		{ &dib_table[25], NULL },
+		{ &dib_table[26], NULL },
+	},
+	{	"Avermedia AverTV DVBT USB1.1",
+		&dibusb_device_classes[DIBUSB1_1],
+		{ &dib_table[0],  NULL },
+		{ &dib_table[1],  NULL },
+	},
+	{	"Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
+		&dibusb_device_classes[DIBUSB1_1],
+		{ &dib_table[4], &dib_table[6], NULL},
+		{ &dib_table[5], NULL },
+	},
+	{	"Unkown USB1.1 DVB-T device ???? please report the name to the author",
+		&dibusb_device_classes[DIBUSB1_1],
+		{ &dib_table[17], NULL },
+		{ &dib_table[18], NULL },
+	},
+	{	"DiBcom USB2.0 DVB-T reference design (MOD3000P)",
+		&dibusb_device_classes[DIBUSB2_0],
+		{ &dib_table[9],  NULL },
+		{ &dib_table[10], NULL },
+	},
+	{	"Artec T1 USB2.0 TVBOX (please report the warm ID)",
+		&dibusb_device_classes[DIBUSB2_0],
+		{ &dib_table[27], NULL },
+		{ NULL },
+	},
+	{	"AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0",
+		&dibusb_device_classes[UMT2_0],
+		{ &dib_table[2], NULL },
+		{ NULL },
+	},	
+	{	"Hanftek UMT-010 DVB-T USB2.0",
+		&dibusb_device_classes[UMT2_0],
+		{ &dib_table[28], NULL },
+		{ &dib_table[29], NULL },
+	},	
+#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
+	{	"Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
+		&dibusb_device_classes[DIBUSB1_1_AN2235],
+		{ &dib_table[30], NULL },
+		{ NULL },
+	},
+	{	"Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
+		&dibusb_device_classes[DIBUSB2_0],
+		{ &dib_table[31], NULL },
+		{ &dib_table[32], 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[33], NULL },
+		{ NULL },
+	},
+#endif
+};
+
+static int dibusb_exit(struct usb_dibusb *dib)
+{
+	deb_info("init_state before exiting everything: %x\n",dib->init_state);
+	dibusb_remote_exit(dib);
+	dibusb_fe_exit(dib);
+	dibusb_i2c_exit(dib);
+	dibusb_pid_list_exit(dib);
+	dibusb_dvb_exit(dib);
+	dibusb_urb_exit(dib);
+	deb_info("init_state should be zero now: %x\n",dib->init_state);
+	dib->init_state = DIBUSB_STATE_INIT;
+	kfree(dib);
+	return 0;
+}
+
+static int dibusb_init(struct usb_dibusb *dib)
+{
+	int ret = 0;
+	sema_init(&dib->usb_sem, 1);
+	sema_init(&dib->i2c_sem, 1);
+
+	dib->init_state = DIBUSB_STATE_INIT;
+	
+	if ((ret = dibusb_urb_init(dib)) ||
+		(ret = dibusb_dvb_init(dib)) || 
+		(ret = dibusb_pid_list_init(dib)) ||
+		(ret = dibusb_i2c_init(dib))) {
+		dibusb_exit(dib);
+		return ret;
+	}
+
+	if ((ret = dibusb_fe_init(dib)))
+		err("could not initialize a frontend.");
+	
+	if ((ret = dibusb_remote_init(dib)))
+		err("could not initialize remote control.");
+	
+	return 0;
+}
+
+static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
+{
+	int i,j;
+	*cold = -1;
+	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 == udev->descriptor.idVendor &&
+				dibusb_devices[i].cold_ids[j]->idProduct == udev->descriptor.idProduct) {
+				*cold = 1;
+				return &dibusb_devices[i];
+			}
+		}
+
+		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 == udev->descriptor.idVendor &&
+				dibusb_devices[i].warm_ids[j]->idProduct == udev->descriptor.idProduct) {
+				*cold = 0;
+				return &dibusb_devices[i];
+			}
+		}
+	}
+	return NULL;
+}
+
+/*
+ * USB 
+ */
+static int dibusb_probe(struct usb_interface *intf, 
+		const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_dibusb *dib = NULL;
+	struct dibusb_usb_device *dibdev = NULL;
+	
+	int ret = -ENOMEM,cold=0;
+
+	if ((dibdev = dibusb_find_device(udev,&cold)) == NULL) {
+		err("something went very wrong, "
+				"unknown product ID: %.4x",udev->descriptor.idProduct);
+		return -ENODEV;
+	}
+	
+	if (cold == 1) {
+		info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
+		ret = dibusb_loadfirmware(udev,dibdev);
+	} else {
+		info("found a '%s' in warm state.",dibdev->name);
+		dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
+		if (dib == NULL) {
+			err("no memory");
+			return ret;
+		}
+		memset(dib,0,sizeof(struct usb_dibusb));
+		
+		dib->udev = udev;
+		dib->dibdev = dibdev;
+
+		usb_set_intfdata(intf, dib);
+		
+		ret = dibusb_init(dib);
+	}
+	
+	if (ret == 0)
+		info("%s successfully initialized and connected.",dibdev->name);
+	else 
+		info("%s error while loading driver (%d)",dibdev->name,ret);
+	return ret;
+}
+
+static void dibusb_disconnect(struct usb_interface *intf)
+{
+	struct usb_dibusb *dib = usb_get_intfdata(intf);
+	const char *name = DRIVER_DESC;
+	
+	usb_set_intfdata(intf,NULL);
+	if (dib != NULL && dib->dibdev != NULL) {
+		name = dib->dibdev->name;
+		dibusb_exit(dib);
+	}
+	info("%s successfully deinitialized and disconnected.",name);
+	
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+struct usb_driver dibusb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= DRIVER_DESC,
+	.probe 		= dibusb_probe,
+	.disconnect = dibusb_disconnect,
+	.id_table 	= dib_table,
+};
+
+/* module stuff */
+static int __init usb_dibusb_init(void)
+{
+	int result;
+	if ((result = usb_register(&dibusb_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+	
+	return 0;
+}
+
+static void __exit usb_dibusb_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&dibusb_driver);
+}
+
+module_init (usb_dibusb_init);
+module_exit (usb_dibusb_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c	2005-01-13 14:24:12.000000000 +0100
@@ -0,0 +1,205 @@
+/*
+ * dvb-dibusb-dvb.c is part of the driver for mobile USB Budget DVB-T devices 
+ * based on reference design made by DiBcom (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * see dvb-dibusb-core.c for more copyright details.
+ *
+ * This file contains functions for initializing and handling the 
+ * linux-dvb API.
+ */
+#include "dvb-dibusb.h"
+
+#include <linux/usb.h>
+#include <linux/version.h>
+
+static u32 urb_compl_count;
+
+/*
+ * MPEG2 TS DVB stuff 
+ */
+void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+{
+	struct usb_dibusb *dib = urb->context;
+	int ret;
+
+	deb_ts("urb complete feedcount: %d, status: %d, length: %d\n",dib->feedcount,urb->status,
+			urb->actual_length);
+
+	urb_compl_count++;
+	if (urb_compl_count % 500 == 0)
+		deb_info("%d urbs completed so far.\n",urb_compl_count);
+
+	switch (urb->status) {
+		case 0:         /* success */
+		case -ETIMEDOUT:    /* NAK */
+			break;
+		case -ECONNRESET:   /* unlink */
+		case -ENOENT:
+		case -ESHUTDOWN:
+			return;
+		default:        /* error */
+			warn("urb completition error %d.", urb->status);
+	}
+
+	if (dib->feedcount > 0) {
+		deb_ts("URB return len: %d\n",urb->actual_length);
+		if (urb->actual_length % 188) 
+			deb_ts("TS Packets: %d, %d\n", urb->actual_length/188,urb->actual_length % 188);
+
+		/* Francois recommends to drop not full-filled packets, even if they may 
+		 * contain valid TS packets, at least for USB1.1
+		 *
+		 * if (urb->actual_length == dib->dibdev->parm->default_size && dib->dvb_is_ready) */
+		if (dib->init_state & DIBUSB_STATE_DVB)
+			dvb_dmx_swfilter(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length);
+		else
+			deb_ts("URB dropped because of the " 
+					"actual_length or !dvb_is_ready (%d).\n",dib->init_state & DIBUSB_STATE_DVB);
+	} else 
+		deb_ts("URB dropped because of feedcount.\n");
+
+	ret = usb_submit_urb(urb,GFP_ATOMIC);
+	deb_ts("urb resubmitted, (%d)\n",ret);
+}
+
+static int dibusb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) 
+{
+	struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
+	int newfeedcount;
+	
+	if (dib == NULL)
+		return -ENODEV;
+
+	newfeedcount = dib->feedcount + (onoff ? 1 : -1);
+
+	/* 
+	 * stop feed before setting a new pid if there will be no pid anymore 
+	 */
+//	if ((dib->dibdev->parm->firmware_bug && dib->feedcount) || 
+	if (newfeedcount == 0) {
+		deb_ts("stop feeding\n");
+		if (dib->xfer_ops.fifo_ctrl != NULL) {
+			if (dib->xfer_ops.fifo_ctrl(dib->fe,0)) {
+				err("error while inhibiting fifo.");
+				return -ENODEV;
+			}
+		}
+	}
+	
+	dib->feedcount = newfeedcount;
+
+	/* get a free pid from the list and activate it on the device
+	 * specific pid_filter
+	 */
+	if (dib->pid_parse)
+		dibusb_ctrl_pid(dib,dvbdmxfeed,onoff);
+
+	/* 
+	 * start the feed, either if there is the firmware bug or 
+	 * if this was the first pid to set and there is still a pid for 
+	 * reception.
+	 */
+	
+//	if ((dib->dibdev->parm->firmware_bug)
+	if (dib->feedcount == onoff && dib->feedcount > 0) {
+
+		deb_ts("controlling pid parser\n");
+		if (dib->xfer_ops.pid_parse != NULL) {
+			if (dib->xfer_ops.pid_parse(dib->fe,dib->pid_parse) < 0) {
+				err("could not handle pid_parser");
+			}
+		}
+		
+		deb_ts("start feeding\n");
+		if (dib->xfer_ops.fifo_ctrl != NULL) {
+			if (dib->xfer_ops.fifo_ctrl(dib->fe,1)) {
+				err("error while enabling fifo.");
+				return -ENODEV;
+			}
+		}
+		dibusb_streaming(dib,1);
+	}
+	return 0;
+}
+
+static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
+	return dibusb_ctrl_feed(dvbdmxfeed,1);
+}
+
+static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
+	return dibusb_ctrl_feed(dvbdmxfeed,0);
+}
+
+int dibusb_dvb_init(struct usb_dibusb *dib)
+{
+	int ret;
+
+	urb_compl_count = 0;
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,4)
+    if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC)) < 0) {
+#else
+    if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC , 
+			THIS_MODULE)) < 0) {
+#endif
+		deb_info("dvb_register_adapter failed: error %d", ret);
+		goto err;
+	}
+	dib->adapter->priv = dib;
+	
+/* i2c is done in dibusb_i2c_init */
+	
+	dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+
+	dib->demux.priv = (void *)dib;
+	/* get pidcount from demod */
+	dib->demux.feednum = dib->demux.filternum = 255;
+	dib->demux.start_feed = dibusb_start_feed;
+	dib->demux.stop_feed = dibusb_stop_feed;
+	dib->demux.write_to_decoder = NULL;
+	if ((ret = dvb_dmx_init(&dib->demux)) < 0) {
+		err("dvb_dmx_init failed: error %d",ret);
+		goto err_dmx;
+	}
+
+	dib->dmxdev.filternum = dib->demux.filternum;
+	dib->dmxdev.demux = &dib->demux.dmx;
+	dib->dmxdev.capabilities = 0;
+	if ((ret = dvb_dmxdev_init(&dib->dmxdev, dib->adapter)) < 0) {
+		err("dvb_dmxdev_init failed: error %d",ret);
+		goto err_dmx_dev;
+	}
+
+	dvb_net_init(dib->adapter, &dib->dvb_net, &dib->demux.dmx);
+
+	goto success;
+err_dmx_dev:
+	dvb_dmx_release(&dib->demux);
+err_dmx:
+	dvb_unregister_adapter(dib->adapter);
+err:
+	return ret;
+success:
+	dib->init_state |= DIBUSB_STATE_DVB;
+	return 0;
+}
+
+int dibusb_dvb_exit(struct usb_dibusb *dib)
+{
+	if (dib->init_state & DIBUSB_STATE_DVB) {
+		dib->init_state &= ~DIBUSB_STATE_DVB;
+		deb_info("unregistering DVB part\n");
+		dvb_net_release(&dib->dvb_net);
+		dib->demux.dmx.close(&dib->demux.dmx);
+		dvb_dmxdev_release(&dib->dmxdev);
+		dvb_dmx_release(&dib->demux);
+		dvb_unregister_adapter(dib->adapter);
+	}
+	return 0;
+}
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c	2005-01-13 14:24:12.000000000 +0100
@@ -0,0 +1,598 @@
+/*
+ * dvb-dibusb-fe-i2c.c is part of the driver for mobile USB Budget DVB-T devices 
+ * based on reference design made by DiBcom (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * see dvb-dibusb-core.c for more copyright details.
+ *
+ * This file contains functions for attaching, initializing of an appropriate
+ * demodulator/frontend. I2C-stuff is also located here.
+ * 
+ */
+#include "dvb-dibusb.h"
+
+#include <linux/usb.h>
+
+int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr, 
+		u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+	u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
+	/* write only ? */
+	int wo = (rbuf == NULL || rlen == 0), 
+		len = 2 + wlen + (wo ? 0 : 2);
+	
+	sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
+	sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
+
+	memcpy(&sndbuf[2],wbuf,wlen);
+	
+	if (!wo) {
+		sndbuf[wlen+2] = (rlen >> 8) & 0xff;
+		sndbuf[wlen+3] = rlen & 0xff;
+	}
+	
+	return dibusb_readwrite_usb(dib,sndbuf,len,rbuf,rlen);
+}
+
+/*
+ * I2C master xfer function
+ */
+static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+	struct usb_dibusb *dib = i2c_get_adapdata(adap);
+	int i;
+
+	if (down_interruptible(&dib->i2c_sem) < 0) 
+		return -EAGAIN;
+
+	if (num > 2)
+		warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+	
+	for (i = 0; i < num; i++) {
+		/* write/read request */
+		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+			if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,
+						msg[i+1].buf,msg[i+1].len) < 0)
+				break;
+			i++;
+		} else 
+			if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
+				break;
+	}
+	
+	up(&dib->i2c_sem);
+	return i;	
+}
+
+static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dibusb_algo = {
+	.name			= "DiBcom USB i2c algorithm",
+	.id				= I2C_ALGO_BIT,
+	.master_xfer	= dibusb_i2c_xfer,
+	.functionality	= dibusb_i2c_func,
+};
+
+static int dibusb_general_demod_init(struct dvb_frontend *fe);
+static u8 dibusb_general_pll_addr(struct dvb_frontend *fe);
+static int dibusb_general_pll_init(struct dvb_frontend *fe, u8 pll_buf[5]);
+static int dibusb_general_pll_set(struct dvb_frontend *fe, 
+		struct dvb_frontend_parameters* params, u8 pll_buf[5]);
+
+static struct mt352_config mt352_hanftek_umt_010_config = {
+	.demod_address = 0x1e,
+	.demod_init = dibusb_general_demod_init,
+   	.pll_set = dibusb_general_pll_set,
+};
+
+static int dibusb_tuner_quirk(struct usb_dibusb *dib) 
+{
+	switch (dib->dibdev->dev_cl->id) {
+		case DIBUSB1_1: /* some these device have the ENV77H11D5 and some the THOMSON CABLE */
+		case DIBUSB1_1_AN2235: { /* actually its this device, but in warm state they are indistinguishable */
+			struct dibusb_tuner *t;
+			u8 b[2] = { 0,0 } ,b2[1];
+			struct i2c_msg msg[2] = {
+				{ .flags = 0, .buf = b, .len = 2 },
+				{ .flags = I2C_M_RD, .buf = b2, .len = 1},
+			};
+			
+			t = &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5];
+			
+			msg[0].addr = msg[1].addr = t->pll_addr;
+		
+			if (dib->xfer_ops.tuner_pass_ctrl != NULL)
+				dib->xfer_ops.tuner_pass_ctrl(dib->fe,1,t->pll_addr);
+			dibusb_i2c_xfer(&dib->i2c_adap,msg,2);
+			if (dib->xfer_ops.tuner_pass_ctrl != NULL)
+				dib->xfer_ops.tuner_pass_ctrl(dib->fe,0,t->pll_addr);
+
+			if (b2[0] == 0xfe)
+				info("this device has the Thomson Cable onboard. Which is default.");
+			else {
+				dib->tuner = t;
+				info("this device has the Panasonic ENV77H11D5 onboard.");
+			}
+			break;	
+		}
+		default:
+			break;
+	}
+	return 0;
+}
+
+/* there is a ugly pid_filter in the firmware of the umt devices, it is accessible 
+ * by i2c address 0x8. Don't know how to deactivate it and how many rows it has.
+ */
+static int dibusb_umt_pid_control(struct dvb_frontend *fe, int index, int pid, int onoff)
+{
+	struct usb_dibusb *dib = fe->dvb->priv;
+	u8 b[3];
+	b[0] = index;
+	if (onoff) {
+		b[1] = (pid >> 8) & 0xff;
+		b[2] = pid & 0xff;
+	} else {
+		b[1] = 0;
+		b[2] = 0;
+	}
+	dibusb_i2c_msg(dib, 0x8, b, 3, NULL,0);
+	dibusb_set_streaming_mode(dib,0);
+	dibusb_set_streaming_mode(dib,1);
+	return 0;
+}
+
+int dibusb_fe_init(struct usb_dibusb* dib)
+{
+	struct dib3000_config demod_cfg;
+	int i;
+	
+	if (dib->init_state & DIBUSB_STATE_I2C) { 
+		for (i = 0; i < sizeof(dib->dibdev->dev_cl->demod->i2c_addrs) / sizeof(unsigned char) && 
+				dib->dibdev->dev_cl->demod->i2c_addrs[i] != 0; i++) {
+
+			demod_cfg.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
+			demod_cfg.pll_addr = dibusb_general_pll_addr;
+			demod_cfg.pll_set = dibusb_general_pll_set;
+			demod_cfg.pll_init = dibusb_general_pll_init;
+
+			switch (dib->dibdev->dev_cl->demod->id) {
+				case DIBUSB_DIB3000MB:
+					dib->fe = dib3000mb_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
+				break;
+				case DIBUSB_DIB3000MC:
+					dib->fe = dib3000mc_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
+				break;
+				case DIBUSB_MT352:
+					mt352_hanftek_umt_010_config.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
+					dib->fe = mt352_attach(&mt352_hanftek_umt_010_config, &dib->i2c_adap);
+					dib->xfer_ops.pid_ctrl = dibusb_umt_pid_control;
+				break;
+			}
+			if (dib->fe != NULL) {
+				info("found demodulator at i2c address 0x%x",dib->dibdev->dev_cl->demod->i2c_addrs[i]);
+				break;
+			}
+		}
+		if (dib->fe->ops->sleep != NULL)
+			dib->fe_sleep = dib->fe->ops->sleep;
+		dib->fe->ops->sleep = dibusb_hw_sleep;
+
+		if (dib->fe->ops->init != NULL ) 
+			dib->fe_init = dib->fe->ops->init;
+		dib->fe->ops->init = dibusb_hw_wakeup;
+	
+		/* setting the default tuner */ 
+		dib->tuner = dib->dibdev->dev_cl->tuner;
+
+		/* check which tuner is mounted on this device, in case this is unsure */
+		dibusb_tuner_quirk(dib);
+	}
+	if (dib->fe == NULL) {
+		err("A frontend driver was not found for device '%s'.",
+		       dib->dibdev->name);
+		return -ENODEV;
+	} else {
+		if (dvb_register_frontend(dib->adapter, dib->fe)) {
+			err("Frontend registration failed.");
+			if (dib->fe->ops->release)
+				dib->fe->ops->release(dib->fe);
+			dib->fe = NULL;
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
+
+int dibusb_fe_exit(struct usb_dibusb *dib)
+{
+	if (dib->fe != NULL)
+		dvb_unregister_frontend(dib->fe);
+	return 0;
+}
+
+int dibusb_i2c_init(struct usb_dibusb *dib)
+{
+	int ret = 0;
+
+	dib->adapter->priv = dib;
+
+	strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE);
+#ifdef I2C_ADAP_CLASS_TV_DIGITAL
+	dib->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
+#else
+	dib->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
+#endif
+	dib->i2c_adap.algo 		= &dibusb_algo;
+	dib->i2c_adap.algo_data = NULL;
+	dib->i2c_adap.id		= I2C_ALGO_BIT;
+	
+	i2c_set_adapdata(&dib->i2c_adap, dib);
+	
+	if ((ret = i2c_add_adapter(&dib->i2c_adap)) < 0)
+		err("could not add i2c adapter");
+	
+	dib->init_state |= DIBUSB_STATE_I2C;
+
+	return ret;
+}
+
+int dibusb_i2c_exit(struct usb_dibusb *dib)
+{
+	if (dib->init_state & DIBUSB_STATE_I2C)
+		i2c_del_adapter(&dib->i2c_adap);
+	dib->init_state &= ~DIBUSB_STATE_I2C;
+	return 0;
+}
+
+
+/* pll stuff, maybe removed soon (thx to Gerd/Andrew in advance) */
+static int thomson_cable_eu_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
+{
+	u32 tfreq = (fep->frequency + 36125000) / 62500;
+	int vu,p0,p1,p2;
+
+	if (fep->frequency > 403250000)
+		vu = 1, p2 = 1, p1 = 0, p0 = 1;
+	else if (fep->frequency > 115750000)
+		vu = 0, p2 = 1, p1 = 1, p0 = 0;
+	else if (fep->frequency > 44250000)
+		vu = 0, p2 = 0, p1 = 1, p0 = 1;
+	else
+		return -EINVAL;
+
+	pllbuf[0] = (tfreq >> 8) & 0x7f;
+	pllbuf[1] = tfreq & 0xff;
+   	pllbuf[2] = 0x8e;
+   	pllbuf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0;
+	return 0;
+}
+
+static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
+{
+	u32 freq = fep->frequency;
+	u32 tfreq = ((freq + 36125000)*6 + 500000) / 1000000;
+	u8 TA, T210, R210, ctrl1, cp210, p4321;
+	if (freq > 858000000) {
+		err("frequency cannot be larger than 858 MHz.");
+		return -EINVAL;
+	}
+	
+	// contol data 1 : 1 | T/A=1 | T2,T1,T0 = 0,0,0 | R2,R1,R0 = 0,1,0
+	TA = 1;
+	T210 = 0;
+	R210 = 0x2;
+	ctrl1 = (1 << 7) | (TA << 6) | (T210 << 3) | R210;
+
+// ********    CHARGE PUMP CONFIG vs RF FREQUENCIES     *****************
+	if (freq < 470000000) 
+		cp210 = 2;  // VHF Low and High band ch E12 to E4 to E12
+	else if (freq < 526000000) 
+		cp210 = 4;  // UHF band Ch E21 to E27
+	else // if (freq < 862000000) 
+		cp210 = 5;  // UHF band ch E28 to E69
+
+//*********************    BW select  *******************************
+	if (freq < 153000000) 
+		p4321  = 1; // BW selected for VHF low
+	else if (freq < 470000000) 
+		p4321  = 2; // BW selected for VHF high E5 to E12
+	else // if (freq < 862000000) 
+		p4321  = 4; // BW selection for UHF E21 to E69
+
+	pllbuf[0] = (tfreq >> 8) & 0xff;
+	pllbuf[1] = (tfreq >> 0) & 0xff;
+	pllbuf[2] = 0xff & ctrl1;
+	pllbuf[3] =  (cp210 << 5) | (p4321);
+
+	return 0;
+}
+
+/*
+ *            	            7	6		5	4	3	2	1	0
+ * Address Byte             1	1		0	0	0	MA1	MA0	R/~W=0
+ *
+ * Program divider byte 1   0	n14		n13	n12	n11	n10	n9	n8
+ * Program divider byte 2	n7	n6		n5	n4	n3	n2	n1	n0
+ *
+ * Control byte 1           1	T/A=1	T2	T1	T0	R2	R1	R0
+ *                          1	T/A=0	0	0	ATC	AL2	AL1	AL0
+ * 
+ * Control byte 2           CP2	CP1		CP0	BS5	BS4	BS3	BS2	BS1
+ * 
+ * MA0/1 = programmable address bits
+ * R/~W  = read/write bit (0 for writing)
+ * N14-0 = programmable LO frequency
+ * 
+ * T/A   = test AGC bit (0 = next 6 bits AGC setting, 
+ *                       1 = next 6 bits test and reference divider ratio settings)
+ * T2-0  = test bits
+ * R2-0  = reference divider ratio and programmable frequency step
+ * ATC   = AGC current setting and time constant
+ *         ATC = 0: AGC current = 220nA, AGC time constant = 2s
+ *         ATC = 1: AGC current = 9uA, AGC time constant = 50ms
+ * AL2-0 = AGC take-over point bits
+ * CP2-0 = charge pump current
+ * BS5-1 = PMOS ports control bits;
+ *             BSn = 0 corresponding port is off, high-impedance state (at power-on)
+ *             BSn = 1 corresponding port is on
+ */
+
+
+static int panasonic_cofdm_env77h11d5_tda6650_init(struct dvb_frontend *fe, u8 pllbuf[4])
+{
+	pllbuf[0] = 0x0b;
+	pllbuf[1] = 0xf5;
+	pllbuf[2] = 0x85;
+	pllbuf[3] = 0xab;
+	return 0;
+}
+
+static int panasonic_cofdm_env77h11d5_tda6650_set (struct dvb_frontend_parameters *fep,u8 pllbuf[4])
+{
+	int tuner_frequency = 0;
+	u8 band, cp, filter;
+
+	// determine charge pump
+	tuner_frequency = fep->frequency + 36166000;
+	if (tuner_frequency < 87000000)
+		return -EINVAL;
+	else if (tuner_frequency < 130000000)
+		cp = 3;
+	else if (tuner_frequency < 160000000)
+		cp = 5;
+	else if (tuner_frequency < 200000000)
+		cp = 6;
+	else if (tuner_frequency < 290000000)
+		cp = 3;
+	else if (tuner_frequency < 420000000)
+		cp = 5;
+	else if (tuner_frequency < 480000000)
+		cp = 6;
+	else if (tuner_frequency < 620000000)
+		cp = 3;
+	else if (tuner_frequency < 830000000)
+		cp = 5;
+	else if (tuner_frequency < 895000000)
+		cp = 7;
+	else
+		return -EINVAL;
+
+	// determine band
+	if (fep->frequency < 49000000)
+		return -EINVAL;
+	else if (fep->frequency < 161000000)
+		band = 1;
+	else if (fep->frequency < 444000000)
+		band = 2;
+	else if (fep->frequency < 861000000)
+		band = 4;
+	else
+		return -EINVAL;
+
+	// setup PLL filter
+	switch (fep->u.ofdm.bandwidth) {
+		case BANDWIDTH_6_MHZ:
+		case BANDWIDTH_7_MHZ:
+			filter = 0;
+			break;
+		case BANDWIDTH_8_MHZ:
+			filter = 1;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	// calculate divisor
+	// ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
+	tuner_frequency = (((fep->frequency / 1000) * 6) + 217496) / 1000;
+
+	// setup tuner buffer
+	pllbuf[0] = (tuner_frequency >> 8) & 0x7f;
+	pllbuf[1] = tuner_frequency & 0xff;
+	pllbuf[2] = 0xca;
+	pllbuf[3] = (cp << 5) | (filter << 3) | band;
+	return 0;
+}
+
+/*
+ *            	            7	6	5	4	3	2	1	0
+ * Address Byte             1	1	0	0	0	MA1	MA0	R/~W=0
+ *
+ * Program divider byte 1   0	n14	n13	n12	n11	n10	n9	n8
+ * Program divider byte 2	n7	n6	n5	n4	n3	n2	n1	n0
+ *
+ * Control byte             1	CP	T2	T1	T0	RSA	RSB	OS
+ * 
+ * Band Switch byte         X	X	X	P4	P3	P2	P1	P0
+ *
+ * Auxiliary byte           ATC	AL2	AL1	AL0	0	0	0	0
+ *
+ * Address: MA1	MA0	Address
+ *          0	0	c0
+ *          0	1	c2 (always valid)
+ *          1	0	c4
+ *          1	1	c6
+ *
+ *
+ * 
+ */
+
+static int lg_tdtp_e102p_tua6034(struct dvb_frontend_parameters* fep, u8 pllbuf[4]) 
+{
+	u32 div;
+	u8 p3210, p4;
+
+#define TUNER_MUL 62500
+
+	div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
+
+	if (fep->frequency < 174500000) 
+		p3210 = 1; // not supported by the tdtp_e102p
+	else if (fep->frequency < 230000000) // VHF
+		p3210 = 2;
+	else 
+		p3210 = 4;
+
+	if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
+		p4 = 0;
+	else 
+		p4 = 1;
+		
+	pllbuf[0] = (div >> 8) & 0x7f;
+	pllbuf[1] = div & 0xff;
+	pllbuf[2] = 0xce;
+	pllbuf[3] = (p4 << 4) | p3210;
+
+	return 0;
+}
+
+static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe)
+{
+	static u8 mt352_clock_config[] = { 0x89, 0xb0, 0x2d };
+	static u8 mt352_reset[] = { 0x50, 0x80 };
+	static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
+	static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
+	static u8 mt352_agc_cfg[] = { 0x67, 0x14, 0x22 };
+	static u8 mt352_sec_agc_cfg[] = { 0x69, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x40, 0x40 };
+
+	static u8 mt352_unk [] = { 0xb5, 0x7a };
+
+	static u8 mt352_acq_ctl[] = { 0x53, 0x5f };
+	static u8 mt352_input_freq_1[] = { 0x56, 0xf1, 0x05 };
+	
+//	static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+	mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+	udelay(2000);
+	mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+	mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
+	
+	mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+	mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
+
+	mt352_write(fe, mt352_sec_agc_cfg, sizeof(mt352_sec_agc_cfg));
+
+	mt352_write(fe, mt352_unk, sizeof(mt352_unk));
+	
+	mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
+	mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
+	
+//	mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+	return 0;
+}
+
+static int dibusb_general_demod_init(struct dvb_frontend *fe)
+{
+	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
+	switch (dib->dibdev->dev_cl->id) {
+		case UMT2_0:
+			return lg_tdtp_e102p_mt352_demod_init(fe);
+		default: /* other device classes do not have device specific demod inits */
+			break;
+	}
+	return 0;
+}
+
+static u8 dibusb_general_pll_addr(struct dvb_frontend *fe)
+{
+	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
+	return dib->tuner->pll_addr;
+}
+
+static int dibusb_pll_i2c_helper(struct usb_dibusb *dib, u8 pll_buf[5], u8 buf[4])
+{
+	if (pll_buf == NULL) {
+		struct i2c_msg msg = { 
+			.addr = dib->tuner->pll_addr, 
+			.flags = 0, 
+			.buf = buf, 
+			.len = sizeof(buf) 
+		};
+		if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1)
+			return -EIO;
+		msleep(1);
+	} else {
+		pll_buf[0] = dib->tuner->pll_addr << 1;
+		memcpy(&pll_buf[1],buf,4);
+	}
+
+	return 0;
+}
+
+static int dibusb_general_pll_init(struct dvb_frontend *fe, 
+		u8 pll_buf[5])
+{
+	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
+	u8 buf[4];
+	int ret=0;
+	switch (dib->tuner->id) {
+		case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
+			ret = panasonic_cofdm_env77h11d5_tda6650_init(fe,buf);
+			break;
+		default:
+			break;
+	}
+	
+	if (ret)
+		return ret;
+
+	return dibusb_pll_i2c_helper(dib,pll_buf,buf);
+}
+
+static int dibusb_general_pll_set(struct dvb_frontend *fe, 
+		struct dvb_frontend_parameters *fep, u8 pll_buf[5])
+{
+	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
+	u8 buf[4];
+	int ret=0;
+
+	switch (dib->tuner->id) {
+		case DIBUSB_TUNER_CABLE_THOMSON: 
+			ret = thomson_cable_eu_pll_set(fep, buf); 
+			break;
+		case DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5:
+			ret = panasonic_cofdm_env57h1xd5_pll_set(fep, buf);
+			break;
+		case DIBUSB_TUNER_CABLE_LG_TDTP_E102P:
+			ret = lg_tdtp_e102p_tua6034(fep, buf); 
+			break;
+		case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
+			ret = panasonic_cofdm_env77h11d5_tda6650_set(fep,buf);
+			break;
+		default:
+			warn("no pll programming routine found for tuner %d.\n",dib->tuner->id);
+			ret = -ENODEV;
+			break;
+	}
+	
+	if (ret)
+		return ret;
+	
+	return dibusb_pll_i2c_helper(dib,pll_buf,buf);
+}
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c	2005-01-07 12:49:57.000000000 +0100
@@ -0,0 +1,85 @@
+/*
+ * dvb-dibusb-firmware.c is part of the driver for mobile USB Budget DVB-T devices 
+ * based on reference design made by DiBcom (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * see dvb-dibusb-core.c for more copyright details.
+ *
+ * This file contains functions for downloading the firmware to the device.
+ */
+#include "dvb-dibusb.h"
+
+#include <linux/firmware.h>
+#include <linux/usb.h>
+
+/*
+ * load a firmware packet to the device 
+ */
+static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
+{
+	return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+			0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ);
+}
+
+int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev)
+{
+	const struct firmware *fw = NULL;
+	u16 addr;
+	u8 *b,*p;
+	int ret = 0,i;
+	
+	if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) {
+		err("did not find a valid firmware file. (%s) "
+			"Please see linux/Documentation/dvb/ for more details on firmware-problems.",
+			dibdev->dev_cl->firmware);
+		return ret;
+	}
+	
+	p = kmalloc(fw->size,GFP_KERNEL);	
+	if (p != NULL) {
+		u8 reset;
+		/*
+		 * you cannot use the fw->data as buffer for 
+		 * usb_control_msg, a new buffer has to be
+		 * created
+		 */
+		memcpy(p,fw->data,fw->size);
+
+		/* stop the CPU */
+		reset = 1;
+		if ((ret = dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1)) != 1) 
+			err("could not stop the USB controller CPU.");
+		for(i = 0; p[i+3] == 0 && i < fw->size; ) { 
+			b = (u8 *) &p[i];
+			addr = *((u16 *) &b[1]);
+
+			ret = dibusb_writemem(udev,addr,&b[4],b[0]);
+		
+			if (ret != b[0]) {
+				err("error while transferring firmware "
+					"(transferred size: %d, block size: %d)",
+					ret,b[0]);
+				ret = -EINVAL;
+				break;
+			}
+			i += 5 + b[0];
+		}
+		/* length in ret */
+		if (ret > 0)
+			ret = 0;
+		/* restart the CPU */
+		reset = 0;
+		if (ret || dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1) != 1) {
+			err("could not restart the USB controller CPU.");
+			ret = -EINVAL;
+		}
+
+		kfree(p);
+	} else { 
+		ret = -ENOMEM;
+	}
+	release_firmware(fw);
+
+	return ret;
+}
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb.h linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb.h
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb.h	2005-01-20 19:54:06.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb.h	2005-01-20 19:56:37.000000000 +0100
@@ -1,15 +1,14 @@
 /*
  * dvb-dibusb.h
  *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License as
  *	published by the Free Software Foundation, version 2.
  *
- * for more information see dvb-dibusb.c .
+ * for more information see dvb-dibusb-core.c .
  */
-
 #ifndef __DVB_DIBUSB_H__
 #define __DVB_DIBUSB_H__
 
@@ -13,281 +12,160 @@
 #ifndef __DVB_DIBUSB_H__
 #define __DVB_DIBUSB_H__
 
+#include <linux/input.h>
+#include <linux/config.h>
+#include <linux/usb.h>
+
+#include "dvb_frontend.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+#include "dmxdev.h"
+
 #include "dib3000.h"
+#include "mt352.h"
+
+/* debug */
+#ifdef CONFIG_DVB_DIBCOM_DEBUG
+#define dprintk(level,args...) \
+	    do { if ((debug & level)) { printk(args); } } while (0)
+
+#define debug_dump(b,l) if (debug) {\
+	int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \
+	for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
+	deb_xfer("\n");\
+}
+
+/* module parameters - declared in -core.c */
+extern int debug;
+
+#else
+#define dprintk(args...)
+#define debug_dump(b,l)
+#endif
+
+/* Version information */
+#define DRIVER_VERSION "0.3"
+#define DRIVER_DESC "Driver for DiBcom based USB Budget DVB-T device"
+#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
+
+/* module parameters - declared in -core.c */
+extern int pid_parse;
+extern int rc_query_interval;
+
+#define deb_info(args...) dprintk(0x01,args)
+#define deb_xfer(args...) dprintk(0x02,args)
+#define deb_alot(args...) dprintk(0x04,args)
+#define deb_ts(args...)   dprintk(0x08,args)
+#define deb_err(args...)  dprintk(0x10,args)
+#define deb_rc(args...)   dprintk(0x20,args)
+
+/* generic log methods - taken from usb.h */
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
+
+struct dibusb_usb_controller {
+	const char *name;       /* name of the usb controller */
+	u16 cpu_cs_register;    /* needs to be restarted, when the firmware has been downloaded. */
+};
 
 typedef enum {
 	DIBUSB1_1 = 0,
-	DIBUSB2_0,
 	DIBUSB1_1_AN2235,
-} dibusb_type;
+	DIBUSB2_0,
+	UMT2_0,
+} dibusb_class_t;
 
-static const char * dibusb_fw_filenames1_1[] = {
-	"dvb-dibusb-5.0.0.11.fw"
-};
+typedef enum {
+	DIBUSB_TUNER_CABLE_THOMSON = 0,
+	DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
+	DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
+	DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
+} dibusb_tuner_t;
 
-static const char * dibusb_fw_filenames1_1_an2235[] = {
-	"dvb-dibusb-an2235-1.fw"
-};
+typedef enum {
+	DIBUSB_DIB3000MB = 0,
+	DIBUSB_DIB3000MC,
+	DIBUSB_MT352,
+} dibusb_demodulator_t;
 
-static const char * dibusb_fw_filenames2_0[] = {
-	"dvb-dibusb-6.0.0.5.fw"
-};
+typedef enum {
+	DIBUSB_RC_NO = 0,
+	DIBUSB_RC_NEC_PROTOCOL = 1,
+} dibusb_remote_t;
 
-struct dibusb_device_parameter {
-	dibusb_type type;
-	u8 demod_addr;
-	const char **fw_filenames;
-	const char *usb_controller;
-	u16 usb_cpu_csreg;
-
-	int num_urbs;
-	int urb_buf_size;
-	int default_size;
-	int firmware_bug;
-
-	int cmd_pipe;
-	int result_pipe;
-	int data_pipe;
-};
+struct dibusb_tuner {
+	dibusb_tuner_t id;
 
-static struct dibusb_device_parameter dibusb_dev_parm[3] = {
-	{	.type = DIBUSB1_1,
-		.demod_addr = 0x10,
-		.fw_filenames = dibusb_fw_filenames1_1,
-		.usb_controller = "Cypress AN2135",
-		.usb_cpu_csreg = 0x7f92,
-
-		.num_urbs = 3,
-		.urb_buf_size = 4096,
-		.default_size = 188*21,
-		.firmware_bug = 1,
-
-		.cmd_pipe = 0x01,
-		.result_pipe = 0x81,
-		.data_pipe = 0x82,
-	},
-	{	.type = DIBUSB2_0,
-		.demod_addr = 0x18,
-		.fw_filenames = dibusb_fw_filenames2_0,
-		.usb_controller = "Cypress FX2",
-		.usb_cpu_csreg = 0xe600,
-
-		.num_urbs = 3,
-		.urb_buf_size = 40960,
-		.default_size = 188*210,
-		.firmware_bug = 0,
-
-		.cmd_pipe = 0x01,
-		.result_pipe = 0x81,
-		.data_pipe = 0x86,
-	},
-	{	.type = DIBUSB1_1_AN2235,
-		.demod_addr = 0x10,
-		.fw_filenames = dibusb_fw_filenames1_1_an2235,
-		.usb_controller = "Cypress CY7C64613 (AN2235)",
-		.usb_cpu_csreg = 0x7f92,
-
-		.num_urbs = 3,
-		.urb_buf_size = 4096,
-		.default_size = 188*21,
-		.firmware_bug = 1,
-
-		.cmd_pipe = 0x01,
-		.result_pipe = 0x81,
-		.data_pipe = 0x82,
-	}
+	u8 pll_addr;       /* tuner i2c address */
 };
+extern struct dibusb_tuner dibusb_tuner[];
 
-struct dibusb_device {
-	const char *name;
-	u16 cold_product_id;
-	u16 warm_product_id;
-	struct dibusb_device_parameter *parm;
-};
+#define DIBUSB_POSSIBLE_I2C_ADDR_NUM 4
+struct dibusb_demod {
+	dibusb_demodulator_t id;
 
-/* Vendor IDs */
-#define USB_VID_ANCHOR						0x0547
-#define USB_VID_AVERMEDIA					0x14aa
-#define USB_VID_COMPRO						0x185b
-#define USB_VID_COMPRO_UNK					0x145f
-#define USB_VID_CYPRESS						0x04b4
-#define USB_VID_DIBCOM						0x10b8
-#define USB_VID_EMPIA						0xeb1a
-#define USB_VID_GRANDTEC					0x5032
-#define USB_VID_HYPER_PALTEK				0x1025
-#define USB_VID_IMC_NETWORKS				0x13d3
-#define USB_VID_TWINHAN						0x1822
-#define USB_VID_ULTIMA_ELECTRONIC			0x05d8
-
-/* Product IDs */
-#define USB_PID_AVERMEDIA_DVBT_USB_COLD		0x0001
-#define USB_PID_AVERMEDIA_DVBT_USB_WARM		0x0002
-#define USB_PID_COMPRO_DVBU2000_COLD		0xd000
-#define USB_PID_COMPRO_DVBU2000_WARM		0xd001
-#define USB_PID_COMPRO_DVBU2000_UNK_COLD	0x010c
-#define USB_PID_COMPRO_DVBU2000_UNK_WARM	0x010d
-#define USB_PID_DIBCOM_MOD3000_COLD			0x0bb8
-#define USB_PID_DIBCOM_MOD3000_WARM			0x0bb9
-#define USB_PID_DIBCOM_MOD3001_COLD			0x0bc6
-#define USB_PID_DIBCOM_MOD3001_WARM			0x0bc7
-#define USB_PID_GRANDTEC_DVBT_USB_COLD		0x0fa0
-#define USB_PID_GRANDTEC_DVBT_USB_WARM		0x0fa1
-#define USB_PID_KWORLD_VSTREAM_COLD			0x17de
-#define USB_PID_KWORLD_VSTREAM_WARM			0x17df
-#define USB_PID_TWINHAN_VP7041_COLD			0x3201
-#define USB_PID_TWINHAN_VP7041_WARM			0x3202
-#define USB_PID_ULTIMA_TVBOX_COLD			0x8105
-#define USB_PID_ULTIMA_TVBOX_WARM			0x8106
-#define USB_PID_ULTIMA_TVBOX_AN2235_COLD	0x8107
-#define USB_PID_ULTIMA_TVBOX_AN2235_WARM	0x8108
-#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD	0x2235
-#define USB_PID_ULTIMA_TVBOX_USB2_COLD		0x8109
-#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD	0x8613
-#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM	0x1002
-#define USB_PID_UNK_HYPER_PALTEK_COLD		0x005e
-#define USB_PID_UNK_HYPER_PALTEK_WARM		0x005f
-#define USB_PID_YAKUMO_DTT200U_COLD			0x0201
-#define USB_PID_YAKUMO_DTT200U_WARM			0x0301
-
-#define DIBUSB_SUPPORTED_DEVICES	15
-
-/* USB Driver stuff */
-static struct dibusb_device dibusb_devices[DIBUSB_SUPPORTED_DEVICES] = {
-	{	.name = "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
-		.cold_product_id = USB_PID_TWINHAN_VP7041_COLD,
-		.warm_product_id = USB_PID_TWINHAN_VP7041_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
-		.cold_product_id = USB_PID_KWORLD_VSTREAM_COLD,
-		.warm_product_id = USB_PID_KWORLD_VSTREAM_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Grandtec USB1.1 DVB-T/DiBcom USB1.1 DVB-T reference design (MOD3000)",
-		.cold_product_id = USB_PID_DIBCOM_MOD3000_COLD,
-		.warm_product_id = USB_PID_DIBCOM_MOD3000_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Artec T1 USB1.1 TVBOX with AN2135",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_COLD,
-		.warm_product_id = USB_PID_ULTIMA_TVBOX_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Artec T1 USB1.1 TVBOX with AN2235",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_AN2235_COLD,
-		.warm_product_id = USB_PID_ULTIMA_TVBOX_AN2235_WARM,
-		.parm = &dibusb_dev_parm[2],
-	},
-	{	.name = "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_ANCHOR_COLD,
-		.warm_product_id = 0, /* undefined, this design becomes USB_PID_DIBCOM_MOD3000_WARM in warm state */
-		.parm = &dibusb_dev_parm[2],
-	},
-	{	.name = "Artec T1 USB2.0 TVBOX (please report the warm ID)",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_USB2_COLD,
-		.warm_product_id = 0, /* don't know, it is most likely that the device will get another USB ID in warm state */
-		.parm = &dibusb_dev_parm[1],
-	},
-	{	.name = "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
-		.cold_product_id = USB_PID_ULTIMA_TVBOX_USB2_FX_COLD,
-		.warm_product_id = USB_PID_ULTIMA_TVBOX_USB2_FX_WARM, /* undefined, it could be that the device will get another USB ID in warm state */
-		.parm = &dibusb_dev_parm[1],
-	},
-	{	.name = "Compro Videomate DVB-U2000 - DVB-T USB1.1",
-		.cold_product_id = USB_PID_COMPRO_DVBU2000_COLD,
-		.warm_product_id = USB_PID_COMPRO_DVBU2000_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Compro Videomate DVB-U2000 - DVB-T USB1.1 (really ?? please report the name!)",
-		.cold_product_id = USB_PID_COMPRO_DVBU2000_UNK_COLD,
-		.warm_product_id = USB_PID_COMPRO_DVBU2000_UNK_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Unkown USB1.1 DVB-T device ???? please report the name to the author",
-		.cold_product_id = USB_PID_UNK_HYPER_PALTEK_COLD,
-		.warm_product_id = USB_PID_UNK_HYPER_PALTEK_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
-		.cold_product_id = USB_PID_DIBCOM_MOD3001_COLD,
-		.warm_product_id = USB_PID_DIBCOM_MOD3001_WARM,
-		.parm = &dibusb_dev_parm[1],
-	},
-	{	.name = "Grandtec DVB-T USB1.1",
-		.cold_product_id = USB_PID_GRANDTEC_DVBT_USB_COLD,
-		.warm_product_id = USB_PID_GRANDTEC_DVBT_USB_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Avermedia AverTV DVBT USB1.1",
-		.cold_product_id = USB_PID_AVERMEDIA_DVBT_USB_COLD,
-		.warm_product_id = USB_PID_AVERMEDIA_DVBT_USB_WARM,
-		.parm = &dibusb_dev_parm[0],
-	},
-	{	.name = "Yakumo DVB-T mobile USB2.0",
-		.cold_product_id = USB_PID_YAKUMO_DTT200U_COLD,
-		.warm_product_id = USB_PID_YAKUMO_DTT200U_WARM,
-		.parm = &dibusb_dev_parm[1],
-	}
+	int pid_filter_count;                       /* counter of the internal pid_filter */
+	u8 i2c_addrs[DIBUSB_POSSIBLE_I2C_ADDR_NUM]; /* list of possible i2c addresses of the demod */
 };
 
-/* USB Driver stuff */
-/* table of devices that work with this driver */
-static struct usb_device_id dibusb_table [] = {
-	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_AVERMEDIA_DVBT_USB_COLD)},
-	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_AVERMEDIA_DVBT_USB_WARM)},
-	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_COLD) },
-	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_WARM) },
-	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_COLD) },
-	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_WARM) },
-	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_COLD) },
-	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_WARM) },
-	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_COLD) },
-	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_WARM) },
-	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_COLD) },
-	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_WARM) },
-	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_COLD) },
-	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_WARM) },
-	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_COLD) },
-	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_WARM) },
-	{ USB_DEVICE(USB_VID_IMC_NETWORKS,	USB_PID_TWINHAN_VP7041_COLD) },
-	{ USB_DEVICE(USB_VID_IMC_NETWORKS,	USB_PID_TWINHAN_VP7041_WARM) },
-	{ USB_DEVICE(USB_VID_TWINHAN, 		USB_PID_TWINHAN_VP7041_COLD) },
-	{ USB_DEVICE(USB_VID_TWINHAN, 		USB_PID_TWINHAN_VP7041_WARM) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
-	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_YAKUMO_DTT200U_COLD) },
-	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_YAKUMO_DTT200U_WARM) },
-	{ USB_DEVICE(USB_PID_COMPRO_DVBU2000_UNK_COLD, USB_VID_COMPRO_UNK) },
-	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+#define DIBUSB_MAX_TUNER_NUM 2
+struct dibusb_device_class {
+	dibusb_class_t id;
 
-/*
- * 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
-	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
-	{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
-	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
-#endif
-	{ }                 /* Terminating entry */
+	const struct dibusb_usb_controller *usb_ctrl; /* usb controller */
+	const char *firmware;                         /* valid firmware filenames */
+
+	int pipe_cmd;                                 /* command pipe (read/write) */
+	int pipe_data;                                /* data pipe */
+	
+	int urb_count;                                /* number of data URBs to be submitted */
+	int urb_buffer_size;                          /* the size of the buffer for each URB */
+
+	dibusb_remote_t remote_type;                  /* does this device have a ir-receiver */
+
+	struct dibusb_demod *demod;                   /* which demodulator is mount */
+	struct dibusb_tuner *tuner;                   /* which tuner can be found here */
 };
 
-MODULE_DEVICE_TABLE (usb, dibusb_table);
+#define DIBUSB_ID_MAX_NUM 15
+struct dibusb_usb_device {
+	const char *name;                                 /* real name of the box */
+	struct dibusb_device_class *dev_cl;               /* which dibusb_device_class is this device part of */
 
-#define DIBUSB_I2C_TIMEOUT 				HZ*5
+	struct usb_device_id *cold_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at pre firmware state */
+	struct usb_device_id *warm_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at post firmware state */
+};
+
+/* a PID for the pid_filter list, when in use */
+struct dibusb_pid
+{
+	int index;
+	u16 pid;
+	int active;
+};
 
 struct usb_dibusb {
 	/* usb */
 	struct usb_device * udev;
 
-	struct dibusb_device * dibdev;
+	struct dibusb_usb_device * dibdev;
+
+#define DIBUSB_STATE_INIT       0x000
+#define DIBUSB_STATE_URB_LIST   0x001
+#define DIBUSB_STATE_URB_BUF    0x002
+#define DIBUSB_STATE_URB_SUBMIT 0x004 
+#define DIBUSB_STATE_DVB        0x008
+#define DIBUSB_STATE_I2C        0x010
+#define DIBUSB_STATE_REMOTE		0x020
+#define DIBUSB_STATE_PIDLIST    0x040
+	int init_state;
 
 	int feedcount;
 	int pid_parse;
-	struct dib3000_xfer_ops xfer_ops;
+	struct dib_fe_xfer_ops xfer_ops;
+
+	struct dibusb_tuner *tuner;
 
 	struct urb **urb_list;
 	u8 *buffer;
@@ -295,49 +173,137 @@
 
 	/* I2C */
 	struct i2c_adapter i2c_adap;
-	struct i2c_client i2c_client;
 
 	/* locking */
 	struct semaphore usb_sem;
 	struct semaphore i2c_sem;
 
+	/* pid filtering */
+	spinlock_t pid_list_lock;
+	struct dibusb_pid *pid_list;
+	
 	/* dvb */
-	int dvb_is_ready;
 	struct dvb_adapter *adapter;
 	struct dmxdev dmxdev;
 	struct dvb_demux demux;
 	struct dvb_net dvb_net;
 	struct dvb_frontend* fe;
 
+	int (*fe_sleep) (struct dvb_frontend *);
+	int (*fe_init) (struct dvb_frontend *);
+
 	/* remote control */
 	struct input_dev rc_input_dev;
 	struct work_struct rc_query_work;
 	int rc_input_event;
 };
 
+/* commonly used functions in the separated files */
+
+/* dvb-dibusb-firmware.c */
+int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev);
+
+/* dvb-dibusb-remote.c */
+int dibusb_remote_exit(struct usb_dibusb *dib);
+int dibusb_remote_init(struct usb_dibusb *dib);
+
+/* dvb-dibusb-fe-i2c.c */
+int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr, 
+		u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen);
+int dibusb_fe_init(struct usb_dibusb* dib);
+int dibusb_fe_exit(struct usb_dibusb *dib);
+int dibusb_i2c_init(struct usb_dibusb *dib);
+int dibusb_i2c_exit(struct usb_dibusb *dib);
+
+/* dvb-dibusb-dvb.c */
+void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs);
+int dibusb_dvb_init(struct usb_dibusb *dib);
+int dibusb_dvb_exit(struct usb_dibusb *dib);
+
+/* dvb-dibusb-usb.c */
+int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
+	u16 rlen);
+
+int dibusb_hw_wakeup(struct dvb_frontend *);
+int dibusb_hw_sleep(struct dvb_frontend *);
+int dibusb_set_streaming_mode(struct usb_dibusb *,u8);
+int dibusb_streaming(struct usb_dibusb *,int);
+
+int dibusb_urb_init(struct usb_dibusb *);
+int dibusb_urb_exit(struct usb_dibusb *);
+
+/* dvb-dibusb-pid.c */
+int dibusb_pid_list_init(struct usb_dibusb *dib);
+void dibusb_pid_list_exit(struct usb_dibusb *dib);
+int dibusb_ctrl_pid(struct usb_dibusb *dib, struct dvb_demux_feed *dvbdmxfeed , int onoff);
+
+/* i2c and transfer stuff */
+#define DIBUSB_I2C_TIMEOUT				HZ*5
+
+/* 
+ * protocol of all dibusb related devices
+ */
 
-/* types of first byte of each buffer */
+/* 
+ * bulk msg to/from endpoint 0x01
+ *
+ * general structure:
+ * request_byte parameter_bytes
+ */
 
 #define DIBUSB_REQ_START_READ			0x00
 #define DIBUSB_REQ_START_DEMOD			0x01
+
+/* 
+ * i2c read 
+ * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
+ * bulk read:  byte_buffer (length_word bytes)
+ */
 #define DIBUSB_REQ_I2C_READ  			0x02
+ 
+/*
+ * i2c write
+ * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
+ */
 #define DIBUSB_REQ_I2C_WRITE 			0x03
 
-/* prefix for reading the current RC key */
+/* 
+ * polling the value of the remote control 
+ * bulk write: 0x04
+ * bulk read:  byte_buffer (5 bytes) 
+ *
+ * first byte of byte_buffer shows the status (0x00, 0x01, 0x02)
+ */
 #define DIBUSB_REQ_POLL_REMOTE			0x04
 
 #define DIBUSB_RC_NEC_EMPTY				0x00
 #define DIBUSB_RC_NEC_KEY_PRESSED		0x01
 #define DIBUSB_RC_NEC_KEY_REPEATED		0x02
 
-/* 0x05 0xXX */
+/* streaming mode:
+ * bulk write: 0x05 mode_byte 
+ *
+ * mode_byte is mostly 0x00
+ */
 #define DIBUSB_REQ_SET_STREAMING_MODE	0x05
 
 /* interrupt the internal read loop, when blocking */
 #define DIBUSB_REQ_INTR_READ		   	0x06
 
-/* IO control
- * 0x07 <cmd 1 byte> <param 32 bytes>
+/* io control
+ * 0x07 cmd_byte param_bytes
+ *
+ * param_bytes can be up to 32 bytes
+ *
+ * cmd_byte function    parameter name 
+ * 0x00     power mode
+ *                      0x00      sleep
+ *                      0x01      wakeup
+ *
+ * 0x01     enable streaming 
+ * 0x02     disable streaming
+ *
+ *
  */
 #define DIBUSB_REQ_SET_IOCTL			0x07
 
@@ -348,4 +314,8 @@
 #define DIBUSB_IOCTL_POWER_SLEEP			0x00
 #define DIBUSB_IOCTL_POWER_WAKEUP			0x01
 
+/* modify streaming of the FX2 */
+#define DIBUSB_IOCTL_CMD_ENABLE_STREAM	0x01
+#define DIBUSB_IOCTL_CMD_DISABLE_STREAM	0x02
+
 #endif
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-pid.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-pid.c
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-pid.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-pid.c	2005-01-13 14:24:13.000000000 +0100
@@ -0,0 +1,80 @@
+/*
+ * dvb-dibusb-pid.c is part of the driver for mobile USB Budget DVB-T devices 
+ * based on reference design made by DiBcom (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * see dvb-dibusb-core.c for more copyright details.
+ *
+ * This file contains functions for initializing and handling the internal
+ * pid-list. This pid-list mirrors the information currently stored in the
+ * devices pid-list.
+ */
+#include "dvb-dibusb.h"
+
+int dibusb_pid_list_init(struct usb_dibusb *dib)
+{
+	int i;
+	dib->pid_list = kmalloc(sizeof(struct dibusb_pid) * dib->dibdev->dev_cl->demod->pid_filter_count,GFP_KERNEL);
+	if (dib->pid_list == NULL)
+		return -ENOMEM;
+
+	deb_xfer("initializing %d pids for the pid_list.\n",dib->dibdev->dev_cl->demod->pid_filter_count);
+	
+	dib->pid_list_lock = SPIN_LOCK_UNLOCKED;
+	memset(dib->pid_list,0,dib->dibdev->dev_cl->demod->pid_filter_count*(sizeof(struct dibusb_pid)));
+	for (i=0; i < dib->dibdev->dev_cl->demod->pid_filter_count; i++) {
+		dib->pid_list[i].index = i;
+		dib->pid_list[i].pid = 0;
+		dib->pid_list[i].active = 0;
+	}
+
+	dib->init_state |= DIBUSB_STATE_PIDLIST;
+	return 0;
+}
+
+void dibusb_pid_list_exit(struct usb_dibusb *dib)
+{
+	if (dib->init_state & DIBUSB_STATE_PIDLIST)
+		kfree(dib->pid_list);
+	dib->init_state &= ~DIBUSB_STATE_PIDLIST;
+}
+
+/* fetch a pid from pid_list and set it on or off */
+int dibusb_ctrl_pid(struct usb_dibusb *dib, struct dvb_demux_feed *dvbdmxfeed , int onoff)
+{
+	int i,ret = -1;
+	unsigned long flags;
+	u16 pid = dvbdmxfeed->pid;
+
+	if (onoff) {
+		spin_lock_irqsave(&dib->pid_list_lock,flags);
+		for (i=0; i < dib->dibdev->dev_cl->demod->pid_filter_count; i++)
+			if (!dib->pid_list[i].active) {
+				dib->pid_list[i].pid = pid;
+				dib->pid_list[i].active = 1;
+				ret = i;
+				break;
+			}
+		dvbdmxfeed->priv = &dib->pid_list[ret];
+		spin_unlock_irqrestore(&dib->pid_list_lock,flags);
+		
+		if (dib->xfer_ops.pid_ctrl != NULL) 
+			dib->xfer_ops.pid_ctrl(dib->fe,dib->pid_list[ret].index,dib->pid_list[ret].pid,1);
+	} else {
+		struct dibusb_pid *dpid = dvbdmxfeed->priv;
+		
+		if (dib->xfer_ops.pid_ctrl != NULL) 
+			dib->xfer_ops.pid_ctrl(dib->fe,dpid->index,0,0);
+		
+		dpid->pid = 0;
+		dpid->active = 0;
+		ret = dpid->index;
+	}
+	
+	/* a free pid from the list */
+	deb_info("setting pid: %5d %04x at index %d '%s'\n",pid,pid,ret,onoff ? "on" : "off");
+
+	return ret;
+}
+
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-remote.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-remote.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-remote.c	2005-01-09 16:50:44.000000000 +0100
@@ -0,0 +1,197 @@
+/*
+ * dvb-dibusb-remote.c is part of the driver for mobile USB Budget DVB-T devices
+ * based on reference design made by DiBcom (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * see dvb-dibusb-core.c for more copyright details.
+ *
+ * This file contains functions for handling the event device on the software
+ * side and the remote control on the hardware side.
+ */
+#include "dvb-dibusb.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; } 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 },
+};
+
+/*
+ * Read the remote control and feed the appropriate event.
+ * NEC protocol is used for remote controls
+ */
+static int dibusb_read_remote_control(struct usb_dibusb *dib)
+{
+	u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5];
+	int ret;
+	int i;
+	if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
+		return ret;
+
+	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 ((0xff - rb[3]) != rb[4]) {
+				deb_rc("remote control checksum failed.\n");
+				break;
+			}
+
+			/* See if we can match the raw key code. */
+			for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++) {
+				if (rc_keys[i].c0 == rb[1] &&
+					rc_keys[i].c1 == rb[2] &&
+				    rc_keys[i].c2 == rb[3]) {
+					dib->rc_input_event = rc_keys[i].key;
+					deb_rc("Translated key 0x%04x\n", dib->rc_input_event);
+					/* Signal down and up events for this key. */
+					input_report_key(&dib->rc_input_dev, dib->rc_input_event, 1);
+					input_report_key(&dib->rc_input_dev, dib->rc_input_event, 0);
+					input_sync(&dib->rc_input_dev);
+					break;
+				}
+			}
+			break;
+		case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
+			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. */
+			deb_rc("Key repeat\n");
+			break;
+		default:
+			break;
+	}
+	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)
+{
+	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(rc_query_interval));
+}
+
+int dibusb_remote_init(struct usb_dibusb *dib)
+{
+	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";
+
+	for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
+		set_bit(rc_keys[i].key, dib->rc_input_dev.keybit);
+
+	input_register_device(&dib->rc_input_dev);
+
+	dib->rc_input_event = KEY_MAX;
+
+	INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib);
+
+	/* Start the remote-control polling. */
+	if (rc_query_interval < 40)
+		rc_query_interval = 100; /* default */
+
+	info("schedule remote query interval to %d msecs.",rc_query_interval);
+	schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(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;
+}
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-usb.c linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/dvb-dibusb-usb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/dvb-dibusb-usb.c	2005-01-13 14:24:13.000000000 +0100
@@ -0,0 +1,259 @@
+/*
+ * dvb-dibusb-usb.c is part of the driver for mobile USB Budget DVB-T devices 
+ * based on reference design made by DiBcom (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * see dvb-dibusb-core.c for more copyright details.
+ *
+ * This file contains functions for initializing and handling the 
+ * usb specific stuff.
+ */
+#include "dvb-dibusb.h"
+
+#include <linux/version.h>
+#include <linux/pci.h>
+
+int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
+		u16 rlen)
+{
+	int actlen,ret = -ENOMEM;
+
+	if (wbuf == NULL || wlen == 0)
+		return -EINVAL;
+
+	if ((ret = down_interruptible(&dib->usb_sem)))
+		return ret;
+
+	if (dib->feedcount && 
+		wbuf[0] == DIBUSB_REQ_I2C_WRITE && 
+		dib->dibdev->dev_cl->id == DIBUSB1_1)
+		deb_err("BUG: writing to i2c, while TS-streaming destroys the stream."
+				"(%x reg: %x %x)\n", wbuf[0],wbuf[2],wbuf[3]);
+			
+	debug_dump(wbuf,wlen);
+
+	ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
+			dib->dibdev->dev_cl->pipe_cmd), wbuf,wlen,&actlen,
+			DIBUSB_I2C_TIMEOUT);
+		
+	if (ret)
+		err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
+	else
+		ret = actlen != wlen ? -1 : 0;
+
+	/* an answer is expected, and no error before */
+	if (!ret && rbuf && rlen) {
+		ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev,
+				dib->dibdev->dev_cl->pipe_cmd),rbuf,rlen,&actlen,
+				DIBUSB_I2C_TIMEOUT);
+
+		if (ret)
+			err("recv bulk message failed: %d",ret);
+		else {
+			deb_alot("rlen: %d\n",rlen);
+			debug_dump(rbuf,actlen);
+		}
+	}
+	
+	up(&dib->usb_sem);
+	return ret;
+}
+
+/*
+ * Cypress controls
+ */
+
+#if 0
+/* 
+ * #if 0'ing the following functions as they are not in use _now_, 
+ * but probably will be sometime.
+ */
+
+/*
+ * do not use this, just a workaround for a bug, 
+ * which will hopefully never occur :).
+ */
+int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
+{
+	u8 b[1] = { DIBUSB_REQ_INTR_READ };
+	return dibusb_write_usb(dib,b,1);
+}
+
+#endif 
+static int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
+{
+	return dibusb_readwrite_usb(dib,buf,len,NULL,0);
+}
+
+/*
+ * ioctl for the firmware 
+ */
+static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen)
+{
+	u8 b[34];
+	int size = plen > 32 ? 32 : plen;
+	memset(b,0,34);
+	b[0] = DIBUSB_REQ_SET_IOCTL;
+	b[1] = cmd;
+
+	if (size > 0)
+		memcpy(&b[2],param,size);
+
+	return dibusb_write_usb(dib,b,34); //2+size);
+}
+
+/*
+ * ioctl for power control
+ */
+int dibusb_hw_wakeup(struct dvb_frontend *fe)
+{
+	struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
+	u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP };
+	deb_info("dibusb-device is getting up.\n");
+	dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
+	
+	if (dib->fe_init)
+		return dib->fe_init(fe);
+	
+	return 0;
+}
+
+int dibusb_hw_sleep(struct dvb_frontend *fe)
+{
+	struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
+	u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP };
+	deb_info("dibusb-device is going to bed.\n");
+	dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
+
+	if (dib->fe_sleep)
+		return dib->fe_sleep(fe);
+	
+	return 0;
+}
+
+int dibusb_set_streaming_mode(struct usb_dibusb *dib,u8 mode)
+{
+	u8 b[2] = { DIBUSB_REQ_SET_STREAMING_MODE, mode };
+	return dibusb_readwrite_usb(dib,b,2,NULL,0);
+}
+
+int dibusb_streaming(struct usb_dibusb *dib,int onoff)
+{
+	switch (dib->dibdev->dev_cl->id) {
+		case DIBUSB2_0:
+			if (onoff)
+				return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0);
+			else
+				return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_DISABLE_STREAM,NULL,0);
+			break;
+		case UMT2_0: 
+			return dibusb_set_streaming_mode(dib,onoff);
+			break;
+		default:
+			break;
+	}
+	return 0;
+}
+
+int dibusb_urb_init(struct usb_dibusb *dib)
+{
+	int ret,i,bufsize;
+	
+	/*
+	 * when reloading the driver w/o replugging the device 
+	 * a timeout occures, this helps
+	 */
+	usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
+	usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
+	usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data));
+
+	/* allocate the array for the data transfer URBs */
+	dib->urb_list = kmalloc(dib->dibdev->dev_cl->urb_count*sizeof(struct urb *),GFP_KERNEL);
+	if (dib->urb_list == NULL)
+		return -ENOMEM;
+	memset(dib->urb_list,0,dib->dibdev->dev_cl->urb_count*sizeof(struct urb *));
+
+	dib->init_state |= DIBUSB_STATE_URB_LIST;
+	
+	bufsize = dib->dibdev->dev_cl->urb_count*dib->dibdev->dev_cl->urb_buffer_size;
+	deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
+	/* allocate the actual buffer for the URBs */
+	if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) {
+		deb_info("not enough memory.\n");
+		return -ENOMEM;
+	}
+	deb_info("allocation complete\n");
+	memset(dib->buffer,0,bufsize);
+	
+	dib->init_state |= DIBUSB_STATE_URB_BUF;
+
+	/* allocate and submit the URBs */
+	for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
+		if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
+			return -ENOMEM;
+		}
+		deb_info("submitting URB no. %d\n",i);
+		
+		usb_fill_bulk_urb( dib->urb_list[i], dib->udev, 
+				usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data),
+				&dib->buffer[i*dib->dibdev->dev_cl->urb_buffer_size], 
+				dib->dibdev->dev_cl->urb_buffer_size, 
+				dibusb_urb_complete, dib);
+		
+		dib->urb_list[i]->transfer_flags = 0;
+
+		if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) {
+			err("could not submit buffer urb no. %d\n",i);
+			return ret;
+		}
+		dib->init_state |= DIBUSB_STATE_URB_SUBMIT;
+	}
+
+
+	dib->pid_parse = 1;
+	switch (dib->dibdev->dev_cl->id) {
+		case DIBUSB2_0:
+			if (dib->udev->speed == USB_SPEED_HIGH && !pid_parse) {
+				dib->pid_parse = 0;
+				info("running at HIGH speed, will deliver the complete TS.");
+			} else
+				info("will use pid_parsing.");
+			break;
+		default: 
+			break;
+	}
+	
+	return 0;
+}
+
+int dibusb_urb_exit(struct usb_dibusb *dib)
+{
+	int i;
+	if (dib->init_state & DIBUSB_STATE_URB_LIST) {
+		for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
+			if (dib->urb_list[i] != NULL) {
+				deb_info("killing URB no. %d.\n",i);
+
+				/* stop the URBs */
+				usb_kill_urb(dib->urb_list[i]);
+				
+				deb_info("freeing URB no. %d.\n",i);
+				/* free the URBs */
+				usb_free_urb(dib->urb_list[i]);
+			}
+		}
+		/* free the urb array */
+		kfree(dib->urb_list);
+		dib->init_state &= ~DIBUSB_STATE_URB_SUBMIT;
+		dib->init_state &= ~DIBUSB_STATE_URB_LIST;
+	}
+
+	if (dib->init_state & DIBUSB_STATE_URB_BUF)
+		pci_free_consistent(NULL,
+			dib->dibdev->dev_cl->urb_buffer_size*dib->dibdev->dev_cl->urb_count,
+			dib->buffer,dib->dma_handle);
+
+	dib->init_state &= ~DIBUSB_STATE_URB_BUF;
+	return 0;
+}
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/Kconfig linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/Kconfig
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/Kconfig	2005-01-20 19:56:17.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/Kconfig	2005-01-20 19:56:37.000000000 +0100
@@ -1,12 +1,13 @@
 config DVB_DIBUSB
-	tristate "DiBcom USB DVB-T devices (see help for device list)"
+	tristate "DiBcom USB DVB-T devices (see help for a complete device list)"
 	depends on DVB_CORE && USB
 	select FW_LOADER
 	select DVB_DIB3000MB
 	select DVB_DIB3000MC
+	select DVB_MT352
 	help
 	  Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
-	  DiBcom (<http://www.dibcom.fr>).
+	  DiBcom (http://www.dibcom.fr) and C&E.
 
 	  Devices supported by this driver:
 
@@ -14,12 +15,14 @@
 		TwinhanDTV Magic Box (VP7041e)
 	    KWorld V-Stream XPERT DTV - DVB-T USB
 	    Hama DVB-T USB-Box
-	    DiBcom reference device (non-public)
+	    DiBcom reference devices (non-public)
 	    Ultima Electronic/Artec T1 USB TVBOX
 	    Compro Videomate DVB-U2000 - DVB-T USB
 	    Grandtec DVB-T USB
 	    Avermedia AverTV DVBT USB
-	    Yakumo DVB-T mobile USB2.0
+	    Artec T1 USB1.1 and USB2.0 boxes
+	    Yakumo/Typhoon DVB-T USB2.0
+	    Hanftek UMT-010 USB2.0
 
 	  The VP7041 seems to be identical to "CTS Portable" (Chinese
 	  Television System).
@@ -27,7 +30,7 @@
 	  These devices can be understood as budget ones, they "only" deliver
 	  (a part of) the MPEG2 transport stream.
 
-	  A firmware is needed to get the device working. See <file:Documentation/dvb/README.dibusb>
+	  A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
 	  details.
 
 	  Say Y if you own such a device and want to use it. You should build it as
@@ -46,6 +49,7 @@
 	    0x0574:0x2235 (Artec T1 USB1.1, cold)
 	    0x04b4:0x8613 (Artec T1 USB2.0, cold)
 	    0x0574:0x1002 (Artec T1 USB2.0, warm)
+	    0x0574:0x2131 (aged DiBcom USB1.1 test device)
 
 	  Say Y if your device has one of the mentioned IDs.
 
diff -uraNwB linux-2.6.11-rc2/drivers/media/dvb/dibusb/Makefile linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/Makefile
--- linux-2.6.11-rc2/drivers/media/dvb/dibusb/Makefile	2005-01-20 19:54:06.000000000 +0100
+++ linux-2.6.11-rc2-dvb/drivers/media/dvb/dibusb/Makefile	2005-01-20 19:56:37.000000000 +0100
@@ -1,3 +1,11 @@
+dvb-dibusb-objs = dvb-dibusb-core.o \
+	dvb-dibusb-dvb.o \
+	dvb-dibusb-fe-i2c.o \
+	dvb-dibusb-firmware.o \
+	dvb-dibusb-remote.o \
+	dvb-dibusb-usb.o \
+	dvb-dibusb-pid.o
+
 obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
 
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/


  parent reply	other threads:[~2005-01-22 18:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-22 17:34 [PATCH 0/9] 2.6.11-rc2 DVB update Johannes Stezenbach
2005-01-22 17:34 ` [PATCH 1/9] fix RPS init race Johannes Stezenbach
2005-01-22 17:34 ` [PATCH 2/9] support pinnacle pctv-sat, clean-ups Johannes Stezenbach
2005-01-22 17:34 ` Johannes Stezenbach [this message]
2005-01-22 17:34 ` [PATCH 4/9] support nxt2002 frontend, misc skystar2 fixes Johannes Stezenbach
2005-01-22 17:34 ` [PATCH 5/9] add ATSC support, misc fixes Johannes Stezenbach
2005-01-22 17:34 ` [PATCH 6/9] refactoring Johannes Stezenbach
2005-01-22 17:34 ` [PATCH 7/9] nxt2002: add ATSC support, misc fixes Johannes Stezenbach
2005-01-22 17:34 ` [PATCH 8/9] dvb-ttpci: fix SMP race, budget: fixe init race, " Johannes Stezenbach

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11064152683716@linuxtv.org \
    --to=js@linuxtv.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.