public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] LinuxTV.org DVB update
@ 2004-02-23 21:04 Michael Hunold
  2004-02-23 21:04 ` [PATCH 1/9] Update the DVB subsystem docs Michael Hunold
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:04 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

Hello Linus, Andrew,

I'm sending you a set of 9 patches that sync the
LinuxTV.org CVS with latest linux-2.6.3.

As usual, detailed informations about what changed can be 
found at the top of each file.

The biggest changes touch the documentation and the various dvb
frontend drivers.

Please apply! 

CU
Michael.



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 2/9] Update saa7146 driver core
  2004-02-23 21:04 ` [PATCH 1/9] Update the DVB subsystem docs Michael Hunold
@ 2004-02-23 21:04   ` Michael Hunold
  2004-02-23 21:04     ` [PATCH 3/9] Minor DVB Skystar2 updates Michael Hunold
  2004-02-23 22:23   ` [PATCH 1/9] Update the DVB subsystem docs Richard B. Johnson
  1 sibling, 1 reply; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:04 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

- [DVB] saa7146: fix timeout bug on AMD64 in saa7146_wait_for_debi_done()
- [DVB] saa7146: release resources for video overlay properly, don't (incorrectly) rely on VIDIOC_OVERLAY(0)
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/common/saa7146_core.c linux-2.6.3.p/drivers/media/common/saa7146_core.c
--- xx-linux-2.6.3/drivers/media/common/saa7146_core.c	2004-02-23 12:34:26.000000000 +0100
+++ linux-2.6.3.p/drivers/media/common/saa7146_core.c	2004-02-23 12:52:31.000000000 +0100
@@ -69,14 +69,14 @@
 /* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
 int saa7146_wait_for_debi_done(struct saa7146_dev *dev)
 {
-	int start;
+	unsigned long start;
 
 	/* wait for registers to be programmed */
 	start = jiffies;
 	while (1) {
                 if (saa7146_read(dev, MC2) & 2)
                         break;
-		if (jiffies-start > HZ/20) {
+		if (time_after(jiffies, start + HZ/20)) {
 			DEB_S(("timed out while waiting for registers getting programmed\n"));
 			return -ETIMEDOUT;
 		}
@@ -88,7 +88,7 @@
 		if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
 			break;
 		saa7146_read(dev, MC2);
-		if (jiffies-start > HZ/4) {
+		if (time_after(jiffies, start + HZ/4)) {
 			DEB_S(("timed out while waiting for transfer completion\n"));
 			return -ETIMEDOUT;
 		}
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/common/saa7146_video.c linux-2.6.3.p/drivers/media/common/saa7146_video.c
--- xx-linux-2.6.3/drivers/media/common/saa7146_video.c	2004-02-23 12:34:26.000000000 +0100
+++ linux-2.6.3.p/drivers/media/common/saa7146_video.c	2004-02-02 21:13:12.000000000 +0100
@@ -1413,6 +1419,7 @@
 			spin_lock_irqsave(&dev->slock,flags);
 			saa7146_stop_preview(fh);
 			spin_unlock_irqrestore(&dev->slock,flags);
+			saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
 		}
 	}
 	



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 3/9] Minor DVB Skystar2 updates
  2004-02-23 21:04   ` [PATCH 2/9] Update saa7146 driver core Michael Hunold
@ 2004-02-23 21:04     ` Michael Hunold
  2004-02-23 21:04       ` [PATCH 4/9] DVB core update Michael Hunold
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:04 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

[DVB] - skystar2: renamed two functions, deleted spurious spaces.
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/b2c2/skystar2.c linux-2.6.3.p/drivers/media/dvb/b2c2/skystar2.c
--- xx-linux-2.6.3/drivers/media/dvb/b2c2/skystar2.c	2004-01-09 09:22:39.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/b2c2/skystar2.c	2004-02-02 19:28:29.000000000 +0100
@@ -500,7 +501,7 @@
 	}
 }
 
-static void sram_writeChunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
+static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
 {
 	u32 bank;
 
@@ -520,7 +521,7 @@
 	flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
 }
 
-static void sram_readChunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
+static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
 {
 	u32 bank;
 
@@ -554,7 +555,7 @@
 			length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
 		}
 
-		sram_readChunk(adapter, addr, buf, length);
+		sram_read_chunk(adapter, addr, buf, length);
 
 		addr = addr + length;
 		buf = buf + length;
@@ -576,7 +577,7 @@
 			length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
 		}
 
-		sram_writeChunk(adapter, addr, buf, length);
+		sram_write_chunk(adapter, addr, buf, length);
 
 		addr = addr + length;
 		buf = buf + length;



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 4/9] DVB core update
  2004-02-23 21:04     ` [PATCH 3/9] Minor DVB Skystar2 updates Michael Hunold
@ 2004-02-23 21:04       ` Michael Hunold
  2004-02-23 21:04         ` [PATCH 5/9] Misc. DVB frontend updates Michael Hunold
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:04 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

- [DVB] - dvb-core: replace usage of sleep_on_...() with wait_event_interruptible_timeout()
- [DVB] - dvb-core: fix dvb_ringbuffer_read/write() buffer pointer bug
- [DVB] video: added VIDEO_EVENT_FRAME_RATE_CHANGED and VIDEO_GET_FRAME_RATE ioctl
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/dvb-core/dvb_frontend.c linux-2.6.3.p/drivers/media/dvb/dvb-core/dvb_frontend.c
--- xx-linux-2.6.3/drivers/media/dvb/dvb-core/dvb_frontend.c	2004-02-23 12:34:27.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/dvb-core/dvb_frontend.c	2004-02-09 18:30:22.000000000 +0100
@@ -426,6 +426,7 @@
 static int dvb_frontend_thread (void *data)
 {
 	struct dvb_frontend_data *fe = (struct dvb_frontend_data *) data;
+	unsigned long timeout;
 	char name [15];
 	int quality = 0, delay = 3*HZ;
 	fe_status_t s;
@@ -442,12 +443,14 @@
 	dvb_call_frontend_notifiers (fe, 0);
 	dvb_frontend_init (fe);
 
-	while (!dvb_frontend_is_exiting (fe)) {
+	while (1) {
 		up (&fe->sem);      /* is locked when we enter the thread... */
 
-		interruptible_sleep_on_timeout (&fe->wait_queue, delay);
-		if (signal_pending(current))
+		timeout = wait_event_interruptible_timeout(fe->wait_queue,0 != dvb_frontend_is_exiting (fe), delay);
+		if (-ERESTARTSYS == timeout || 0 != dvb_frontend_is_exiting (fe)) {
+			/* got signal or quitting */
 			break;
+		}
 
 		if (down_interruptible (&fe->sem))
 			break;
@@ -455,9 +458,6 @@
 		if (fe->lost_sync_count == -1)
 			continue;
 
-		if (dvb_frontend_is_exiting (fe))
-			break;
-
 		dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s);
 
 		update_delay (&quality, &delay, s & FE_HAS_LOCK);
@@ -509,6 +509,8 @@
 
 static void dvb_frontend_stop (struct dvb_frontend_data *fe)
 {
+	unsigned long ret;
+	
 	dprintk ("%s\n", __FUNCTION__);
 
 		fe->exit = 1;
@@ -526,10 +528,16 @@
 		return;
 	}
 
+	/* wake up the frontend thread, so it notices that fe->exit == 1 */
 		wake_up_interruptible (&fe->wait_queue);
-	interruptible_sleep_on(&fe->wait_queue);
 
-	/* paranoia check */
+	/* wait until the frontend thread has exited */
+	ret = wait_event_interruptible(fe->wait_queue,0 == fe->thread_pid);
+	if (-ERESTARTSYS != ret) {
+		return;
+	}
+
+	/* paranoia check in case a signal arrived */
 	if (fe->thread_pid)
 		printk("dvb_frontend_stop: warning: thread PID %d won't exit\n",
 				fe->thread_pid);
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/dvb-core/dvb_ringbuffer.c linux-2.6.3.p/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
--- xx-linux-2.6.3/drivers/media/dvb/dvb-core/dvb_ringbuffer.c	2004-01-09 09:22:39.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/dvb-core/dvb_ringbuffer.c	2004-02-23 12:52:31.000000000 +0100
@@ -123,7 +123,7 @@
                 if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
                         return -EFAULT;
 
-        rbuf->pread = (rbuf->pread + len) % rbuf->size;
+        rbuf->pread = (rbuf->pread + todo) % rbuf->size;
 
         return len;
 }
@@ -155,7 +155,7 @@
                 if (copy_from_user(rbuf->data+rbuf->pwrite, buf, todo)) 
                         return -EFAULT;
 
-        rbuf->pwrite = (rbuf->pwrite + len) % rbuf->size;
+        rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
 
 	return len;
 }
diff -uNrwB --new-file xx-linux-2.6.3/include/linux/dvb/video.h linux-2.6.3.p/include/linux/dvb/video.h
--- xx-linux-2.6.3/include/linux/dvb/video.h	2003-12-18 12:55:30.000000000 +0100
+++ linux-2.6.3.p/include/linux/dvb/video.h	2004-02-02 19:28:30.000000000 +0100
@@ -81,9 +81,11 @@
 struct video_event { 
         int32_t type; 
 #define VIDEO_EVENT_SIZE_CHANGED 1
+#define VIDEO_EVENT_FRAME_RATE_CHANGED	2
         time_t timestamp;
 	union { 
 	        video_size_t size;
+		unsigned int frame_rate;	/* in frames per 1000sec */
 	} u; 
 };
 
@@ -194,6 +196,7 @@
 #define VIDEO_GET_NAVI             _IOR('o', 52, video_navi_pack_t)
 #define VIDEO_SET_ATTRIBUTES       _IO('o', 53)
 #define VIDEO_GET_SIZE             _IOR('o', 55, video_size_t)
+#define VIDEO_GET_FRAME_RATE       _IOR('o', 56, unsigned int)
 
 #endif /*_DVBVIDEO_H_*/
 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 5/9] Misc. DVB frontend updates
  2004-02-23 21:04       ` [PATCH 4/9] DVB core update Michael Hunold
@ 2004-02-23 21:04         ` Michael Hunold
  2004-02-23 21:05           ` [PATCH 6/9] stv0299 DVB frontend update Michael Hunold
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:04 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

