summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r--linux/drivers/media/dvb/Kconfig3
-rw-r--r--linux/drivers/media/dvb/Makefile2
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/Kconfig (renamed from linux/drivers/media/dvb/av7110/Kconfig)7
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/Makefile9
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/budget.c739
-rw-r--r--linux/drivers/media/dvb/ttpci/Kconfig9
-rw-r--r--linux/drivers/media/dvb/ttpci/Makefile (renamed from linux/drivers/media/dvb/av7110/Makefile)0
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c (renamed from linux/drivers/media/dvb/av7110/av7110.c)478
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.h (renamed from linux/drivers/media/dvb/av7110/av7110.h)46
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_firm.h (renamed from linux/drivers/media/dvb/av7110/av7110_firm.h)0
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_ipack.c (renamed from linux/drivers/media/dvb/av7110/av7110_ipack.c)0
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_ipack.h (renamed from linux/drivers/media/dvb/av7110/av7110_ipack.h)0
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_ir.c (renamed from linux/drivers/media/dvb/av7110/av7110_ir.c)0
13 files changed, 852 insertions, 441 deletions
diff --git a/linux/drivers/media/dvb/Kconfig b/linux/drivers/media/dvb/Kconfig
index 5aba59f9e..edbec1c88 100644
--- a/linux/drivers/media/dvb/Kconfig
+++ b/linux/drivers/media/dvb/Kconfig
@@ -35,7 +35,8 @@ source "drivers/media/dvb/frontends/Kconfig"
comment "Supported DVB Adapters"
depends on DVB
-source "drivers/media/dvb/av7110/Kconfig"
+source "drivers/media/dvb/ttpci/Kconfig"
+source "drivers/media/dvb/ttpci-budget/Kconfig"
endmenu
diff --git a/linux/drivers/media/dvb/Makefile b/linux/drivers/media/dvb/Makefile
index 3290afb80..d23a404bf 100644
--- a/linux/drivers/media/dvb/Makefile
+++ b/linux/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y := dvb-core/ frontends/ av7110/
+obj-y := dvb-core/ frontends/ ttpci/ ttpci-budget/
diff --git a/linux/drivers/media/dvb/av7110/Kconfig b/linux/drivers/media/dvb/ttpci-budget/Kconfig
index 93270f079..3c4d43d41 100644
--- a/linux/drivers/media/dvb/av7110/Kconfig
+++ b/linux/drivers/media/dvb/ttpci-budget/Kconfig
@@ -1,13 +1,12 @@
config DVB_AV7110
- tristate "SAA7146 based AV7110 and Nova/Budget PCI cards"
+ tristate "SAA7146 based AV7110 PCI cards"
depends on VIDEO_DEV && DVB_CORE
help
Support for SAA7146 and AV7110 based DVB cards as produced
by Fujitsu-Siemens, Technotrend, Hauppauge and others.
- Simple cards like so called Budget- or Nova-PCI cards are
- supported as well as fullfeatured cards with onboard MPEG2
- decoder.
+ This driver only supports the fullfeatured cards with
+ onboard MPEG2 decoder.
Say Y if you own such a card and want to use it.
diff --git a/linux/drivers/media/dvb/ttpci-budget/Makefile b/linux/drivers/media/dvb/ttpci-budget/Makefile
new file mode 100644
index 000000000..11c671d1b
--- /dev/null
+++ b/linux/drivers/media/dvb/ttpci-budget/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the kernel AV7110 DVB device driver
+#
+
+dvb-ttpci-budget-objs := budget.o
+
+obj-$(CONFIG_DVB_BUDGET) += dvb-ttpci-budget.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -I$(src)/../../common/ -I$(src)/../../common/saa7146
diff --git a/linux/drivers/media/dvb/ttpci-budget/budget.c b/linux/drivers/media/dvb/ttpci-budget/budget.c
new file mode 100644
index 000000000..b50b1d4ad
--- /dev/null
+++ b/linux/drivers/media/dvb/ttpci-budget/budget.c
@@ -0,0 +1,739 @@
+/*
+ * budget.c: driver for the SAA7146 based Nova/Budget DVB cards
+ *
+ * Copyright (C) 1999-2002 Ralph Metzler
+ * & Marcus Metzler for convergence integrated media GmbH
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/dvb/
+ */
+
+#include "dvb_i2c.h"
+#include "dvb_frontend.h"
+#include "dvbdev.h"
+#include "demux.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_filter.h"
+#include "dvb_net.h"
+
+#include "saa7146.h"
+
+static int budget_debug = 0;
+#if 1
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+ #define KBUILD_MODNAME budget
+#endif
+#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__)
+#define DEB_S(x) if (0!=(budget_debug&0x01)) { DEBUG_PROLOG; printk x; } /* simple debug messages */
+#define DEB_D(x) if (0!=(budget_debug&0x02)) { DEBUG_PROLOG; printk x; } /* more detailed debug messages */
+#define DEB_EE(x) if (0!=(budget_debug&0x04)) { DEBUG_PROLOG; printk x; } /* print enter and exit of functions */
+#else
+#define DEB_S(x)
+#define DEB_D(x)
+#define DEB_EE(x)
+#endif
+
+int budget_num = 0;
+
+/* place to store all the necessary device information */
+typedef struct budget_s {
+
+ /* devices */
+ struct dvb_device dvb_dev;
+ dvb_net_t dvb_net;
+
+ struct saa7146_dev *dev;
+
+ struct dvb_i2c_bus *i2c_bus;
+ struct card_info *card_type;
+
+ unsigned char *grabbing;
+ struct saa7146_pgtable pt;
+
+ struct tasklet_struct fidb_tasklet;
+
+ dmxdev_t dmxdev;
+ struct dvb_demux demux;
+ char demux_id[16];
+
+ dmx_frontend_t hw_frontend;
+ dmx_frontend_t mem_frontend;
+
+ int fe_synced;
+ struct semaphore pid_mutex;
+
+ int tsf;
+ u32 ttbp;
+ int feeding;
+
+ int registered;
+
+ struct dvb_adapter *dvb_adapter;
+} budget_t;
+
+/****************************************************************************
+ * General helper functions
+ ****************************************************************************/
+
+/* this is videobuf_vmalloc_to_sg() from video-buf.c */
+struct scatterlist*
+vmalloc_to_sg(unsigned char *virt, int nr_pages)
+{
+ struct scatterlist *sglist;
+ struct page *pg;
+ int i;
+
+ sglist = kmalloc(sizeof(struct scatterlist)*nr_pages, GFP_KERNEL);
+ if (NULL == sglist)
+ return NULL;
+ memset(sglist,0,sizeof(struct scatterlist)*nr_pages);
+ for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
+ pg = vmalloc_to_page(virt);
+ if (NULL == pg)
+ goto err;
+ if (PageHighMem(pg))
+ BUG();
+ sglist[i].page = pg;
+ sglist[i].length = PAGE_SIZE;
+ }
+ return sglist;
+
+ err:
+ kfree(sglist);
+ return NULL;
+}
+
+
+static inline void ddelay(int i)
+{
+ current->state=TASK_INTERRUPTIBLE;
+ schedule_timeout((HZ*i)/100);
+}
+
+/****************************************************************************
+ * TT budget / WinTV Nova
+ ****************************************************************************/
+
+static int
+TTBStop(budget_t *budget)
+{
+ DEB_EE(("budget: %p\n",budget));
+
+ if (--budget->feeding)
+ return budget->feeding;
+
+ saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off
+ IER_DISABLE(budget->dev, MASK_07);
+ return 0;
+}
+
+#define TS_WIDTH (4*188)
+#define TS_HEIGHT (1024/4)
+#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
+
+static int
+TTBStart(budget_t *budget)
+{
+ struct saa7146_dev *dev=budget->dev;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if (budget->feeding)
+ return ++budget->feeding;
+
+ saa7146_write(dev, MC1, MASK_20); // DMA3 off
+
+ memset(budget->grabbing, 0x00, TS_HEIGHT*TS_WIDTH);
+
+ saa7146_write(dev, PCI_BT_V1, 0x001c0000);
+
+ budget->tsf=0;
+ budget->ttbp=0;
+ saa7146_write(dev, DD1_INIT, 0x02000680);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+ saa7146_write(dev, BRS_CTRL, 0x60000000);
+ saa7146_write(dev, MC2, (MASK_08 | MASK_24));
+ mdelay(10);
+
+ saa7146_write(dev, BASE_ODD3, 0);
+ saa7146_write(dev, BASE_EVEN3, TS_WIDTH*TS_HEIGHT/2);
+ saa7146_write(dev, PROT_ADDR3, TS_WIDTH*TS_HEIGHT);
+ saa7146_write(dev, BASE_PAGE3, budget->pt.dma |ME1|0xb0);
+ saa7146_write(dev, PITCH3, TS_WIDTH);
+
+ saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT/2)<<16)|TS_WIDTH);
+ saa7146_write(dev, MC2, (MASK_04 | MASK_20));
+
+ saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on
+
+ // FIDB
+ IER_ENABLE(budget->dev, MASK_07);
+
+ return ++budget->feeding;
+}
+
+static
+void fidbirq (unsigned long data)
+{
+ struct budget_s *budget = (struct budget_s*) data;
+ u8 *mem=(u8 *)(budget->grabbing);
+ int num;
+ u32 dmapos;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ dmapos=saa7146_read(budget->dev, PCI_VDP3);
+ dmapos-=(dmapos%188);
+
+ if (dmapos>=TS_BUFLEN) {
+ DEB_S(("bogus dmapos value ignored, budget: %p\n",budget));
+ return;
+ }
+
+ if (budget->tsf) {
+ mem+=budget->ttbp;
+ if (dmapos<0x20000) {
+ num=1024-budget->ttbp/188;
+ budget->ttbp=0;
+ } else {
+ num=(dmapos - budget->ttbp)/188;
+ budget->ttbp=dmapos;
+ }
+ } else {
+ if (budget->ttbp>1000*188 && budget->ttbp<1024*188) {
+ if (budget->feeding)
+ dvb_dmx_swfilter_packets(&budget->demux,
+ mem+budget->ttbp,
+ 1024- budget->ttbp / 188);
+ }
+ num=dmapos/188;
+ budget->ttbp=dmapos;
+ }
+
+ budget->tsf^=1;
+ saa7146_write(budget->dev, DD1_INIT, 0x02000600|(budget->tsf ? 0x40:0x80));
+ saa7146_write(budget->dev, MC2,
+ (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+
+ // FIXME: use bottom half or tasklet
+ if (budget->feeding && mem[0]==0x47)
+ dvb_dmx_swfilter_packets(&budget->demux, mem, num);
+}
+
+inline static void
+Set22K(budget_t *budget, int state)
+{
+ struct saa7146_dev *dev=budget->dev;
+ DEB_EE(("budget: %p\n",budget));
+ saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
+}
+
+
+/* Diseqc functions only for TT Budget card */
+/* taken from the Skyvision DVB driver by
+ Ralph Metzler <rjkm@metzlerbros.de> */
+
+inline static void
+DiseqcSendBit(budget_t *budget, int data)
+{
+ struct saa7146_dev *dev=budget->dev;
+ DEB_EE(("budget: %p\n",budget));
+
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+ udelay(data ? 500 : 1000);
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ udelay(data ? 1000 : 500);
+}
+
+static void
+DiseqcSendByte(budget_t *budget, int data)
+{
+ struct saa7146_dev *dev=budget->dev;
+ int i, par=1, d;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ for (i=7; i>=0; i--)
+ {
+ d=(data>>i)&1;
+ par^=d;
+ DiseqcSendBit(budget, d);
+ }
+ DiseqcSendBit(budget, par);
+}
+
+inline static int
+SendDiSEqCMsg(budget_t *budget, int len, u8 *msg, int burst)
+{
+ struct saa7146_dev *dev=budget->dev;
+ int i;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ mdelay(16);
+
+ for (i=0; i<len; i++)
+ DiseqcSendByte(budget, msg[i]);
+
+ mdelay(16);
+
+ if (burst!=-1) {
+ if (burst)
+ DiseqcSendByte(budget, 0xff);
+ else {
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+ udelay(12500);
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ }
+ ddelay(2);
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * DVB API SECTION
+ ****************************************************************************/
+
+static int
+budget_start_feed(struct dvb_demux_feed *feed)
+{
+ struct dvb_demux *demux = feed->demux;
+ budget_t *budget = (budget_t *) demux->priv;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if (!demux->dmx.frontend)
+ return -EINVAL;
+
+ return TTBStart(budget);
+}
+
+static int
+budget_stop_feed(struct dvb_demux_feed *feed)
+{
+ struct dvb_demux *demux = feed->demux;
+ budget_t *budget = (budget_t *) demux->priv;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ return TTBStop(budget);
+}
+
+/******************************************************************************
+ * SEC device file operations
+ ******************************************************************************/
+
+static
+int budget_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
+{
+ budget_t *budget = fe->before_after_data;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ switch (cmd) {
+ case FE_SET_TONE:
+ switch ((fe_sec_tone_mode_t) arg) {
+ case SEC_TONE_ON:
+ Set22K (budget, 1);
+ break;
+ case SEC_TONE_OFF:
+ Set22K (budget, 0);
+ break;
+ default:
+ return -EINVAL;
+ };
+ break;
+
+ case FE_DISEQC_SEND_MASTER_CMD:
+ {
+ struct dvb_diseqc_master_cmd *cmd = arg;
+
+ SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
+ break;
+ }
+
+ case FE_DISEQC_SEND_BURST:
+ SendDiSEqCMsg (budget, 0, NULL, (int) arg);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ };
+
+ return 0;
+}
+
+static
+int budget_register(budget_t *budget)
+{
+ int ret;
+ dmx_frontend_t *dvbfront=&budget->hw_frontend;
+ struct dvb_demux *dvbdemux=&budget->demux;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if (budget->registered)
+ return -1;
+
+ budget->registered=1;
+
+ /* init DiSEqC stuff */
+ dvb_add_frontend_ioctls (budget->dvb_adapter, budget_diseqc_ioctl, NULL, budget);
+
+ memcpy(budget->demux_id, "demux0_0", 9);
+ budget->demux_id[7]=budget->dvb_adapter->num+0x30;
+ dvbdemux->priv=(void *) budget;
+
+ dvbdemux->filternum=256;
+ dvbdemux->feednum=256;
+ dvbdemux->start_feed=budget_start_feed;
+ dvbdemux->stop_feed=budget_stop_feed;
+ dvbdemux->write_to_decoder=NULL;
+
+ dvbdemux->dmx.vendor="CIM";
+ dvbdemux->dmx.model="sw";
+ dvbdemux->dmx.id=budget->demux_id;
+ dvbdemux->dmx.capabilities=(DMX_TS_FILTERING|
+ DMX_SECTION_FILTERING|
+ DMX_MEMORY_BASED_FILTERING);
+
+ dvb_dmx_init(&budget->demux);
+
+ dvbfront->id="hw_frontend";
+ dvbfront->vendor="VLSI";
+ dvbfront->model="DVB Frontend";
+ dvbfront->source=DMX_FRONTEND_0;
+
+ budget->dmxdev.filternum=256;
+ budget->dmxdev.demux=&dvbdemux->dmx;
+ budget->dmxdev.capabilities=0;
+
+ dvb_dmxdev_init(&budget->dmxdev, budget->dvb_adapter);
+
+ ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
+ &budget->hw_frontend);
+ if (ret<0)
+ return ret;
+
+ budget->mem_frontend.id="mem_frontend";
+ budget->mem_frontend.vendor="memory";
+ budget->mem_frontend.model="sw";
+ budget->mem_frontend.source=DMX_MEMORY_FE;
+ ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
+ &budget->mem_frontend);
+ if (ret<0)
+ return ret;
+
+ ret=dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
+ &budget->hw_frontend);
+ 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;
+}
+
+
+static void
+dvb_unregister(budget_t *budget)
+{
+ struct dvb_demux *dvbdemux=&budget->demux;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if (!budget->registered)
+ return;
+
+ dvb_net_release(&budget->dvb_net);
+
+ dvbdemux->dmx.close(&dvbdemux->dmx);
+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend);
+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend);
+
+ dvb_dmxdev_release(&budget->dmxdev);
+ dvb_dmx_release(&budget->demux);
+ dvb_remove_frontend_ioctls (budget->dvb_adapter, budget_diseqc_ioctl, NULL);
+}
+
+static
+int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num)
+{
+ struct saa7146_dev *dev = i2c->data;
+ return saa7146_i2c_transfer(dev, msgs, num, 6);
+}
+
+/****************************************************************************
+ * INITIALIZATION
+ ****************************************************************************/
+
+int budget_preinit(struct saa7146_dev* dev)
+{
+ DEB_EE(("dev: %p\n",dev));
+ return 0;
+}
+
+struct card_info {
+ int type;
+ char *name;
+};
+
+#define DVB_CARD_TT_BUDGET 0
+#define DVB_CARD_TT_BUDGET_CI 1
+#define DVB_CARD_KNC1 2
+
+static struct card_info ttbs = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-S PCI" };
+static struct card_info ttbc = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-C PCI" };
+static struct card_info ttbt = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-T PCI" };
+static struct card_info ttbci = { DVB_CARD_TT_BUDGET_CI, "TT-Budget/WinTV-NOVA-CI PCI" };
+static struct card_info satel = { DVB_CARD_TT_BUDGET, "SATELCO Multimedia PCI"};
+static struct card_info knc1 = { DVB_CARD_KNC1, "KNC1 DVB-S" };
+
+static struct saa7146_sub_info sub_data[] = {
+ { 0x1131, 0x4f56 },
+ { 0x13c2, 0x1003 },
+ { 0x13c2, 0x1004 },
+ { 0x13c2, 0x1005 },
+ { 0x13c2, 0x100c },
+ { 0x13c2, 0x1013 },
+ { 0xffff, 0xffff },
+};
+
+struct card_match {
+ struct saa7146_sub_info *sub; /* Subsystem IDs or PCI_ANY_ID */
+ struct card_info *card;
+};
+
+static struct card_match match_data[] = {
+ { &sub_data[ 0], &knc1 },
+ { &sub_data[ 1], &ttbs },
+ { &sub_data[ 2], &ttbc },
+ { &sub_data[ 3], &ttbt },
+ { &sub_data[ 4], &ttbci },
+ { &sub_data[ 5], &satel },
+ { &sub_data[ 6], NULL },
+};
+
+
+int budget_probe(struct saa7146_dev* dev, unsigned int subvendor, unsigned int subdevice)
+{
+ budget_t *budget;
+ int i = 0;
+
+ DEB_EE(("dev: %p\n",dev));
+
+ for(i = 0;;i++) {
+ if( 0xffff == match_data[i].sub->subvendor ) {
+ printk(KERN_ERR "dvb: device subvendor:0x%04x, subdevice:0x%04x is not a known dvb card.\n",subvendor,subdevice);
+ return -ENODEV;
+ }
+ if( subvendor == match_data[i].sub->subvendor && subdevice == match_data[i].sub->subdevice ) {
+ break;
+ }
+ }
+
+ if (!(budget = kmalloc (sizeof (struct budget_s), GFP_KERNEL))) {
+ printk ("%s: out of memory!\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+ memset(budget, 0, sizeof(budget_t));
+ budget->card_type = match_data[i].card;
+
+ (budget_t*)dev->ext_priv = budget;
+
+ return 0;
+}
+
+static
+int budget_attach (struct saa7146_dev* dev)
+{
+ budget_t *budget = (budget_t*)dev->ext_priv;
+ struct scatterlist *slist = NULL;
+ int slen = 0;
+ int length = TS_WIDTH*TS_HEIGHT;
+ int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
+ int ret = 0;
+
+ DEB_EE(("dev: %p, budget: %p\n",dev,budget));
+
+ budget->dev=(struct saa7146_dev *)dev;
+ dvb_register_adapter(&budget->dvb_adapter, budget->card_type->name);
+
+ saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_3200);
+ budget->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, budget->dvb_adapter, 0);
+
+ if (!budget->i2c_bus) {
+ dvb_unregister_adapter (budget->dvb_adapter);
+ return -ENOMEM;
+ }
+
+ budget->grabbing = vmalloc(length);
+ if (!budget->grabbing) {
+ printk(KERN_ERR "dvb: vmalloc() failed.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (!(slist = vmalloc_to_sg(budget->grabbing, pages))) {
+ printk(KERN_ERR "dvb: vmalloc_to_sg() failed.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (saa7146_pgtable_alloc(dev->pci, &budget->pt)) {
+ printk(KERN_ERR "dvb: saa7146_pgtable_alloc() failed.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ slen = pci_map_sg(dev->pci,slist,pages,PCI_DMA_FROMDEVICE);
+ saa7146_pgtable_build_single(dev->pci, &budget->pt, slist, slen);
+
+ saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
+ /* set dd1 stream a & b */
+ saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+ saa7146_write(dev, DD1_INIT, 0x02000000);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+ /* upload all */
+ saa7146_write(dev, MC2, 0x077c077c);
+ saa7146_write(dev, GPIO_CTRL, 0x000000);
+
+ tasklet_init (&budget->fidb_tasklet, fidbirq, (unsigned long) budget);
+
+ saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); /* frontend power on */
+
+ budget_register(budget);
+
+ printk(KERN_INFO "budget: found budget-%d.\n",budget_num);
+ budget_num++;
+ return 0;
+
+err:
+ if( NULL != budget->grabbing ) {
+ vfree(budget->grabbing);
+ }
+ if( NULL != slist ) {
+ kfree(slist);
+ }
+ dvb_unregister_i2c_bus (master_xfer,budget->i2c_bus->adapter, budget->i2c_bus->id);
+ dvb_unregister_adapter (budget->dvb_adapter);
+ return ret;
+}
+
+static
+int budget_detach (struct saa7146_dev* saa)
+{
+ budget_t *budget = (budget_t*)saa->ext_priv;
+ DEB_EE(("budget: %p\n",budget));
+
+ dvb_unregister(budget);
+ dvb_unregister_i2c_bus (master_xfer,budget->i2c_bus->adapter, budget->i2c_bus->id);
+ dvb_unregister_adapter (budget->dvb_adapter);
+
+ saa7146_pgtable_free(saa->pci, &budget->pt);
+ vfree(budget->grabbing);
+ kfree (budget);
+
+ saa->ext_priv = NULL;
+ budget_num--;
+
+ return 0;
+}
+
+
+static
+void budget_irq(struct saa7146_dev* dev, u32 *isr)
+{
+ budget_t *budget = (budget_t*)dev->ext_priv;
+
+ DEB_EE(("dev: %p, budget: %p\n",dev,budget));
+
+ if (*isr & MASK_07)
+ tasklet_schedule (&budget->fidb_tasklet);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+static
+void budget_inc_use(struct saa7146_dev* adap)
+{
+ MOD_INC_USE_COUNT;
+}
+
+static
+void budget_dec_use(struct saa7146_dev* adap)
+{
+ MOD_DEC_USE_COUNT;
+}
+#endif
+
+static
+struct saa7146_extension budget_extension = {
+ .name = "budget dvb\0",
+ .devices = &sub_data[0],
+ .module = THIS_MODULE,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+ .inc_use = budget_inc_use,
+ .dec_use = budget_dec_use,
+#endif
+ .preinit = budget_preinit,
+ .probe = budget_probe,
+ .attach = budget_attach,
+ .detach = budget_detach,
+
+ .irq_mask = MASK_07,
+ .irq_func = budget_irq,
+};
+
+
+static
+int __init budget_init(void)
+{
+ DEB_EE((".\n"));
+
+ if (saa7146_register_extension(&budget_extension))
+ return -ENODEV;
+
+ return 0;
+}
+
+
+static
+void __exit budget_exit(void)
+{
+ DEB_EE((".\n"));
+
+ if (saa7146_unregister_extension(&budget_extension))
+ printk(KERN_ERR "dvb: extension deregistration failed.\n");
+}
+
+module_init(budget_init);
+module_exit(budget_exit);
+
+MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards by "
+ "Siemens, Technotrend, Hauppauge");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(budget_debug,"i");
diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig
new file mode 100644
index 000000000..cf8fe5251
--- /dev/null
+++ b/linux/drivers/media/dvb/ttpci/Kconfig
@@ -0,0 +1,9 @@
+config DVB_BUDGET
+ tristate "SAA7146 based Nova/Budget PCI cards"
+ depends on VIDEO_DEV && DVB_CORE
+ help
+ Support for simple SAA7146 based DVB cards
+ (so called Budget- or Nova-PCI cards) without onboard
+ MPEG2 decoder.
+
+ Say Y if you own such a card and want to use it.
diff --git a/linux/drivers/media/dvb/av7110/Makefile b/linux/drivers/media/dvb/ttpci/Makefile
index 5a9fd0c0c..5a9fd0c0c 100644
--- a/linux/drivers/media/dvb/av7110/Makefile
+++ b/linux/drivers/media/dvb/ttpci/Makefile
diff --git a/linux/drivers/media/dvb/av7110/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c
index 77ccc15db..f196ec210 100644
--- a/linux/drivers/media/dvb/av7110/av7110.c
+++ b/linux/drivers/media/dvb/ttpci/av7110.c
@@ -1,6 +1,5 @@
/*
* av7110.c: driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
- * and Nova/Budget DVB cards
*
* Copyright (C) 1999-2002 Ralph Metzler
* & Marcus Metzler for convergence integrated media GmbH
@@ -121,21 +120,9 @@ static inline void ddelay(int i)
/****************************************************************************
- * GPIO and DEBI functions
+ * DEBI functions
****************************************************************************/
-inline static void
-setgpio(av7110_t *av7110, int port, u32 data)
-{
- struct saa7146_dev *dev = av7110->dev;
- u32 val = 0;
-
- val=saa7146_read(dev,GPIO_CTRL);
- val&=~(0xff << (8*(port)));
- val|=(data)<<(8*(port));
- saa7146_write(dev, GPIO_CTRL, val);
-}
-
/* This DEBI code is based on the Stradis driver
by Nathan Laredo <laredo@gnu.org> */
@@ -311,7 +298,7 @@ reset_arm(av7110_t *av7110)
{
DEB_EE(("av7110: %p\n",av7110));
- setgpio(av7110, RESET_LINE, GPIO_OUTLO);
+ saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
/* Disable DEBI and GPIO irq */
IER_DISABLE(av7110->dev, (MASK_19 | MASK_03));
@@ -320,7 +307,7 @@ reset_arm(av7110_t *av7110)
saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03));
mdelay(800);
- setgpio(av7110, RESET_LINE, GPIO_OUTHI);
+ saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
mdelay(800);
ARM_ResetMailBox(av7110);
@@ -703,84 +690,6 @@ ring_buffer_put(ring_buffer_t *db, u8 *buf, int len)
}
#endif
-
-/****************************************************************************
- * TT budget / WinTV Nova
- ****************************************************************************/
-
-static int
-TTBStop(av7110_t *av7110)
-{
- DEB_EE(("av7110: %p\n",av7110));
-
- if (--av7110->feeding)
- return av7110->feeding;
- saa7146_write(av7110->dev, MC1, MASK_20); // DMA3 off
-
-// saa7146_write(av7110->dev, MC1, MASK_28); // RPS0 off
-
- IER_DISABLE(av7110->dev, (MASK_07 | MASK_10));
-/*
- saa7146_write(av7110->dev, IER,
- saa7146_read(av7110->dev, IER) & ~MASK_10 );
- saa7146_write(av7110->dev, IER,
- saa7146_read(av7110->dev, IER)& ~MASK_07);
-*/
- return 0;
-}
-
-#define TS_WIDTH (4*188)
-#define TS_HEIGHT (1024/4)
-#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
-
-static int
-TTBStart(av7110_t *av7110)
-{
- struct saa7146_dev *dev=av7110->dev;
-
- DEB_EE(("av7110: %p\n",av7110));
-
- //printk ("function : %s\n", __FUNCTION__);
- if (av7110->feeding)
- return ++av7110->feeding;
-
- saa7146_write(dev, MC1, MASK_20); // DMA3 off
-
- memset(av7110->grabbing, 0x00, TS_HEIGHT*TS_WIDTH);
-
- saa7146_write(dev, PCI_BT_V1, 0x001c0000);
-
- av7110->tsf=0;
- av7110->ttbp=0;
- saa7146_write(dev, DD1_INIT, 0x02000680);
- saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- saa7146_write(dev, BRS_CTRL, 0x60000000);
- saa7146_write(dev, MC2, (MASK_08 | MASK_24));
- mdelay(10);
-
- saa7146_write(dev, BASE_ODD3, 0);
- saa7146_write(dev, BASE_EVEN3, TS_WIDTH*TS_HEIGHT/2);
- saa7146_write(dev, PROT_ADDR3, TS_WIDTH*TS_HEIGHT);
- saa7146_write(dev, BASE_PAGE3, av7110->pt.dma |ME1|0xb0);
- saa7146_write(dev, PITCH3, TS_WIDTH);
-
- saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT/2)<<16)|TS_WIDTH);
- saa7146_write(dev, MC2, (MASK_04 | MASK_20));
-
- // VPE
- IER_ENABLE(av7110->dev, MASK_10);
-// saa7146_write(dev, IER, saa7146_read(saa->mem, IER)|MASK_10);
-
- saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on
-
- // FIDB
- IER_ENABLE(av7110->dev, MASK_07);
-// saa7146_write(dev, IER, saa7146_read(saa->mem, IER)|MASK_07);
-
- return ++av7110->feeding;
-}
-
/**
* Hack! we save the last av7110 ptr. This should be ok, since
* you rarely will use more then one IR control.
@@ -928,86 +837,6 @@ u8 pshead[0x26] = {
};
-static void vpeirq (unsigned long data)
-{
- //printk("vpeirq %08x\n", saa7146_read(av7110->dev, PCI_VDP3));
-}
-
-#if 0
-static void fidbirq(struct saa7146_dev* saa, void *data)
-{
- av7110_t *av7110=(av7110_t *) data;
- u8 *mem;
-
- DEB_EE(("av7110: %p\n",av7110));
-
- mem=(av7110->tsf ? TS_HEIGHT*TS_WIDTH/2 :0)+(u8 *)av7110->grabbing;
-
- // FIXME: think of something better without busy waiting
- if (av7110->tsf)
- while (saa7146_read(av7110->dev, PCI_VDP3)>0x20000);
- else
- while (saa7146_read(av7110->dev, PCI_VDP3)<0x17800);
-
- av7110->tsf^=1;
- saa7146_write(av7110->dev, DD1_INIT, 0x02000600|(av7110->tsf ? 0x40:0x80));
- saa7146_write(av7110->dev, MC2,
- (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- // FIXME: use bottom half or tasklet
- if (av7110->feeding && mem[0]==0x47)
- dvb_dmx_swfilter_packets(&av7110->demux, mem, 512);
-}
-#else
-static
-void fidbirq (unsigned long data)
-{
- struct av7110_s *av7110 = (struct av7110_s*) data;
- u8 *mem=(u8 *)(av7110->grabbing);
- int num;
- u32 dmapos;
-
- DEB_EE(("av7110: %p\n",av7110));
-
- dmapos=saa7146_read(av7110->dev, PCI_VDP3);
- dmapos-=(dmapos%188);
-
- if (dmapos>=TS_BUFLEN) {
- DEB_S(("bogus dmapos value ignored, av7110: %p\n",av7110));
- return;
- }
-
- if (av7110->tsf) {
- mem+=av7110->ttbp;
- if (dmapos<0x20000) {
- num=1024-av7110->ttbp/188;
- av7110->ttbp=0;
- } else {
- num=(dmapos - av7110->ttbp)/188;
- av7110->ttbp=dmapos;
- }
- } else {
- if (av7110->ttbp>1000*188 && av7110->ttbp<1024*188) {
- if (av7110->feeding)
- dvb_dmx_swfilter_packets(&av7110->demux,
- mem+av7110->ttbp,
- 1024- av7110->ttbp / 188);
- }
- num=dmapos/188;
- av7110->ttbp=dmapos;
- }
-
- av7110->tsf^=1;
- saa7146_write(av7110->dev, DD1_INIT, 0x02000600|(av7110->tsf ? 0x40:0x80));
- saa7146_write(av7110->dev, MC2,
- (MASK_09 | MASK_25 | MASK_10 | MASK_26));
-
- // FIXME: use bottom half or tasklet
- if (av7110->feeding && mem[0]==0x47)
- dvb_dmx_swfilter_packets(&av7110->demux, mem, num);
-}
-#endif
-
//#define DEBUG_TIMING
inline static void
print_time(char *s)
@@ -2247,12 +2076,13 @@ bootcode[] = {
static int
bootarm(av7110_t *av7110)
{
+ struct saa7146_dev *dev= av7110->dev;
u32 ret;
int i;
DEB_EE(("av7110: %p\n",av7110));
- setgpio(av7110, RESET_LINE, GPIO_OUTLO);
+ saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
/* Disable DEBI and GPIO irq */
IER_DISABLE(av7110->dev, MASK_03|MASK_19);
@@ -2282,15 +2112,15 @@ bootarm(av7110_t *av7110)
/* boot */
DEB_D(("bootarm: load boot code\n"));
- setgpio(av7110, ARM_IRQ_LINE, GPIO_IRQLO);
- //setgpio(av7110, DEBI_DONE_LINE, GPIO_INPUT);
- //setgpio(av7110, 3, GPIO_INPUT);
+ saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
+ //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
+ //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
iwdebi(av7110, DEBISWAB, DPRAM_BASE, (u32) bootcode, sizeof(bootcode));
iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
wait_for_debi_done(av7110);
- setgpio(av7110, RESET_LINE, GPIO_OUTHI);
+ saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
current->state=TASK_INTERRUPTIBLE;
schedule_timeout(HZ);
@@ -2299,7 +2129,7 @@ bootarm(av7110_t *av7110)
if (load_dram(av7110, (u32 *)Root, sizeof(Root))<0)
return -1;
- setgpio(av7110, RESET_LINE, GPIO_OUTLO);
+ saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
mdelay(1);
DEB_D(("bootarm: load dpram code\n"));
@@ -2308,7 +2138,7 @@ bootarm(av7110_t *av7110)
wait_for_debi_done(av7110);
- setgpio(av7110, RESET_LINE, GPIO_OUTHI);
+ saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
mdelay(800);
//ARM_ClearIrq(av7110);
@@ -2412,43 +2242,8 @@ inline static void
Set22K(av7110_t *av7110, int state)
{
DEB_EE(("av7110: %p\n",av7110));
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
outcom(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
- if (av7110->card_type->type==DVB_CARD_TT_BUDGET)
- setgpio(av7110, 3, (state ? GPIO_OUTHI : GPIO_OUTLO));
-}
-
-
-/* Diseqc functions only for TT Budget card */
-/* taken from the Skyvision DVB driver by
- Ralph Metzler <rjkm@metzlerbros.de> */
-
-
-inline static void
-DiseqcSendBit(av7110_t *av7110, int data)
-{
- DEB_EE(("av7110: %p\n",av7110));
-
- setgpio(av7110, 3, GPIO_OUTHI);
- udelay(data ? 500 : 1000);
- setgpio(av7110, 3, GPIO_OUTLO);
- udelay(data ? 1000 : 500);
-}
-
-static void
-DiseqcSendByte(av7110_t *av7110, int data)
-{
- int i, par=1, d;
-
- DEB_EE(("av7110: %p\n",av7110));
-
- for (i=7; i>=0; i--)
- {
- d=(data>>i)&1;
- par^=d;
- DiseqcSendBit(av7110, d);
- }
- DiseqcSendBit(av7110, par);
}
inline static int
@@ -2458,8 +2253,10 @@ SendDiSEqCMsg(av7110_t *av7110, int len, u8 *msg, int burst)
DEB_EE(("av7110: %p\n",av7110));
+/*
switch (av7110->card_type->type) {
case DVB_CARD_TT_SIEMENS:
+*/
{
u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -2479,35 +2276,12 @@ SendDiSEqCMsg(av7110_t *av7110, int len, u8 *msg, int burst)
buf[i+4]=msg[i];
SOutCommand(av7110, buf, 18);
+/*
break;
}
-
- case DVB_CARD_TT_BUDGET:
- setgpio(av7110, 3, GPIO_OUTLO);
-
- mdelay(16);
-
- for (i=0; i<len; i++)
- DiseqcSendByte(av7110, msg[i]);
-
- mdelay(16);
-
- if (burst!=-1) {
- if (burst)
- DiseqcSendByte(av7110, 0xff);
- else {
- setgpio(av7110, 3, GPIO_OUTHI);
- udelay(12500);
- setgpio(av7110, 3, GPIO_OUTLO);
- }
-
- ddelay(2);
- }
-
- break;
-
default:
return -1;
+*/
}
return 0;
}
@@ -3223,9 +2997,6 @@ av7110_start_feed(struct dvb_demux_feed *feed)
if (!demux->dmx.frontend)
return -EINVAL;
- if (av7110->card_type->type >= DVB_CARD_TT_BUDGET)
- return TTBStart(av7110);
-
if (feed->pid > 0x1fff)
return -EINVAL;
@@ -3282,9 +3053,6 @@ av7110_stop_feed(struct dvb_demux_feed *feed)
DEB_EE(("av7110: %p\n",av7110));
- if (av7110->card_type->type >= DVB_CARD_TT_BUDGET)
- return TTBStop(av7110);
-
if (feed->type == DMX_TYPE_TS) {
if (feed->ts_type & TS_DECODER) {
if (feed->pes_type >= DMX_TS_PES_OTHER ||
@@ -4221,14 +3989,13 @@ int av7110_register(av7110_t *av7110)
av7110->registered=1;
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
dvb_add_frontend_notifier (av7110->dvb_adapter,
av7110_before_after_tune, av7110);
/**
* init DiSEqC stuff
*/
- if (av7110->card_type->type==DVB_CARD_TT_BUDGET ||
- av7110->card_type->type==DVB_CARD_TT_SIEMENS)
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
dvb_add_frontend_ioctls (av7110->dvb_adapter,
av7110_diseqc_ioctl, NULL, av7110);
@@ -4250,7 +4017,7 @@ int av7110_register(av7110_t *av7110)
av7110->demux_id[7]=av7110->dvb_adapter->num+0x30;
dvbdemux->priv=(void *) av7110;
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
for (i=0; i<32; i++)
av7110->handle2filter[i]=NULL;
@@ -4280,35 +4047,7 @@ int av7110_register(av7110_t *av7110)
av7110->dmxdev.capabilities=0;
dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
- }
-
- if (av7110->card_type->type>=DVB_CARD_TT_BUDGET) {
- dvbdemux->filternum=256;
- dvbdemux->feednum=256;
- dvbdemux->start_feed=av7110_start_feed;
- dvbdemux->stop_feed=av7110_stop_feed;
- dvbdemux->write_to_decoder=NULL;
-
- dvbdemux->dmx.vendor="CIM";
- dvbdemux->dmx.model="sw";
- dvbdemux->dmx.id=av7110->demux_id;
- dvbdemux->dmx.capabilities=(DMX_TS_FILTERING|
- DMX_SECTION_FILTERING|
- DMX_MEMORY_BASED_FILTERING);
-
- dvb_dmx_init(&av7110->demux);
-
- dvbfront->id="hw_frontend";
- dvbfront->vendor="VLSI";
- dvbfront->model="DVB Frontend";
- dvbfront->source=DMX_FRONTEND_0;
-
- av7110->dmxdev.filternum=256;
- av7110->dmxdev.demux=&dvbdemux->dmx;
- av7110->dmxdev.capabilities=0;
-
- dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
- }
+// }
ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
&av7110->hw_frontend);
@@ -4329,7 +4068,7 @@ int av7110_register(av7110_t *av7110)
if (ret<0)
return ret;
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
dvb_register_device(av7110->dvb_adapter, &av7110->video_dev,
&dvbdev_video, av7110, DVB_DEVICE_VIDEO);
dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev,
@@ -4347,7 +4086,7 @@ int av7110_register(av7110_t *av7110)
dvb_audio_write,
av7110->audio_dev);
#endif
- }
+// }
av7110->dvb_net.card_num=av7110->dvb_adapter->num;
dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
@@ -4375,14 +4114,14 @@ dvb_unregister(av7110_t *av7110)
dvb_dmxdev_release(&av7110->dmxdev);
dvb_dmx_release(&av7110->demux);
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS)
dvb_remove_frontend_notifier (av7110->dvb_adapter,
av7110_before_after_tune);
dvb_remove_frontend_ioctls (av7110->dvb_adapter,
av7110_diseqc_ioctl, NULL);
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
dvb_unregister_device(av7110->audio_dev);
dvb_unregister_device(av7110->video_dev);
dvb_unregister_device(av7110->osd_dev);
@@ -4390,7 +4129,7 @@ dvb_unregister(av7110_t *av7110)
#ifdef USE_DVB_DSP
dvb_unregister_dsp(av7110->dsp_dev);
#endif
- }
+// }
}
static
@@ -4423,32 +4162,25 @@ int av7110_preinit(struct saa7146_dev* dev)
return 0;
}
-static struct card_info fs_1_5 = { DVB_CARD_TT_SIEMENS, "Siemens cable card PCI rev1.5" };
-static struct card_info fs_1_3 = { DVB_CARD_TT_SIEMENS, "Siemens/Technotrend/Hauppauge PCI rev1.3" };
-static struct card_info ttbs = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-S PCI" };
-static struct card_info ttbc = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-C PCI" };
-static struct card_info ttbt = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-T PCI" };
-static struct card_info ttbci = { DVB_CARD_TT_BUDGET_CI, "TT-Budget/WinTV-NOVA-CI PCI" };
-static struct card_info satel = { DVB_CARD_TT_BUDGET, "SATELCO Multimedia PCI"};
-static struct card_info unkwn = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev?(unknown0)?"};
-static struct card_info tt_1_6 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev1.3 or 1.6" };
-static struct card_info tt_2_1 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev2.1" };
-static struct card_info tt_t = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI DVB-T" };
-static struct card_info knc1 = { DVB_CARD_KNC1, "KNC1 DVB-S" };
+struct card_info {
+ char *name;
+};
+
+static char *fs_1_5 = { "Siemens cable card PCI rev1.5" };
+static char *fs_1_3 = { "Siemens/Technotrend/Hauppauge PCI rev1.3" };
+static char *unkwn = { "Technotrend/Hauppauge PCI rev?(unknown0)?"};
+static char *tt_1_6 = { "Technotrend/Hauppauge PCI rev1.3 or 1.6" };
+static char *tt_2_1 = { "Technotrend/Hauppauge PCI rev2.1" };
+static char *tt_t = { "Technotrend/Hauppauge PCI DVB-T" };
struct card_match {
- struct saa7146_sub_info *sub; /* Subsystem ID's or PCI_ANY_ID */
- struct card_info *card;
+ struct saa7146_sub_info *sub; /* Subsystem IDs or PCI_ANY_ID */
+ char **card;
};
static struct saa7146_sub_info sub_data[] = {
{ 0x110a, 0xffff },
{ 0x110a, 0x0000 },
- { 0x13c2, 0x1003 },
- { 0x13c2, 0x1004 },
- { 0x13c2, 0x1005 },
- { 0x13c2, 0x100c },
- { 0x13c2, 0x1013 },
{ 0x13c2, 0x0000 },
{ 0x13c2, 0x1002 },
{ 0x13c2, 0x0001 },
@@ -4458,29 +4190,22 @@ static struct saa7146_sub_info sub_data[] = {
{ 0x13c2, 0x0006 },
{ 0x13c2, 0x0008 },
{ 0xffc2, 0x0000 },
- { 0x1131, 0x4f56 },
{ 0xffff, 0xffff },
};
static struct card_match match_data[] = {
{ &sub_data[ 0], &fs_1_5 },
{ &sub_data[ 1], &fs_1_5 },
- { &sub_data[ 2], &ttbs },
- { &sub_data[ 3], &ttbc },
- { &sub_data[ 4], &ttbt },
- { &sub_data[ 5], &ttbci },
- { &sub_data[ 6], &satel },
- { &sub_data[ 7], &fs_1_3 },
- { &sub_data[ 8], &unkwn },
- { &sub_data[ 9], &tt_1_6 },
- { &sub_data[10], &tt_2_1 },
- { &sub_data[11], &tt_2_1 },
- { &sub_data[12], &tt_2_1 },
- { &sub_data[13], &tt_1_6 },
- { &sub_data[14], &tt_t },
- { &sub_data[15], &unkwn },
- { &sub_data[16], &knc1 },
- { &sub_data[17], NULL },
+ { &sub_data[ 2], &fs_1_3 },
+ { &sub_data[ 3], &unkwn },
+ { &sub_data[ 4], &tt_1_6 },
+ { &sub_data[ 5], &tt_2_1 },
+ { &sub_data[ 6], &tt_2_1 },
+ { &sub_data[ 7], &tt_2_1 },
+ { &sub_data[ 8], &tt_1_6 },
+ { &sub_data[ 9], &tt_t },
+ { &sub_data[10], &unkwn },
+ { &sub_data[11], NULL },
};
@@ -4506,7 +4231,7 @@ int av7110_probe(struct saa7146_dev* dev, unsigned int subvendor, unsigned int s
return -ENOMEM;
}
memset(av7110, 0, sizeof(av7110_t));
- av7110->card_type = match_data[i].card;
+ av7110->card_name = *match_data[i].card;
(av7110_t*)dev->ext_priv = av7110;
@@ -4517,56 +4242,33 @@ static
int av7110_attach (struct saa7146_dev* dev)
{
av7110_t *av7110 = (av7110_t*)dev->ext_priv;
- struct scatterlist *slist = NULL;
- int slen = 0;
- int length = TS_WIDTH*TS_HEIGHT;
- int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
int ret = 0;
DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
- saa7146_video_uops.init(dev);
+ if( 0 != saa7146_vv_init(dev)) {
+ ERR(("cannot init capture device. skipping.\n"));
+ return -1;
+ }
+
if( 0 != saa7146_register_device(&av7110->vd, dev, "av7710", VFL_TYPE_GRABBER)) {
ERR(("cannot register capture device. skipping.\n"));
+ saa7146_vv_release(dev);
return -1;
}
av7110->dev=(struct saa7146_dev *)dev;
- dvb_register_adapter(&av7110->dvb_adapter, av7110->card_type->name);
+ dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name);
saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_3200);
av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, av7110->dvb_adapter, 0);
if (!av7110->i2c_bus) {
+ saa7146_unregister_device(&av7110->vd, dev);
+ saa7146_vv_release(dev);
dvb_unregister_adapter (av7110->dvb_adapter);
return -ENOMEM;
}
-
-// fixme if (av7110->card_type->type >= DVB_CARD_TT_BUDGET)
- av7110->grabbing = vmalloc(length);
- if (!av7110->grabbing) {
- printk(KERN_ERR "dvb: vmalloc() failed.\n");
- ret = -ENOMEM;
- goto err;
- }
-
- if (!(slist = videobuf_vmalloc_to_sg(av7110->grabbing, pages))) {
- printk(KERN_ERR "dvb: videobuf_vmalloc_to_sg() failed.\n");
- ret = -ENOMEM;
- goto err;
- }
-
- if (saa7146_pgtable_alloc(dev->pci, &av7110->pt)) {
- printk(KERN_ERR "dvb: saa7146_pgtable_alloc() failed.\n");
- ret = -ENOMEM;
- goto err;
- }
-
- slen = pci_map_sg(dev->pci,slist,pages,PCI_DMA_FROMDEVICE);
- saa7146_pgtable_build_single(dev->pci, &av7110->pt, slist, slen);
-
-// }
-
saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
saa7146_write(dev, BCS_CTRL, 0x80400040);
@@ -4581,8 +4283,6 @@ int av7110_attach (struct saa7146_dev* dev)
tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
- tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
- tasklet_init (&av7110->fidb_tasklet, fidbirq, (unsigned long) av7110);
sema_init(&av7110->pid_mutex, 1);
@@ -4640,23 +4340,18 @@ int av7110_attach (struct saa7146_dev* dev)
/* handle different card types */
/* load firmware into AV7110 cards */
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
bootarm(av7110);
firmversion(av7110);
if ((av7110->arm_app&0xffff)<0x2502) {
printk("av7110: Warning, firmware version is too old. System might be unstable!!!\n");
}
kernel_thread(arm_thread, (void *) av7110, 0);
- } else {
- saa7146_write(av7110->dev, DD1_INIT, 0x02000600);
- saa7146_write(av7110->dev, MC2,
- (MASK_09 | MASK_25 | MASK_10 | MASK_26));
- setgpio(av7110, 2, GPIO_OUTHI); /* frontend power on */
- }
+// }
SetVolume(av7110, 0xff, 0xff);
- if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
+// if (av7110->card_type->type==DVB_CARD_TT_SIEMENS) {
VidMode(av7110, vidmode);
/* remaining inits according to card and frontend type */
@@ -4693,11 +4388,11 @@ int av7110_attach (struct saa7146_dev* dev)
outcom(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
- //setgpio(av7110, 1, GPIO_OUTHI); // RGB on, SCART pin 16
- //setgpio(av7110, 3, GPIO_OUTLO); // SCARTpin 8
+ //saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
+ //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
av7110->adac_type = DVB_ADAC_NONE;
}
- }
+// }
av7110_setup_irc_config (av7110, 0);
av7110_register(av7110);
@@ -4707,12 +4402,9 @@ int av7110_attach (struct saa7146_dev* dev)
return 0;
err:
- if( NULL != av7110->grabbing ) {
- vfree(av7110->grabbing);
- }
- if( NULL != slist ) {
- kfree(slist);
- }
+ /* FIXME: error handling is totally bogus: memory does not get freed ... */
+ saa7146_unregister_device(&av7110->vd, dev);
+ saa7146_vv_release(dev);
dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter);
return ret;
@@ -4747,11 +4439,6 @@ int av7110_detach (struct saa7146_dev* saa)
pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
av7110->debi_bus);
-// fixme if (av7110->card_type->type >= DVB_CARD_TT_BUDGET)
- saa7146_pgtable_free(saa->pci, &av7110->pt);
- vfree(av7110->grabbing);
-// }
-
dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter);
@@ -4776,12 +4463,6 @@ void av7110_irq(struct saa7146_dev* dev, u32 *isr)
if (*isr & MASK_03)
tasklet_schedule (&av7110->gpio_tasklet);
-
- if (*isr & MASK_10)
- tasklet_schedule (&av7110->vpe_tasklet);
-
- if (*isr & MASK_07)
- tasklet_schedule (&av7110->fidb_tasklet);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
@@ -4809,35 +4490,38 @@ struct saa7146_standard standard[] = {
};
static
-struct saa7146_extension av7110_extension = {
- .name = "dvb\0",
+struct saa7146_ext_vv av7110_vv_data = {
.inputs = 1,
.audios = 1,
.capabilities = 0,
-
.flags = SAA7146_EXT_SWAP_ODD_EVEN,
+ .stds = &standard[0],
+ .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
+ .std_callback = NULL,
+
+ .ioctls = &ioctls[0],
+ .ioctl = av7110_ioctl,
+};
+
+static
+struct saa7146_extension av7110_extension = {
+ .name = "dvb\0",
+
.devices = &sub_data[0],
.module = THIS_MODULE,
-
+ .ext_vv_data = &av7110_vv_data,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
.inc_use = av7110_inc_use,
.dec_use = av7110_dec_use,
#endif
- .stds = &standard[0],
- .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
- .std_callback = NULL,
-
- .ioctls = &ioctls[0],
-
.preinit = av7110_preinit,
.probe = av7110_probe,
.attach = av7110_attach,
.detach = av7110_detach,
- .ioctl = av7110_ioctl,
- .irq_mask = MASK_07|MASK_10|MASK_19|MASK_03, // |MASK_27,
+ .irq_mask = MASK_19|MASK_03,
.irq_func = av7110_irq,
};
diff --git a/linux/drivers/media/dvb/av7110/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h
index a379a3fcd..d1eabe3ab 100644
--- a/linux/drivers/media/dvb/av7110/av7110.h
+++ b/linux/drivers/media/dvb/ttpci/av7110.h
@@ -11,7 +11,7 @@
#include <linux/devfs_fs_kernel.h>
#endif
-#include "saa7146.h"
+#include "saa7146_vv.h"
/* DEBI transfer mode defs */
@@ -39,11 +39,6 @@
#include "dvb_filter.h"
#include "dvb_net.h"
-#define DVB_CARD_TT_SIEMENS 0
-#define DVB_CARD_TT_BUDGET 1
-#define DVB_CARD_TT_BUDGET_CI 2
-#define DVB_CARD_KNC1 3
-
typedef enum BOOTSTATES
{
BOOTSTATE_BUFFER_EMPTY = 0,
@@ -51,16 +46,6 @@ typedef enum BOOTSTATES
BOOTSTATE_BOOT_COMPLETE = 2
} BOOTSTATES;
-typedef enum GPIO_MODE
-{
- GPIO_INPUT = 0x00,
- GPIO_IRQHI = 0x10,
- GPIO_IRQLO = 0x20,
- GPIO_IRQHL = 0x30,
- GPIO_OUTLO = 0x40,
- GPIO_OUTHI = 0x50
-} GPIO_MODE;
-
typedef enum
{ RP_None,
AudioPES,
@@ -111,14 +96,14 @@ typedef enum {
// switch defines
#define SB_GPIO 3
-#define SB_OFF GPIO_OUTLO //SlowBlank aus (TV-Mode)
-#define SB_ON GPIO_INPUT //SlowBlank an (AV-Mode)
-#define SB_WIDE GPIO_OUTHI //SlowBlank 6V (16/9-Mode) nicht realisiert
+#define SB_OFF SAA7146_GPIO_OUTLO //SlowBlank aus (TV-Mode)
+#define SB_ON SAA7146_GPIO_INPUT //SlowBlank an (AV-Mode)
+#define SB_WIDE SAA7146_GPIO_OUTHI //SlowBlank 6V (16/9-Mode) nicht realisiert
#define FB_GPIO 1
-#define FB_OFF GPIO_LO //FastBlank aus (CVBS-Mode)
-#define FB_ON GPIO_OUTHI //FastBlank an (RGB-Mode)
-#define FB_LOOP GPIO_INPUT //FastBlank der PC-Grafik durchschleifen
+#define FB_OFF SAA7146_GPIO_LO //FastBlank aus (CVBS-Mode)
+#define FB_ON SAA7146_GPIO_OUTHI //FastBlank an (RGB-Mode)
+#define FB_LOOP SAA7146_GPIO_INPUT //FastBlank der PC-Grafik durchschleifen
typedef enum VIDEOOUTPUTMODE
{
@@ -471,11 +456,6 @@ typedef struct p2t_s {
struct dvb_demux_feed *feed;
} p2t_t;
-struct card_info {
- int type;
- char *name;
-};
-
/* place to store all the necessary device information */
typedef struct av7110_s {
@@ -488,15 +468,10 @@ typedef struct av7110_s {
struct saa7146_dev *dev;
struct dvb_i2c_bus *i2c_bus;
- struct card_info *card_type;
-
- unsigned char *grabbing;
- struct saa7146_pgtable pt;
+ char *card_name;
struct tasklet_struct debi_tasklet;
struct tasklet_struct gpio_tasklet;
- struct tasklet_struct vpe_tasklet;
- struct tasklet_struct fidb_tasklet;
int adac_type; /* audio DAC type */
#define DVB_ADAC_TI 0
@@ -586,11 +561,6 @@ typedef struct av7110_s {
u8 *kbuf[2];
int sinfo;
- int shsize;
- int swsize;
-
- int tsf;
- u32 ttbp;
int feeding;
int arm_errors;
diff --git a/linux/drivers/media/dvb/av7110/av7110_firm.h b/linux/drivers/media/dvb/ttpci/av7110_firm.h
index 5c93deb3d..5c93deb3d 100644
--- a/linux/drivers/media/dvb/av7110/av7110_firm.h
+++ b/linux/drivers/media/dvb/ttpci/av7110_firm.h
diff --git a/linux/drivers/media/dvb/av7110/av7110_ipack.c b/linux/drivers/media/dvb/ttpci/av7110_ipack.c
index 3d16442e6..3d16442e6 100644
--- a/linux/drivers/media/dvb/av7110/av7110_ipack.c
+++ b/linux/drivers/media/dvb/ttpci/av7110_ipack.c
diff --git a/linux/drivers/media/dvb/av7110/av7110_ipack.h b/linux/drivers/media/dvb/ttpci/av7110_ipack.h
index d1c995aff..d1c995aff 100644
--- a/linux/drivers/media/dvb/av7110/av7110_ipack.h
+++ b/linux/drivers/media/dvb/ttpci/av7110_ipack.h
diff --git a/linux/drivers/media/dvb/av7110/av7110_ir.c b/linux/drivers/media/dvb/ttpci/av7110_ir.c
index 4e89ed71f..4e89ed71f 100644
--- a/linux/drivers/media/dvb/av7110/av7110_ir.c
+++ b/linux/drivers/media/dvb/ttpci/av7110_ir.c