Skip to contentSkip to conversation

Update the saa7146 driver core

PATCH In review Michael Hunold (LinuxTV.org CVS maintainer) 2 participants 19 messages Jul 15, 2003 – Jul 16, 2003 Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

PATCH 1/17 Update the saa7146 driver core

[DVB] - fix WRITE_RPS0 and WRITE_RPS1 inlines, fix usage in mxb and budget drivers
[DVB] - export "saa7146_start_preview" and "saa7146_stop_preview" to allow drivers to start and stop video overlay (necessary for analog module support in the av7110 driver) [DVB] - fix i2c implementation: some frontend drivers transfer a huge amount of firmware data (> 30kB), speed up the transmission by busy waiting between byte transfers for bigger transmissions [DVB] - change ioctl function in various driver to accept a saa7146 filehandle instead of a saa714 device structure

drivers/media/common/saa7146_hlp.c +1 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/common/saa7146_hlp.c linux-2.5.73.work/drivers/media/common/saa7146_hlp.c
@@ -935,6 +935,7 @@
 static void program_capture_engine(struct saa7146_dev *dev, int planar)
 {
 	struct saa7146_vv *vv = dev->vv_data;
+	int count = 0;
 
 	unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
 	unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
drivers/media/common/saa7146_vbi.c +1 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/common/saa7146_vbi.c linux-2.5.73.work/drivers/media/common/saa7146_vbi.c
@@ -9,6 +9,7 @@
         u32          *cpu;
         dma_addr_t   dma_addr;
 	
+	int count = 0;
 	int i;
 
 	DECLARE_WAITQUEUE(wait, current);
drivers/media/dvb/ttpci/budget-patch.c +1 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/ttpci/budget-patch.c linux-2.5.73.work/drivers/media/dvb/ttpci/budget-patch.c
@@ -165,6 +165,7 @@
 {
         struct budget_patch *budget;
         int err;
+	int count = 0;
 
         if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
                 return -ENOMEM;
drivers/media/common/saa7146_i2c.c +15 -5
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/common/saa7146_i2c.c linux-2.5.73.work/drivers/media/common/saa7146_i2c.c
@@ -181,9 +181,10 @@
 /* this functions writes out the data-byte 'dword' to the i2c-device.
    it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
    failed badly (e.g. address error) */
-static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword)
+static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_delay)
 {
 	u32 status = 0, mc2 = 0;
+	int trial = 0;
 	int timeout;
 
 	/* write out i2c-command */
@@ -224,10 +225,13 @@
 		/* wait until we get a transfer done or error */
 		timeout = jiffies + HZ/100 + 1; /* 10ms */
 		while(1) {
+			/**
+			 *  first read usually delivers bogus results...
+			 */
+			saa7146_i2c_status(dev);
 			status = saa7146_i2c_status(dev);
-			if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {
+			if ((status & 0x3) != 1)
 				break;
-			}
 			if (jiffies > timeout) {
 				/* this is normal when probing the bus
 				 * (no answer from nonexisistant device...)
@@ -235,6 +239,9 @@
 				DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
 				return -EIO;
 			}
+			if ((++trial < 20) && short_delay)
+				udelay(10);
+			else
 			my_wait(dev,1);
 		}
 	}
@@ -277,6 +284,7 @@
 	u32* buffer = dev->d_i2c.cpu_addr;
 	int err = 0;
         int address_err = 0;
+        int short_delay = 0;
 	
 	if (down_interruptible (&dev->i2c_lock))
 		return -ERESTARTSYS;
@@ -292,6 +300,8 @@
 		goto out;
 	}
 
+        if (count > 3) short_delay = 1;
+  
 	do {
 		/* reset the i2c-device if necessary */
 		err = saa7146_i2c_reset(dev);
@@ -302,7 +312,7 @@
 
 		/* write out the u32s one after another */
 		for(i = 0; i < count; i++) {
-			err = saa7146_i2c_writeout(dev, &buffer[i] );
+			err = saa7146_i2c_writeout(dev, &buffer[i], short_delay);
 			if ( 0 != err) {
 				/* this one is unsatisfying: some i2c slaves on some
 				   dvb cards don't acknowledge correctly, so the saa7146
@@ -357,7 +367,7 @@
 	if( 0 == dev->revision ) {
 		u32 zero = 0;
 		saa7146_i2c_reset(dev);
-		if( 0 != saa7146_i2c_writeout(dev, &zero)) {
+		if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
 			INFO(("revision 0 error. this should never happen.\n"));
 		}
 	}
drivers/media/common/saa7146_video.c +19 -16
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/common/saa7146_video.c linux-2.5.73.work/drivers/media/common/saa7146_video.c
@@ -220,7 +220,7 @@
 	}
 }
 
-static int start_preview(struct saa7146_fh *fh)
+int saa7146_start_preview(struct saa7146_fh *fh)
 {
 	struct saa7146_dev *dev = fh->dev;
 	struct saa7146_vv *vv = dev->vv_data;
@@ -266,12 +266,12 @@
 	return 0;
 }
 
-static int stop_preview(struct saa7146_fh *fh)
+int saa7146_stop_preview(struct saa7146_fh *fh)
 {
 	struct saa7146_dev *dev = fh->dev;
 	struct saa7146_vv *vv = dev->vv_data;
 
-	DEB_EE(("saa7146.o: stop_preview()\n"));
+	DEB_EE(("saa7146.o: saa7146_stop_preview()\n"));
 
 	/* check if overlay is running */
 	if( 0 == vv->ov_data ) {
@@ -333,8 +333,8 @@
 		if( vv->ov_data != NULL ) {
 			if( fh == vv->ov_data->fh) {
 				spin_lock_irqsave(&dev->slock,flags);
-				stop_preview(fh);
-				start_preview(fh);
+				saa7146_stop_preview(fh);
+				saa7146_start_preview(fh);
 				spin_unlock_irqrestore(&dev->slock,flags);
 			}
 		}
@@ -522,8 +522,8 @@
 		if( 0 != vv->ov_data ) {
 			if( fh == vv->ov_data->fh ) {
 				spin_lock_irqsave(&dev->slock,flags);
-				stop_preview(fh);
-				start_preview(fh);
+				saa7146_stop_preview(fh);
+				saa7146_start_preview(fh);
 				spin_unlock_irqrestore(&dev->slock,flags);
 			}
 		}
@@ -747,12 +747,12 @@
 	
 	if( 0 != (dev->ext->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
 		DEB_D(("extension handles ioctl exclusive.\n"));
-		result = dev->ext->ext_vv_data->ioctl(dev, cmd, arg);
+		result = dev->ext->ext_vv_data->ioctl(fh, cmd, arg);
 		return result;
 	}
 	if( 0 != (dev->ext->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
 		DEB_D(("extension handles ioctl before.\n"));
-		result = dev->ext->ext_vv_data->ioctl(dev, cmd, arg);
+		result = dev->ext->ext_vv_data->ioctl(fh, cmd, arg);
 		if( -EAGAIN != result ) {
 			return result;
 		}
@@ -968,7 +968,7 @@
 
 		if( vv->ov_data != NULL ) {
 			ov_fh = vv->ov_data->fh;
-			stop_preview(ov_fh);
+			saa7146_stop_preview(ov_fh);
 			restart_overlay = 1;
 		}
 
@@ -983,7 +983,7 @@
 		}
 
 		if( 0 != restart_overlay ) {
-			start_preview(ov_fh);
+			saa7146_start_preview(ov_fh);
 		}
 		up(&dev->lock);
 
@@ -1013,7 +1013,7 @@
 				}
 			}
 			spin_lock_irqsave(&dev->slock,flags);
-			err = start_preview(fh);
+			err = saa7146_start_preview(fh);
 			spin_unlock_irqrestore(&dev->slock,flags);
 		} else {
 			if( vv->ov_data != NULL ) {
@@ -1022,7 +1022,7 @@
 				}
 			}
 			spin_lock_irqsave(&dev->slock,flags);
-			err = stop_preview(fh);
+			err = saa7146_stop_preview(fh);
 			spin_unlock_irqrestore(&dev->slock,flags);
 		}
 		return err;
@@ -1287,7 +1287,7 @@
 	if( 0 != vv->ov_data ) {
 		if( fh == vv->ov_data->fh ) {
 			spin_lock_irqsave(&dev->slock,flags);
-			stop_preview(fh);
+			saa7146_stop_preview(fh);
 			spin_unlock_irqrestore(&dev->slock,flags);
 		}
 	}
@@ -1331,7 +1331,7 @@
 
 	if( vv->ov_data != NULL ) {
 		ov_fh = vv->ov_data->fh;
-		stop_preview(ov_fh);
+		saa7146_stop_preview(ov_fh);
 		restart_overlay = 1;
 	}
 
@@ -1343,7 +1343,7 @@
 
 	/* restart overlay if it was active before */
 	if( 0 != restart_overlay ) {
-		start_preview(ov_fh);
+		saa7146_start_preview(ov_fh);
 	}
 	
 	return ret;
@@ -1360,3 +1360,6 @@
 };
 
 EXPORT_SYMBOL_GPL(saa7146_video_uops);
+
+EXPORT_SYMBOL_GPL(saa7146_start_preview);
+EXPORT_SYMBOL_GPL(saa7146_stop_preview);
include/media/saa7146_vv.h +3 -3
diff -uNrwB --new-file linux-2.5.73.bk/include/media/saa7146_vv.h linux-2.5.73.work/include/media/saa7146_vv.h
@@ -10,12 +10,10 @@
 #define BUFFER_TIMEOUT     (HZ/2)  /* 0.5 seconds */
 
 #define WRITE_RPS0(x) do { \
-	static int count = 0;	\
 	dev->d_rps0.cpu_addr[ count++ ] = cpu_to_le32(x); \
 	} while (0);
 
 #define WRITE_RPS1(x) do { \
-	static int count = 0;	\
 	dev->d_rps1.cpu_addr[ count++ ] = cpu_to_le32(x); \
 	} while (0);
 
@@ -166,7 +164,7 @@
 	int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *);
 		
 	struct saa7146_extension_ioctls *ioctls;
-	int (*ioctl)(struct saa7146_dev*, unsigned int cmd, void *arg);
+	int (*ioctl)(struct saa7146_fh*, unsigned int cmd, void *arg);
 };
 
 struct saa7146_use_ops  {
@@ -201,6 +199,8 @@
 
 /* from saa7146_video.c */
 extern struct saa7146_use_ops saa7146_video_uops;
+int saa7146_start_preview(struct saa7146_fh *fh);
+int saa7146_stop_preview(struct saa7146_fh *fh);
 
 /* from saa7146_vbi.c */
 extern struct saa7146_use_ops saa7146_vbi_uops;
drivers/media/dvb/ttpci/budget-av.c +2 -1
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/ttpci/budget-av.c linux-2.5.73.work/drivers/media/dvb/ttpci/budget-av.c
@@ -256,8 +256,9 @@
 };
 
 