- [DVB] alps_tdlb7 + alps_tdmb7: Changed to use full i2c reads in probing instead of i2c pings to be compatable with ttusb
- [DVB] nxt6000: bugfix by Robert Cook: FE_RESET did the same as FE_INIT, thus invalidating current channel settings on FE_RESET
- [DVB] sp887x: fixed typo
- [DVB] Makefile: add nxt6000 frontend driver to Makefiles
- [DVB] Kconfig: DVB_TDA1004X and DVB_NXT6000 do not depend on !STANDALONE (i.e. no compile-time firmware image necessary)
- [DVB] ves1820: turn off ves1820 test output pins
- [DVB] ves1820: verbose-print AFC only if carrier has been recovered
- [DVB] ves1820: change AFC handling as suggested by Robert Schlabbach, use bit 1 of the SYNC register for FE_HAS_SIGNAL
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/alps_tdlb7.c linux-2.6.3.p/drivers/media/dvb/frontends/alps_tdlb7.c
--- xx-linux-2.6.3/drivers/media/dvb/frontends/alps_tdlb7.c	2003-12-18 12:54:50.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/alps_tdlb7.c	2004-02-02 19:28:30.000000000 +0100
@@ -664,11 +663,14 @@
 
 static int tdlb7_attach (struct dvb_i2c_bus *i2c, void **data)
 {
-	struct i2c_msg msg = { addr: 0x71, flags: 0, buf: NULL, len: 0 };
+        u8 b0 [] = { 0x02 , 0x00 };
+        u8 b1 [] = { 0, 0 };
+        struct i2c_msg msg [] = { { addr: 0x71, flags: 0, buf: b0, len: 2 },
+                                  { addr: 0x71, flags: I2C_M_RD, buf: b1, len: 2 } };
 
 	dprintk ("%s\n", __FUNCTION__);
 
-	if (i2c->xfer (i2c, &msg, 1) != 1)
+        if (i2c->xfer (i2c, msg, 2) != 2)
                 return -ENODEV;
 
 	sp8870_firmware_upload(i2c);
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/alps_tdmb7.c linux-2.6.3.p/drivers/media/dvb/frontends/alps_tdmb7.c
--- xx-linux-2.6.3/drivers/media/dvb/frontends/alps_tdmb7.c	2004-02-23 12:34:27.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/alps_tdmb7.c	2004-02-02 19:28:30.000000000 +0100
@@ -404,11 +404,14 @@
 
 static int tdmb7_attach (struct dvb_i2c_bus *i2c, void **data)
 {
-	struct i2c_msg msg = { .addr = 0x43, .flags = 0, .buf = NULL,. len = 0 };
+        u8 b0 [] = { 0x7 };
+        u8 b1 [] = { 0 };
+        struct i2c_msg msg [] = { { .addr = 0x43, .flags = 0, .buf = b0, .len = 1 },
+                                  { .addr = 0x43, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
 	dprintk ("%s\n", __FUNCTION__);
 
-	if (i2c->xfer (i2c, &msg, 1) != 1)
+        if (i2c->xfer (i2c, msg, 2) != 2)
                 return -ENODEV;
 
 	return dvb_register_frontend (tdmb7_ioctl, i2c, NULL, &tdmb7_info);
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/nxt6000.c linux-2.6.3.p/drivers/media/dvb/frontends/nxt6000.c
--- xx-linux-2.6.3/drivers/media/dvb/frontends/nxt6000.c	2004-02-23 12:34:27.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/nxt6000.c	2004-02-02 19:28:30.000000000 +0100
@@ -758,11 +653,11 @@
 		}
 	
 		case FE_INIT:
-		case FE_RESET:
-		
 			nxt6000_reset(fe);
 			nxt6000_setup(fe);
+		break;
 
+	case FE_RESET:
 			break;
 		
 		case FE_SET_FRONTEND:
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/sp887x.c linux-2.6.3.p/drivers/media/dvb/frontends/sp887x.c
--- xx-linux-2.6.3/drivers/media/dvb/frontends/sp887x.c	2004-01-09 09:22:40.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/sp887x.c	2004-02-23 12:52:31.000000000 +0100
@@ -57,7 +57,7 @@
 
 static
 struct dvb_frontend_info sp887x_info = {
-	.name = "Microtune MT7072DTF",
+	.name = "Microtune MT7202DTF",
 	.type = FE_OFDM,
 	.frequency_min =  50500000,
 	.frequency_max = 858000000,
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/Kconfig linux-2.6.3.p/drivers/media/dvb/frontends/Kconfig
--- xx-linux-2.6.3/drivers/media/dvb/frontends/Kconfig	2004-01-09 09:22:39.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/Kconfig	2004-02-23 12:52:31.000000000 +0100
@@ -154,8 +153,8 @@
 	  right one will get autodetected.
 
 config DVB_TDA1004X
-	tristate "Frontends with external TDA1004X demodulators (OFDM)"
-	depends on DVB_CORE && !STANDALONE
+	tristate "Frontends with external TDA10045H or TDA10046H demodulators (OFDM)"
+	depends on DVB_CORE
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
@@ -173,3 +172,15 @@
             wget http://www.technotrend.de/new/215/TTweb_215a_budget_20_05_2003.zip
             unzip -j TTweb_215a_budget_20_05_2003.zip Software/Oem/PCI/App/ttlcdacc.dll
             mv ttlcdacc.dll /usr/lib/hotplug/firmware/tda1004x.bin
+	  Note: even if you're using a USB device, you MUST get the file from the
+	  TechnoTrend PCI drivers.
+
+config DVB_NXT6000
+	tristate "Frontends with NxtWave Communications NXT6000 demodulator (OFDM)"
+	depends on DVB_CORE
+	help
+	  A DVB-T tuner module. Say Y when you want to support this frontend.
+
+	  If you don't know what tuner module is soldered on your
+	  DVB adapter simply enable all supported frontends, the
+	  right one will get autodetected.
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/Makefile linux-2.6.3.p/drivers/media/dvb/frontends/Makefile
--- xx-linux-2.6.3/drivers/media/dvb/frontends/Makefile	2004-01-09 09:22:39.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/Makefile	2004-02-09 18:30:22.000000000 +0100
@@ -17,3 +17,4 @@
 obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
 obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
 obj-$(CONFIG_DVB_SP887X) += sp887x.o
+obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/ves1820.c linux-2.6.3.p/drivers/media/dvb/frontends/ves1820.c
--- xx-linux-2.6.3/drivers/media/dvb/frontends/ves1820.c	2004-02-23 12:35:57.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/ves1820.c	2004-02-23 12:52:31.000000000 +0100
@@ -120,7 +120,7 @@
 static u8 ves1820_inittab [] =
 {
 	0x69, 0x6A, 0x9B, 0x12, 0x12, 0x46, 0x26, 0x1A,
-	0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x28,
+	0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20,
 	0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
 	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -380,7 +380,7 @@
 
                 sync = ves1820_readreg (fe, 0x11);
 
-		if (sync & 2)
+		if (sync & 1)
 			*status |= FE_HAS_SIGNAL;
 
 		if (sync & 2)
@@ -440,13 +440,14 @@
 		s8 afc = 0;
                 
                 sync = ves1820_readreg (fe, 0x11);
-		if (sync & 2)
-			/* AFC only valid when carrier has been recovered */
 			afc = ves1820_readreg(fe, 0x19);
-		if (verbose)
-			printk ("DVB: VES1820(%d): AFC (%d) %dHz\n",
+		if (verbose) {
+			/* AFC only valid when carrier has been recovered */
+			printk(sync & 2 ? "DVB: VES1820(%d): AFC (%d) %dHz\n" :
+					  "DVB: VES1820(%d): [AFC (%d) %dHz]\n",
 					fe->i2c->adapter->num, afc,
-				-((s32)(p->u.qam.symbol_rate >> 3) * afc >> 7));
+			       -((s32)p->u.qam.symbol_rate * afc) >> 10);
+		}
 
 		p->inversion = HAS_INVERSION(reg0) ? INVERSION_ON : INVERSION_OFF;
 		p->u.qam.modulation = ((reg0 >> 2) & 7) + QAM_16;
@@ -454,9 +455,8 @@
 		p->u.qam.fec_inner = FEC_NONE;
 
 		p->frequency = ((p->frequency + 31250) / 62500) * 62500;
-		/* To prevent overflow, shift symbol rate first a
-		   couple of bits. */
-		p->frequency -= (s32)(p->u.qam.symbol_rate >> 3) * afc >> 7;
+		if (sync & 2)
+			p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
 		break;
 	}
 	case FE_SLEEP:



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/9] Update the DVB subsystem docs
  2004-02-23 21:04 [PATCH 0/9] LinuxTV.org DVB update Michael Hunold
@ 2004-02-23 21:04 ` Michael Hunold
  2004-02-23 21:04   ` [PATCH 2/9] Update saa7146 driver core Michael Hunold
  2004-02-23 22:23   ` [PATCH 1/9] Update the DVB subsystem docs Richard B. Johnson
  0 siblings, 2 replies; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:04 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

- [DVB] dvb docs: added a nice howto on how to get Avermedia DVB-T running - nice tutorial for DVB newbie, too
- [DVB] dvb docs: fix various incorrect informations in cards.txt, faq.txt, firmware.txt
diff -uNrwB --new-file xx-linux-2.6.3/Documentation/dvb/avermedia.txt linux-2.6.3.p/Documentation/dvb/avermedia.txt
--- xx-linux-2.6.3/Documentation/dvb/avermedia.txt	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.3.p/Documentation/dvb/avermedia.txt	2004-02-02 19:28:29.000000000 +0100
@@ -0,0 +1,324 @@
+
+HOWTO: Get An Avermedia DVB-T working under Linux
+           ______________________________________________
+
+   Table of Contents
+   Assumptions and Introduction
+   The Avermedia DVB-T
+   Getting the card going
+   Getting the Firmware
+   Receiving DVB-T in Australia
+   Known Limitations
+   Further Update
+
+Assumptions and Introduction
+
+   It  is assumed that the reader understands the basic structure
+   of  the Linux Kernel DVB drivers and the general principles of
+   Digital TV.
+
+   One  significant difference between Digital TV and Analogue TV
+   that  the  unwary  (like  myself)  should  consider  is  that,
+   although  the  component  structure  of budget DVB-T cards are
+   substantially  similar  to Analogue TV cards, they function in
+   substantially different ways.
+
+   The  purpose  of  an  Analogue TV is to receive and display an
+   Analogue  Television  signal. An Analogue TV signal (otherwise
+   known  as  composite  video)  is  an  analogue  encoding  of a
+   sequence  of  image frames (25 per second) rasterised using an
+   interlacing   technique.   Interlacing  takes  two  fields  to
+   represent  one  frame.  Computers today are at their best when
+   dealing  with  digital  signals,  not  analogue  signals and a
+   composite  video signal is about as far removed from a digital
+   data stream as you can get. Therefore, an Analogue TV card for
+   a PC has the following purpose:
+
+     * Tune the receiver to receive a broadcast signal
+     * demodulate the broadcast signal
+     * demultiplex  the  analogue video signal and analogue audio
+       signal  (note some countries employ a digital audio signal
+       embedded  within the modulated composite analogue signal -
+       NICAM.)
+     * digitize  the analogue video signal and make the resulting
+       datastream available to the data bus.
+
+   The  digital  datastream from an Analogue TV card is generated
+   by  circuitry on the card and is often presented uncompressed.
+   For  a PAL TV signal encoded at a resolution of 768x576 24-bit
+   color pixels over 25 frames per second - a fair amount of data
+   is  generated and must be proceesed by the PC before it can be
+   displayed  on the video monitor screen. Some Analogue TV cards
+   for  PC's  have  onboard  MPEG2  encoders which permit the raw
+   digital  data  stream  to be presented to the PC in an encoded
+   and  compressed  form  -  similar  to the form that is used in
+   Digital TV.
+
+   The  purpose of a simple budget digital TV card (DVB-T,C or S)
+   is to simply:
+
+     * Tune the received to receive a broadcast signal.
+     * Extract  the encoded digital datastream from the broadcast
+       signal.
+     * Make  the  encoded digital datastream (MPEG2) available to
+       the data bus.
+
+   The  significant  difference between the two is that the tuner
+   on  the analogue TV card spits out an Analogue signal, whereas
+   the  tuner  on  the  digital  TV  card  spits out a compressed
+   encoded   digital   datastream.   As  the  signal  is  already
+   digitised,  it  is  trivial  to pass this datastream to the PC
+   databus  with  minimal  additional processing and then extract
+   the  digital  video  and audio datastreams passing them to the
+   appropriate software or hardware for decoding and viewing.
+     _________________________________________________________
+
+The Avermedia DVB-T
+
+   The Avermedia DVB-T is a budget PCI DVB card. It has 3 inputs:
+
+     * RF Tuner Input
+     * Composite Video Input (RCA Jack)
+     * SVIDEO Input (Mini-DIN)
+
+   The  RF  Tuner  Input  is the input to the tuner module of the
+   card.  The  Tuner  is  otherwise known as the "Frontend" . The
+   Frontend of the Avermedia DVB-T is a Microtune 7202D. A timely
+   post  to  the  linux-dvb  mailing  list  ascertained  that the
+   Microtune  7202D  is  supported  by the sp887x driver which is
+   found in the dvb-hw CVS module.
+
+   The  DVB-T card is based around the BT878 chip which is a very
+   common multimedia bridge and often found on Analogue TV cards.
+   There is no on-board MPEG2 decoder, which means that all MPEG2
+   decoding  must  be done in software, or if you have one, on an
+   MPEG2 hardware decoding card or chipset.
+     _________________________________________________________
+
+Getting the card going
+
+   In order to fire up the card, it is necessary to load a number
+   of modules from the DVB driver set. Prior to this it will have
+   been  necessary to download these drivers from the linuxtv CVS
+   server and compile them successfully.
+
+   Depending on the card's feature set, the Device Driver API for
+   DVB under Linux will expose some of the following device files
+   in the /dev tree:
+
+     * /dev/dvb/adapter0/audio0
+     * /dev/dvb/adapter0/ca0
+     * /dev/dvb/adapter0/demux0
+     * /dev/dvb/adapter0/dvr0
+     * /dev/dvb/adapter0/frontend0
+     * /dev/dvb/adapter0/net0
+     * /dev/dvb/adapter0/osd0
+     * /dev/dvb/adapter0/video0
+
+   The  primary  device  nodes that we are interested in (at this
+   stage) for the Avermedia DVB-T are:
+
+     * /dev/dvb/adapter0/dvr0
+     * /dev/dvb/adapter0/frontend0
+
+   The dvr0 device node is used to read the MPEG2 Data Stream and
+   the frontend0 node is used to tune the frontend tuner module.
+
+   At  this  stage,  it  has  not  been  able  to  ascertain  the
+   functionality  of the remaining device nodes in respect of the
+   Avermedia  DVBT.  However,  full  functionality  in respect of
+   tuning,  receiving  and  supplying  the  MPEG2  data stream is
+   possible  with the currently available versions of the driver.
+   It  may be possible that additional functionality is available
+   from  the  card  (i.e.  viewing the additional analogue inputs
+   that  the card presents), but this has not been tested yet. If
+   I get around to this, I'll update the document with whatever I
+   find.
+
+   To  power  up  the  card,  load  the  following modules in the
+   following order:
+
+     * insmod dvb-core.o
+     * modprobe bttv.o
+     * insmod bt878.o
+     * insmod dvb-bt8xx.o
+     * insmod sp887x.o
+
+   Insertion  of  these  modules  into  the  running  kernel will
+   activate the appropriate DVB device nodes. It is then possible
+   to start accessing the card with utilities such as scan, tzap,
+   dvbstream etc.
+
+   The  current version of the frontend module sp887x.o, contains
+   no firmware drivers?, so the first time you open it with a DVB
+   utility  the driver will try to download some initial firmware
+   to  the card. You will need to download this firmware from the
+   web,  or  copy  it from an installation of the Windows drivers
+   that probably came with your card, before you can use it.
+
+   The  default  Linux  filesystem  location for this firmware is
+   /usr/lib/hotplug/firmware/sc_main.mc .
+     _________________________________________________________
+
+Getting the Firmware
+
+   As the firmware for the card is no longer contained within the
+   driver,  it  is  necessary  to  extract  it  from  the windows
+   drivers.
+
+   The  Windows  drivers  for the Avermedia DVB-T can be obtained
+   from: http://babyurl.com/H3U970 and you can get an application
+   to extract the firmware from:
+   http://www.kyz.uklinux.net/cabextract.php.
+     _________________________________________________________
+
+Receiving DVB-T in Australia
+
+   I  have  no  experience of DVB-T in other countries other than
+   Australia,  so  I will attempt to explain how it works here in
+   Melbourne  and how this affects the configuration of the DVB-T
+   card.
+
+   The  Digital  Broadcasting  Australia  website has a Reception
+   locatortool which provides information on transponder channels
+   and  frequencies.  My  local  transmitter  happens to be Mount
+   Dandenong.
+
+   The frequencies broadcast by Mount Dandenong are:
+
+   Table 1. Transponder Frequencies Mount Dandenong, Vic, Aus.
+   Broadcaster Channel Frequency
+   ABC         VHF 12  226.5 MHz
+   TEN         VHF 11  219.5 MHz
+   NINE        VHF 8   191.625 MHz
+   SEVEN       VHF 6   177.5 MHz
+   SBS         UHF 29  536.5 MHz
+
+   The Scan utility has a set of compiled-in defaults for various
+   countries and regions, but if they do not suit, or if you have
+   a pre-compiled scan binary, you can specify a data file on the
+   command  line which contains the transponder frequencies. Here
+   is a sample file for the above channel transponders:
+# Data file for DVB scan program
+#
+# C Frequency SymbolRate FEC QAM
+# S Frequency Polarisation SymbolRate FEC
+# T Frequency Bandwidth FEC FEC2 QAM Mode Guard Hier
+T 226500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 191625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 219500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 177500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+T 536500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
+
+   The   defaults   for   the  transponder  frequency  and  other
+   modulation parameters were obtained from www.dba.org.au.
+
+   When  Scan  runs, it will output channels.conf information for
+   any  channel's transponders which the card's frontend can lock
+   onto.  (i.e.  any  whose  signal  is  strong  enough  at  your
+   antenna).
+
+   Here's my channels.conf file for anyone who's interested:
+ABC HDTV:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64
+:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:0:560
+ABC TV Melbourne:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_
+4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:65
+0:561
+ABC TV 2:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64
+:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:562
+ABC TV 3:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64
+:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:563
+ABC TV 4:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64
+:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:564
+ABC DiG Radio:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:Q
+AM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2311:56
+6
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:158
+5
+TEN Digital 1:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:Q
+AM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1
+586
+TEN Digital 2:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:Q
+AM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1
+587
+TEN Digital 3:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:Q
+AM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1
+588
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:158
+9
+TEN Digital 4:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:Q
+AM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1
+590
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:159
+1
+TEN HD:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:T
+RANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1592
+TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:159
+3
+Nine Digital:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QA
+M_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:513:660:10
+72
+Nine Digital HD:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2
+:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:0:1
+073
+Nine Guide:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_
+64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:670:1074
+7 Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_6
+4:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1328
+7 Digital 1:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1329
+7 Digital 2:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1330
+7 Digital 3:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1331
+7 HD Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QA
+M_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:833:834:133
+2
+7 Program Guide:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3
+:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:865:866:
+1334
+SBS HD:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:T
+RANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:784
+SBS DIGITAL 1:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:Q
+AM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:785
+SBS DIGITAL 2:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:Q
+AM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:786
+SBS EPG:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:
+TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:787
+SBS RADIO 1:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:798
+SBS RADIO 2:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM
+_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:799
+     _________________________________________________________
+
+Known Limitations
+
+   At  present  I can say with confidence that the frontend tunes
+   via /dev/dvb/adapter{x}/frontend0 and supplies an MPEG2 stream
+   via   /dev/dvb/adapter{x}/dvr0.   I   have   not   tested  the
+   functionality  of any other part of the card yet. I will do so
+   over time and update this document.
+
+   There  are some limitations in the i2c layer due to a returned
+   error message inconsistency. Although this generates errors in
+   dmesg  and  the  system logs, it does not appear to affect the
+   ability of the frontend to function correctly.
+     _________________________________________________________
+
+Further Update
+
+   dvbstream  and  VideoLAN  Client on windows works a treat with
+   DVB,  in  fact  this  is  currently  serving as my main way of
+   viewing  DVB-T  at  the  moment.  Additionally, VLC is happily
+   decoding  HDTV  signals,  although  the PC is dropping the odd
+   frame here and there - I assume due to processing capability -
+   as all the decoding is being done under windows in software.
+
+   Many  thanks to Nigel Pearson for the updates to this document
+   since the recent revision of the driver.
+
+   January 29th 2004
diff -uNrwB --new-file xx-linux-2.6.3/Documentation/dvb/cards.txt linux-2.6.3.p/Documentation/dvb/cards.txt
--- xx-linux-2.6.3/Documentation/dvb/cards.txt	2004-01-09 09:22:32.000000000 +0100
+++ linux-2.6.3.p/Documentation/dvb/cards.txt	2004-02-23 12:52:31.000000000 +0100
@@ -8,7 +8,7 @@
   DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed seperately.
 
   Note 1: There is no guarantee that every frontend driver works
-  out-of-the box with every card, because of different wiring.
+  out of the box with every card, because of different wiring.
 
   Note 2: The demodulator chips can be used with a variety of
   tuner/PLL chips, and not all combinations are supported. Often
@@ -19,13 +19,13 @@
 o Frontends drivers: 
   - dvb_dummy_fe: for testing...
   DVB-S:
-   - alps_bsrv2		: Alps BSRV2 (ves1893 demodulator)
+   - ves1x93		: Alps BSRV2 (ves1893 demodulator) and dbox2 (ves1993)
    - cx24110		: Conexant HM1221/HM1811 (cx24110 or cx24106 demod, cx24108 PLL)
    - grundig_29504-491	: Grundig 29504-491 (Philips TDA8083 demodulator), tsa5522 PLL
    - mt312		: Zarlink mt312 or Mitel vp310 demodulator, sl1935 or tsa5059 PLL
    - stv0299		: Alps BSRU6 (tsa5059 PLL), LG TDQB-S00x (tsa5059 PLL),
    			  LG TDQF-S001F (sl1935 PLL), Philips SU1278 (tua6100 PLL), 
-			  Philips SU1278SH (tsa5059 PLL)
+			  Philips SU1278SH (tsa5059 PLL), Samsung TBMU24112IMB
   DVB-C:
    - ves1820		: various (ves1820 demodulator, sp5659c or spXXXX PLL)
    - at76c651		: Atmel AT76c651(B) with DAT7021 PLL
@@ -37,6 +37,9 @@
    - nxt6000 		: Alps TDME7 (MITEL SP5659 PLL), Alps TDED4 (TI ALP510 PLL),
                		  Comtech DVBT-6k07 (SP5730 PLL)
                		  (NxtWave Communications NXT6000 demodulator)
+   - sp887x		: Microtune 7202D
+  DVB-S/C/T:
+   - dst		: TwinHan DST Frontend
 
 
 o Cards based on the Phillips saa7146 multimedia PCI bridge chip:
@@ -48,16 +51,17 @@
     - SATELCO Multimedia PCI
     - KNC1 DVB-S
 
-o Cards based on the B2C2 Inc. FlexCopII:
-  - Technisat SkyStar2 PCI DVB
+o Cards based on the B2C2 Inc. FlexCopII/IIb/III:
+  - Technisat SkyStar2 PCI DVB card revision 2.3, 2.6B, 2.6C
 
 o Cards based on the Conexant Bt8xx PCI bridge:
   - Pinnacle PCTV Sat DVB
   - Nebula Electronics DigiTV
+  - TwinHan DST
+  - Avermedia DVB-T
 
 o Technotrend / Hauppauge DVB USB devices:
   - Nova USB
-  - DEC 2000-T
-
-o Preliminary support for the analog module of the Siemens DVB-C PCI card
+  - DEC 2000-T, 3000-S, 2540-T
 
+o Experimental support for the analog module of the Siemens DVB-C PCI card
diff -uNrwB --new-file xx-linux-2.6.3/Documentation/dvb/faq.txt linux-2.6.3.p/Documentation/dvb/faq.txt
--- xx-linux-2.6.3/Documentation/dvb/faq.txt	2004-01-09 09:22:32.000000000 +0100
+++ linux-2.6.3.p/Documentation/dvb/faq.txt	2004-02-02 19:28:29.000000000 +0100
@@ -99,11 +99,57 @@
 	If you are using a Technotrend/Hauppauge DVB-C card *without* analog
 	module, you might have to use module parameter adac=-1 (dvb-ttpci.o).
 
-5. The dvb_net device doesn't give me any multicast packets
+5. The dvb_net device doesn't give me any packets at all
+
+	Run tcpdump on the dvb0_0 interface. This sets the interface
+	into promiscous mode so it accepts any packets from the PID
+	you have configured with the dvbnet utility. Check if there
+	are any packets with the IP addr and MAC addr you have
+	configured with ifconfig.
+
+	If tcpdump doesn't give you any output, check the statistics
+	which ifconfig outputs. (Note: If the MAC address is wrong,
+	dvb_net won't get any input; thus you have to run tcpdump
+	before checking the statistics.) If there are no packets at
+	all then maybe the PID is wrong. If there are error packets,
+	then either the PID is wrong or the stream does not conform to
+	the MPE standard (EN 301 192, http://www.etsi.org/). You can
+	use e.g. dvbsnoop for debugging.
+
+6. The dvb_net device doesn't give me any multicast packets
 
 	Check your routes if they include the multicast address range.
 	Additionally make sure that "source validation by reversed path
 	lookup" is disabled:
 	  $ "echo 0 > /proc/sys/net/ipv4/conf/dvb0/rp_filter"
 
+7. What the hell are all those modules that need to be loaded?
+         
+	For a dvb-ttpci av7110 based full-featured card the following
+	modules are loaded:
+
+	- videodev: Video4Linux core module. This is the base module that
+	  gives you access to the "analog" tv picture of the av7110 mpeg2
+	  decoder.
+	  
+	- v4l2-common: common functions for Video4Linux-2 drivers
+	
+	- v4l1-compat: backward compatiblity layer for Video4Linux-1 legacy
+	  applications
+
+	- dvb-core: DVB core module. This provides you with the
+	  /dev/dvb/adapter entries
+	
+	- saa7146: SAA7146 core driver. This is need to access any SAA7146
+	  based card in your system.
+	
+	- saa7146_vv: SAA7146 video and vbi functions. These are only needed
+	  for full-featured cards.
+
+	- video-buf: capture helper module for the saa7146_vv driver. This
+	  one is responsible to handle capture buffers.
+
+	- dvb-ttpci: The main driver for AV7110 based, full-featued
+	  DVB-S/C/T cards
+
 eof
diff -uNrwB --new-file xx-linux-2.6.3/Documentation/dvb/firmware.txt linux-2.6.3.p/Documentation/dvb/firmware.txt
--- xx-linux-2.6.3/Documentation/dvb/firmware.txt	2004-01-09 09:22:32.000000000 +0100
+++ linux-2.6.3.p/Documentation/dvb/firmware.txt	2004-02-09 18:30:22.000000000 +0100
@@ -20,7 +20,7 @@
 		extracted from the Windows driver (Sc_main.mc).
 - tda1004x: firmware is loaded from path specified in
 		DVB_TDA1004X_FIRMWARE_FILE kernel config
-		variable (default /etc/dvb/tda1004x.bin); the
+		variable (default /usr/lib/hotplug/firmware/tda1004x.bin); the
 		firmware binary must be extracted from the windows
 		driver
 - ttusb-dec: see "ttusb-dec.txt" for details
@@ -76,11 +76,15 @@
 Step c) Getting a usable firmware file for the dvb-ttpci driver/av7110 card.
 
 You can download the firmware files from
-http://www.linuxtv.org/download/dvb/
+http://linuxtv.org/download/dvb/
 
 Please note that in case of the dvb-ttpci driver this is *not* the "Root"
 file you probably know from the 2.4 DVB releases driver.
 
+The ttpci-firmware utility from linuxtv.org CVS can be used to
+convert Dpram and Root files into a usable firmware image.
+See dvb-kerrnel/scripts/ in http://linuxtv.org/cvs/.
+
 > wget http://www.linuxtv.org/download/dvb/dvb-ttpci-01.fw
 gets you the version 01 of the firmware fot the ttpci driver.
 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 6/9] stv0299 DVB frontend update
  2004-02-23 21:04         ` [PATCH 5/9] Misc. DVB frontend updates Michael Hunold
@ 2004-02-23 21:05           ` Michael Hunold
  2004-02-23 21:05             ` [PATCH 7/9] tda1004x " Michael Hunold
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:05 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

- [DVB] stv0299: Added seperate settings for SU1278 on Technotrend hardware
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/stv0299.c linux-2.6.3.p/drivers/media/dvb/frontends/stv0299.c
--- xx-linux-2.6.3/drivers/media/dvb/frontends/stv0299.c	2004-01-09 09:22:40.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/stv0299.c	2004-02-23 12:52:31.000000000 +0100
@@ -25,6 +25,9 @@
 
     Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
 
+    Support for Philips SU1278 on Technotrend hardware
+
+    Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
 
     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
@@ -65,15 +68,19 @@
 
 /* frontend types */
 #define UNKNOWN_FRONTEND  -1
-#define PHILIPS_SU1278SH   0
+#define PHILIPS_SU1278_TSA      0 // SU1278 with TSA5959 synth and datasheet recommended settings
 #define ALPS_BSRU6         1
 #define LG_TDQF_S001F      2
-#define PHILIPS_SU1278     3
+#define PHILIPS_SU1278_TUA      3 // SU1278 with TUA6100 synth
 #define SAMSUNG_TBMU24112IMB    4
+#define PHILIPS_SU1278_TSA_TT   5 // SU1278 with TSA5959 synth and TechnoTrend settings
 
 /* Master Clock = 88 MHz */
 #define M_CLK (88000000UL) 
 
+/* Master Clock for TT cards = 64 MHz */
+#define M_CLK_SU1278_TSA_TT (64000000UL)
+
 static struct dvb_frontend_info uni0299_info = {
 	.name			= "STV0299/TSA5059/SL1935 based",
 	.type			= FE_QPSK,
@@ -201,6 +208,51 @@
 };
 
 
+static u8 init_tab_su1278_tsa_tt [] = {
+        0x01, 0x0f,
+        0x02, 0x30,
+        0x03, 0x00,
+        0x04, 0x5b,
+        0x05, 0x85,
+        0x06, 0x02,
+        0x07, 0x00,
+        0x08, 0x02,
+        0x09, 0x00,
+        0x0C, 0x01,
+        0x0D, 0x81, 
+        0x0E, 0x44,
+        0x0f, 0x14,
+        0x10, 0x3c,
+        0x11, 0x84,
+        0x12, 0xda,
+        0x13, 0x97,
+        0x14, 0x95,
+        0x15, 0xc9,
+        0x16, 0x19,
+        0x17, 0x8c,
+        0x18, 0x59,
+        0x19, 0xf8,
+        0x1a, 0xfe,
+        0x1c, 0x7f,
+        0x1d, 0x00,
+        0x1e, 0x00,
+        0x1f, 0x50,
+        0x20, 0x00,
+        0x21, 0x00,
+        0x22, 0x00,
+        0x23, 0x00,
+        0x28, 0x00,
+        0x29, 0x28,
+        0x2a, 0x14,
+        0x2b, 0x0f,
+        0x2c, 0x09,
+        0x2d, 0x09,
+        0x31, 0x1f,
+        0x32, 0x19,
+        0x33, 0xfc,
+        0x34, 0x13
+};
+
 static int stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
 {
 	int ret;
@@ -297,21 +349,26 @@
 	u8 addr;
 	u32 div;
 	u8 buf[4];
+        int i, divisor, regcode;
 
 	dprintk ("%s: freq %i, ftype %i\n", __FUNCTION__, freq, ftype);
 
 	if ((freq < 950000) || (freq > 2150000)) return -EINVAL;
 
+        divisor = 500;
+        regcode = 2;
+
 	// setup frequency divisor
-	div = freq / 1000;
+	div = freq / divisor;
 	buf[0] = (div >> 8) & 0x7f;
 	buf[1] = div & 0xff;
-	buf[2] = 0x81 | ((div & 0x18000) >> 10);
+	buf[2] = 0x80 | ((div & 0x18000) >> 10) | regcode;
 	buf[3] = 0;
 
 	// tuner-specific settings
 	switch(ftype) {
-	case PHILIPS_SU1278SH:
+	case PHILIPS_SU1278_TSA:
+	case PHILIPS_SU1278_TSA_TT:
 		addr = 0x60;
 		buf[3] |= 0x20;
 
@@ -332,7 +389,6 @@
 		return -EINVAL;
 	}
 
-	// charge pump
 	return pll_write (i2c, addr, buf, sizeof(buf));
 }
 
@@ -465,15 +521,20 @@
 
 static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate)
 {
-	if (ftype == SAMSUNG_TBMU24112IMB)
+	switch(ftype) {
+	case SAMSUNG_TBMU24112IMB:
 		return sl1935_set_tv_freq(i2c, freq, ftype);
-	else if (ftype == LG_TDQF_S001F)
+	
+	case LG_TDQF_S001F:
 		return sl1935_set_tv_freq(i2c, freq, ftype);
-	else if (ftype == PHILIPS_SU1278)
+	    
+	case PHILIPS_SU1278_TUA:
 		return tua6100_set_tv_freq(i2c, freq, ftype, srate);
-	else
+
+	default:
 		return tsa5059_set_tv_freq(i2c, freq, ftype, srate);
 }
+}
 
 #if 0
 static int tsa5059_read_status	(struct dvb_i2c_bus *i2c)
@@ -515,18 +576,24 @@
 		}
 		break;
 
+	case PHILIPS_SU1278_TSA_TT:
+	        for (i=0; i<sizeof(init_tab_su1278_tsa_tt); i+=2) {
+			stv0299_writereg (i2c, init_tab_su1278_tsa_tt[i], init_tab_su1278_tsa_tt[i+1]);
+		} 
+	        break;
+	    
 	default:
 	stv0299_writereg (i2c, 0x01, 0x15);
-	stv0299_writereg (i2c, 0x02, ftype == PHILIPS_SU1278 ? 0x00 : 0x30);
+		stv0299_writereg (i2c, 0x02, ftype == PHILIPS_SU1278_TUA ? 0x00 : 0x30);
 	stv0299_writereg (i2c, 0x03, 0x00);
 
 	for (i=0; i<sizeof(init_tab); i+=2)
 		stv0299_writereg (i2c, init_tab[i], init_tab[i+1]);
 
         /* AGC1 reference register setup */
-	if (ftype == PHILIPS_SU1278SH)
+		if (ftype == PHILIPS_SU1278_TSA)
 		  stv0299_writereg (i2c, 0x0f, 0x92);  /* Iagc = Inverse, m1 = 18 */
-	else if (ftype == PHILIPS_SU1278)
+		else if (ftype == PHILIPS_SU1278_TUA)
 		  stv0299_writereg (i2c, 0x0f, 0x94);  /* Iagc = Inverse, m1 = 20 */
 	else
 	  stv0299_writereg (i2c, 0x0f, 0x52);  /* Iagc = Normal,  m1 = 18 */
@@ -796,10 +863,49 @@
 	u8 aclk = 0;
 	u8 bclk = 0;
 	u8 m1;
+        int Mclk = M_CLK;
 
+        // check rate is within limits
 	if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
+    
+        // calculate value to program
+	if (tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT;
+        big = big << 20;
+        do_div(big, Mclk);
+        ratio = big << 4;
+    
+        // program registers
 	switch(tuner_type) {
-	case PHILIPS_SU1278SH:
+	case PHILIPS_SU1278_TSA_TT:
+	        stv0299_writereg (i2c, 0x0e, 0x44);
+	        if (srate >= 10000000) {
+		        stv0299_writereg (i2c, 0x13, 0x97);
+		        stv0299_writereg (i2c, 0x14, 0x95);
+		        stv0299_writereg (i2c, 0x15, 0xc9);
+		        stv0299_writereg (i2c, 0x17, 0x8c);
+		        stv0299_writereg (i2c, 0x1a, 0xfe);
+		        stv0299_writereg (i2c, 0x1c, 0x7f);
+		        stv0299_writereg (i2c, 0x2d, 0x09);
+		} else {
+		        stv0299_writereg (i2c, 0x13, 0x99);
+		        stv0299_writereg (i2c, 0x14, 0x8d);
+		        stv0299_writereg (i2c, 0x15, 0xce);
+		        stv0299_writereg (i2c, 0x17, 0x43);
+		        stv0299_writereg (i2c, 0x1a, 0x1d);
+		        stv0299_writereg (i2c, 0x1c, 0x12);
+		        stv0299_writereg (i2c, 0x2d, 0x05);
+		}
+	        stv0299_writereg (i2c, 0x0e, 0x23);
+	        stv0299_writereg (i2c, 0x0f, 0x94);
+	        stv0299_writereg (i2c, 0x10, 0x39);
+	        stv0299_writereg (i2c, 0x15, 0xc9);
+	    
+	        stv0299_writereg (i2c, 0x1f, (ratio >> 16) & 0xff);
+	        stv0299_writereg (i2c, 0x20, (ratio >>  8) & 0xff);
+	        stv0299_writereg (i2c, 0x21, (ratio      ) & 0xf0);
+	        break;
+	    
+	case PHILIPS_SU1278_TSA:
 		aclk = 0xb5;
 		if (srate < 2000000) bclk = 0x86;
 		else if (srate < 5000000) bclk = 0x89;
@@ -808,6 +914,13 @@
 
 		m1 = 0x14;
 		if (srate < 4000000) m1 = 0x10;
+
+	    	stv0299_writereg (i2c, 0x13, aclk);
+  	        stv0299_writereg (i2c, 0x14, bclk);
+	        stv0299_writereg (i2c, 0x1f, (ratio >> 16) & 0xff);
+	        stv0299_writereg (i2c, 0x20, (ratio >>  8) & 0xff);
+	        stv0299_writereg (i2c, 0x21, (ratio      ) & 0xf0);
+	        stv0299_writereg (i2c, 0x0f, (stv0299_readreg(i2c, 0x0f) & 0xc0) | m1);
 		break;
 
 	case ALPS_BSRU6:
@@ -818,24 +931,7 @@
 		else if (srate <= 14000000) { aclk = 0xb7; bclk = 0x93; }
 		else if (srate <= 30000000) { aclk = 0xb6; bclk = 0x93; }
 		else if (srate <= 45000000) { aclk = 0xb4; bclk = 0x91; }
-
 		m1 = 0x12;
-		break;   
-	}
-        
-	dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff),  (int) (big & 0xffffffff) );
-        
-	big = big << 20;
-
-	dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff),  (int) (big & 0xffffffff) );
-
-	do_div(big, M_CLK);
-
-	dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff),  (int) (big & 0xffffffff) );
-
-	ratio = big << 4;
-
-	dprintk("%s : ratio = %i\n", __FUNCTION__, ratio);
   
 	stv0299_writereg (i2c, 0x13, aclk);
 	stv0299_writereg (i2c, 0x14, bclk);