-static int av_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) 
+static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
 {
+	struct saa7146_dev *dev = fh->dev;
 	struct budget_av *budget_av = (struct budget_av*) dev->ext_priv;
 /*
 	struct saa7146_vv *vv = dev->vv_data; 
drivers/media/video/dpc7146.c +2 -1
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/video/dpc7146.c linux-2.5.73.work/drivers/media/video/dpc7146.c
@@ -246,8 +246,9 @@
 }
 #endif
 
-static int dpc_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) 
+static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
 {
+	struct saa7146_dev *dev = fh->dev;
 	struct dpc* dpc = (struct dpc*)dev->ext_priv;
 /*
 	struct saa7146_vv *vv = dev->vv_data; 
drivers/media/video/mxb.c +2 -1
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/video/mxb.c linux-2.5.73.work/drivers/media/video/mxb.c
@@ -566,8 +566,9 @@
 	return 0;
 }
 
-static int mxb_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) 
+static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
 {
+	struct saa7146_dev *dev = fh->dev;
 	struct mxb* mxb = (struct mxb*)dev->ext_priv;
 	struct saa7146_vv *vv = dev->vv_data; 
 	
#1 lore raw

PATCH 2/17 Various small fixes in dvb-core

[DVB] - indentation fixes in dvb_demux.c [DVB] - include cleanup in various files [DVB] - simplify dvb/ttpci/Makefile

drivers/media/dvb/dvb-core/dvb_demux.c +4 -4
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvb_demux.c linux-2.5.73.work/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1110,8 +1130,8 @@
 	return 0;
 }
 
-int 
-dvb_dmx_init(struct dvb_demux *dvbdemux)
+
+int dvb_dmx_init(struct dvb_demux *dvbdemux)
 {
 	int i, err;
 	struct dmx_demux *dmx = &dvbdemux->dmx;
@@ -1181,8 +1207,8 @@
 	return 0;
 }
 
-int 
-dvb_dmx_release(struct dvb_demux *dvbdemux)
+
+int dvb_dmx_release(struct dvb_demux *dvbdemux)
 {
 	struct dmx_demux *dmx = &dvbdemux->dmx;
 
drivers/media/dvb/dvb-core/dvb_functions.c +3 -3
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvb_functions.c linux-2.5.73.work/drivers/media/dvb/dvb-core/dvb_functions.c
@@ -1,10 +1,10 @@
 #include <linux/version.h>
-#include <linux/string.h>
-#include <linux/smp_lock.h>
-#include <linux/fs.h>
 #include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/string.h>
 #include <linux/module.h>
 #include <linux/ioctl.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
drivers/media/dvb/dvb-core/dvb_functions.h +2 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvb_functions.h linux-2.5.73.work/drivers/media/dvb/dvb-core/dvb_functions.h
@@ -1,6 +1,8 @@
 #ifndef __DVB_FUNCTIONS_H__
 #define __DVB_FUNCTIONS_H__
 
+#include <linux/version.h>
+
 /**
  *  a sleeping delay function, waits i ms
  *
drivers/media/dvb/dvb-core/dvbdev.c +0 -2
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvbdev.c linux-2.5.73.work/drivers/media/dvb/dvb-core/dvbdev.c
@@ -29,8 +29,6 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/version.h>
-#include <asm/semaphore.h>
 
 #include "dvbdev.h"
 #include "dvb_functions.h"

int dvb_generic_open(struct inode *inode, struct file *file)

drivers/media/dvb/dvb-core/dvbdev.h +2 -1
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvbdev.h linux-2.5.73.work/drivers/media/dvb/dvb-core/dvbdev.h
@@ -27,8 +27,9 @@
 #include <linux/types.h>
 #include <linux/poll.h>
 #include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/list.h>
+#include <linux/version.h>
+#include <linux/devfs_fs_kernel.h>
 
 #define DVB_MAJOR 250
 
drivers/media/dvb/ttpci/Makefile +5 -9
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/ttpci/Makefile linux-2.5.73.work/drivers/media/dvb/ttpci/Makefile
@@ -3,16 +3,12 @@
 # and the AV7110 DVB device driver
 #
 
-dvb-ttpci-budget-objs := budget.o
-dvb-ttpci-budget-av-objs := budget-av.o
-dvb-ttpci-budget-ci-objs := budget-ci.o
-dvb-ttpci-budget-patch-objs := budget-patch.o
 dvb-ttpci-objs := av7110.o av7110_ipack.o av7110_ir.o
 
-obj-$(CONFIG_DVB_BUDGET) += budget-core.o dvb-ttpci-budget.o
-obj-$(CONFIG_DVB_BUDGET_CI) += budget-core.o dvb-ttpci-budget-ci.o
-obj-$(CONFIG_DVB_BUDGET_AV) += budget-core.o dvb-ttpci-budget-av.o
-obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o dvb-ttpci-budget-patch.o
-obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
+obj-$(CONFIG_DVB_BUDGET) += budget-core.o budget.o ttpci-eeprom.o
+obj-$(CONFIG_DVB_BUDGET_AV) += budget-core.o budget-av.o ttpci-eeprom.o
+obj-$(CONFIG_DVB_BUDGET_CI) += budget-core.o budget-ci.o ttpci-eeprom.o
+obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o budget-patch.o ttpci-eeprom.o
+obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o
 
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
#2 lore raw

PATCH 3/17 Major dvb net code cleanup, many fixes

[DVB] - code review and fix the old race condition in dev->set_multicast_list [DVB] - use tq_schedule instead of tq_immediate
[DVB] - remove card_num and dev_num from struct dvb_net (now obsolete) [DVB] - prevent interface from being removed while it is in use [DVB] - allow add/remove only for the superuser
[DVB] - set check-CRC flag on section filter to drop broken packets [DVB] - some more debug printfs in filter handling code
[DVB] - cleaned up and commented packet reception handler
[DVB] - fix formatting

drivers/media/dvb/dvb-core/dvb_net.c +207 -134
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvb_net.c linux-2.5.73.work/drivers/media/dvb/dvb-core/dvb_net.c
@@ -24,22 +24,25 @@
  * 
  */
 
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-
 #include <linux/dvb/net.h>
+#include <asm/uaccess.h>
 
 #include "dvb_demux.h"
 #include "dvb_net.h"
 #include "dvb_functions.h"
 
+
+#if 1
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+
 #define DVB_NET_MULTICAST_MAX 10
 
 struct dvb_net_priv {
+	int in_use;
         struct net_device_stats stats;
         char name[6];
 	u16 pid;
@@ -49,10 +52,16 @@
 	int multi_num;
 	struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX];
 	unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6];
-	int mode;
+	int rx_mode;
+#define RX_MODE_UNI 0
+#define RX_MODE_MULTI 1
+#define RX_MODE_ALL_MULTI 2
+#define RX_MODE_PROMISC 3
+	struct work_struct wq;
 };
 
-/*
+
+/**
  *	Determine the packet's protocol ID. The rule here is that we 
  *	assume 802.3 if the type field is short enough to be a length.
  *	This is normal practice and works for any 'now in use' protocol.
@@ -60,8 +69,8 @@
  *  stolen from eth.c out of the linux kernel, hacked for dvb-device
  *  by Michael Holzt <[email protected]>
  */
- 
-unsigned short my_eth_type_trans(struct sk_buff *skb, struct net_device *dev)
+static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct ethhdr *eth;
 	unsigned char *rawp;
@@ -70,8 +79,7 @@
 	skb_pull(skb,dev->hard_header_len);
 	eth= skb->mac.ethernet;
 	
-	if(*eth->h_dest&1)
-	{
+	if (*eth->h_dest & 1) {
 		if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
 			skb->pkt_type=PACKET_BROADCAST;
 		else
@@ -83,7 +91,7 @@
 		
 	rawp = skb->data;
 	
-	/*
+	/**
 	 *	This is a magic hack to spot IPX packets. Older Novell breaks
 	 *	the protocol design and runs IPX over 802.3 without an 802.2 LLC
 	 *	layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
@@ -92,31 +100,60 @@
 	if (*(unsigned short *)rawp == 0xFFFF)
 		return htons(ETH_P_802_3);
 		
-	/*
+	/**
 	 *	Real 802.2 LLC
 	 */
 	return htons(ETH_P_802_2);
 }
 
-static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int pkt_len)
+
+static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
 {
         u8 *eth;
         struct sk_buff *skb;
 
-        if (pkt_len<13) {
-                printk("%s: IP/MPE packet length = %d too small.\n", dev->name, pkt_len);
+	/* note: pkt_len includes a 32bit checksum */
+	if (pkt_len < 16) {
+		printk("%s: IP/MPE packet length = %d too small.\n",
+			dev->name, pkt_len);
+		((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
+		((struct dvb_net_priv *) dev->priv)->stats.rx_length_errors++;
+		return;
+	}
+	if ((pkt[5] & 0xfd) != 0xc1) {
+		/* drop scrambled or broken packets */
+		((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
+		((struct dvb_net_priv *) dev->priv)->stats.rx_crc_errors++;
 		return;
 	}
-        skb = dev_alloc_skb(pkt_len+2);
-        if (skb == NULL) {
-                printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
-                       dev->name);
+	if (pkt[5] & 0x02) {
+		//FIXME: handle LLC/SNAP
                 ((struct dvb_net_priv *)dev->priv)->stats.rx_dropped++;
                 return;
         }
-        eth=(u8 *) skb_put(skb, pkt_len+2);
-        memcpy(eth+14, (void*)pkt+12, pkt_len-12);
+	if (pkt[7]) {
+		/* FIXME: assemble datagram from multiple sections */
+		((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
+		((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
+		return;
+	}
+
+	/* we have 14 byte ethernet header (ip header follows);
+	 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment
+	 */
+	if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2))) {
+		//printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+		((struct dvb_net_priv *) dev->priv)->stats.rx_dropped++;
+		return;
+	}
+	skb_reserve(skb, 2);    /* longword align L3 header */
+	skb->dev = dev;
+
+	/* copy L3 payload */
+	eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14);
+	memcpy(eth + 14, pkt + 12, pkt_len - 12 - 4);
 
+	/* create ethernet header: */
         eth[0]=pkt[0x0b];
         eth[1]=pkt[0x0a];
         eth[2]=pkt[0x09];
@@ -123,11 +160,13 @@
         eth[3]=pkt[0x08];
         eth[4]=pkt[0x04];
         eth[5]=pkt[0x03];
+
         eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
-        eth[12]=0x08; eth[13]=0x00;
 
-	skb->protocol=my_eth_type_trans(skb,dev);
-        skb->dev=dev;
+	eth[12] = 0x08;	/* ETH_P_IP */
+	eth[13] = 0x00;
+
+	skb->protocol = dvb_net_eth_type_trans(skb, dev);
         
         ((struct dvb_net_priv *)dev->priv)->stats.rx_packets++;
         ((struct dvb_net_priv *)dev->priv)->stats.rx_bytes+=skb->len;
@@ -141,9 +180,11 @@
 {
         struct net_device *dev=(struct net_device *) filter->priv;
 
-	/* FIXME: this only works if exactly one complete section is
-	          delivered in buffer1 only */
-	dvb_net_sec(dev, buffer1, buffer1_len);
+	/**
+	 * we rely on the DVB API definition where exactly one complete
+	 * section is delivered in buffer1
+	 */
+	dvb_net_sec (dev, (u8*) buffer1, buffer1_len);
 	return 0;
 }
 
@@ -178,24 +223,27 @@
 	memset((*secfilter)->filter_mode,  0xff, DMX_MAX_FILTER_SIZE);
 
 	(*secfilter)->filter_value[0]=0x3e;
-	(*secfilter)->filter_mask[0]=0xff;
-
 	(*secfilter)->filter_value[3]=mac[5];
-	(*secfilter)->filter_mask[3]=mac_mask[5];
 	(*secfilter)->filter_value[4]=mac[4];
-	(*secfilter)->filter_mask[4]=mac_mask[4];
 	(*secfilter)->filter_value[8]=mac[3];
-	(*secfilter)->filter_mask[8]=mac_mask[3];
 	(*secfilter)->filter_value[9]=mac[2];
-	(*secfilter)->filter_mask[9]=mac_mask[2];
-
 	(*secfilter)->filter_value[10]=mac[1];
-	(*secfilter)->filter_mask[10]=mac_mask[1];
 	(*secfilter)->filter_value[11]=mac[0];
+
+	(*secfilter)->filter_mask[0] = 0xff;
+	(*secfilter)->filter_mask[3] = mac_mask[5];
+	(*secfilter)->filter_mask[4] = mac_mask[4];
+	(*secfilter)->filter_mask[8] = mac_mask[3];
+	(*secfilter)->filter_mask[9] = mac_mask[2];
+	(*secfilter)->filter_mask[10] = mac_mask[1];
 	(*secfilter)->filter_mask[11]=mac_mask[0];
 
-	printk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n", 
+	dprintk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n",
 	       dev->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+	dprintk("%s: filter mask=%02x %02x %02x %02x %02x %02x\n",
+	       dev->name, mac_mask[0], mac_mask[1], mac_mask[2],
+	       mac_mask[3], mac_mask[4], mac_mask[5]);
+
 	return 0;
 }
 
@@ -206,46 +254,57 @@
         struct dmx_demux *demux = priv->demux;
         unsigned char *mac = (unsigned char *) dev->dev_addr;
 		
+	dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
+	if (priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
+		printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
+
 	priv->secfeed=0;
 	priv->secfilter=0;
 
+	dprintk("%s: alloc secfeed\n", __FUNCTION__);
 	ret=demux->allocate_section_feed(demux, &priv->secfeed, 
 					 dvb_net_callback);
 	if (ret<0) {
-		printk("%s: could not get section feed\n", dev->name);
+		printk("%s: could not allocate section feed\n", dev->name);
 		return ret;
 	}
 
-	ret=priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 0);
+	ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 1);
+
 	if (ret<0) {
 		printk("%s: could not set section feed\n", dev->name);
-		priv->demux->
-		        release_section_feed(priv->demux, priv->secfeed);
+		priv->demux->release_section_feed(priv->demux, priv->secfeed);
 		priv->secfeed=0;
 		return ret;
 	}
-	/* fixme: is this correct? */
-	try_module_get(THIS_MODULE);
 
-	if (priv->mode<3) 
+	if (priv->rx_mode != RX_MODE_PROMISC) {
+		dprintk("%s: set secfilter\n", __FUNCTION__);
 		dvb_net_filter_set(dev, &priv->secfilter, mac, mask_normal);
+	}
 
-	switch (priv->mode) {
-	case 1:
-		for (i=0; i<priv->multi_num; i++) 
+	switch (priv->rx_mode) {
+	case RX_MODE_MULTI:
+		for (i = 0; i < priv->multi_num; i++) {
+			dprintk("%s: set multi_secfilter[%d]\n", __FUNCTION__, i);
 			dvb_net_filter_set(dev, &priv->multi_secfilter[i],
 					   priv->multi_macs[i], mask_normal);
+		}
 		break;
-	case 2:
+	case RX_MODE_ALL_MULTI:
 		priv->multi_num=1;
-		dvb_net_filter_set(dev, &priv->multi_secfilter[0], mac_allmulti, mask_allmulti);
+		dprintk("%s: set multi_secfilter[0]\n", __FUNCTION__);
+		dvb_net_filter_set(dev, &priv->multi_secfilter[0],
+				   mac_allmulti, mask_allmulti);
 		break;
-	case 3:
+	case RX_MODE_PROMISC:
 		priv->multi_num=0;
+		dprintk("%s: set secfilter\n", __FUNCTION__);
 		dvb_net_filter_set(dev, &priv->secfilter, mac, mask_promisc);
 		break;
 	}
 	
+	dprintk("%s: start filtering\n", __FUNCTION__);
 	priv->secfeed->start_filtering(priv->secfeed);
 	return 0;
 }
@@ -255,89 +315,93 @@
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 	int i;
 
+	dprintk("%s\n", __FUNCTION__);
         if (priv->secfeed) {
-	        if (priv->secfeed->is_filtering)
+		if (priv->secfeed->is_filtering) {
+			dprintk("%s: stop secfeed\n", __FUNCTION__);
 		        priv->secfeed->stop_filtering(priv->secfeed);
-	        if (priv->secfilter)
-		        priv->secfeed->
-			        release_filter(priv->secfeed, 
+		}
+
+		if (priv->secfilter) {
+			dprintk("%s: release secfilter\n", __FUNCTION__);
+			priv->secfeed->release_filter(priv->secfeed,
 					       priv->secfilter);
 		priv->secfilter=0;
+		}
 
 		for (i=0; i<priv->multi_num; i++) {
-			if (priv->multi_secfilter[i])
-				priv->secfeed->
-					release_filter(priv->secfeed, 
+			if (priv->multi_secfilter[i]) {
+				dprintk("%s: release multi_filter[%d]\n", __FUNCTION__, i);
+				priv->secfeed->release_filter(priv->secfeed,
 						       priv->multi_secfilter[i]);
 			priv->multi_secfilter[i]=0;
 		}
-		priv->demux->
-		        release_section_feed(priv->demux, priv->secfeed);
+		}
+
+		priv->demux->release_section_feed(priv->demux, priv->secfeed);
 		priv->secfeed=0;
-		/* fixme: is this correct? */
-		module_put(THIS_MODULE);
 	} else
 		printk("%s: no feed to stop\n", dev->name);
 }
 
-static int dvb_add_mc_filter(struct net_device *dev, struct dev_mc_list *mc)
+
+static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
-	int ret;
 
-	if (priv->multi_num >= DVB_NET_MULTICAST_MAX)
+	if (priv->multi_num == DVB_NET_MULTICAST_MAX)
 		return -ENOMEM;
 
-	ret = memcmp(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
 	memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
 
 	priv->multi_num++;
-
-	return ret;
+	return 0;
 }
 
-static void dvb_net_set_multi(struct net_device *dev)
+
+static void tq_set_multicast_list (void *data)
 {
+	struct net_device *dev = data;
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
-	struct dev_mc_list *mc;
-	int mci;
-	int update = 0;
+
+	dvb_net_feed_stop(dev);
+
+	priv->rx_mode = RX_MODE_UNI;
 	
 	if(dev->flags & IFF_PROMISC) {
-//	printk("%s: promiscuous mode\n", dev->name);
-		if(priv->mode != 3)
-			update = 1;
-		priv->mode = 3;
-	} else if(dev->flags & IFF_ALLMULTI) {
-//	printk("%s: allmulti mode\n", dev->name);
-		if(priv->mode != 2)
-			update = 1;
-		priv->mode = 2;
-	} else if(dev->mc_count > 0) {
-//	printk("%s: set_mc_list, %d entries\n", 
-//	       dev->name, dev->mc_count);
-		if(priv->mode != 1)
-			update = 1;
-		priv->mode = 1;
+		dprintk("%s: promiscuous mode\n", dev->name);
+		priv->rx_mode = RX_MODE_PROMISC;
+	} else if ((dev->flags & IFF_ALLMULTI)) {
+		dprintk("%s: allmulti mode\n", dev->name);
+		priv->rx_mode = RX_MODE_ALL_MULTI;
+	} else if (dev->mc_count) {
+		int mci;
+		struct dev_mc_list *mc;
+
+		dprintk("%s: set_mc_list, %d entries\n",
+			dev->name, dev->mc_count);
+
+		priv->rx_mode = RX_MODE_MULTI;
 		priv->multi_num = 0;
+
 		for (mci = 0, mc=dev->mc_list; 
 		     mci < dev->mc_count;
-		     mc=mc->next, mci++)
-			if(dvb_add_mc_filter(dev, mc) != 0)
-				update = 1;
-	} else {
-		if(priv->mode != 0)
-			update = 1;
-		priv->mode = 0;
+		     mc = mc->next, mci++) {
+			dvb_set_mc_filter(dev, mc);
+		}
 	}
 
-	if(netif_running(dev) != 0 && update > 0)
-	{
-		dvb_net_feed_stop(dev);
 		dvb_net_feed_start(dev);
 	}
+
+
+static void dvb_net_set_multicast_list (struct net_device *dev)
+{
+	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+	schedule_work(&priv->wq);
 }
 
+
 static int dvb_net_set_config(struct net_device *dev, struct ifmap *map)
 {
 	if (netif_running(dev))
@@ -348,11 +413,10 @@
 static int dvb_net_set_mac(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr=p;
-	int update;
 
-	update = memcmp(dev->dev_addr, addr->sa_data, dev->addr_len);
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-	if (netif_running(dev) != 0 && update > 0) {
+
+	if (netif_running(dev)) {
 		dvb_net_feed_stop(dev);
 		dvb_net_feed_start(dev);
 	}
@@ -362,6 +427,9 @@
 
 static int dvb_net_open(struct net_device *dev)
 {
+	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+
+	priv->in_use++;
 	dvb_net_feed_start(dev);
 	return 0;
 }
@@ -366,8 +434,12 @@
 	return 0;
 }
 
+
 static int dvb_net_stop(struct net_device *dev)
 {
+	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+
+	priv->in_use--;
         dvb_net_feed_stop(dev);
 	return 0;
 }
@@ -386,16 +459,14 @@
 	dev->stop		= dvb_net_stop;
 	dev->hard_start_xmit	= dvb_net_tx;
 	dev->get_stats		= dvb_net_get_stats;
-	dev->set_multicast_list = dvb_net_set_multi;
+	dev->set_multicast_list = dvb_net_set_multicast_list;
 	dev->set_config         = dvb_net_set_config;
 	dev->set_mac_address    = dvb_net_set_mac;
 	dev->mtu		= 4096;
 	dev->mc_count           = 0;
-
-	dev->flags             |= IFF_NOARP;
 	dev->hard_header_cache  = NULL;
 
-	//SET_MODULE_OWNER(dev);
+	dev->flags |= IFF_NOARP;
 	
 	return 0;
 }
@@ -404,11 +476,13 @@
 {
 	int i;
 
-	for (i=0; i<dvbnet->dev_num; i++) 
+	for (i=0; i<DVB_NET_DEVICES_MAX; i++)
 		if (!dvbnet->state[i])
 			break;
-	if (i==dvbnet->dev_num)
+
+	if (i == DVB_NET_DEVICES_MAX)
 		return -1;
+
 	dvbnet->state[i]=1;
 	return i;
 }
@@ -414,8 +488,7 @@
 }
 
 
-int 
-dvb_net_add_if(struct dvb_net *dvbnet, u16 pid)
+static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid)
 {
         struct net_device *net;
 	struct dmx_demux *demux;
@@ -423,8 +496,7 @@
 	int result;
 	int if_num;
  
-	if_num=get_if(dvbnet);
-	if (if_num<0)
+	if ((if_num = get_if(dvbnet)) < 0)
 		return -EINVAL;
 
 	net=&dvbnet->device[if_num];
@@ -435,47 +507,52 @@
 	net->dma       = 0;
 	net->mem_start = 0;
         memcpy(net->name, "dvb0_0", 7);
-        net->name[3]=dvbnet->card_num+0x30;
-        net->name[5]=if_num+0x30;
+	net->name[3]   = dvbnet->dvbdev->adapter->num + '0';
+	net->name[5]   = if_num + '0';
+	net->addr_len  = 6;
+	memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
         net->next      = NULL;
         net->init      = dvb_net_init_dev;
-        net->priv      = kmalloc(sizeof(struct dvb_net_priv), GFP_KERNEL);
-	if (net->priv == NULL)
+
+	if (!(net->priv = kmalloc(sizeof(struct dvb_net_priv), GFP_KERNEL)))
 			return -ENOMEM;
 
 	priv = net->priv;
 	memset(priv, 0, sizeof(struct dvb_net_priv));
         priv->demux = demux;
         priv->pid = pid;
-	priv->mode = 0;
+	priv->rx_mode = RX_MODE_UNI;
+
+	INIT_WORK(&priv->wq, tq_set_multicast_list, net);
 
         net->base_addr = pid;
                 
 	if ((result = register_netdev(net)) < 0) {
 		return result;
 	}
-	/* fixme: is this correct? */
-	try_module_get(THIS_MODULE);
 
         return if_num;
 }
 
-int 
-dvb_net_remove_if(struct dvb_net *dvbnet, int num)
+
+static int dvb_net_remove_if(struct dvb_net *dvbnet, int num)
 {
+	struct dvb_net_priv *priv = dvbnet->device[num].priv;
+
 	if (!dvbnet->state[num])
 		return -EINVAL;
+	if (priv->in_use)
+		return -EBUSY;
+
 	dvb_net_stop(&dvbnet->device[num]);
-        kfree(dvbnet->device[num].priv);
+	kfree(priv);
         unregister_netdev(&dvbnet->device[num]);
 	dvbnet->state[num]=0;
-	/* fixme: is this correct? */
-	module_put(THIS_MODULE);
-
 	return 0;
 }
 
-int dvb_net_do_ioctl(struct inode *inode, struct file *file, 
+
+static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
 		  unsigned int cmd, void *parg)
 {
 	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
@@ -490,6 +567,8 @@
 		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
 		int result;
 		
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
 		result=dvb_net_add_if(dvbnet, dvbnetif->pid);
 		if (result<0)
 			return result;
@@ -502,7 +581,7 @@
 		struct dvb_net_priv *priv_data;
 		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
 
-		if (dvbnetif->if_num >= dvbnet->dev_num ||
+		if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
 		    !dvbnet->state[dvbnetif->if_num])
 			return -EFAULT;
 
@@ -512,7 +591,9 @@
 		break;
 	}
 	case NET_REMOVE_IF:
-		return dvb_net_remove_if(dvbnet, (long) parg);
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		return dvb_net_remove_if(dvbnet, (int) parg);
 	default:
 		return -EINVAL;
 	}
@@ -542,28 +627,29 @@
         .fops = &dvb_net_fops,
 };
 
-void
-dvb_net_release(struct dvb_net *dvbnet)
+
+void dvb_net_release (struct dvb_net *dvbnet)
 {
 	int i;
 
 	dvb_unregister_device(dvbnet->dvbdev);
-	for (i=0; i<dvbnet->dev_num; i++) {
+
+	for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
 		if (!dvbnet->state[i])
 			continue;
 		dvb_net_remove_if(dvbnet, i);
 	}
 }
 
-int
-dvb_net_init(struct dvb_adapter *adap, struct dvb_net *dvbnet, struct dmx_demux *dmx)
+
+int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
+		  struct dmx_demux *dmx)
 {
 	int i;
 		
 	dvbnet->demux = dmx;
-	dvbnet->dev_num = DVB_NET_DEVICES_MAX;
 
-	for (i=0; i<dvbnet->dev_num; i++) 
+	for (i=0; i<DVB_NET_DEVICES_MAX; i++)
 		dvbnet->state[i] = 0;
 
 	dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net,
drivers/media/dvb/dvb-core/dvb_net.h +0 -2
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvb_net.h linux-2.5.73.work/drivers/media/dvb/dvb-core/dvb_net.h
@@ -35,8 +35,6 @@
 
 struct dvb_net {
 	struct dvb_device *dvbdev;
-	int card_num;
-	int dev_num;
 	struct net_device device[DVB_NET_DEVICES_MAX];
 	int state[DVB_NET_DEVICES_MAX];
 	struct dmx_demux *demux;
#3 lore raw

PATCH 4/17 Update dvb frontend drivers

[DVB] - grundig_29504-401.c: fix charge pump and band switch setting bug, catched by Robert Schlabbach <[email protected]> [DVB] - grundig_29504-401.c: pass apply_frontend_param() return value to upper layers
[DVB] - grundig_29504-401.c: try to make a more specific detection mechanism
[DVB] - grundig_29504-491.c:remove bogus out-of-range check, FEC table index is limited to 0...7 due to &= ~0x03 anyway... [DVB] - nxt6000.c: Patch by Paul Andreassen: Add Support for Comtech DVBT-6k07 (PLL IC: SP5730)
[DVB] - ves1820.c: use Robert Schlabbach's suggestions for CLKCONF (0x03) and CARCONF (0x04)
[DVB] - alps_bsrv2.c: don't enable voltage on init + inversion bugfix

drivers/media/dvb/dvb-core/dvb_frontend.c +6 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvb_frontend.c linux-2.5.73.work/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -263,8 +263,14 @@
                 if (flags & O_NONBLOCK)
                         return -EWOULDBLOCK;
 
+		up(&fe->sem);
+
                 ret = wait_event_interruptible (events->wait_queue,
                                                 events->eventw != events->eventr);
+
+        	if (down_interruptible (&fe->sem))
+			return -ERESTARTSYS;
+
                 if (ret < 0)
                         return ret;
         }
drivers/media/dvb/frontends/alps_bsrv2.c +18 -4
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/frontends/alps_bsrv2.c linux-2.5.73.work/drivers/media/dvb/frontends/alps_bsrv2.c
@@ -55,7 +55,7 @@
         0x01, 0xA4, 0x35, 0x81, 0x2A, 0x0d, 0x55, 0xC4,
         0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7F, 0x00,
         0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	
-        0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xDC, 0x20,
+        0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xDC, 0x00,
         0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
@@ -158,6 +158,11 @@
 {
 	u8 val;
 
+	/*
+	 * inversion on/off are interchanged because i and q seem to
+	 * be swapped on the hardware
+	 */
+
 	switch (inversion) {
 	case INVERSION_OFF:
 		val = 0xc0;
@@ -166,13 +171,16 @@
 		val = 0x80;
 		break;
 	case INVERSION_AUTO:
-		val = 0x40;
+		val = 0x00;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	return ves1893_writereg (i2c, 0x0c, (init_1893_tab[0x0c] & 0x3f) | val);
+	/* needs to be saved for FE_GET_FRONTEND */
+	init_1893_tab[0x0c] = (init_1893_tab[0x0c] & 0x3f) | val;
+
+	return ves1893_writereg (i2c, 0x0c, init_1893_tab[0x0c]);
 }
 
 
@@ -383,8 +391,14 @@
 		afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16;
 
 		p->frequency -= afc;
+
+		/*
+		 * inversion indicator is only valid
+		 * if auto inversion was used
+		 */
+		if (!(init_1893_tab[0x0c] & 0x80))
 		p->inversion = (ves1893_readreg (i2c, 0x0f) & 2) ? 
-					INVERSION_ON : INVERSION_OFF;
+					INVERSION_OFF : INVERSION_ON;
 		p->u.qpsk.fec_inner = ves1893_get_fec (i2c);
 	/*  XXX FIXME: timing offset !! */
 		break;
drivers/media/dvb/frontends/grundig_29504-401.c +57 -21

131 lines not on this page · raw message

drivers/media/dvb/frontends/grundig_29504-491.c +1 -4
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/frontends/grundig_29504-491.c linux-2.5.73.work/drivers/media/dvb/frontends/grundig_29504-491.c
@@ -179,10 +179,7 @@
 	static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
 				       FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
 
-	index = tda8083_readreg (i2c, 0x0e) & 0x3;
-
-	if (index > 7)
-		return FEC_NONE;
+	index = tda8083_readreg(i2c, 0x0e) & 0x07;
 
 	return fec_tab [index];
 }
drivers/media/dvb/frontends/nxt6000.c +51 -0

83 lines not on this page · raw message

drivers/media/dvb/frontends/ves1820.c +5 -5
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/frontends/ves1820.c linux-2.5.73.work/drivers/media/dvb/frontends/ves1820.c
@@ -95,7 +95,7 @@
 
 static u8 ves1820_inittab [] =
 {
-	0x69, 0x6A, 0x9B, 0x0A, 0x52, 0x46, 0x26, 0x1A,
+	0x69, 0x6A, 0x9B, 0x12, 0x12, 0x46, 0x26, 0x1A,
 	0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x28,
 	0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
@@ -109,7 +109,7 @@
 {
 	u8 addr = GET_DEMOD_ADDR(fe->data);
         u8 buf[] = { 0x00, reg, data };
-	struct i2c_msg msg = { addr: addr, .flags = 0, .buf = buf, .len = 3 };
+	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
 	struct dvb_i2c_bus *i2c = fe->i2c;
         int ret;
 
@@ -130,8 +130,8 @@
 	u8 b0 [] = { 0x00, reg };
 	u8 b1 [] = { 0 };
 	u8 addr = GET_DEMOD_ADDR(fe->data);
-	struct i2c_msg msg [] = { { addr: addr, .flags = 0, .buf = b0, .len = 2 },
-	                   { addr: addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+	struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b0, .len = 2 },
+	                   { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 	struct dvb_i2c_bus *i2c = fe->i2c;
 	int ret;
 
@@ -147,7 +147,7 @@
 static int tuner_write (struct dvb_i2c_bus *i2c, u8 addr, u8 data [4])
 {
         int ret;
-        struct i2c_msg msg = { addr: addr, .flags = 0, .buf = data, .len = 4 };
+        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
 
         ret = i2c->xfer (i2c, &msg, 1);
 
#4 lore raw

PATCH 5/17 Add Zarlink MT312 DVB-T frontend driver

[DVB] - Zarlink MT312 satellite channel decoder driver contributed by Andreas Oberritter

drivers/media/dvb/frontends/Kconfig +10 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/frontends/Kconfig linux-2.5.73.work/drivers/media/dvb/frontends/Kconfig
@@ -93,6 +93,16 @@
 	  DVB adapter simply enable all supported frontends, the 
 	  right one will get autodetected.
 
+config DVB_MT312
+	tristate "Zarlink MT312 Satellite Channel Decoder (QPSK)"
+	depends on DVB_CORE
+	help
+	  A DVB-S 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.
+
 config DVB_VES1820
 	tristate "Frontends with external VES1820 demodulator (QAM)"
 	depends on DVB_CORE
drivers/media/dvb/frontends/Makefile +1 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/frontends/Makefile linux-2.5.73.work/drivers/media/dvb/frontends/Makefile
@@ -12,4 +12,5 @@
 obj-$(CONFIG_DVB_CX24110) += cx24110.o
 obj-$(CONFIG_DVB_GRUNDIG_29504_491) += grundig_29504-491.o
 obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o
+obj-$(CONFIG_DVB_MT312) += mt312.o
 obj-$(CONFIG_DVB_VES1820) += ves1820.o
drivers/media/dvb/frontends/mt312.c +714 -0

714 lines not on this page · raw message

drivers/media/dvb/frontends/mt312.h +162 -0

162 lines not on this page · raw message

#5 lore raw

PATCH 6/17 Update the DVB budget drivers

[DVB] - follow changes in dvb_net, use new eeprom parse code to properly detect the mac [DVB] - add new subvendor/subystem id pair

drivers/media/dvb/ttpci/budget-core.c +4 -2
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/ttpci/budget-core.c linux-2.5.73.work/drivers/media/dvb/ttpci/budget-core.c
@@ -1,4 +1,5 @@
 #include "budget.h"
+#include "ttpci-eeprom.h"
 
 int budget_debug = 0;
 
@@ -165,7 +166,6 @@
         if (ret < 0)
                 return ret;
 
-        budget->dvb_net.card_num = budget->dvb_adapter->num;
         dvb_net_init(budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
 
 	return 0;
@@ -222,7 +222,7 @@
            get recognized before the main driver is loaded */
         saa7146_write(dev, GPIO_CTRL, 0x500000);
 	
-	saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_3200);
+	saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_120);
 
 	budget->i2c_bus = dvb_register_i2c_bus (master_xfer, dev,
 						budget->dvb_adapter, 0);
@@ -232,6 +232,8 @@
 		return -ENOMEM;
 	}
 
+	ttpci_eeprom_parse_mac(budget->i2c_bus);
+
 	if( NULL == (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci,length,&budget->pt))) {
 		ret = -ENOMEM;
 		goto err;
drivers/media/dvb/ttpci/budget.c +2 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/ttpci/budget.c linux-2.5.73.work/drivers/media/dvb/ttpci/budget.c
@@ -192,6 +192,7 @@
 MAKE_BUDGET_INFO(ttbs,	"TT-Budget/WinTV-NOVA-S  PCI",	BUDGET_TT);
 MAKE_BUDGET_INFO(ttbc,	"TT-Budget/WinTV-NOVA-C  PCI",	BUDGET_TT);
 MAKE_BUDGET_INFO(ttbt,	"TT-Budget/WinTV-NOVA-T  PCI",	BUDGET_TT);
+MAKE_BUDGET_INFO(ttbt2,	"TT-Budget/WinTV-NOVA-T  PCI",	BUDGET_TT);
 MAKE_BUDGET_INFO(satel,	"SATELCO Multimedia PCI",	BUDGET_TT_HW_DISEQC);
 /* Uncomment for Budget Patch */
 /*MAKE_BUDGET_INFO(fs_1_3,"Siemens/Technotrend/Hauppauge PCI rev1.3+Budget_Patch", BUDGET_PATCH);*/
@@ -202,6 +203,7 @@
 	MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
 	MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
 	MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
+	MAKE_EXTENSION_PCI(ttbt2,  0x13c2, 0x1011),	
 	MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
 	{
 		.vendor    = 0,
#6 lore raw

PATCH 7/17 Update the DVB av7110 driver

[DVB] - Fix to 'Sharing SDRAM between TT re-insertion and OSD...' - OSD didn't get the maximum available memory in one piece; needs new firmware version 0x2616
[DVB] - Improved performance when setting palette with full 256 color OSD
[DVB] - read MAC from EEPROM if available, contributed by Michael Glaum <[email protected]>
[DVB] - add some MODULE_PARM_DESC for modinfo
[DVB] - add support for the "analog module" available for DVB-C cards: the saa7113 is initialized and some more v4l2 ioctls are available. you can use "xawtv" now to switch between "dvb" and "analog" input. when you are one the "analog" input, you can tune in analog channels.

drivers/media/dvb/ttpci/av7110.c +328 -22
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/ttpci/av7110.c linux-2.5.73.work/drivers/media/dvb/ttpci/av7110.c
@@ -86,6 +86,7 @@
 	#define DEB_EE(x)
 #endif
 
+#include "ttpci-eeprom.h"
 #include "av7110.h"
 #include "av7110_ipack.h"
 
@@ -110,7 +112,8 @@
 
 int av7110_num = 0;
 
-#define FW_CI_LL_SUPPORT(arm_app) (((arm_app) >> 16) & 0x8000)
+#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
+#define FW_VERSION(arm_app)       ((arm_app) & 0x0000FFFF)
 
 /****************************************************************************
  * DEBI functions
@@ -1089,7 +1092,7 @@
         u32 stat;
 #endif
 
-	DEB_EE(("av7110: %p\n",av7110));
+//	DEB_EE(("av7110: %p\n",av7110));
 
 	if (!av7110->arm_ready) {
 		DEB_D(("arm not ready.\n"));
@@ -1166,7 +1169,7 @@
 {
         int ret;
         
- 	DEB_EE(("av7110: %p\n",av7110));
+// 	DEB_EE(("av7110: %p\n",av7110));
 
         if (!av7110->arm_ready) {
 		DEB_D(("arm not ready.\n"));
@@ -1190,7 +1193,7 @@
         u16 buf[num+2];
         int i, ret;
 
- 	DEB_EE(("av7110: %p\n",av7110));
+// 	DEB_EE(("av7110: %p\n",av7110));
 
         buf[0]=(( type << 8 ) | com);
         buf[1]=num;
@@ -1332,7 +1335,7 @@
 
 static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
 {
- 	DEB_EE(("av7110: %p\n",av7110));
+// 	DEB_EE(("av7110: %p\n",av7110));
 
         return outcom(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
 }
@@ -1659,6 +1662,24 @@
                   color, ((blend>>4)&0x0f));
 }
 
+static int OSDSetPalette(struct av7110 *av7110, u32 *colors, u8 first, u8 last)
+{
+       int i;
+       int length = last - first + 1;
+
+       if (length * 4 > DATA_BUFF3_SIZE)
+               return -1;
+
+       for (i=0; i<length; i++) {
+               u32 blend = (colors[i] & 0xF0000000) >> 4;
+               u32 yuv = blend ? RGB2YUV(colors[i] & 0xFF, (colors[i] >> 8) & 0xFF, (colors[i] >> 16) & 0xFF) | blend : 0;
+               yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16); // TODO kls2003-06-15: not sure if this is endian-proof
+               wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i*4, yuv, 4);
+       }
+       return outcom(av7110, COMTYPE_OSD, Set_Palette, 4,
+               av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], first, last);
+}
+
 static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data)
 {
         uint w, h, bpp, bpl, size, lpb, bnum, brest;
@@ -1721,6 +1742,9 @@
                 return 0;
         case OSD_SetPalette:
         {      
+                if (FW_VERSION(av7110->arm_app) >= 0x2618)
+                        OSDSetPalette(av7110, (u32 *)dc->data, dc->color, dc->x0);
+                else {
                 int i, len=dc->x0-dc->color+1;
                 u8 *colors=(u8 *)dc->data;
 
@@ -1728,6 +1752,7 @@
                         OSDSetColor(av7110, dc->color+i,
                                     colors[i*4]  , colors[i*4+1],
                                     colors[i*4+2], colors[i*4+3]);
+                }
                 return 0;
         }
         case OSD_SetTrans: 
@@ -2087,28 +2112,28 @@
 
 static inline void TestMode(struct av7110 *av7110, int mode)
 {
- 	DEB_EE(("av7110: %p\n",av7110));
+//	DEB_EE(("av7110: %p\n",av7110));
         outcom(av7110, COMTYPE_ENCODER, SetTestMode, 1, mode);
 }
 
 static inline void VidMode(struct av7110 *av7110, int mode)
 {
- 	DEB_EE(("av7110: %p\n",av7110));
+// 	DEB_EE(("av7110: %p\n",av7110));
         outcom(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
 }
            
 
-static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
+static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg)
 {
- 	DEB_EE(("av7110: %p\n",av7110));
+// 	DEB_EE(("av7110: %p\n",av7110));
         return outcom(av7110, 0x80, 0x02, 4, 
                       (com>>16), (com&0xffff), 
                       (arg>>16), (arg&0xffff));
 }
 
-static inline int audcom(struct av7110 *av7110, u32 com)
+static int inline audcom(struct av7110 *av7110, u32 com)
 {
-	DEB_EE(("av7110: %p\n",av7110));
+//	DEB_EE(("av7110: %p\n",av7110));
 	return outcom(av7110, 0x80, 0x03, 4, 
                       (com>>16), (com&0xffff));
 }
@@ -2583,38 +2608,274 @@
  * V4L SECTION
  ****************************************************************************/
 
-int av7110_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) 
+static struct v4l2_input inputs[2] = {
+	{ 0,	"DVB",		V4L2_INPUT_TYPE_CAMERA,	1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, 
+	{ 1,	"ANALOG",	V4L2_INPUT_TYPE_TUNER,	2, 1, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
+};
+
+/* taken from ves1820.c */
+static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data)
 {
+	u8 addr = 0x09;
+        u8 buf[] = { 0x00, reg, data };
+	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
+
+  	DEB_EE(("av7710: dev: %p\n",dev));
+
+	if( 1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) {
+		return -1;
+	}
+	return 0;
+}
+
+static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
+{
+        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
+
+  	DEB_EE(("av7710: dev: %p\n",dev));
+
+	if( 1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) {
+		return -1;
+	}
+	return 0;
+}
+
+
+/**
+ *   set up the downconverter frequency divisor for a
+ *   reference clock comparision frequency of 62.5 kHz.
+ */
+static int tuner_set_tv_freq (struct saa7146_dev *dev, u32 freq)
+{
+        u32 div;
+	u8 config;
+        u8 buf [4];
+
+ 	DEB_EE(("av7710: freq: 0x%08x\n",freq));
+
+	/* magic number: 56. tuning with the frequency given by v4l2
+	   is always off by 56*62.5 kHz...*/
+	div = freq + 56;
+
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] = div & 0xff;
+	buf[2] = 0x8e;
+
+	if (freq < 16*168.25 ) 
+		config = 0xa0;
+	else if (freq < 16*447.25) 
+		config = 0x90;
+	else
+		config = 0x30;
+	config &= ~0x02;
+
+	buf[3] = config;
+
+        return tuner_write (dev, 0x61, buf);
+}
+
+static struct saa7146_standard analog_standard[];
+static struct saa7146_standard dvb_standard[];
+static struct saa7146_standard standard[];
+
+int av7110_dvb_c_switch(struct saa7146_fh *fh)
+{
+	struct saa7146_dev *dev = fh->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
+	u16 buf[3] = { ((COMTYPE_AUDIODAC << 8) + ADSwitch), 1, 1 };
+
+	u8 band = 0;
+	int source, sync;
+	struct saa7146_fh *ov_fh = NULL;
+	int restart_overlay = 0;
+
+	DEB_EE(("av7110: %p\n",av7110));
+
+	if( vv->ov_data != NULL ) {
+		ov_fh = vv->ov_data->fh;
+		saa7146_stop_preview(ov_fh);
+		restart_overlay = 1;
+	}
+
+	if( 0 != av7110->current_input ) {
+		buf[2] = 0;
+		band = 0x68; /* analog band */
+		source = SAA7146_HPS_SOURCE_PORT_B;
+		sync = SAA7146_HPS_SYNC_PORT_B;
+		memcpy(standard,analog_standard,sizeof(struct saa7146_standard)*2);
+	} else {
+		buf[2] = 1;
+		band = 0x28; /* digital band */	
+		source = SAA7146_HPS_SOURCE_PORT_A;
+		sync = SAA7146_HPS_SYNC_PORT_A;
+		memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2);
+	}
+
+	/* hmm, this does not do anything!? */
+	if (OutCommand(av7110, buf, 3)) {
+		printk("ADSwitch error\n");
+	}
+
+	if( 0 != ves1820_writereg(dev, 0x0f, band )) {
+		printk("setting band in demodulator failed.\n");
+	}
+	saa7146_set_hps_source_and_sync(dev, source, sync);
+
+	/* restart overlay if it was active before */
+	if( 0 != restart_overlay ) {
+		saa7146_start_preview(ov_fh);
+	}
+
+	return 0;
+}
+
+int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
+{
+	struct saa7146_dev *dev = fh->dev;
+	struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
  	DEB_EE(("saa7146_dev: %p\n",dev));
 
 	switch(cmd) {
+	case VIDIOC_G_TUNER:
+	{
+		struct v4l2_tuner *t = arg;
+
+		DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
+
+		if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
+			return -EINVAL;
+		}
+
+		memset(t,0,sizeof(*t));
+		strcpy(t->name, "Television");
+
+		t->type = V4L2_TUNER_ANALOG_TV;
+		t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+		t->rangelow = 772;	/* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
+		t->rangehigh = 13684;	/* 855.25 MHz / 62.5 kHz = 13684 */
+		/* FIXME: add the real signal strength here */
+		t->signal = 0xffff;
+		t->afc = 0;		
+		/* fixme: real autodetection here */
+		t->rxsubchans 	= V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+
+		return 0;
+	}
+	case VIDIOC_S_TUNER:
+	{
+		struct v4l2_tuner *t = arg;
+		
+		DEB_EE(("VIDIOC_S_TUNER: %d\n", t->index));
+
+		if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
+			return -EINVAL;
+		}
+
+
+		switch(t->audmode) {
+			case V4L2_TUNER_MODE_STEREO: {
+				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
+				break;
+			}
+			case V4L2_TUNER_MODE_LANG1: {
+				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
+				break;
+			}
+			case V4L2_TUNER_MODE_LANG2: {
+				DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
+				break;
+			}
+			default: { /* case V4L2_TUNER_MODE_MONO: {*/
+				DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
+				break;
+			}
+		}
+
+		return 0;
+	}
+	case VIDIOC_G_FREQUENCY:
+	{
+		struct v4l2_frequency *f = arg;
+
+		DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency));
+
+		if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
+			return -EINVAL;
+		}
+
+		memset(f,0,sizeof(*f));
+		f->type = V4L2_TUNER_ANALOG_TV;
+		f->frequency =  av7110->current_freq;
+
+		return 0;
+	}
+	case VIDIOC_S_FREQUENCY:
+	{
+		struct v4l2_frequency *f = arg;
+
+		DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
+
+		if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
+			return -EINVAL;
+		}
+
+		if (V4L2_TUNER_ANALOG_TV != f->type)
+			return -EINVAL;
+
+		/* tune in desired frequency */			
+		tuner_set_tv_freq(dev, f->frequency);
+		av7110->current_freq = f->frequency;
+
+		return 0;
+	}
 	case VIDIOC_ENUMINPUT:
 	{
 		struct v4l2_input *i = arg;
 		
+		DEB_EE(("VIDIOC_ENUMINPUT: %d\n", i->index));
+
+		if( 0 != av7110->has_analog_tuner ) {
+			if( i->index < 0 || i->index >= 2) {
+				return -EINVAL;
+			}
+		} else {
 		if( i->index != 0 ) {
 			return -EINVAL;
 		}
+		}		
 
-		memset(i,0,sizeof(*i));
-		i->index = 0;
-		strcpy(i->name, "DVB");
-		i->type = V4L2_INPUT_TYPE_CAMERA;
-		i->audioset = 1;
+		memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
 		
 		return 0;
 	}
 	case VIDIOC_G_INPUT:
 	{
 		int *input = (int *)arg;
-		*input = 0;
+		*input = av7110->current_input;
+		DEB_EE(("VIDIOC_G_INPUT: %d\n", *input));
 		return 0;		
 	}	
 	case VIDIOC_S_INPUT:
 	{
+		int input = *(int *)arg;
+
+		DEB_EE(("VIDIOC_S_INPUT: %d\n", input));
+
+		if( 0 == av7110->has_analog_tuner ) {
 		return 0;		
 	}	
+		
+		if( input < 0 || input >= 2) {
+			return -EINVAL;
+		}
+		
+		/* fixme: switch inputs here */
+		av7110->current_input = input;
+		return av7110_dvb_c_switch(fh);
+	}	
 	default:
+		printk("no such ioctl\n");
 		return -ENOIOCTLCMD;
 	}
 	return 0;
@@ -4006,7 +4267,6 @@
 #endif
 //        }
         
-        av7110->dvb_net.card_num=av7110->dvb_adapter->num;
         dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
 
 	return 0;
@@ -4061,6 +4321,10 @@
 	{ VIDIOC_ENUMINPUT, 	SAA7146_EXCLUSIVE },
 	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
 	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
+	{ VIDIOC_G_FREQUENCY,	SAA7146_EXCLUSIVE },
+	{ VIDIOC_S_FREQUENCY, 	SAA7146_EXCLUSIVE },
+	{ VIDIOC_G_TUNER, 	SAA7146_EXCLUSIVE },
+	{ VIDIOC_S_TUNER, 	SAA7146_EXCLUSIVE },
 	{ 0, 0 }
 };
 
@@ -4114,6 +4378,8 @@
 		return -ENOMEM;
 	}
 
+	ttpci_eeprom_parse_mac(av7110->i2c_bus);
+
 	saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
 	saa7146_write(dev, BCS_CTRL, 0x80400040);
 
@@ -4186,9 +4452,9 @@
 	bootarm(av7110);
 	firmversion(av7110);
 
-	if ((av7110->arm_app&0xffff)<0x2501)
+	if (FW_VERSION(av7110->arm_app)<0x2501)
 		printk ("av7110: Warning, firmware version 0x%04x is too old. "
-			"System might be unstable!\n", av7110->arm_app&0xffff);
+			"System might be unstable!\n", FW_VERSION(av7110->arm_app));
 
 	kernel_thread(arm_thread, (void *) av7110, 0);
 
@@ -4199,6 +4465,8 @@
 	VidMode(av7110, vidmode);
 
 	/* remaining inits according to card and frontend type */
+	av7110->has_analog_tuner = 0;
+	av7110->current_input = 0;
 	if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) {
 		printk ("av7110(%d): Crystal audio DAC detected\n",
 			av7110->dvb_adapter->num);
@@ -4225,6 +4493,31 @@
 			msp_writereg(av7110, 0x12, 0x000a, 0x0220); // SCART 1 source
 			msp_writereg(av7110, 0x12, 0x0007, 0x7f00); // SCART 1 volume
 			msp_writereg(av7110, 0x12, 0x000d, 0x4800); // prescale SCART
+		
+		if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
+			INFO(("saa7113 not accessible.\n"));
+		} else {
+			av7110->has_analog_tuner = 1;
+			/* init the saa7113 */
+			i2c_writereg(av7110, 0x48, 0x02, 0xd0); i2c_writereg(av7110, 0x48, 0x03, 0x23); i2c_writereg(av7110, 0x48, 0x04, 0x00);
+			i2c_writereg(av7110, 0x48, 0x05, 0x00); i2c_writereg(av7110, 0x48, 0x06, 0xe9); i2c_writereg(av7110, 0x48, 0x07, 0x0d);
+			i2c_writereg(av7110, 0x48, 0x08, 0x98); i2c_writereg(av7110, 0x48, 0x09, 0x02); i2c_writereg(av7110, 0x48, 0x0a, 0x80);
+			i2c_writereg(av7110, 0x48, 0x0b, 0x40); i2c_writereg(av7110, 0x48, 0x0c, 0x40); i2c_writereg(av7110, 0x48, 0x0d, 0x00);
+			i2c_writereg(av7110, 0x48, 0x0e, 0x01);	i2c_writereg(av7110, 0x48, 0x0f, 0x7c); i2c_writereg(av7110, 0x48, 0x10, 0x48);
+			i2c_writereg(av7110, 0x48, 0x11, 0x0c);	i2c_writereg(av7110, 0x48, 0x12, 0x8b);	i2c_writereg(av7110, 0x48, 0x13, 0x10);
+			i2c_writereg(av7110, 0x48, 0x14, 0x00);	i2c_writereg(av7110, 0x48, 0x15, 0x00);	i2c_writereg(av7110, 0x48, 0x16, 0x00);
+			i2c_writereg(av7110, 0x48, 0x17, 0x00);	i2c_writereg(av7110, 0x48, 0x18, 0x00);	i2c_writereg(av7110, 0x48, 0x19, 0x00);
+			i2c_writereg(av7110, 0x48, 0x1a, 0x00);	i2c_writereg(av7110, 0x48, 0x1b, 0x00);	i2c_writereg(av7110, 0x48, 0x1c, 0x00);
+			i2c_writereg(av7110, 0x48, 0x1d, 0x00);	i2c_writereg(av7110, 0x48, 0x1e, 0x00);
+		}	
+
+		memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2);
+		/* set dd1 stream a & b */
+      		saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+		saa7146_write(dev, DD1_INIT, 0x0200700);
+		saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+
 	} else if (dev->pci->subsystem_vendor == 0x110a) {
 		printk("av7110(%d): DVB-C w/o analog module detected\n",
 			av7110->dvb_adapter->num);
@@ -4330,6 +4623,16 @@
 	{ "NTSC", V4L2_STD_NTSC, 0x10, 244, 480, 0x40, 708, 709, 480, 640 },
 };
 
+static struct saa7146_standard analog_standard[] = {
+	{ "PAL", V4L2_STD_PAL, 0x18, 288, 576, 0x08, 708, 709, 576, 768 },
+	{ "NTSC", V4L2_STD_NTSC, 0x10, 244, 480, 0x40, 708, 709, 480, 640 },
+};
+
+static struct saa7146_standard dvb_standard[] = {
+	{ "PAL", V4L2_STD_PAL, 0x14, 288, 576, 0x4a, 708, 709, 576, 768 },
+	{ "NTSC", V4L2_STD_NTSC, 0x10, 244, 480, 0x40, 708, 709, 480, 640 },
+};
+
 static struct saa7146_extension av7110_extension;
 
 #define MAKE_AV7110_INFO(x_var,x_name) \
@@ -4390,7 +4693,7 @@
 static struct saa7146_ext_vv av7110_vv_data = {
 	.inputs		= 1,
 	.audios 	= 1,
-	.capabilities	= 0,
+	.capabilities	= V4L2_CAP_TUNER,
 	.flags		= SAA7146_EXT_SWAP_ODD_EVEN,
 
 	.stds		= &standard[0],
@@ -4442,7 +4745,11 @@
 
 MODULE_PARM(av7110_debug,"i");
 MODULE_PARM(vidmode,"i");
+MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
 MODULE_PARM(pids_off,"i");
+MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
 MODULE_PARM(adac,"i");
+MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
 MODULE_PARM(hw_sections, "i");
+MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
 
drivers/media/dvb/ttpci/av7110.h +10 -1
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/ttpci/av7110.h linux-2.5.73.work/drivers/media/dvb/ttpci/av7110.h
@@ -153,7 +153,8 @@
 	BlitBmp,
 	ReleaseBmp,
 	SetWTrans,
-	SetWNoTrans
+        SetWNoTrans,
+        Set_Palette
 };
 
 enum av7110_pid_command { 
@@ -405,6 +406,11 @@
 	struct dvb_i2c_bus	*i2c_bus;	
 	char			*card_name;
 
+	/* support for analog module of dvb-c */
+	int			has_analog_tuner;
+	int			current_input;
+	u32			current_freq;
+				
 	struct tasklet_struct   debi_tasklet;
 	struct tasklet_struct   gpio_tasklet;
 
@@ -572,6 +578,9 @@
 #define DATA_BUFF2_BASE	(DATA_BUFF1_BASE+DATA_BUFF1_SIZE)
 #define DATA_BUFF2_SIZE	0x0800
 
+#define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE)
+#define DATA_BUFF3_SIZE 0x0400
+
 #define Reserved	(DPRAM_BASE + 0x1E00)
 #define Reserved_SIZE	0x1C0
 
drivers/media/dvb/ttpci/ttpci-eeprom.c +120 -0

120 lines not on this page · raw message

drivers/media/dvb/ttpci/ttpci-eeprom.h +32 -0
diff -uNrwB --new-file linux-2.5.73.patch/drivers/media/dvb/ttpci/ttpci-eeprom.h linux-2.5.73.work/drivers/media/dvb/ttpci/ttpci-eeprom.h
@@ -0,0 +1,32 @@
+/*
+    Retrieve encoded MAC address from ATMEL ttpci_eeprom serial 2-wire EEPROM,
+    decode it and store it in associated adapter net device
+
+    Robert Schlabbach	GMX
+    Michael Glaum	KVH Industries
+    Holger Waechtler	Convergence
+
+    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
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __TTPCI_EEPROM_H__
+#define __TTPCI_EEPROM_H__
+
+#include "dvb_i2c.h"
+
+extern int ttpci_eeprom_parse_mac(struct dvb_i2c_bus *i2c);
+
+#endif
drivers/media/dvb/dvb-core/dvbdev.h +1 -0
diff -uNrwB --new-file linux-2.5.73.bk/drivers/media/dvb/dvb-core/dvbdev.h linux-2.5.73.work/drivers/media/dvb/dvb-core/dvbdev.h
@@ -48,6 +48,7 @@
 	struct list_head list_head;
 	struct list_head device_list;
 	const char *name;
+	u8 proposed_mac [6];
 };
 
 
#8 lore raw

PATCH 9/17 More saa7146 driver core updates

[V4L] - separate all EXPORT_SYMBOL stuff to saa7146_ksyms.c
[V4L] - properly stop capturing when no more buffers are available (missing register upload) [V4L] - make extension data a per-device member, not a per-extension member, so that every device
can have it's own private data (necessary for DVB drivers which handle more than one device)
[V4L] - implement field based capturing, ie. capturing fields to different capture buffers [V4L] - change default old of capture fields for ALTERNATE mode (comply with bttv) [V4L] - follow these changes in various analog saa7146 based cards drivers (mxb.c and dpc7146.c) [DVB] - follow these changes in various saa7146 based budget card drivers

drivers/media/common/Makefile +1 -1
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/common/Makefile linux-2.6.0-test1.patch/drivers/media/common/Makefile
@@ -1,5 +1,5 @@
 saa7146-objs    := saa7146_i2c.o saa7146_core.o 
-saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o  
+saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o  
 
 obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o saa7146_vv.o
 
drivers/media/common/saa7146_core.c +3 -3
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/common/saa7146_core.c linux-2.6.0-test1.patch/drivers/media/common/saa7146_core.c
@@ -373,6 +372,9 @@
 	dev->module = THIS_MODULE;
 	init_waitqueue_head(&dev->i2c_wq);
 
+	/* set some default values */
+	saa7146_write(dev, BCS_CTRL, 0x80400040);
+
 	if( 0 != ext->probe) {
 		if( 0 != ext->probe(dev) ) {
 			DEB_D(("ext->probe() failed for %p. skipping device.\n",dev));
@@ -391,9 +393,6 @@
 	list_add_tail(&dev->item,&saa7146_devices);
 	saa7146_num++;
 
-	/* set some default values */
-	saa7146_write(dev, BCS_CTRL, 0x80400040);
-
 	err = 0;
 	goto out;
 attach_error:
drivers/media/common/saa7146_fops.c +17 -8
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/common/saa7146_fops.c linux-2.6.0-test1.patch/drivers/media/common/saa7146_fops.c
@@ -106,10 +106,21 @@
 			// fixme: fix this for vflip != 0
 
 			saa7146_write(dev, PROT_ADDR1, 0);
+			saa7146_write(dev, MC2, (MASK_02|MASK_18));		
+
 			/* write the address of the rps-program */
 			saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
 			/* turn on rps */
 			saa7146_write(dev, MC1, (MASK_12 | MASK_28));
+				
+/*
+			printk("vdma%d.base_even:     0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
+			printk("vdma%d.base_odd:      0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
+			printk("vdma%d.prot_addr:     0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
+			printk("vdma%d.base_page:     0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
+			printk("vdma%d.pitch:         0x%08x\n", 1,saa7146_read(dev,PITCH1));
+			printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
+*/
 		}
 		del_timer(&q->timeout);
 	}
@@ -374,7 +385,7 @@
 	.minor		= -1,
 };
 
-int saa7146_vv_init(struct saa7146_dev* dev)
+int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
 {
 	struct saa7146_vv *vv = kmalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
 	if( NULL == vv ) {
@@ -385,6 +396,11 @@
 
 	DEB_EE(("dev:%p\n",dev));
 	
+	/* save per-device extension data (one extension can
+	   handle different devices that might need different
+	   configuration data) */
+	dev->ext_vv_data = ext_vv;
+	
 	vv->video_minor = -1;
 	vv->vbi_minor = -1;
 
@@ -475,13 +491,6 @@
 module_init(saa7146_vv_init_module);
 module_exit(saa7146_vv_cleanup_module);
 
-EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
-EXPORT_SYMBOL_GPL(saa7146_register_device);
-EXPORT_SYMBOL_GPL(saa7146_unregister_device);
-
-EXPORT_SYMBOL_GPL(saa7146_vv_init);
-EXPORT_SYMBOL_GPL(saa7146_vv_release);
-
 MODULE_AUTHOR("Michael Hunold <[email protected]>");
 MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware");
 MODULE_LICENSE("GPL");
drivers/media/common/saa7146_hlp.c +63 -9

142 lines not on this page · raw message

drivers/media/common/saa7146_i2c.c +5 -0
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/common/saa7146_i2c.c linux-2.6.0-test1.patch/drivers/media/common/saa7146_i2c.c
@@ -407,8 +407,13 @@
 
 	if( NULL != i2c_adapter ) {
 		memset(i2c_adapter,0,sizeof(struct i2c_adapter));
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+		strcpy(i2c_adapter->name, dev->name);	
+		i2c_adapter->data = dev;
+#else
 		strcpy(i2c_adapter->dev.name, dev->name);	
 		i2c_set_adapdata(i2c_adapter,dev);
+#endif
 		i2c_adapter->algo	   = &saa7146_algo;
 		i2c_adapter->algo_data     = NULL;
 		i2c_adapter->id 	   = I2C_ALGO_SAA7146;
drivers/media/common/saa7146_vbi.c +0 -2
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/common/saa7146_vbi.c linux-2.6.0-test1.patch/drivers/media/common/saa7146_vbi.c
@@ -444,5 +444,3 @@
 	.irq_done	= vbi_irq_done,
 	.read 		= vbi_read,
 };
-
-EXPORT_SYMBOL_GPL(saa7146_vbi_uops);
drivers/media/common/saa7146_video.c +40 -30

167 lines not on this page · raw message

drivers/media/common/saa7146_vv_ksyms.c +15 -0
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/common/saa7146_vv_ksyms.c linux-2.6.0-test1.patch/drivers/media/common/saa7146_vv_ksyms.c
@@ -0,0 +1,15 @@
+#include <linux/module.h>
+#include <media/saa7146_vv.h>
+
+EXPORT_SYMBOL_GPL(saa7146_vbi_uops);
+EXPORT_SYMBOL_GPL(saa7146_video_uops);
+
+EXPORT_SYMBOL_GPL(saa7146_start_preview);
+EXPORT_SYMBOL_GPL(saa7146_stop_preview);
+
+EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
+EXPORT_SYMBOL_GPL(saa7146_register_device);
+EXPORT_SYMBOL_GPL(saa7146_unregister_device);
+
+EXPORT_SYMBOL_GPL(saa7146_vv_init);
+EXPORT_SYMBOL_GPL(saa7146_vv_release);
drivers/media/dvb/ttpci/budget-av.c +21 -8
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/ttpci/budget-av.c linux-2.6.0-test1.patch/drivers/media/dvb/ttpci/budget-av.c
@@ -170,6 +170,7 @@
 	return err;
 }
 
+static struct saa7146_ext_vv vv_data;
 
 static int budget_av_attach (struct saa7146_dev* dev,
 		      struct saa7146_pci_extension_data *info)
@@ -207,16 +208,22 @@
 	dvb_delay(500);
 
 	if ((err = saa7113_init (budget_av))) {
-		budget_av_detach(dev);
+		/* fixme: proper cleanup here */
+		ERR(("cannot init saa7113.\n"));
+		return err;
+	}
+
+	if ( 0 != saa7146_vv_init(dev,&vv_data)) {
+		/* fixme: proper cleanup here */
+		ERR(("cannot init vv subsystem.\n"));
 		return err;
 	}
 
-	saa7146_vv_init(dev);
 	if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1",
 					   VFL_TYPE_GRABBER)))
 	{
+		/* fixme: proper cleanup here */
 		ERR(("cannot register capture v4l2 device.\n"));
-		budget_av_detach(dev);
 		return err;
 	}
 
@@ -300,11 +307,19 @@
 }
 
 static struct saa7146_standard standard[] = {
-	{ "PAL",	V4L2_STD_PAL,	SAA7146_PAL_VALUES },
-	{ "NTSC",	V4L2_STD_NTSC,	SAA7146_NTSC_VALUES },
+	{
+		.name	= "PAL", 	.id	= V4L2_STD_PAL,
+		.v_offset	= 0x17,	.v_field 	= 288,	.v_calc		= 576,
+		.h_offset	= 0x14,	.h_pixels 	= 680,	.h_calc		= 680+1,
+		.v_max_out	= 576,	.h_max_out	= 768,
+	}, {
+		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
+		.v_offset	= 0x16,	.v_field 	= 240,	.v_calc		= 480,
+		.h_offset	= 0x06,	.h_pixels 	= 708,	.h_calc		= 708+1,
+		.v_max_out	= 480,	.h_max_out	= 640,
+	}
 };
 
-
 static struct saa7146_ext_vv vv_data = {
 	.inputs		= 2,
 	.capabilities	= 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
@@ -339,8 +354,6 @@
 	.attach		= budget_av_attach,
 	.detach		= budget_av_detach,
 
-	.ext_vv_data	= &vv_data,
-
 	.irq_mask	= MASK_10,
 	.irq_func	= ttpci_budget_irq10_handler,
 };	
drivers/media/dvb/ttpci/budget-ci.c +0 -1
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/ttpci/budget-ci.c linux-2.6.0-test1.patch/drivers/media/dvb/ttpci/budget-ci.c
@@ -371,7 +377,6 @@
 static struct saa7146_extension budget_extension = {
 	.name		= "budget_ci dvb\0",
 	.flags	 	= 0,
-	.ext_vv_data	= NULL,
 
 	.module		= THIS_MODULE,
 	.pci_tbl	= &pci_tbl[0],
drivers/media/dvb/ttpci/budget-patch.c +0 -1
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/ttpci/budget-patch.c linux-2.6.0-test1.patch/drivers/media/dvb/ttpci/budget-patch.c
@@ -264,7 +264,6 @@
 static struct saa7146_extension budget_extension = {
         .name           = "budget_patch dvb\0",
         .flags          = 0,
-        .ext_vv_data    = NULL,
         
         .module         = THIS_MODULE,
         .pci_tbl        = pci_tbl,
drivers/media/dvb/ttpci/budget.c +0 -1
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/ttpci/budget.c linux-2.6.0-test1.patch/drivers/media/dvb/ttpci/budget.c
@@ -215,7 +215,6 @@
 static struct saa7146_extension budget_extension = {
 	.name		= "budget dvb\0",
 	.flags	 	= 0,
-	.ext_vv_data	= NULL,
 	
 	.module		= THIS_MODULE,
 	.pci_tbl	= pci_tbl,
drivers/media/video/dpc7146.c +24 -16
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/video/dpc7146.c linux-2.6.0-test1.patch/drivers/media/video/dpc7146.c
@@ -173,6 +173,8 @@
 	return 0;
 }
 
+static struct saa7146_ext_vv vv_data;
+
 /* this function only gets called when the probing was successful */
 static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
 {
@@ -183,7 +185,7 @@
 	/* checking for i2c-devices can be omitted here, because we
 	   already did this in "dpc_vl42_probe" */
 
-	saa7146_vv_init(dev);
+	saa7146_vv_init(dev,&vv_data);
 	if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) {
 		ERR(("cannot register capture v4l2 device. skipping.\n"));
 		return -1;
@@ -308,23 +310,32 @@
 }
 
 static struct saa7146_standard standard[] = {
-	{ "PAL-BG",	V4L2_STD_PAL_BG,	SAA7146_PAL_VALUES },
-	{ "PAL-I",	V4L2_STD_PAL_I,		SAA7146_PAL_VALUES },
-	{ "NTSC",	V4L2_STD_NTSC,		SAA7146_NTSC_VALUES },
-	{ "SECAM", 	V4L2_STD_SECAM,		SAA7146_SECAM_VALUES },
+	{
+		.name	= "PAL", 	.id	= V4L2_STD_PAL,
+		.v_offset	= 0x17,	.v_field 	= 288,	.v_calc		= 576,
+		.h_offset	= 0x14,	.h_pixels 	= 680,	.h_calc		= 680+1,
+		.v_max_out	= 576,	.h_max_out	= 768,
+	}, {
+		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
+		.v_offset	= 0x16,	.v_field 	= 240,	.v_calc		= 480,
+		.h_offset	= 0x06,	.h_pixels 	= 708,	.h_calc		= 708+1,
+		.v_max_out	= 480,	.h_max_out	= 640,
+	}, {
+		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
+		.v_offset	= 0x14,	.v_field 	= 288,	.v_calc		= 576,
+		.h_offset	= 0x14,	.h_pixels 	= 720,	.h_calc		= 720+1,
+		.v_max_out	= 576,	.h_max_out	= 768,
+	}
 };
 
-static
-struct saa7146_extension extension;
+static struct saa7146_extension extension;
 
-static
-struct saa7146_pci_extension_data dpc = {
+static struct saa7146_pci_extension_data dpc = {
         .ext_priv = "Multimedia eXtension Board",
         .ext = &extension,
 };
 
-static
-struct pci_device_id pci_tbl[] = {
+static struct pci_device_id pci_tbl[] = {
 	{
 		.vendor    = PCI_VENDOR_ID_PHILIPS,
 		.device	   = PCI_DEVICE_ID_PHILIPS_SAA7146,
@@ -338,8 +349,7 @@
 
 MODULE_DEVICE_TABLE(pci, pci_tbl);
 
-static
-struct saa7146_ext_vv vv_data = {
+static struct saa7146_ext_vv vv_data = {
 	.inputs		= DPC_INPUTS,
 	.capabilities	= V4L2_CAP_VBI_CAPTURE,
 	.stds		= &standard[0],
@@ -349,14 +359,12 @@
 	.ioctl		= dpc_ioctl,
 };
 
-static
-struct saa7146_extension extension = {
+static struct saa7146_extension extension = {
 	.name		= "dpc7146 demonstration board",
 	.flags		= SAA7146_USE_I2C_IRQ,
 	
 	.pci_tbl	= &pci_tbl[0],
 	.module		= THIS_MODULE,
-	.ext_vv_data	= &vv_data,
 
 	.probe		= dpc_probe,
 	.attach		= dpc_attach,
drivers/media/video/mxb.c +35 -21

123 lines not on this page · raw message

include/media/saa7146.h +1 -2
diff -uNrwB --new-file linux-2.6.0-test1.work/include/media/saa7146.h linux-2.6.0-test1.patch/include/media/saa7146.h
@@ -89,8 +89,6 @@
 #define SAA7146_USE_I2C_IRQ	0x1
 	int	flags;
 	
-	struct saa7146_ext_vv	*ext_vv_data;
-	
 	/* pairs of subvendor and subdevice ids for
 	   supported devices, last entry 0xffff, 0xfff */
 	struct module *module;
@@ -134,6 +132,7 @@
 	/* extension handling */
 	struct saa7146_extension	*ext;		/* indicates if handled by extension */
 	void				*ext_priv;	/* pointer for extension private use (most likely some private data) */
+	struct saa7146_ext_vv		*ext_vv_data;
 
 	/* per device video/vbi informations (if available) */
 	struct saa7146_vv	*vv_data;
include/media/saa7146_vv.h +9 -37

70 lines not on this page · raw message

#9 lore raw

PATCH 10/17 Various kconfig and Makefile updates

drivers/media/dvb/Kconfig +11 -1
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/Kconfig linux-2.6.0-test1.patch/drivers/media/dvb/Kconfig
@@ -33,9 +33,19 @@
 source "drivers/media/dvb/frontends/Kconfig"
 
 comment "Supported SAA7146 based PCI Adapters"
-	depends on DVB
+	depends on DVB && PCI
 
 source "drivers/media/dvb/ttpci/Kconfig"
 
+comment "Supported USB Adapters"
+	depends on DVB && USB
+
+source "drivers/media/dvb/ttusb-budget/Kconfig"
+source "drivers/media/dvb/ttusb-dec/Kconfig"
+
+comment "Supported FlexCopII (B2C2) Adapters"
+	depends on DVB && PCI
+source "drivers/media/dvb/b2c2/Kconfig"
+
 endmenu
 
drivers/media/dvb/Makefile +2 -1
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/Makefile linux-2.6.0-test1.patch/drivers/media/dvb/Makefile
@@ -2,4 +2,5 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y        := dvb-core/ frontends/ ttpci/ # ttusb-budget/
+obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/
+
#10 lore raw

PATCH 11/17 Add a driver for the Technisat Skystar2 DVB card

[DVB] - add DVB driver for Technisat Skystar2 card, which is based on
the FlexCop2 chipset by B2C2

drivers/media/dvb/b2c2/Kconfig +8 -0
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/b2c2/Kconfig linux-2.6.0-test1.patch/drivers/media/dvb/b2c2/Kconfig
@@ -0,0 +1,8 @@
+config DVB_B2C2_SKYSTAR
+	tristate "Technisat Skystar2 PCI"
+	depends on DVB_CORE
+	help
+	  Support for the Skystar2 PCI DVB card by Technisat, which
+	  is equipped with the FlexCopII chipset by B2C2.
+
+	  Say Y if you own such a device and want to use it.
drivers/media/dvb/b2c2/Makefile +3 -0
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/b2c2/Makefile linux-2.6.0-test1.patch/drivers/media/dvb/b2c2/Makefile
@@ -0,0 +1,3 @@
+obj-$(DVB_B2C2_SKYSTAR) += skystar.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
drivers/media/dvb/b2c2/skystar2.c +2548 -0

2,548 lines not on this page · raw message

#11 lore raw

PATCH 12/17 Add two drivers for Hexium frame grabber cards

[V4L] - add drivers for the Orion and Gemini frame grabber cards, based on the saa7146. For details, see http://www.hexium.hu/. Thanks to Michael Hunold <[email protected]>.

drivers/media/video/Kconfig +25 -0
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/video/Kconfig linux-2.6.0-test1.patch/drivers/media/video/Kconfig
@@ -257,5 +257,30 @@
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
 
+config VIDEO_HEXIUM_ORION
+	tristate "Hexium HV-PCI6 and Orion frame grabber"
+	depends on VIDEO_DEV && PCI
+	---help---
+	  This is a video4linux driver for the Hexium HV-PCI6 and
+	  Orion frame grabber cards by Hexium.
+	  
+	  This driver is available as a module called hexium_orion
+	  ( = code which can be inserted in and removed from the
+	  running kernel whenever you want). If you want to compile
+	  it as a module, say M here and read <file:Documentation/modules.txt>.
+
+config VIDEO_HEXIUM_GEMINI
+	tristate "Hexium Gemini frame grabber"
+	depends on VIDEO_DEV && PCI
+	---help---
+	  This is a video4linux driver for the Hexium Gemini frame
+	  grabber card by Hexium. Please note that the Gemini Dual
+	  card is *not* fully supported.
+	  
+	  This driver is available as a module called hexium_gemini
+	  ( = code which can be inserted in and removed from the
+	  running kernel whenever you want). If you want to compile
+	  it as a module, say M here and read <file:Documentation/modules.txt>.
+
 endmenu
 
drivers/media/video/Makefile +2 -0
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/video/Makefile linux-2.6.0-test1.patch/drivers/media/video/Makefile
@@ -31,6 +31,8 @@
 obj-$(CONFIG_VIDEO_MEYE) += meye.o
 obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
 obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
+obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
+obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
 obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 
drivers/media/video/hexium.h +51 -0

51 lines not on this page · raw message

drivers/media/video/hexium_gemini.c +411 -0

411 lines not on this page · raw message

drivers/media/video/hexium_gemini.h +103 -0

103 lines not on this page · raw message

drivers/media/video/hexium_orion.c +328 -0

328 lines not on this page · raw message

drivers/media/video/hexium_orion.h +138 -0

138 lines not on this page · raw message

#12 lore raw

PATCH 13/17 More updates for the dvb core

drivers/media/dvb/dvb-core/dvb_demux.c +11 -3
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/dvb-core/dvb_demux.c linux-2.6.0-test1.patch/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -403,13 +404,16 @@
 {
 	int p = 0,i, j;
 	
+	spin_lock(&demux->lock);
+
 	if ((i = demux->tsbufp)) {
 		if (count < (j=188-i)) {
 			memcpy(&demux->tsbuf[i], buf, count);
 			demux->tsbufp += count;
-			return;
+			goto bailout;
 		}
 		memcpy(&demux->tsbuf[i], buf, j);
+		if (demux->tsbuf[0] == 0x47)
 		dvb_dmx_swfilter_packet(demux, demux->tsbuf);
 		demux->tsbufp = 0;
 		p += j;
@@ -424,11 +428,14 @@
 				i = count-p;
 				memcpy(demux->tsbuf, buf+p, i);
 				demux->tsbufp=i;
-				return;
+				goto bailout;
 			}
 		} else 
 			p++;
 	}
+
+bailout:
+	spin_unlock(&demux->lock);
 }
 
 
@@ -1030,9 +1051,11 @@
 
 	if (down_interruptible (&dvbdemux->mutex))
 		return -ERESTARTSYS;
-
 	dvb_dmx_swfilter(dvbdemux, buf, count);
 	up(&dvbdemux->mutex);
+
+	if (signal_pending(current))
+		return -EINTR;
 	return count;
 }
 
drivers/media/dvb/dvb-core/dvb_net.c +25 -12
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/dvb-core/dvb_net.c linux-2.6.0-test1.patch/drivers/media/dvb/dvb-core/dvb_net.c
@@ -57,7 +57,8 @@
 #define RX_MODE_MULTI 1
 #define RX_MODE_ALL_MULTI 2
 #define RX_MODE_PROMISC 3
-	struct work_struct wq;
+	struct work_struct set_multicast_list_wq;
+	struct work_struct restart_net_feed_wq;
 };
 
 
@@ -354,7 +361,7 @@
 }
 
 
-static void tq_set_multicast_list (void *data)
+static void wq_set_multicast_list (void *data)
 {
 	struct net_device *dev = data;
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
@@ -393,7 +400,7 @@
 static void dvb_net_set_multicast_list (struct net_device *dev)
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
-	schedule_work(&priv->wq);
+	schedule_work(&priv->set_multicast_list_wq);
 }
 
 
@@ -404,16 +411,28 @@
 	return 0;
 }
 
-static int dvb_net_set_mac(struct net_device *dev, void *p)
-{
-	struct sockaddr *addr=p;
 
-	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+static void wq_restart_net_feed (void *data)
+{
+	struct net_device *dev = data;
 
 	if (netif_running(dev)) {
 		dvb_net_feed_stop(dev);
 		dvb_net_feed_start(dev);
 	}
+}
+
+
+static int dvb_net_set_mac (struct net_device *dev, void *p)
+{
+	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+	struct sockaddr *addr=p;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	if (netif_running(dev))
+		schedule_work(&priv->restart_net_feed_wq);
+
 	return 0;
 }
 
@@ -493,10 +514,8 @@
 	net=&dvbnet->device[if_num];
 	demux=dvbnet->demux;
 	
-	net->base_addr = 0;
-	net->irq       = 0;
-	net->dma       = 0;
-	net->mem_start = 0;
+	memset(net, 0, sizeof(struct net_device));
+
         memcpy(net->name, "dvb0_0", 7);
 	net->name[3]   = dvbnet->dvbdev->adapter->num + '0';
 	net->name[5]   = if_num + '0';
@@ -514,7 +533,8 @@
         priv->pid = pid;
 	priv->rx_mode = RX_MODE_UNI;
 
-	INIT_WORK(&priv->wq, tq_set_multicast_list, net);
+	INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
+	INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
 
         net->base_addr = pid;
                 
@@ -536,6 +556,7 @@
 		return -EBUSY;
 
 	dvb_net_stop(&dvbnet->device[num]);
+	flush_scheduled_work();
 	kfree(priv);
         unregister_netdev(&dvbnet->device[num]);
 	dvbnet->state[num]=0;
#13 lore raw

PATCH 14/17 Add TDA14500x DVB-T frontend driver

[DVB] - tda1004x DVB-T driver contributed by Andrew de Quincy and Robert Schlalach

drivers/media/dvb/frontends/Kconfig +20 -0
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/frontends/Kconfig linux-2.6.0-test1.patch/drivers/media/dvb/frontends/Kconfig
@@ -115,3 +115,23 @@
 	  DVB adapter simply enable all supported frontends, the 
 	  right one will get autodetected.
 
+config DVB_TDA1004X
+	tristate "Frontends with external TDA1004X demodulators (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.
+
+config DVB_TDA1004X_FIRMWARE_FILE
+        string "Full pathname of tda1004x.bin firmware file"
+        depends on DVB_TDA1004X
+        default "/etc/dvb/tda1004x.bin"
+        help
+          The TDA1004X requires additional firmware in order to function.
+          The firmware file can obtained as follows:
+            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 /etc/dvb/tda1004x.bin
drivers/media/dvb/frontends/Makefile +2 -1
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/frontends/Makefile linux-2.6.0-test1.patch/drivers/media/dvb/frontends/Makefile
@@ -12,5 +12,6 @@
 obj-$(CONFIG_DVB_CX24110) += cx24110.o
 obj-$(CONFIG_DVB_GRUNDIG_29504_491) += grundig_29504-491.o
 obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o
-obj-$(CONFIG_DVB_MT312) += mt312.o
+obi-$(CONFIG_DVB_MT312) += mt312.o
 obj-$(CONFIG_DVB_VES1820) += ves1820.o
+obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
drivers/media/dvb/frontends/tda1004x.c +1158 -0

1,158 lines not on this page · raw message

#14 lore raw

PATCH 15/17 Update various other frontend drivers

[DVB] - In alps_tdlb7.c read SP8870 status reg to clear pending irqs in FE_SET_FRONTEND, as suggested by Ragnar Sundblad to avoid frontend hang-ups. [DVB] - the vp310 support in mt312.c support should be configured to 90Mhz, too. skystar2 driver with bugfixed master_xfer() should probably work now.

drivers/media/dvb/frontends/alps_tdlb7.c +3 -0
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/frontends/alps_tdlb7.c linux-2.6.0-test1.patch/drivers/media/dvb/frontends/alps_tdlb7.c
@@ -349,6 +349,9 @@
 
 		sp5659_set_tv_freq (i2c, p->frequency);
 
+		// read status reg in order to clear pending irqs
+		sp8870_readreg(i2c, 0x200);
+
 		// sample rate correction bit [23..17]
 		sp8870_writereg(i2c,0x0319,0x000A);
 		
drivers/media/dvb/frontends/mt312.c +44 -9

112 lines not on this page · raw message

#15 lore raw

PATCH 16/17 Update the av7110 DVB driver

[DVB] - fix DMX_GET_STC to get the msb right
[DVB] - follow changes in saa7146 driver core, separate some data for DVB-C and DVB-S cards

drivers/media/dvb/ttpci/av7110.c +31 -5
diff -uNrwB --new-file linux-2.6.0-test1.work/drivers/media/dvb/ttpci/av7110.c linux-2.6.0-test1.patch/drivers/media/dvb/ttpci/av7110.c
@@ -3257,7 +3258,7 @@
 	DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n",
 			fwstc[0], fwstc[1], fwstc[2], fwstc[3]));
 
-	*stc =  (((uint64_t)fwstc[2] & 1) << 32) |
+	*stc =  (((uint64_t)(~fwstc[2]) & 1) << 32) |
 		(((uint64_t)fwstc[1])     << 16) | ((uint64_t)fwstc[0]);
 	*base = 1;
 
@@ -4327,6 +4328,9 @@
 	{ 0, 0 }
 };
 
+static struct saa7146_ext_vv av7110_vv_data_st;
+static struct saa7146_ext_vv av7110_vv_data_c;
+
 static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
 {
 	struct av7110 *av7110 = NULL;
@@ -4344,7 +4348,16 @@
 
 	DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
 
-	if (saa7146_vv_init(dev)) {
+	/* special case DVB-C: these cards have an analog tuner
+	   plus need some special handling, so we have separate
+	   saa7146_ext_vv data for these... */
+	if (dev->pci->subsystem_vendor == 0x110a) {
+		ret = saa7146_vv_init(dev, &av7110_vv_data_c);
+	} else {
+		ret = saa7146_vv_init(dev, &av7110_vv_data_st);
+	}
+	
+	if ( 0 != ret) {
 		ERR(("cannot init capture device. skipping.\n"));
 		kfree(av7110);
 		return -1;
@@ -4689,10 +4702,10 @@
 }
 
 
-static struct saa7146_ext_vv av7110_vv_data = {
+static struct saa7146_ext_vv av7110_vv_data_st = {
 	.inputs		= 1,
 	.audios 	= 1,
-	.capabilities	= V4L2_CAP_TUNER,
+	.capabilities	= 0,
 	.flags		= SAA7146_EXT_SWAP_ODD_EVEN,
 
 	.stds		= &standard[0],
@@ -4703,9 +4716,23 @@
 	.ioctl		= av7110_ioctl,
 };
 
+static struct saa7146_ext_vv av7110_vv_data_c = {
+	.inputs		= 1,
+	.audios 	= 1,
+	.capabilities	= V4L2_CAP_TUNER,
+	.flags		= 0,
+
+	.stds		= &standard[0],
+	.num_stds	= sizeof(standard)/sizeof(struct saa7146_standard),
+	.std_callback	= &std_callback, 
+
+	.ioctls		= &ioctls[0],
+	.ioctl		= av7110_ioctl,
+};
+
+
 static struct saa7146_extension av7110_extension = {
 	.name		= "dvb\0",
-	.ext_vv_data	= &av7110_vv_data,
 
 	.module		= THIS_MODULE,
 	.pci_tbl	= &pci_tbl[0],
#16 lore raw

Re: [PATCH 11/17] Add a driver for the Technisat Skystar2 DVB card

In reply to Michael Hunold (LinuxTV.org CVS maintainer)

drivers/media/dvb/b2c2/skystar2.c line 117

Quoted 6 lines · Michael Hunold
drivers/media/dvb/b2c2/skystar2.c +6 -0
+
+/////////////////////////////////////////////////////////////////////
+//              register functions
+/////////////////////////////////////////////////////////////////////
+
+void WriteRegDW(struct adapter *adapter, u32 reg, u32 value)

Hm, this really isn't the proper Linux coding style. Please read Documentation/CodingStyle on how to name functions.

Review

Quoted 2 lines
(quoted diff) +2 -0
+{
+	u32 flags;

flags has to be a unsigned long.

drivers/media/dvb/b2c2/skystar2.c line 122

Quoted 3 lines
drivers/media/dvb/b2c2/skystar2.c +3 -0
+
+	save_flags(flags);
+	cli();

Huh? Did you even compile this on a SMP kernel on 2.5? (Hint, it will not...) Please fix this up.

drivers/media/dvb/b2c2/skystar2.c line 132

Quoted 4 lines
drivers/media/dvb/b2c2/skystar2.c +4 -0
+u32 ReadRegDW(struct adapter *adapter, u32 reg)
+{
+	return readl(adapter->io_mem + reg);
+}

Why? Why not just write the readl() function whereever you call ReadRegDW?

drivers/media/dvb/b2c2/skystar2.c line 156

Quoted 5 lines
drivers/media/dvb/b2c2/skystar2.c +5 -0
+/////////////////////////////////////////////////////////////////////
+//                      I2C
+////////////////////////////////////////////////////////////////////
+
+u32 i2cMainWriteForFlex2(struct adapter * adapter, u32 command, u8 * buf, u32 retries)

kernel functions traditionally return an int. A negative number if there is an error, and 0 if there isn't.

Oh, any reason for not tying this to the existing i2c core? Or is that done somewhere else?

thanks,

greg k-h

#17 lore raw

Re: [PATCH 11/17] Add a driver for the Technisat Skystar2 DVB card

Hello Greg KH,

thanks for reviewing these patches.

Quoted 10 lines

drivers/media/dvb/b2c2/skystar2.c line 117

Quoted 6 lines
drivers/media/dvb/b2c2/skystar2.c +6 -0
+
+/////////////////////////////////////////////////////////////////////
+//              register functions
+/////////////////////////////////////////////////////////////////////
+
+void WriteRegDW(struct adapter *adapter, u32 reg, u32 value)

Hm, this really isn't the proper Linux coding style. Please read Documentation/CodingStyle on how to name functions.

Yes, I know. The code was imported from an external source, and the code was kept mostly unchanged to keep syncing easier.

But with all the problems you mentioned, I'm now going to review the code. I'll send an updated patch later.

Quoted 5 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+{
+	u32 flags;

flags has to be a unsigned long.

Yes.

Quoted 9 lines

drivers/media/dvb/b2c2/skystar2.c line 122

Quoted 5 lines
drivers/media/dvb/b2c2/skystar2.c +3 -0
+
+	save_flags(flags);
+	cli();

Huh? Did you even compile this on a SMP kernel on 2.5? (Hint, it will not...) Please fix this up.

OMG. I'm sorry for having submitted something like this. It was not tested by me, no. I'll fix it and test compiling for SMP.

Quoted 10 lines

drivers/media/dvb/b2c2/skystar2.c line 132

Quoted 6 lines
drivers/media/dvb/b2c2/skystar2.c +4 -0
+u32 ReadRegDW(struct adapter *adapter, u32 reg)
+{
+	return readl(adapter->io_mem + reg);
+}

Why? Why not just write the readl() function whereever you call ReadRegDW?

I don't want to defend the original author, but perhaps these functions were copy&pasted from a Windoze driver.

Quoted 9 lines

drivers/media/dvb/b2c2/skystar2.c line 156

Quoted 5 lines
drivers/media/dvb/b2c2/skystar2.c +5 -0
+/////////////////////////////////////////////////////////////////////
+//                      I2C
+////////////////////////////////////////////////////////////////////
+
+u32 i2cMainWriteForFlex2(struct adapter * adapter, u32 command, u8 * buf, u32 retries)

kernel functions traditionally return an int. A negative number if there is an error, and 0 if there isn't.

I'll review it.

Quoted 2 lines

Oh, any reason for not tying this to the existing i2c core? Or is that done somewhere else?

No. I2C is used by all devices at least to access the different chipsets that make up the tuning.

In former times, the project had a hard time getting tuning to work in a reliable way, because some of these chipsets are particularly picky when it comes to timing and expect messages in a fixed form. Especially probing of other i2c devices was a problem, which locked up the i2c bus often.

I know that an class field for i2c adapters exists now and that i2c clients can check if they want to probe that bus at all now.

The DVB core is quite self contained and we decided to copy the i2c functionality needed for our purposes. So we ended up in using about 100 lines of code instead of the whole i2c core.

Now that you have finished improving the i2c core, perhaps we can switch back to the kernel i2c system at a later time.

Quoted 3 lines

thanks,

greg k-h

CU
Michael.

#18 lore raw

Re: [PATCH 11/17] Add a driver for the Technisat Skystar2 DVB card

Quoted 7 lines · Michael Hunold

The DVB core is quite self contained and we decided to copy the i2c functionality needed for our purposes. So we ended up in using about 100 lines of code instead of the whole i2c core.

Now that you have finished improving the i2c core, perhaps we can switch back to the kernel i2c system at a later time.

Please, that would help reduce the number of times the i2c code has been copied around :)

thanks,

greg k-h