@@ -843,12 +939,15 @@
 	stv0299_writereg (i2c, 0x20, (ratio >>  8) & 0xff);
 	stv0299_writereg (i2c, 0x21, (ratio      ) & 0xf0);
 	stv0299_writereg (i2c, 0x0f, (stv0299_readreg(i2c, 0x0f) & 0xc0) | m1);
+		break;
+	}
+    
 
 	return 0;
 }
 
 
-static int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c)
+static int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c, int tuner_type)
 {
 	u32 Mclk = M_CLK / 4096L;
 	u32 srate;
@@ -858,6 +957,8 @@
 
 	dprintk ("%s\n", __FUNCTION__);
 
+    	if (tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT / 4096L;
+    
 	stv0299_readregs (i2c, 0x1f, sfr, 3);
 	stv0299_readregs (i2c, 0x1a, &rtf, 1);
 
@@ -891,8 +991,15 @@
 
 	switch (cmd) {
 	case FE_GET_INFO:
+	{
+	        struct dvb_frontend_info* tmp = (struct dvb_frontend_info*) arg;
 		memcpy (arg, &uni0299_info, sizeof(struct dvb_frontend_info));
+
+	        if (tuner_type == PHILIPS_SU1278_TSA_TT) {
+		        tmp->frequency_tolerance = M_CLK_SU1278_TSA_TT / 2000;
+		}
 		break;
+	}
 
 	case FE_READ_STATUS:
 	{
@@ -976,8 +1083,10 @@
                 stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, tuner_type);
 		stv0299_writereg (i2c, 0x22, 0x00);
 		stv0299_writereg (i2c, 0x23, 0x00);
+	        if (tuner_type != PHILIPS_SU1278_TSA_TT) {
 		stv0299_readreg (i2c, 0x23);
 		stv0299_writereg (i2c, 0x12, 0xb9);
+		}
 		stv0299_check_inversion (i2c);
 
 		/* printk ("%s: tsa5059 status: %x\n", __FUNCTION__, tsa5059_read_status(i2c)); */
@@ -988,11 +1097,14 @@
         {
 		struct dvb_frontend_parameters *p = arg;
 		s32 derot_freq;
+	        int Mclk = M_CLK;
+
+	        if (tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT;
 
 		derot_freq = (s32)(s16) ((stv0299_readreg (i2c, 0x22) << 8)
 					| stv0299_readreg (i2c, 0x23));
 
-		derot_freq *= (M_CLK >> 16);
+		derot_freq *= (Mclk >> 16);
 		derot_freq += 500;
 		derot_freq /= 1000;
 
@@ -1000,7 +1112,7 @@
 		p->inversion = (stv0299_readreg (i2c, 0x0c) & 1) ?
 						INVERSION_OFF : INVERSION_ON;
 		p->u.qpsk.fec_inner = stv0299_get_fec (i2c);
-		p->u.qpsk.symbol_rate = stv0299_get_symbolrate (i2c);
+		p->u.qpsk.symbol_rate = stv0299_get_symbolrate (i2c, tuner_type);
                 break;
         }
 
@@ -1062,10 +1174,16 @@
     	    return SAMSUNG_TBMU24112IMB;
 	}
 
-
 	if ((ret = i2c->xfer(i2c, msg1, 2)) == 2) {
-		printk ("%s: setup for tuner SU1278/SH\n", __FILE__);
-		return PHILIPS_SU1278SH;
+	        if ( strcmp(adapter->name, "TT-Budget/WinTV-NOVA-CI PCI") == 0 ) {
+		        // technotrend cards require non-datasheet settings
+		        printk ("%s: setup for tuner SU1278 (TSA5959 synth) on TechnoTrend hardware\n", __FILE__);
+		        return PHILIPS_SU1278_TSA_TT;
+		}  else {
+		        // fall back to datasheet-recommended settings
+		        printk ("%s: setup for tuner SU1278 (TSA5959 synth)\n", __FILE__);
+		        return PHILIPS_SU1278_TSA;
+		}
 		}
 
 	if ((ret = i2c->xfer(i2c, msg2, 2)) == 2) {
@@ -1086,8 +1204,8 @@
 	stv0299_writereg (i2c, 0x02, 0x00);
 
 	if ((ret = i2c->xfer(i2c, msg3, 2)) == 2) {
-		printk ("%s: setup for tuner Philips SU1278\n", __FILE__);
-		return PHILIPS_SU1278;
+		printk ("%s: setup for tuner Philips SU1278 (TUA6100 synth)\n", __FILE__);
+		return PHILIPS_SU1278_TUA;
 	}
 
 	printk ("%s: unknown PLL synthesizer (ret == %i), "



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 8/9] av7110 DVB driver update
  2004-02-23 21:05             ` [PATCH 7/9] tda1004x " Michael Hunold
@ 2004-02-23 21:05               ` Michael Hunold
  2004-02-23 21:05                 ` [PATCH 9/9] TTUSB-Budget " Michael Hunold
  2004-02-23 21:18               ` [PATCH 7/9] tda1004x DVB frontend update Christoph Hellwig
  2004-02-23 22:09               ` Andrew Morton
  2 siblings, 1 reply; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:05 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

- [DVB] av7110: check result of saa7146_wait_for_debi_done() in av7110_bootarm() and bail out early if booting the ARM failed
- [DVB] av7110: correct voffset for analog standard
- [DVB] av7110: replace usage of sleep_on_interruptible_timeout() with wait_event_interruptible_timeout()
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/ttpci/av7110.c linux-2.6.3.p/drivers/media/dvb/ttpci/av7110.c
--- xx-linux-2.6.3/drivers/media/dvb/ttpci/av7110.c	2004-02-23 12:34:27.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/ttpci/av7110.c	2004-02-23 12:52:31.000000000 +0100
@@ -105,6 +108,7 @@
 static int arm_thread(void *data)
 {
 	struct av7110 *av7110 = data;
+	unsigned long timeout;
         u16 newloops = 0;
 
 	DEB_EE(("av7110: %p\n",av7110));
@@ -112,8 +116,12 @@
 	dvb_kernel_thread_setup ("arm_mon");
 	av7110->arm_thread = current;
 
-	while (!av7110->arm_rmmod && !signal_pending(current)) {
-                interruptible_sleep_on_timeout(&av7110->arm_wait, 5*HZ);
+	while (1) {
+		timeout = wait_event_interruptible_timeout(av7110->arm_wait,0 != av7110->arm_rmmod, 5*HZ);
+		if (-ERESTARTSYS == timeout || 0 != av7110->arm_rmmod) {
+			/* got signal or told to quit*/
+			break;
+		}
 
                 if (!av7110->arm_ready)
                         continue;
@@ -1283,7 +1290,7 @@
 		return -EINVAL;
 	}
 	if( crc != crc32_le(0,ptr,len)) {
-		printk("dvb-ttpci: crc32 of dpram file does not match.\n");
+		printk("dvb-ttpci: crc32 of root file does not match.\n");
 		return -EINVAL;
 	}
 	av7110->bin_root = ptr;
@@ -1426,7 +1433,10 @@
 
         /* load firmware into AV7110 cards */
 	av7110_bootarm(av7110);
-	av7110_firmversion(av7110);
+	if (av7110_firmversion(av7110)) {
+		ret = -EIO;
+		goto err2;
+	}
 
 	if (FW_VERSION(av7110->arm_app)<0x2501)
 		printk ("av7110: Warning, firmware version 0x%04x is too old. "
@@ -1497,6 +1507,9 @@
 	av7110_num++;
         return 0;
 
+err2:
+	av7110_ca_exit(av7110);
+	av7110_av_exit(av7110);
 err:
 	if (NULL != av7110 ) {
 		kfree(av7110);
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/ttpci/av7110_hw.c linux-2.6.3.p/drivers/media/dvb/ttpci/av7110_hw.c
--- xx-linux-2.6.3/drivers/media/dvb/ttpci/av7110_hw.c	2004-02-23 12:34:27.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/ttpci/av7110_hw.c	2004-02-23 12:52:31.000000000 +0100
@@ -249,7 +249,11 @@
 	mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode));
 	iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 
-	saa7146_wait_for_debi_done(av7110->dev);
+	if (saa7146_wait_for_debi_done(av7110->dev)) {
+		printk(KERN_ERR "dvb: av7110_bootarm(): "
+		       "saa7146_wait_for_debi_done() timed out\n");
+		return -1;
+	}
 	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
 	//FIXME: necessary?
 	set_current_state(TASK_INTERRUPTIBLE);
@@ -265,7 +269,11 @@
 	DEB_D(("av7110_bootarm: load dpram code\n"));
 	mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
 
-	saa7146_wait_for_debi_done(av7110->dev);
+	if (saa7146_wait_for_debi_done(av7110->dev)) {
+		printk(KERN_ERR "dvb: av7110_bootarm(): "
+		       "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
+		return -1;
+	}
 	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
 	//FIXME: necessary?
 	mdelay(800);
@@ -515,14 +523,18 @@
  ****************************************************************************/
 
 /* get version of the firmware ROM, RTSL, video ucode and ARM application  */
-void av7110_firmversion(struct av7110 *av7110)
+int av7110_firmversion(struct av7110 *av7110)
 {
 	u16 buf[20];
 	u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);
 
 	DEB_EE(("av7110: %p\n", av7110));
 
-	av7110_fw_query(av7110, tag, buf, 16);
+	if (av7110_fw_query(av7110, tag, buf, 16)) {
+		printk("DVB: AV7110-%d: ERROR: Failed to boot firmware\n",
+		       av7110->dvb_adapter->num);
+		return -EIO;
+	}
 
 	av7110->arm_fw = (buf[0] << 16) + buf[1];
 	av7110->arm_rtsl = (buf[2] << 16) + buf[3];
@@ -542,7 +554,7 @@
 		printk("DVB: AV711%d(%d) - no firmware support for CI link layer interface\n",
 		       av7110->avtype, av7110->dvb_adapter->num);
 
-	return;
+	return 0;
 }
 
 
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/ttpci/av7110_hw.h linux-2.6.3.p/drivers/media/dvb/ttpci/av7110_hw.h
--- xx-linux-2.6.3/drivers/media/dvb/ttpci/av7110_hw.h	2004-02-23 12:34:27.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/ttpci/av7110_hw.h	2004-02-23 12:52:31.000000000 +0100
@@ -362,7 +362,7 @@
 
 extern void av7110_reset_arm(struct av7110 *av7110);
 extern int av7110_bootarm(struct av7110 *av7110);
-extern void av7110_firmversion(struct av7110 *av7110);
+extern int av7110_firmversion(struct av7110 *av7110);
 #define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
 #define FW_VERSION(arm_app)	  ((arm_app) & 0x0000FFFF)
 
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/ttpci/av7110_v4l.c linux-2.6.3.p/drivers/media/dvb/ttpci/av7110_v4l.c
--- xx-linux-2.6.3/drivers/media/dvb/ttpci/av7110_v4l.c	2004-02-23 12:34:27.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/ttpci/av7110_v4l.c	2004-02-23 12:52:31.000000000 +0100
@@ -191,11 +191,11 @@
 
 	if (0 != av7110->current_input) {
 		adswitch = 1;
-		band = 0x68; /* analog band */
+		band = 0x60; /* analog band */
 		source = SAA7146_HPS_SOURCE_PORT_B;
 		sync = SAA7146_HPS_SYNC_PORT_B;
 		memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
-		DEB_S(("av7110: switching to analog TV\n"));
+		DEB_S(("av7110: switching to analog TV\n"));
 		msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
 		msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
 		msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
@@ -204,11 +204,11 @@
 		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
 	} else {
 		adswitch = 0;
-		band = 0x28; /* digital band */
+		band = 0x20; /* digital band */
 		source = SAA7146_HPS_SOURCE_PORT_A;
 		sync = SAA7146_HPS_SYNC_PORT_A;
 		memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
-		DEB_S(("av7110: switching DVB mode\n"));
+		DEB_S(("av7110: switching DVB mode\n"));
 		msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
 		msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
 		msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
@@ -638,7 +638,7 @@
 static struct saa7146_standard analog_standard[] = {
 	{
 		.name	= "PAL",	.id		= V4L2_STD_PAL_BG,
-		.v_offset	= 0x18 /* 0 */ ,	.v_field	= 288,		.v_calc	= 576,
+		.v_offset	= 0x1b,	.v_field	= 288,		.v_calc	= 576,
 		.h_offset	= 0x08,	.h_pixels	= 708,		.h_calc	= 709,
 		.v_max_out	= 576,	.h_max_out	= 768,
 	}, {



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 9/9] TTUSB-Budget DVB driver update
  2004-02-23 21:05               ` [PATCH 8/9] av7110 DVB driver update Michael Hunold
@ 2004-02-23 21:05                 ` Michael Hunold
  0 siblings, 0 replies; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:05 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

- [DVB] dvb-ttusb-budget: Fixed i2c code to detect nearly all errors
- [DVB] dvb-ttusb-budget: Added "V 2.1" to prevent warning message on driver load
- [DVB] dvb-ttusb-budget: Some printks turned into dprintks
- [DVB] dvb-ttusb-budget: Removed __initdata. It is now possible in kernel 2.6 to compile the DVB drivers into a monolithic kernel.
- [DVB] dvb-ttusb-budget: Fix for failing urb submission under 2.6 kernels
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c linux-2.6.3.p/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
--- xx-linux-2.6.3/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2004-01-09 09:22:40.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2004-02-02 19:28:30.000000000 +0100
@@ -29,6 +29,7 @@
 #include <linux/dvb/dmx.h>
 #include <linux/pci.h>
 
+#include "dvb_usb_compat.h"
 #include "dvb_functions.h"
 
 /*
@@ -223,6 +224,9 @@
 
 	err = ttusb_result(ttusb, b, 0x20);
 
+        /* check if the i2c transaction was successful */
+        if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
+
 	if (rcv_len > 0) {
 
 		if (err || b[0] != 0x55 || b[1] != id) {
@@ -273,7 +277,7 @@
 				    snd_buf, snd_len, rcv_buf, rcv_len);
 
 		if (err < rcv_len) {
-			printk("%s: i == %i\n", __FUNCTION__, i);
+			dprintk("%s: i == %i\n", __FUNCTION__, i);
 			break;
 		}
 
@@ -432,7 +436,8 @@
 		get_version[7], get_version[8]);
 
 	if (memcmp(get_version + 4, "V 0.0", 5) &&
-	    memcmp(get_version + 4, "V 1.1", 5)) {
+	    memcmp(get_version + 4, "V 1.1", 5) &&
+   	    memcmp(get_version + 4, "V 2.1", 5)) {
 		printk
 		    ("%s: unknown STC version %c%c%c%c%c, please report!\n",
 		     __FUNCTION__, get_version[4], get_version[5],
@@ -932,7 +953,7 @@
 	struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
 	struct ttusb_channel *channel;
 
-	printk("ttusb_start_feed\n");
+	dprintk("ttusb_start_feed\n");
 
 	switch (dvbdmxfeed->type) {
 	case DMX_TYPE_TS:
@@ -1004,7 +1025,7 @@
 
 static int ttusb_setup_interfaces(struct ttusb *ttusb)
 {
-	usb_reset_configuration(ttusb->dev);
+	usb_set_configuration(ttusb->dev, 1);
 	usb_set_interface(ttusb->dev, 1, 1);
 
 	ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
@@ -1186,7 +1238,7 @@
 static struct usb_device_id ttusb_table[] = {
 	{USB_DEVICE(0xb48, 0x1003)},
 	{USB_DEVICE(0xb48, 0x1004)},	/* to be confirmed ????  */
-	{USB_DEVICE(0xb48, 0x1005)},	/* to be confirmed ????  */
+	{USB_DEVICE(0xb48, 0x1005)},
 	{}
 };
 
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h linux-2.6.3.p/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
--- xx-linux-2.6.3/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h	2003-12-18 12:54:50.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h	2004-02-02 19:28:30.000000000 +0100
@@ -1,7 +1,7 @@
 
 #include <asm/types.h>
 
-u8 dsp_bootcode [] __initdata = {
+u8 dsp_bootcode [] = {
 	0x08, 0xaa, 0x00, 0x18, 0x00, 0x03, 0x08, 0x00, 
 	0x00, 0x10, 0x00, 0x00, 0x01, 0x80, 0x18, 0x5f, 
 	0x00, 0x00, 0x01, 0x80, 0x77, 0x18, 0x2a, 0xeb, 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 21:05           ` [PATCH 6/9] stv0299 DVB frontend update Michael Hunold
@ 2004-02-23 21:05             ` Michael Hunold
  2004-02-23 21:05               ` [PATCH 8/9] av7110 DVB driver update Michael Hunold
                                 ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 21:05 UTC (permalink / raw)
  To: torvalds, akpm, linux-kernel, hunold

- [DVB] tda1004x: standardised where the firmware should be.
- [DVB] tda1004x: need to re-invert inversion for tda10046 in get_fe()
- [DVB] tda1004x: reset chip before uploading firmware
- [DVB] tda1004x: split firmware upload off from frontend init. the initial tune attempt was taking too long. provide explanation of tuner frequency calculations
- [DVB] tda1004x: Fixed signal strength reading for tda10046h
diff -uNrwB --new-file xx-linux-2.6.3/drivers/media/dvb/frontends/tda1004x.c linux-2.6.3.p/drivers/media/dvb/frontends/tda1004x.c
--- xx-linux-2.6.3/drivers/media/dvb/frontends/tda1004x.c	2004-01-09 09:22:40.000000000 +0100
+++ linux-2.6.3.p/drivers/media/dvb/frontends/tda1004x.c	2004-02-02 19:28:30.000000000 +0100
@@ -1,6 +1,8 @@
   /*
      Driver for Philips tda1004xh OFDM Frontend
 
+     (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach
+
      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; either version 2 of the License, or
@@ -20,7 +22,7 @@
 
 /*
     This driver needs a copy of the DLL "ttlcdacc.dll" from the Haupauge or Technotrend
-    windows driver saved as '/usr/lib/hotplug/firmware/tda1004x.mc'.
+    windows driver saved as '/usr/lib/hotplug/firmware/tda1004x.bin'.
     You can also pass the complete file name with the module parameter 'tda1004x_firmware'.
 
     Currently the DLL from v2.15a of the technotrend driver is supported. Other versions can
@@ -45,16 +47,12 @@
 #include "dvb_functions.h"
 
 #ifndef DVB_TDA1004X_FIRMWARE_FILE
-#define DVB_TDA1004X_FIRMWARE_FILE "/usr/lib/hotplug/firmware/tda1004x.mc"
+#define DVB_TDA1004X_FIRMWARE_FILE "/usr/lib/hotplug/firmware/tda1004x.bin"
 #endif
 
 static int tda1004x_debug = 0;
 static char *tda1004x_firmware = DVB_TDA1004X_FIRMWARE_FILE;
 
-
-#define TDA10045H_ADDRESS        0x08
-#define TD1344_ADDRESS           0x61
-#define TDM1316L_ADDRESS         0x63
 #define MC44BC374_ADDRESS        0x65
 
 #define TDA1004X_CHIPID          0x00
@@ -66,8 +64,8 @@
 #define TDA1004X_STATUS_CD       0x06
 #define TDA1004X_CONFC4          0x07
 #define TDA1004X_DSSPARE2        0x0C
-#define TDA1004X_CODE_IN         0x0D
-#define TDA1004X_FWPAGE          0x0E
+#define TDA10045H_CODE_IN        0x0D
+#define TDA10045H_FWPAGE         0x0E
 #define TDA1004X_SCAN_CPT        0x10
 #define TDA1004X_DSP_CMD         0x11
 #define TDA1004X_DSP_ARG         0x12
@@ -75,10 +73,11 @@
 #define TDA1004X_DSP_DATA2       0x14
 #define TDA1004X_CONFADC1        0x15
 #define TDA1004X_CONFC1          0x16
-#define TDA1004X_SIGNAL_STRENGTH 0x1a
+#define TDA10045H_S_AGC          0x1a
+#define TDA10046H_AGC_TUN_LEVEL  0x1a
 #define TDA1004X_SNR             0x1c
-#define TDA1004X_REG1E           0x1e
-#define TDA1004X_REG1F           0x1f
+#define TDA1004X_CONF_TS1        0x1e
+#define TDA1004X_CONF_TS2        0x1f
 #define TDA1004X_CBER_RESET      0x20
 #define TDA1004X_CBER_MSB        0x21
 #define TDA1004X_CBER_LSB        0x22
@@ -87,18 +86,58 @@
 #define TDA1004X_VBER_MID        0x25
 #define TDA1004X_VBER_LSB        0x26
 #define TDA1004X_UNCOR           0x27
-#define TDA1004X_CONFPLL_P       0x2D
-#define TDA1004X_CONFPLL_M_MSB   0x2E
-#define TDA1004X_CONFPLL_M_LSB   0x2F
-#define TDA1004X_CONFPLL_N       0x30
-#define TDA1004X_UNSURW_MSB      0x31
-#define TDA1004X_UNSURW_LSB      0x32
-#define TDA1004X_WREF_MSB        0x33
-#define TDA1004X_WREF_MID        0x34
-#define TDA1004X_WREF_LSB        0x35
-#define TDA1004X_MUXOUT          0x36
+
+#define TDA10045H_CONFPLL_P      0x2D
+#define TDA10045H_CONFPLL_M_MSB  0x2E
+#define TDA10045H_CONFPLL_M_LSB  0x2F
+#define TDA10045H_CONFPLL_N      0x30
+
+#define TDA10046H_CONFPLL1       0x2D
+#define TDA10046H_CONFPLL2       0x2F
+#define TDA10046H_CONFPLL3       0x30
+#define TDA10046H_TIME_WREF1     0x31
+#define TDA10046H_TIME_WREF2     0x32
+#define TDA10046H_TIME_WREF3     0x33
+#define TDA10046H_TIME_WREF4     0x34
+#define TDA10046H_TIME_WREF5     0x35
+
+#define TDA10045H_UNSURW_MSB     0x31
+#define TDA10045H_UNSURW_LSB     0x32
+#define TDA10045H_WREF_MSB       0x33
+#define TDA10045H_WREF_MID       0x34
+#define TDA10045H_WREF_LSB       0x35
+#define TDA10045H_MUXOUT         0x36
 #define TDA1004X_CONFADC2        0x37
-#define TDA1004X_IOFFSET         0x38
+
+#define TDA10045H_IOFFSET        0x38
+
+#define TDA10046H_CONF_TRISTATE1 0x3B
+#define TDA10046H_CONF_TRISTATE2 0x3C
+#define TDA10046H_CONF_POLARITY  0x3D
+#define TDA10046H_FREQ_OFFSET    0x3E
+#define TDA10046H_GPIO_OUT_SEL   0x41
+#define TDA10046H_GPIO_SELECT    0x42
+#define TDA10046H_AGC_CONF       0x43
+#define TDA10046H_AGC_GAINS      0x46
+#define TDA10046H_AGC_TUN_MIN    0x47
+#define TDA10046H_AGC_TUN_MAX    0x48
+#define TDA10046H_AGC_IF_MIN     0x49
+#define TDA10046H_AGC_IF_MAX     0x4A
+
+#define TDA10046H_FREQ_PHY2_MSB  0x4D
+#define TDA10046H_FREQ_PHY2_LSB  0x4E
+
+#define TDA10046H_CVBER_CTRL     0x4F
+#define TDA10046H_AGC_IF_LEVEL   0x52
+#define TDA10046H_CODE_CPT       0x57
+#define TDA10046H_CODE_IN        0x58
+
+
+#define FE_TYPE_TDA10045H     0
+#define FE_TYPE_TDA10046H     1
+
+#define TUNER_TYPE_TD1344     0
+#define TUNER_TYPE_TD1316     1
 
 #define dprintk if (tda1004x_debug) printk
 
@@ -115,11 +154,27 @@
 	    FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
 };
 
+static struct dvb_frontend_info tda10046h_info = {
+        .name = "Philips TDA10046H",
+        .type = FE_OFDM,
+        .frequency_min = 51000000,
+        .frequency_max = 858000000,
+        .frequency_stepsize = 166667,
+        .caps =
+            FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+            FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+            FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+            FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
+};
+
+
 #pragma pack(1)
 struct tda1004x_state {
 	u8 tda1004x_address;
 	u8 tuner_address;
 	u8 initialised:1;
+        u8 tuner_type:2;
+        u8 fe_type:2;
 };
 #pragma pack()
 
@@ -131,6 +186,9 @@
 static struct fwinfo tda10045h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x34cc5,.fw_size = 30555} };
 static int tda10045h_fwinfo_count = sizeof(tda10045h_fwinfo) / sizeof(struct fwinfo);
 
+static struct fwinfo tda10046h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x3c4f9,.fw_size = 24479} };
+static int tda10046h_fwinfo_count = sizeof(tda10046h_fwinfo) / sizeof(struct fwinfo);
+
 static int errno;
 
 
@@ -245,46 +302,98 @@
         switch (bandwidth) {
 	case BANDWIDTH_6_MHZ:
 		tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x14);
-		tda1004x_write_buf(i2c, tda_state, TDA1004X_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
+                tda1004x_write_buf(i2c, tda_state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
 		break;
 
 	case BANDWIDTH_7_MHZ:
 		tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x80);
-		tda1004x_write_buf(i2c, tda_state, TDA1004X_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
+                tda1004x_write_buf(i2c, tda_state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
 		break;
 
 	case BANDWIDTH_8_MHZ:
 		tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x14);
-		tda1004x_write_buf(i2c, tda_state, TDA1004X_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
+                tda1004x_write_buf(i2c, tda_state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
 		break;
 
 	default:
 		return -EINVAL;
 	}
 
-	tda1004x_write_byte(i2c, tda_state, TDA1004X_IOFFSET, 0);
+        tda1004x_write_byte(i2c, tda_state, TDA10045H_IOFFSET, 0);
+
+        // done
+        return 0;
+}
+
+
+static int tda10046h_set_bandwidth(struct dvb_i2c_bus *i2c,
+                                   struct tda1004x_state *tda_state,
+                                   fe_bandwidth_t bandwidth)
+{
+        static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e };
+        static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 };
+        static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd };
+
+        switch (bandwidth) {
+        case BANDWIDTH_6_MHZ:
+                tda1004x_write_buf(i2c, tda_state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
+                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0);
+                break;
+
+        case BANDWIDTH_7_MHZ:
+                tda1004x_write_buf(i2c, tda_state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
+                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0);
+                break;
+
+        case BANDWIDTH_8_MHZ:
+                tda1004x_write_buf(i2c, tda_state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
+                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0xFF);
+                break;
+
+        default:
+                return -EINVAL;
+        }
 
         // done
         return 0;
 }
 
 
-static int tda1004x_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state)
+static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state)
 {
 	u8 fw_buf[65];
 	struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = fw_buf,.len = 0 };
-	struct i2c_msg tuner_msg = {.addr = 0,.flags = 0,.buf = 0,.len = 0 };
 	unsigned char *firmware = NULL;
 	int filesize;
 	int fd;
 	int fwinfo_idx;
 	int fw_size = 0;
-	int fw_pos;
+        int fw_pos, fw_offset;
 	int tx_size;
-        static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
 	mm_segment_t fs = get_fs();
-
-	dprintk("%s\n", __FUNCTION__);
+        int dspCodeCounterReg=0, dspCodeInReg=0, dspVersion=0;
+        int fwInfoCount=0;
+        struct fwinfo* fwInfo = NULL;
+        unsigned long timeout;
+
+        // DSP parameters
+        switch(tda_state->fe_type) {
+        case FE_TYPE_TDA10045H:
+                dspCodeCounterReg = TDA10045H_FWPAGE;
+                dspCodeInReg = TDA10045H_CODE_IN;
+                dspVersion = 0x2c;
+                fwInfoCount = tda10045h_fwinfo_count;
+                fwInfo = tda10045h_fwinfo;
+                break;
+
+        case FE_TYPE_TDA10046H:
+                dspCodeCounterReg = TDA10046H_CODE_CPT;
+                dspCodeInReg = TDA10046H_CODE_IN;
+                dspVersion = 0x20;
+                fwInfoCount = tda10046h_fwinfo_count;
+                fwInfo = tda10046h_fwinfo;
+                break;
+        }
 
 	// Load the firmware
 	set_fs(get_ds());
@@ -302,17 +411,18 @@
 		return -EIO;
 	}
 
-	// find extraction parameters
-	for (fwinfo_idx = 0; fwinfo_idx < tda10045h_fwinfo_count; fwinfo_idx++) {
-		if (tda10045h_fwinfo[fwinfo_idx].file_size == filesize)
+        // find extraction parameters for firmware
+        for (fwinfo_idx = 0; fwinfo_idx < fwInfoCount; fwinfo_idx++) {
+                if (fwInfo[fwinfo_idx].file_size == filesize)
 			break;
 	}
-	if (fwinfo_idx >= tda10045h_fwinfo_count) {
+        if (fwinfo_idx >= fwInfoCount) {
 		printk("%s: Unsupported firmware %s\n", __FUNCTION__, tda1004x_firmware);
 		sys_close(fd);
 		return -EIO;
 	}
-	fw_size = tda10045h_fwinfo[fwinfo_idx].fw_size;
+        fw_size = fwInfo[fwinfo_idx].fw_size;
+        fw_offset = fwInfo[fwinfo_idx].fw_offset;
 
 	// allocate buffer for it
 	firmware = vmalloc(fw_size);
@@ -324,7 +434,7 @@
 	}
 
 	// read it!
-	lseek(fd, tda10045h_fwinfo[fwinfo_idx].fw_offset, 0);
+        lseek(fd, fw_offset, 0);
 	if (read(fd, firmware, fw_size) != fw_size) {
 		printk("%s: Failed to read firmware\n", __FUNCTION__);
 		vfree(firmware);
@@ -334,26 +444,35 @@
 	sys_close(fd);
 	set_fs(fs);
 
-	// Disable the MC44BC374C
-	tda1004x_enable_tuner_i2c(i2c, tda_state);
-	tuner_msg.addr = MC44BC374_ADDRESS;
-	tuner_msg.buf = disable_mc44BC374c;
-	tuner_msg.len = sizeof(disable_mc44BC374c);
-	if (i2c->xfer(i2c, &tuner_msg, 1) != 1) {
-		i2c->xfer(i2c, &tuner_msg, 1);
-	}
-	tda1004x_disable_tuner_i2c(i2c, tda_state);
+        // set some valid bandwith parameters before uploading
+        switch(tda_state->fe_type) {
+        case FE_TYPE_TDA10045H:
+                // reset chip
+                tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8);
+                tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 0);
+                dvb_delay(10);
 
-	// set some valid bandwith parameters
-        switch(tda_state->tda1004x_address) {
-        case TDA10045H_ADDRESS:
+                // set parameters
                 tda10045h_set_bandwidth(i2c, tda_state, BANDWIDTH_8_MHZ);
                 break;
+
+        case FE_TYPE_TDA10046H:
+                // reset chip
+                tda1004x_write_mask(i2c, tda_state, TDA10046H_CONF_TRISTATE1, 1, 0);
+                dvb_delay(10);
+
+                // set parameters
+                tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL2, 10);
+                tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL3, 0);
+                tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_OFFSET, 99);
+                tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
+                tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
+                tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
+                break;
         }
-	dvb_delay(500);
 
 	// do the firmware upload
-	tda1004x_write_byte(i2c, tda_state, TDA1004X_FWPAGE, 0);
+        tda1004x_write_byte(i2c, tda_state, dspCodeCounterReg, 0); // clear code counter
         fw_msg.addr = tda_state->tda1004x_address;
 	fw_pos = 0;
 	while (fw_pos != fw_size) {
@@ -357,16 +476,19 @@
         fw_msg.addr = tda_state->tda1004x_address;
 	fw_pos = 0;
 	while (fw_pos != fw_size) {
+
 		// work out how much to send this time
 		tx_size = fw_size - fw_pos;
-		if (tx_size > 64) {
-			tx_size = 64;
+                if (tx_size > 0x10) {
+                        tx_size = 0x10;
 		}
+
 		// send the chunk
-		fw_buf[0] = TDA1004X_CODE_IN;
+                fw_buf[0] = dspCodeInReg;
 		memcpy(fw_buf + 1, firmware + fw_pos, tx_size);
 		fw_msg.len = tx_size + 1;
 		if (i2c->xfer(i2c, &fw_msg, 1) != 1) {
+                        printk("tda1004x: Error during firmware upload\n");
 			vfree(firmware);
 			return -EIO;
 		}
@@ -374,35 +496,128 @@
 
 		dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, fw_pos);
 	}
-	dvb_delay(100);
 	vfree(firmware);
 
-	// Initialise the DSP and check upload was OK
-	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x10, 0);
+        // wait for DSP to initialise
+        switch(tda_state->fe_type) {
+        case FE_TYPE_TDA10045H:
+                // DSPREADY doesn't seem to work on the TDA10045H
+                dvb_delay(100);
+                break;
+
+        case FE_TYPE_TDA10046H:
+                timeout = jiffies + HZ;
+                while(!(tda1004x_read_byte(i2c, tda_state, TDA1004X_STATUS_CD) & 0x20)) {
+                        if (time_after(jiffies, timeout)) {
+                                printk("tda1004x: DSP failed to initialised.\n");
+                                return -EIO;
+                        }
+
+                        dvb_delay(1);
+                }
+                break;
+        }
+
+        // check upload was OK
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
 	tda1004x_write_byte(i2c, tda_state, TDA1004X_DSP_CMD, 0x67);
 	if ((tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA1) != 0x67) ||
-	    (tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA2) != 0x2c)) {
+            (tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA2) != dspVersion)) {
 		printk("%s: firmware upload failed!\n", __FUNCTION__);
 		return -EIO;
 	}
 
+        // success
+        return 0;
+}
+
+
+static int tda10045h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state)
+{
+        struct i2c_msg tuner_msg = {.addr = 0,.flags = 0,.buf = 0,.len = 0 };
+        static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
+
+        dprintk("%s\n", __FUNCTION__);
+
+        // Disable the MC44BC374C
+        tda1004x_enable_tuner_i2c(i2c, tda_state);
+        tuner_msg.addr = MC44BC374_ADDRESS;
+        tuner_msg.buf = disable_mc44BC374c;
+        tuner_msg.len = sizeof(disable_mc44BC374c);
+        if (i2c->xfer(i2c, &tuner_msg, 1) != 1) {
+                i2c->xfer(i2c, &tuner_msg, 1);
+        }
+        tda1004x_disable_tuner_i2c(i2c, tda_state);
+
 	// tda setup
-	tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 8, 0);
-        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x10, 0x10);
-        tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0xC0, 0x0);
-        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x20, 0);
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 8, 0); // select HP stream
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x40, 0); // no frequency inversion
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset
+        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface
+        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
         tda1004x_write_byte(i2c, tda_state, TDA1004X_CONFADC1, 0x2e);
-	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x80, 0x80);
-	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x40, 0);
-	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x10, 0);
-        tda1004x_write_byte(i2c, tda_state, TDA1004X_REG1E, 0);
-	tda1004x_write_byte(i2c, tda_state, TDA1004X_REG1F, 0);
-	tda1004x_write_mask(i2c, tda_state, TDA1004X_VBER_MSB, 0xe0, 0xa0);
 
 	// done
 	return 0;
 }
 
+
+
+static int tda10046h_init(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state)
+{
+        struct i2c_msg tuner_msg = {.addr = 0,.flags = 0,.buf = 0,.len = 0 };
+        static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
+
+        dprintk("%s\n", __FUNCTION__);
+
+        // Disable the MC44BC374C
+        tda1004x_enable_tuner_i2c(i2c, tda_state);
+        tuner_msg.addr = MC44BC374_ADDRESS;
+        tuner_msg.buf = disable_mc44BC374c;
+        tuner_msg.len = sizeof(disable_mc44BC374c);
+        if (i2c->xfer(i2c, &tuner_msg, 1) != 1) {
+                i2c->xfer(i2c, &tuner_msg, 1);
+        }
+        tda1004x_disable_tuner_i2c(i2c, tda_state);
+
+        // tda setup
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x40, 0x40); // TT TDA10046H needs inversion ON
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 8, 0); // select HP stream
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL2, 10); // PLL M = 10
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // }
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_CONF, 0); // AGC setup
+        tda1004x_write_mask(i2c, tda_state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_TUN_MIN, 0);    // }
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_IF_MIN, 0);     // }
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_IF_MAX, 0xff);  // }
+        tda1004x_write_mask(i2c, tda_state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm
+        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
+        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config
+        tda1004x_write_mask(i2c, tda_state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
+        tda1004x_write_byte(i2c, tda_state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
+        tda1004x_write_mask(i2c, tda_state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select
+        tda10046h_set_bandwidth(i2c, tda_state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
+
+        // done
+        return 0;
+}
+
+
+
 static int tda1004x_encode_fec(int fec)
 {
 	// convert known FEC values
@@ -449,17 +664,18 @@
 {
 	u8 tuner_buf[4];
 	struct i2c_msg tuner_msg = {.addr=0, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
-	int tuner_frequency;
+        int tuner_frequency = 0;
         u8 band, cp, filter;
 	int counter, counter2;
 
 	dprintk("%s\n", __FUNCTION__);
 
 	// setup the frequency buffer
-	switch (tda_state->tuner_address) {
-	case TD1344_ADDRESS:
+        switch (tda_state->tuner_type) {
+        case TUNER_TYPE_TD1344:
 
 		// setup tuner buffer
+                // ((Fif+((1000000/6)/2)) + Finput)/(1000000/6)
 		tuner_frequency =
                         (((fe_params->frequency / 1000) * 6) + 217502) / 1000;
 		tuner_buf[0] = tuner_frequency >> 8;
@@ -498,7 +714,7 @@
 		tda1004x_disable_tuner_i2c(i2c, tda_state);
 		break;
 
-	case TDM1316L_ADDRESS:
+        case TUNER_TYPE_TD1316:
 		// determine charge pump
 		tuner_frequency = fe_params->frequency + 36130000;
 		if (tuner_frequency < 87000000) {
@@ -541,9 +757,7 @@
 		// work out filter
 		switch (fe_params->u.ofdm.bandwidth) {
 		case BANDWIDTH_6_MHZ:
-                        // 6 MHz isn't supported directly, but set this to
-                        // the 8 MHz setting in case we can fiddle it later
-                        filter = 1;
+                        filter = 0;
                         break;
 
                 case BANDWIDTH_7_MHZ:
@@ -558,15 +772,27 @@
 			return -EINVAL;
 		}
 
-		// calculate tuner parameters
+                // calculate divisor
+                // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
 		tuner_frequency =
                         (((fe_params->frequency / 1000) * 6) + 217280) / 1000;
+
+                // setup tuner buffer
 		tuner_buf[0] = tuner_frequency >> 8;
 		tuner_buf[1] = tuner_frequency & 0xff;
 		tuner_buf[2] = 0xca;
 		tuner_buf[3] = (cp << 5) | (filter << 3) | band;
 
 		// tune it
+                if (tda_state->fe_type == FE_TYPE_TDA10046H) {
+                        // setup auto offset
+                        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x10, 0x10);
+                        tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x80, 0);
+                        tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0xC0, 0);
+
+                        // disable agc_conf[2]
+                        tda1004x_write_mask(i2c, tda_state, TDA10046H_AGC_CONF, 4, 0);
+                }
 		tda1004x_enable_tuner_i2c(i2c, tda_state);
 		tuner_msg.addr = tda_state->tuner_address;
 		tuner_msg.len = 4;
@@ -575,6 +801,8 @@
 		}
 		dvb_delay(1);
 		tda1004x_disable_tuner_i2c(i2c, tda_state);
+                if (tda_state->fe_type == FE_TYPE_TDA10046H)
+                        tda1004x_write_mask(i2c, tda_state, TDA10046H_AGC_CONF, 4, 4);
 		break;
 
 	default:
@@ -592,6 +820,7 @@
 		           struct dvb_frontend_parameters *fe_params)
 {
 	int tmp;
+        int inversion;
 
 	dprintk("%s\n", __FUNCTION__);
 
@@ -595,10 +824,8 @@
 
 	dprintk("%s\n", __FUNCTION__);
 
-
 	// set frequency
-	tmp = tda1004x_set_frequency(i2c, tda_state, fe_params);
-	if (tmp < 0)
+        if ((tmp = tda1004x_set_frequency(i2c, tda_state, fe_params)) < 0)
 		return tmp;
 
         // hardcoded to use auto as much as possible
@@ -672,14 +899,24 @@
 	}
 
         // set bandwidth
-        switch(tda_state->tda1004x_address) {
-        case TDA10045H_ADDRESS:
+        switch(tda_state->fe_type) {
+        case FE_TYPE_TDA10045H:
                 tda10045h_set_bandwidth(i2c, tda_state, fe_params->u.ofdm.bandwidth);
                 break;
+
+        case FE_TYPE_TDA10046H:
+                tda10046h_set_bandwidth(i2c, tda_state, fe_params->u.ofdm.bandwidth);
+                break;
+        }
+
+        // need to invert the inversion for TT TDA10046H
+        inversion = fe_params->inversion;
+        if (tda_state->fe_type == FE_TYPE_TDA10046H) {
+                inversion = inversion ? INVERSION_OFF : INVERSION_ON;
         }
 
 	// set inversion
-	switch (fe_params->inversion) {
+        switch (inversion) {
 	case INVERSION_OFF:
 		tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x20, 0);
 		break;
@@ -744,10 +981,19 @@
 		return -EINVAL;
 	}
 
-	// reset DSP
+        // start the lock
+        switch(tda_state->fe_type) {
+        case FE_TYPE_TDA10045H:
 	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8);
 	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 0);
 	dvb_delay(10);
+                break;
+
+        case FE_TYPE_TDA10046H:
+                tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x40, 0x40);
+                dvb_delay(10);
+                break;
+        }
 
 	// done
 	return 0;
@@ -765,8 +1010,15 @@
 		fe_params->inversion = INVERSION_ON;
 	}
 
+        // need to invert the inversion for TT TDA10046H
+        if (tda_state->fe_type == FE_TYPE_TDA10046H) {
+                fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
+        }
+
 	// bandwidth
-	switch (tda1004x_read_byte(i2c, tda_state, TDA1004X_WREF_LSB)) {
+        switch(tda_state->fe_type) {
+        case FE_TYPE_TDA10045H:
+                switch (tda1004x_read_byte(i2c, tda_state, TDA10045H_WREF_LSB)) {
 	case 0x14:
 		fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
 		break;
@@ -777,6 +1029,22 @@
 		fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
 		break;
 	}
+                break;
+
+        case FE_TYPE_TDA10046H:
+                switch (tda1004x_read_byte(i2c, tda_state, TDA10046H_TIME_WREF1)) {
+                case 0x60:
+                        fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+                        break;
+                case 0x6e:
+                        fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
+                        break;
+                case 0x80:
+                        fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
+                        break;
+                }
+                break;
+        }
 
 	// FEC
 	fe_params->u.ofdm.code_rate_HP =
@@ -905,11 +1173,23 @@
 static int tda1004x_read_signal_strength(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, u16 * signal)
 {
 	int tmp;
+        int reg = 0;
 
 	dprintk("%s\n", __FUNCTION__);
 
+        // determine the register to use
+        switch(tda_state->fe_type) {
+        case FE_TYPE_TDA10045H:
+                reg = TDA10045H_S_AGC;
+                break;
+
+        case FE_TYPE_TDA10046H:
+                reg = TDA10046H_AGC_IF_LEVEL;
+                break;
+        }
+
 	// read it
-	tmp = tda1004x_read_byte(i2c, tda_state, TDA1004X_SIGNAL_STRENGTH);
+        tmp = tda1004x_read_byte(i2c, tda_state, reg);
 	if (tmp < 0)
 		return -EIO;
 
@@ -1008,10 +1288,14 @@
 
 	switch (cmd) {
 	case FE_GET_INFO:
-                switch(tda_state->tda1004x_address) {
-                case TDA10045H_ADDRESS:
+                switch(tda_state->fe_type) {
+                case FE_TYPE_TDA10045H:
         		memcpy(arg, &tda10045h_info, sizeof(struct dvb_frontend_info));
                         break;
+
+                case FE_TYPE_TDA10046H:
+                        memcpy(arg, &tda10046h_info, sizeof(struct dvb_frontend_info));
+                        break;
                 }
 		break;
 
@@ -1042,7 +1327,15 @@
 			return 0;
 
 		// OK, perform initialisation
-                status = tda1004x_init(i2c, tda_state);
+                switch(tda_state->fe_type) {
+                case FE_TYPE_TDA10045H:
+                        status = tda10045h_init(i2c, tda_state);
+                        break;
+
+                case FE_TYPE_TDA10046H:
+                        status = tda10046h_init(i2c, tda_state);
+                        break;
+                }
 		if (status == 0)
 			tda_state->initialised = 1;
 		return status;
@@ -1059,42 +1352,81 @@
 {
         int tda1004x_address = -1;
 	int tuner_address = -1;
+        int fe_type = -1;
+        int tuner_type = -1;
 	struct tda1004x_state tda_state;
 	struct i2c_msg tuner_msg = {.addr=0, .flags=0, .buf=0, .len=0 };
         static u8 td1344_init[] = { 0x0b, 0xf5, 0x88, 0xab };
-        static u8 tdm1316l_init[] = { 0x0b, 0xf5, 0x85, 0xab };
+        static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
+        static u8 td1316_init_tda10046h[] = { 0x0b, 0xf5, 0x80, 0xab };
+        int status;
 
 	dprintk("%s\n", __FUNCTION__);
 
-	// probe for frontend
-        tda_state.tda1004x_address = TDA10045H_ADDRESS;
+        // probe for tda10045h
+        if (tda1004x_address == -1) {
+                tda_state.tda1004x_address = 0x08;
 	if (tda1004x_read_byte(i2c, &tda_state, TDA1004X_CHIPID) == 0x25) {
-                tda1004x_address = TDA10045H_ADDRESS;
+                        tda1004x_address = 0x08;
+                        fe_type = FE_TYPE_TDA10045H;
                 printk("tda1004x: Detected Philips TDA10045H.\n");
         }
+        }
+
+        // probe for tda10046h
+        if (tda1004x_address == -1) {
+                tda_state.tda1004x_address = 0x08;
+                if (tda1004x_read_byte(i2c, &tda_state, TDA1004X_CHIPID) == 0x46) {
+                        tda1004x_address = 0x08;
+                        fe_type = FE_TYPE_TDA10046H;
+                        printk("tda1004x: Detected Philips TDA10046H.\n");
+                }
+        }
 
         // did we find a frontend?
         if (tda1004x_address == -1) {
 		return -ENODEV;
         }
 
-	// supported tuner?
+        // enable access to the tuner
 	tda1004x_enable_tuner_i2c(i2c, &tda_state);
-	tuner_msg.addr = TD1344_ADDRESS;
+
+        // check for a TD1344 first
+        if (tuner_address == -1) {
+                tuner_msg.addr = 0x61;
 	tuner_msg.buf = td1344_init;
 	tuner_msg.len = sizeof(td1344_init);
 	if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {
                 dvb_delay(1);
-		tuner_address = TD1344_ADDRESS;
-		printk("tda1004x: Detected Philips TD1344 tuner. PLEASE CHECK THIS AND REPORT BACK!.\n");
-	} else {
-		tuner_msg.addr = TDM1316L_ADDRESS;
-                tuner_msg.buf = tdm1316l_init;
-                tuner_msg.len = sizeof(tdm1316l_init);
+                        tuner_address = 0x61;
+                        tuner_type = TUNER_TYPE_TD1344;
+                        printk("tda1004x: Detected Philips TD1344 tuner.\n");
+                }
+        }
+
+        // OK, try a TD1316 on address 0x63
+        if (tuner_address == -1) {
+                tuner_msg.addr = 0x63;
+                tuner_msg.buf = td1316_init;
+                tuner_msg.len = sizeof(td1316_init);
                 if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {
                         dvb_delay(1);
-			tuner_address = TDM1316L_ADDRESS;
-			printk("tda1004x: Detected Philips TDM1316L tuner.\n");
+                        tuner_address = 0x63;
+                        tuner_type = TUNER_TYPE_TD1316;
+                        printk("tda1004x: Detected Philips TD1316 tuner.\n");
+                }
+        }
+
+        // OK, TD1316 again, on address 0x60 (TDA10046H)
+        if (tuner_address == -1) {
+                tuner_msg.addr = 0x60;
+                tuner_msg.buf = td1316_init_tda10046h;
+                tuner_msg.len = sizeof(td1316_init_tda10046h);
+                if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {
+                        dvb_delay(1);
+                        tuner_address = 0x60;
+                        tuner_type = TUNER_TYPE_TD1316;
+                        printk("tda1004x: Detected Philips TD1316 tuner.\n");
 		}
 	}
 	tda1004x_disable_tuner_i2c(i2c, &tda_state);
@@ -1107,16 +1439,25 @@
 
         // create state
         tda_state.tda1004x_address = tda1004x_address;
+        tda_state.fe_type = fe_type;
 	tda_state.tuner_address = tuner_address;
+        tda_state.tuner_type = tuner_type;
 	tda_state.initialised = 0;
 
+        // upload firmware
+        if ((status = tda1004x_fwupload(i2c, &tda_state)) != 0) return status;
+
 	// register
-        switch(tda_state.tda1004x_address) {
-        case TDA10045H_ADDRESS:
+        switch(tda_state.fe_type) {
+        case FE_TYPE_TDA10045H:
         	return dvb_register_frontend(tda1004x_ioctl, i2c, (void *)(*((u32*) &tda_state)), &tda10045h_info);
-	default:
-		return -ENODEV;
+
+        case FE_TYPE_TDA10046H:
+                return dvb_register_frontend(tda1004x_ioctl, i2c, (void *)(*((u32*) &tda_state)), &tda10046h_info);
         }
+
+        // should not get here
+        return -EINVAL;
 }
 
 
@@ -1145,7 +1486,7 @@
 module_init(init_tda1004x);
 module_exit(exit_tda1004x);
 
-MODULE_DESCRIPTION("Philips TDA10045H DVB-T Frontend");
+MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Frontend");
 MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
 MODULE_LICENSE("GPL");
 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 21:05             ` [PATCH 7/9] tda1004x " Michael Hunold
  2004-02-23 21:05               ` [PATCH 8/9] av7110 DVB driver update Michael Hunold
@ 2004-02-23 21:18               ` Christoph Hellwig
  2004-02-23 22:47                 ` Michael Hunold
  2004-02-23 22:09               ` Andrew Morton
  2 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2004-02-23 21:18 UTC (permalink / raw)
  To: Michael Hunold; +Cc: torvalds, akpm, linux-kernel

>  #ifndef DVB_TDA1004X_FIRMWARE_FILE
> -#define DVB_TDA1004X_FIRMWARE_FILE "/usr/lib/hotplug/firmware/tda1004x.mc"
> +#define DVB_TDA1004X_FIRMWARE_FILE "/usr/lib/hotplug/firmware/tda1004x.bin"
>  #endif

Why would the kernel driver want to know the exact path of the firmware file?


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 21:05             ` [PATCH 7/9] tda1004x " Michael Hunold
  2004-02-23 21:05               ` [PATCH 8/9] av7110 DVB driver update Michael Hunold
  2004-02-23 21:18               ` [PATCH 7/9] tda1004x DVB frontend update Christoph Hellwig
@ 2004-02-23 22:09               ` Andrew Morton
  2004-02-23 22:52                 ` Michael Hunold
  2 siblings, 1 reply; 21+ messages in thread
From: Andrew Morton @ 2004-02-23 22:09 UTC (permalink / raw)
  To: Michael Hunold; +Cc: torvalds, linux-kernel, hunold

Michael Hunold <hunold@linuxtv.org> wrote:
>
>  	// read it!
> -	lseek(fd, tda10045h_fwinfo[fwinfo_idx].fw_offset, 0);
> +        lseek(fd, fw_offset, 0);
>  	if (read(fd, firmware, fw_size) != fw_size) {

was there some plan to convert DVB over to using the firmware loader?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/9] Update the DVB subsystem docs
  2004-02-23 21:04 ` [PATCH 1/9] Update the DVB subsystem docs Michael Hunold
  2004-02-23 21:04   ` [PATCH 2/9] Update saa7146 driver core Michael Hunold
@ 2004-02-23 22:23   ` Richard B. Johnson
  2004-02-23 22:57     ` Michael Hunold
  1 sibling, 1 reply; 21+ messages in thread
From: Richard B. Johnson @ 2004-02-23 22:23 UTC (permalink / raw)
  To: Michael Hunold; +Cc: torvalds, akpm, Linux kernel

On Mon, 23 Feb 2004, Michael Hunold wrote:

> +
> +Getting the card going
> +
> +   To  power  up  the  card,  load  the  following modules in the
> +   following order:
> +
> +     * insmod dvb-core.o
> +     * modprobe bttv.o
> +     * insmod bt878.o
> +     * insmod dvb-bt8xx.o
> +     * insmod sp887x.o
> +
> +   The  current version of the frontend module sp887x.o, contains
> +   no firmware drivers?, so the first time you open it with a DVB
> +   utility  the driver will try to download some initial firmware
> +   to  the card. You will need to download this firmware from the
> +   web,  or  copy  it from an installation of the Windows drivers
> +   that probably came with your card, before you can use it.
> +
> +   The  default  Linux  filesystem  location for this firmware is
> +   /usr/lib/hotplug/firmware/sc_main.mc .

What does this have to do with the kernel? Isn't this for some
utility that starts Aver/TV? Surely the kernel doesn't read files.

I run this same TV card in W$ and the W$ program loads firmware
and starts the card. Who's process context gets stolen to read
these files from within the kernel?

> +
> +   The  Windows  drivers  for the Avermedia DVB-T can be obtained
> +   from: http://babyurl.com/H3U970 and you can get an application
> +   to extract the firmware from:
> +   http://www.kyz.uklinux.net/cabextract.php.
> +     _________________________________________________________

Truly bizarre, weird........

> +Known Limitations
> +

Truly bizarre, weird........

> @@ -20,7 +20,7 @@
>  		extracted from the Windows driver (Sc_main.mc).
>  - tda1004x: firmware is loaded from path specified in
>  		DVB_TDA1004X_FIRMWARE_FILE kernel config

WTF? The __kernel__ doesn't read files. User mode programs
use the kernel to read files for them, on their behalf.

> -		variable (default /etc/dvb/tda1004x.bin); the
> +		variable (default /usr/lib/hotplug/firmware/tda1004x.bin); the
>  		firmware binary must be extracted from the windows
>  		driver

Truly bizarre, weird........ It's not April 1st yet!

Cheers,
Dick Johnson
Penguin : Linux version 2.4.24 on an i686 machine (797.90 BogoMips).
            Note 96.31% of all statistics are fiction.



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 21:18               ` [PATCH 7/9] tda1004x DVB frontend update Christoph Hellwig
@ 2004-02-23 22:47                 ` Michael Hunold
  2004-02-23 22:54                   ` Christoph Hellwig
  0 siblings, 1 reply; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 22:47 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Michael Hunold, torvalds, akpm, linux-kernel

On 02/23/04 22:18, Christoph Hellwig wrote:
>> #ifndef DVB_TDA1004X_FIRMWARE_FILE
>>-#define DVB_TDA1004X_FIRMWARE_FILE "/usr/lib/hotplug/firmware/tda1004x.mc"
>>+#define DVB_TDA1004X_FIRMWARE_FILE "/usr/lib/hotplug/firmware/tda1004x.bin"
>> #endif

> Why would the kernel driver want to know the exact path of the firmware file?

Because we don't use the in-kernel firmware loader at the moment.

The driver comes from a time were 2.4 didn't have the firmware loader 
and drivers cloned the firmware loading stuff from one of the soundcard 
drivers.

Currently there is no way to solve this problem, because we don't have 
any kernel structure that we could attach to and have it export the 
sysfs and firmware loading magic.

We plan to use the kernel i2c subsystem again, then all our problems 
hopefully vanish.

CU
Michael.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 22:09               ` Andrew Morton
@ 2004-02-23 22:52                 ` Michael Hunold
  2004-02-23 23:11                   ` Andrew Morton
                                     ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 22:52 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Michael Hunold, torvalds, linux-kernel

Hello Andrew,

On 02/23/04 23:09, Andrew Morton wrote:
>> 	// read it!
>>-	lseek(fd, tda10045h_fwinfo[fwinfo_idx].fw_offset, 0);
>>+        lseek(fd, fw_offset, 0);
>> 	if (read(fd, firmware, fw_size) != fw_size) {

> was there some plan to convert DVB over to using the firmware loader?

Yes. But as I wrote in the mail to Christoph, we currently don't have a 
chance to use some in-kernel structure (pci device, i2c bus) that 
automatically exports the firmware loading magic through sysfs.

Because of this, we would have to write our own sysfs backend for the 
dvb i2c subsystem, in order to get proper firmware loading support.

As I already mentioned in another mail, we want to go back to the kernel 
i2c subsystem.

Currently, the stuff is running quite stable and is "in use".

Changing the i2c subsystem would require changes in all frontend drivers 
+ plus in the dvb drivers exporting the i2c facilities.

Is such a big change acceptable for 2.6 if it fixes these horrible hacks 
or is this 2.7 stuff?

CU
Michael.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 22:47                 ` Michael Hunold
@ 2004-02-23 22:54                   ` Christoph Hellwig
  2004-02-23 23:01                     ` Michael Hunold
  0 siblings, 1 reply; 21+ messages in thread
From: Christoph Hellwig @ 2004-02-23 22:54 UTC (permalink / raw)
  To: Michael Hunold
  Cc: Christoph Hellwig, Michael Hunold, torvalds, akpm, linux-kernel

On Mon, Feb 23, 2004 at 11:47:55PM +0100, Michael Hunold wrote:
> > Why would the kernel driver want to know the exact path of the firmware file?
> 
> Because we don't use the in-kernel firmware loader at the moment.
> 
> The driver comes from a time were 2.4 didn't have the firmware loader 
> and drivers cloned the firmware loading stuff from one of the soundcard 
> drivers.

Sorry, but that's a bad excuse.  It's bogus in 2.4 too (or any given
kernel).


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/9] Update the DVB subsystem docs
  2004-02-23 22:23   ` [PATCH 1/9] Update the DVB subsystem docs Richard B. Johnson
@ 2004-02-23 22:57     ` Michael Hunold
  0 siblings, 0 replies; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 22:57 UTC (permalink / raw)
  To: root; +Cc: torvalds, akpm, Linux kernel

Hello Richard,

On 02/23/04 23:23, Richard B. Johnson wrote:
> On Mon, 23 Feb 2004, Michael Hunold wrote:

>>+   The  Windows  drivers  for the Avermedia DVB-T can be obtained
>>+   from: http://babyurl.com/H3U970 and you can get an application
>>+   to extract the firmware from:
>>+   http://www.kyz.uklinux.net/cabextract.php.
>>+     _________________________________________________________
> 
> 
> Truly bizarre, weird........

DVB under Linux is sometimes cruel. Newer devices require firmware which 
cannot be legally distributed.

So these curde workarounds are necessary, unfortunately.


>>+   The  default  Linux  filesystem  location for this firmware is
>>+   /usr/lib/hotplug/firmware/sc_main.mc .

> What does this have to do with the kernel? Isn't this for some
> utility that starts Aver/TV? Surely the kernel doesn't read files.

The description said, that the file is also a nice introduction to DVB 
in general (with a close look to the avermedia cards), so this 
information wasn't stripped.

>> 		extracted from the Windows driver (Sc_main.mc).
>> - tda1004x: firmware is loaded from path specified in
>> 		DVB_TDA1004X_FIRMWARE_FILE kernel config
> 
> 
> WTF? The __kernel__ doesn't read files. User mode programs
> use the kernel to read files for them, on their behalf.

Please refer to my other mail to Christoph and Andrew. Some of the 
drivers uses historical cruft and we have a plan to overcome this.

> Cheers,
> Dick Johnson

CU
Michael.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 22:54                   ` Christoph Hellwig
@ 2004-02-23 23:01                     ` Michael Hunold
  0 siblings, 0 replies; 21+ messages in thread
From: Michael Hunold @ 2004-02-23 23:01 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Michael Hunold, torvalds, akpm, linux-kernel

Hello Christoph,

On 02/23/04 23:54, Christoph Hellwig wrote:
> On Mon, Feb 23, 2004 at 11:47:55PM +0100, Michael Hunold wrote:
> 
>>>Why would the kernel driver want to know the exact path of the firmware file?
>>
>>Because we don't use the in-kernel firmware loader at the moment.
>>
>>The driver comes from a time were 2.4 didn't have the firmware loader 
>>and drivers cloned the firmware loading stuff from one of the soundcard 
>>drivers.

> Sorry, but that's a bad excuse.  It's bogus in 2.4 too (or any given
> kernel).

I cannnot speak against this, I completely agree.

If I personally would use these type of cards, I think I would have 
converted them already.

*sigh* I think I'll step forward and have the first drivers converted to 
in-kernel i2c as soon as possible, so I can coerce the other driver 
authors to use proper firmware loading.

CU
Michael.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 22:52                 ` Michael Hunold
@ 2004-02-23 23:11                   ` Andrew Morton
  2004-02-23 23:15                   ` Ralph Metzler
  2004-02-24 11:34                   ` Marcel Holtmann
  2 siblings, 0 replies; 21+ messages in thread
From: Andrew Morton @ 2004-02-23 23:11 UTC (permalink / raw)
  To: Michael Hunold; +Cc: torvalds, linux-kernel

Michael Hunold <hunold@convergence.de> wrote:
>
> Changing the i2c subsystem would require changes in all frontend drivers 
> + plus in the dvb drivers exporting the i2c facilities.
> 
> Is such a big change acceptable for 2.6 if it fixes these horrible hacks 
> or is this 2.7 stuff?

Depends on your confidence level, Michael.  We have ways of getting such
things tested before pushing them into the mainline kernel and we wouldn't
do that until you're confident in it.

And it's not really the end of the world if DVB is a bit wobbly for a while
(sorry ;)).

So yeah, I'd be inclined to push ahead and do the right thing here.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 22:52                 ` Michael Hunold
  2004-02-23 23:11                   ` Andrew Morton
@ 2004-02-23 23:15                   ` Ralph Metzler
  2004-02-24 11:34                   ` Marcel Holtmann
  2 siblings, 0 replies; 21+ messages in thread
From: Ralph Metzler @ 2004-02-23 23:15 UTC (permalink / raw)
  To: Michael Hunold; +Cc: Andrew Morton, Michael Hunold, torvalds, linux-kernel

Michael Hunold writes:
 > Yes. But as I wrote in the mail to Christoph, we currently don't have a 
 > chance to use some in-kernel structure (pci device, i2c bus) that 
 > automatically exports the firmware loading magic through sysfs.
 > 
 > Because of this, we would have to write our own sysfs backend for the 
 > dvb i2c subsystem, in order to get proper firmware loading support.
 > 
 > As I already mentioned in another mail, we want to go back to the kernel 
 > i2c subsystem.
 > 
 > Currently, the stuff is running quite stable and is "in use".
 > 
 > Changing the i2c subsystem would require changes in all frontend drivers 
 > + plus in the dvb drivers exporting the i2c facilities.


I converted back to using normal i2c a long time ago (as soon as I was
"free to") but nobody ever was interested ... 
You can see how to do it in my DVB drivers, at least for the cards
I am supporting.

Ralph

-- 
/--------------------------------------------------------------------\
| Dr. Ralph J.K. Metzler    | Metzler Brothers Systementwicklung GbR |
|---------------------------|----------------------------------------|
| rjkm@metzlerbros.de       | http://www.metzlerbros.de/             |
\--------------------------------------------------------------------/







^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 7/9] tda1004x DVB frontend update
  2004-02-23 22:52                 ` Michael Hunold
  2004-02-23 23:11                   ` Andrew Morton
  2004-02-23 23:15                   ` Ralph Metzler
@ 2004-02-24 11:34                   ` Marcel Holtmann
  2 siblings, 0 replies; 21+ messages in thread
From: Marcel Holtmann @ 2004-02-24 11:34 UTC (permalink / raw)
  To: Michael Hunold
  Cc: Andrew Morton, Michael Hunold, Linus Torvalds,
	Linux Kernel Mailing List

Hi Michael,

> > was there some plan to convert DVB over to using the firmware loader?
> 
> Yes. But as I wrote in the mail to Christoph, we currently don't have a 
> chance to use some in-kernel structure (pci device, i2c bus) that 
> automatically exports the firmware loading magic through sysfs.
> 
> Because of this, we would have to write our own sysfs backend for the 
> dvb i2c subsystem, in order to get proper firmware loading support.

I don't know if this is the right way, but the atmel_cs driver uses this
workaround to make use of the firmware loader.

	/* This is strictly temporary, until PCMCIA devices get integrated into the device model. */
	static struct device atmel_device = {
	        .bus_id    = "pcmcia",
	};

Regards

Marcel



^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2004-02-24 11:36 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-23 21:04 [PATCH 0/9] LinuxTV.org DVB update Michael Hunold
2004-02-23 21:04 ` [PATCH 1/9] Update the DVB subsystem docs Michael Hunold
2004-02-23 21:04   ` [PATCH 2/9] Update saa7146 driver core Michael Hunold
2004-02-23 21:04     ` [PATCH 3/9] Minor DVB Skystar2 updates Michael Hunold
2004-02-23 21:04       ` [PATCH 4/9] DVB core update Michael Hunold
2004-02-23 21:04         ` [PATCH 5/9] Misc. DVB frontend updates Michael Hunold
2004-02-23 21:05           ` [PATCH 6/9] stv0299 DVB frontend update Michael Hunold
2004-02-23 21:05             ` [PATCH 7/9] tda1004x " Michael Hunold
2004-02-23 21:05               ` [PATCH 8/9] av7110 DVB driver update Michael Hunold
2004-02-23 21:05                 ` [PATCH 9/9] TTUSB-Budget " Michael Hunold
2004-02-23 21:18               ` [PATCH 7/9] tda1004x DVB frontend update Christoph Hellwig
2004-02-23 22:47                 ` Michael Hunold
2004-02-23 22:54                   ` Christoph Hellwig
2004-02-23 23:01                     ` Michael Hunold
2004-02-23 22:09               ` Andrew Morton
2004-02-23 22:52                 ` Michael Hunold
2004-02-23 23:11                   ` Andrew Morton
2004-02-23 23:15                   ` Ralph Metzler
2004-02-24 11:34                   ` Marcel Holtmann
2004-02-23 22:23   ` [PATCH 1/9] Update the DVB subsystem docs Richard B. Johnson
2004-02-23 22:57     ` Michael Hunold

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox