diff options
author | Michael Hunold <devnull@localhost> | 2003-01-04 18:00:25 +0000 |
---|---|---|
committer | Michael Hunold <devnull@localhost> | 2003-01-04 18:00:25 +0000 |
commit | f9baa931e2c4bc43371addc9b654afa06ae325a0 (patch) | |
tree | 21be91354e235ed17470ce3ee173e06648ad1db7 | |
parent | 6ef9b1ac86347c93e5bed9c3dc83893f12c7e0d6 (diff) | |
download | mediapointer-dvb-s2-f9baa931e2c4bc43371addc9b654afa06ae325a0.tar.gz mediapointer-dvb-s2-f9baa931e2c4bc43371addc9b654afa06ae325a0.tar.bz2 |
Some more changes... (but we're stabilizing...)
2.5.x:
- exchanged the Kconfig files for "ttpci" and "ttpci-budget"
- removed the "SAA7146 based" from the card descriptions, but put
it to the remark some lines above
saa7146:
- simplified the probe(), attach(), detach() logic, since all
dvb devices can be identified by their subvendor/subdevice ids
av7110:
- added two wait_for_debi_done() calls in gpioirq(). (All other
IER_ENABLE() calls are preceded by wait_for_debi_done())
budget:
- budget.c has been split up into budget.c and budget-av.c. The latter
is for budget cards with analog video (av) inputs. Definitions are
now in budget.h. budget.c exports various functions that are used by
budget-av.c, too. The av code is currently missing, though, and needs
to be added.
unsorted:
- various c99 initializer cleanups
-rw-r--r-- | linux/drivers/media/common/Kconfig | 4 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146.h | 10 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146_core.c | 14 | ||||
-rw-r--r-- | linux/drivers/media/dvb/Kconfig | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci-budget/Kconfig | 39 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci-budget/Makefile | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci-budget/budget.c | 273 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/Kconfig | 25 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.c | 148 | ||||
-rw-r--r-- | linux/drivers/media/video/mxb.c | 2 |
10 files changed, 241 insertions, 278 deletions
diff --git a/linux/drivers/media/common/Kconfig b/linux/drivers/media/common/Kconfig index 17cb90bc3..87edcbb98 100644 --- a/linux/drivers/media/common/Kconfig +++ b/linux/drivers/media/common/Kconfig @@ -1,7 +1,7 @@ config VIDEO_SAA7146 tristate - default y if DVB_AV7110=y || VIDEO_MXB=y - default m if DVB_AV7110=m || VIDEO_MXB=m + default y if DVB_AV7110=y || DVB_BUDGET=y || DVB_BUDGET_AV=y || VIDEO_MXB=y + default m if DVB_AV7110=y || DVB_BUDGET=m || DVB_BUDGET_AV=m || VIDEO_MXB=m depends on VIDEO_DEV && PCI config VIDEO_VIDEOBUF diff --git a/linux/drivers/media/common/saa7146.h b/linux/drivers/media/common/saa7146.h index 972e7774f..907989cfe 100644 --- a/linux/drivers/media/common/saa7146.h +++ b/linux/drivers/media/common/saa7146.h @@ -55,7 +55,10 @@ struct saa7146_extension; struct saa7146_vv; struct saa7146_sub_info { - unsigned int subvendor, subdevice; + unsigned int subvendor; + unsigned int subdevice; + char **name; + int type; }; /* saa7146 page table */ @@ -88,8 +91,7 @@ struct saa7146_extension /* extension functions */ int (*preinit)(struct saa7146_dev*); int (*probe)(struct saa7146_dev*, unsigned int subvendor, unsigned int subdevice); - - int (*attach)(struct saa7146_dev*); + int (*attach)(struct saa7146_dev *, struct saa7146_sub_info *); int (*detach)(struct saa7146_dev*); u32 irq_mask; /* mask to indicate, which irq-events are handled by the extension */ @@ -112,6 +114,8 @@ struct saa7146_dev /* pci-device & irq stuff*/ char name[32]; struct pci_dev *pci; + u32 int_todo; + spinlock_t int_slock; /* extension handling */ struct saa7146_extension *ext; /* indicates if handled by extension */ diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 1b4ca2222..432fa4f4e 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -233,15 +233,16 @@ void try_attach_extension_and_device(struct saa7146_dev *dev, struct saa7146_ext DEB_S(("ext->preinit() failed for %p. skipping.\n",dev)); return; } - - if( 0 != ext->probe(dev, dev->pci->subsystem_vendor, dev->pci->subsystem_device) ) { - DEB_D(("ext->probe() failed for %p. skipping device.\n",dev)); - return; + + if( 0 != ext->probe) { + if( 0 != ext->probe(dev, dev->pci->subsystem_vendor, dev->pci->subsystem_device) ) { + DEB_D(("ext->probe() failed for %p. skipping device.\n",dev)); + return; + } } dev->ext = ext; - - if( 0 != ext->attach(dev) ) { + if( 0 != ext->attach(dev, &ext->devices[i]) ) { DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); dev->ext = NULL; return; @@ -447,6 +448,7 @@ static int config_a_device(struct pci_dev *pci) pci_set_drvdata(pci,dev); init_MUTEX(&dev->lock); + dev->int_slock = SPIN_LOCK_UNLOCKED; dev->slock = SPIN_LOCK_UNLOCKED; init_MUTEX(&dev->i2c_lock); diff --git a/linux/drivers/media/dvb/Kconfig b/linux/drivers/media/dvb/Kconfig index edbec1c88..3a9a37a97 100644 --- a/linux/drivers/media/dvb/Kconfig +++ b/linux/drivers/media/dvb/Kconfig @@ -32,7 +32,7 @@ source "drivers/media/dvb/dvb-core/Kconfig" source "drivers/media/dvb/frontends/Kconfig" -comment "Supported DVB Adapters" +comment "Supported SAA7146 based PCI Adapters" depends on DVB source "drivers/media/dvb/ttpci/Kconfig" diff --git a/linux/drivers/media/dvb/ttpci-budget/Kconfig b/linux/drivers/media/dvb/ttpci-budget/Kconfig index 3c4d43d41..ced13d6fd 100644 --- a/linux/drivers/media/dvb/ttpci-budget/Kconfig +++ b/linux/drivers/media/dvb/ttpci-budget/Kconfig @@ -1,24 +1,31 @@ -config DVB_AV7110 - tristate "SAA7146 based AV7110 PCI cards" +config DVB_BUDGET + tristate "Budget 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. - - This driver only supports the fullfeatured cards with - onboard MPEG2 decoder. + 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. -config DVB_AV7110_OSD - bool "AV7110 OSD support" - depends on DVB_AV7110 + This driver is available as a module called + dvb-ttpci-budget.o ( = 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 DVB_BUDGET_AV + tristate "Budget cards with analog video inputs" + depends on VIDEO_DEV && DVB_CORE && DVB_BUDGET help - The AV7110 firmware provides some code to generate an OnScreenDisplay - on the video output. This is kind of nonstandard and not guaranteed to - be maintained. + Support for simple SAA7146 based DVB cards + (so called Budget- or Nova-PCI cards) without onboard + MPEG2 decoder, but with one or more analog video inputs. - Anyway, some popular DVB software like VDR uses this OSD to render - its menus, so say Y if you want to use this software. + Say Y if you own such a card and want to use it. - All other people say N. + This driver is available as a module called + dvb-ttpci-budget-av.o ( = 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>. diff --git a/linux/drivers/media/dvb/ttpci-budget/Makefile b/linux/drivers/media/dvb/ttpci-budget/Makefile index 11c671d1b..10c075828 100644 --- a/linux/drivers/media/dvb/ttpci-budget/Makefile +++ b/linux/drivers/media/dvb/ttpci-budget/Makefile @@ -3,7 +3,9 @@ # dvb-ttpci-budget-objs := budget.o +dvb-ttpci-budget-av-objs := budget-av.o obj-$(CONFIG_DVB_BUDGET) += dvb-ttpci-budget.o +obj-$(CONFIG_DVB_BUDGET_AV) += dvb-ttpci-budget-av.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 index b50b1d4ad..20e3a98a3 100644 --- a/linux/drivers/media/dvb/ttpci-budget/budget.c +++ b/linux/drivers/media/dvb/ttpci-budget/budget.c @@ -1,5 +1,9 @@ /* - * budget.c: driver for the SAA7146 based Nova/Budget DVB cards + * budget.c: driver for the SAA7146 based Budget DVB cards + * + * Compiled from various sources by Michael Hunold <michael@mihu.de> + * + * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> * * Copyright (C) 1999-2002 Ralph Metzler * & Marcus Metzler for convergence integrated media GmbH @@ -25,69 +29,9 @@ * 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" +#include "budget.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 @@ -133,7 +77,7 @@ static inline void ddelay(int i) ****************************************************************************/ static int -TTBStop(budget_t *budget) +TTBStop(struct budget_s *budget) { DEB_EE(("budget: %p\n",budget)); @@ -145,12 +89,8 @@ TTBStop(budget_t *budget) 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) +TTBStart(struct budget_s *budget) { struct saa7146_dev *dev=budget->dev; @@ -240,7 +180,7 @@ void fidbirq (unsigned long data) } inline static void -Set22K(budget_t *budget, int state) +Set22K(struct budget_s *budget, int state) { struct saa7146_dev *dev=budget->dev; DEB_EE(("budget: %p\n",budget)); @@ -253,7 +193,7 @@ Set22K(budget_t *budget, int state) Ralph Metzler <rjkm@metzlerbros.de> */ inline static void -DiseqcSendBit(budget_t *budget, int data) +DiseqcSendBit(struct budget_s *budget, int data) { struct saa7146_dev *dev=budget->dev; DEB_EE(("budget: %p\n",budget)); @@ -265,7 +205,7 @@ DiseqcSendBit(budget_t *budget, int data) } static void -DiseqcSendByte(budget_t *budget, int data) +DiseqcSendByte(struct budget_s *budget, int data) { struct saa7146_dev *dev=budget->dev; int i, par=1, d; @@ -282,7 +222,7 @@ DiseqcSendByte(budget_t *budget, int data) } inline static int -SendDiSEqCMsg(budget_t *budget, int len, u8 *msg, int burst) +SendDiSEqCMsg(struct budget_s *budget, int len, u8 *msg, int burst) { struct saa7146_dev *dev=budget->dev; int i; @@ -319,7 +259,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - budget_t *budget = (budget_t *) demux->priv; + struct budget_s *budget = (struct budget_s *) demux->priv; DEB_EE(("budget: %p\n",budget)); @@ -333,7 +273,7 @@ static int budget_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - budget_t *budget = (budget_t *) demux->priv; + struct budget_s *budget = (struct budget_s *) demux->priv; DEB_EE(("budget: %p\n",budget)); @@ -347,7 +287,7 @@ budget_stop_feed(struct dvb_demux_feed *feed) static int budget_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { - budget_t *budget = fe->before_after_data; + struct budget_s *budget = fe->before_after_data; DEB_EE(("budget: %p\n",budget)); @@ -384,8 +324,7 @@ int budget_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) return 0; } -static -int budget_register(budget_t *budget) +int budget_register(struct budget_s *budget) { int ret; dmx_frontend_t *dvbfront=&budget->hw_frontend; @@ -458,7 +397,7 @@ int budget_register(budget_t *budget) static void -dvb_unregister(budget_t *budget) +dvb_unregister(struct budget_s *budget) { struct dvb_demux *dvbdemux=&budget->demux; @@ -489,103 +428,106 @@ int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) * 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 char *ttbs = "TT-Budget/WinTV-NOVA-S PCI"; +static char *ttbc = "TT-Budget/WinTV-NOVA-C PCI"; +static char *ttbt = "TT-Budget/WinTV-NOVA-T PCI"; +static char *ttbci = "TT-Budget/WinTV-NOVA-CI PCI"; +static char *satel = "SATELCO Multimedia PCI"; +static char *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 }, + { + .subvendor = 0x1131, + .subdevice = 0x4f56, + .name = &knc1, + .type = DVB_CARD_KNC1 + }, { + .subvendor = 0x13c2, + .subdevice = 0x1003, + .name = &ttbs, + .type = DVB_CARD_TT_BUDGET + }, { + .subvendor = 0x13c2, + .subdevice = 0x1004, + .name = &ttbc, + .type = DVB_CARD_TT_BUDGET + }, { + .subvendor = 0x13c2, + .subdevice = 0x1005, + .name = &ttbt, + .type = DVB_CARD_TT_BUDGET + }, { + .subvendor = 0x13c2, + .subdevice = 0x100c, + .name = &ttbci, + .type = DVB_CARD_TT_BUDGET_CI + }, { + /* TT_BUDGET_CI without CI (connector not soldered in) */ + .subvendor = 0x13c2, + .subdevice = 0x100f, + .name = &ttbci, + .type = DVB_CARD_TT_BUDGET_CI + }, { + .subvendor = 0x13c2, + .subdevice = 0x1013, + .name = &satel, + .type = DVB_CARD_TT_BUDGET + }, { + .subvendor = 0xffff, + .subdevice = 0xffff, + .name = NULL, + .type = 0 + } }; - -int budget_probe(struct saa7146_dev* dev, unsigned int subvendor, unsigned int subdevice) +static +int this_budget_attach (struct saa7146_dev* dev, struct saa7146_sub_info *info) { - 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; - } + struct budget_s *budget = NULL; + if( 0 != budget_attach(dev,info)) { + return -1; } + budget = (struct budget_s*)dev->ext_priv; - 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; + /* 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)); - return 0; + // FIXME: cope with error here! + budget_register(budget); + printk(KERN_INFO "budget: found budget card.\n"); } -static -int budget_attach (struct saa7146_dev* dev) +int budget_attach (struct saa7146_dev* dev, struct saa7146_sub_info *info) { - budget_t *budget = (budget_t*)dev->ext_priv; + struct budget_s *budget = NULL; struct scatterlist *slist = NULL; int slen = 0; int length = TS_WIDTH*TS_HEIGHT; int pages = (length+PAGE_SIZE-1)/PAGE_SIZE; int ret = 0; + if (!(budget = kmalloc (sizeof (struct budget_s), GFP_KERNEL))) { + printk ("%s: out of memory!\n", __FUNCTION__); + return -ENOMEM; + } + memset(budget, 0, sizeof(struct budget_s)); + DEB_EE(("dev: %p, budget: %p\n",dev,budget)); + budget->card_type = info; budget->dev=(struct saa7146_dev *)dev; - dvb_register_adapter(&budget->dvb_adapter, budget->card_type->name); + (struct budget_s*)dev->ext_priv = budget; + + 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); + kfree(budget); return -ENOMEM; } @@ -612,10 +554,6 @@ int budget_attach (struct saa7146_dev* dev) 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); @@ -623,11 +561,6 @@ int budget_attach (struct saa7146_dev* dev) 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: @@ -639,13 +572,15 @@ err: } dvb_unregister_i2c_bus (master_xfer,budget->i2c_bus->adapter, budget->i2c_bus->id); dvb_unregister_adapter (budget->dvb_adapter); + if( NULL != budget ) { + kfree(budget); + } return ret; } -static int budget_detach (struct saa7146_dev* saa) { - budget_t *budget = (budget_t*)saa->ext_priv; + struct budget_s *budget = (struct budget_s*)saa->ext_priv; DEB_EE(("budget: %p\n",budget)); dvb_unregister(budget); @@ -657,16 +592,13 @@ int budget_detach (struct saa7146_dev* saa) 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; + struct budget_s *budget = (struct budget_s*)dev->ext_priv; DEB_EE(("dev: %p, budget: %p\n",dev,budget)); @@ -697,9 +629,7 @@ struct saa7146_extension budget_extension = { .inc_use = budget_inc_use, .dec_use = budget_dec_use, #endif - .preinit = budget_preinit, - .probe = budget_probe, - .attach = budget_attach, + .attach = this_budget_attach, .detach = budget_detach, .irq_mask = MASK_07, @@ -723,9 +653,7 @@ static void __exit budget_exit(void) { DEB_EE((".\n")); - - if (saa7146_unregister_extension(&budget_extension)) - printk(KERN_ERR "dvb: extension deregistration failed.\n"); + saa7146_unregister_extension(&budget_extension); } module_init(budget_init); @@ -737,3 +665,8 @@ MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); MODULE_LICENSE("GPL"); MODULE_PARM(budget_debug,"i"); + +EXPORT_SYMBOL_GPL(budget_register); +EXPORT_SYMBOL_GPL(budget_irq); +EXPORT_SYMBOL_GPL(budget_attach); +EXPORT_SYMBOL_GPL(budget_detach); diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig index cf8fe5251..8396852b0 100644 --- a/linux/drivers/media/dvb/ttpci/Kconfig +++ b/linux/drivers/media/dvb/ttpci/Kconfig @@ -1,9 +1,24 @@ -config DVB_BUDGET - tristate "SAA7146 based Nova/Budget PCI cards" +config DVB_AV7110 + tristate "AV7110 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. + Support for SAA7146 and AV7110 based DVB cards as produced + by Fujitsu-Siemens, Technotrend, Hauppauge and others. + + This driver only supports the fullfeatured cards with + onboard MPEG2 decoder. Say Y if you own such a card and want to use it. + +config DVB_AV7110_OSD + bool "AV7110 OSD support" + depends on DVB_AV7110 + help + The AV7110 firmware provides some code to generate an OnScreenDisplay + on the video output. This is kind of nonstandard and not guaranteed to + be maintained. + + Anyway, some popular DVB software like VDR uses this OSD to render + its menus, so say Y if you want to use this software. + + All other people say N. diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index f196ec210..b5caa33d5 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -890,7 +890,7 @@ void debiirq (unsigned long data) saa7146_write(av7110->dev, ISR, MASK_19 ); if (type==-1) { - printk("DEBI irq oops\n"); + printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR)); ARM_ClearMailBox(av7110); ARM_ClearIrq(av7110); return; @@ -1073,7 +1073,7 @@ void gpioirq (unsigned long data) DEB_EE(("av7110: %p\n",av7110)); if (av7110->debitype !=-1) { - DEB_D(("GPIO0 irq oops, av7110: %p\n",av7110)); + printk("GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR)); } spin_lock(&av7110->debilock); @@ -1225,6 +1225,7 @@ void gpioirq (unsigned long data) } /* yes, fall through */ case DATA_TS_RECORD: case DATA_PES_RECORD: + wait_for_debi_done(av7110); IER_ENABLE(av7110->dev, MASK_19); // saa7146_write(av7110->dev, IER, // saa7146_read(av7110->dev, IER) | MASK_19); @@ -1233,6 +1234,7 @@ void gpioirq (unsigned long data) return; case DATA_DEBUG_MESSAGE: + wait_for_debi_done(av7110); if (!len || len>0xff) { iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); break; @@ -1258,7 +1260,6 @@ void gpioirq (unsigned long data) ARM_ClearMailBox(av7110); av7110->debitype=-1; spin_unlock(&av7110->debilock); - DEB_D(("GPIO0 irq exit 0\n")); } @@ -4162,98 +4163,92 @@ int av7110_preinit(struct saa7146_dev* dev) return 0; } -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 *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 IDs or PCI_ANY_ID */ - char **card; -}; - static struct saa7146_sub_info sub_data[] = { - { 0x110a, 0xffff }, - { 0x110a, 0x0000 }, - { 0x13c2, 0x0000 }, - { 0x13c2, 0x1002 }, - { 0x13c2, 0x0001 }, - { 0x13c2, 0x0002 }, - { 0x13c2, 0x0003 }, - { 0x13c2, 0x0004 }, - { 0x13c2, 0x0006 }, - { 0x13c2, 0x0008 }, - { 0xffc2, 0x0000 }, - { 0xffff, 0xffff }, -}; - -static struct card_match match_data[] = { - { &sub_data[ 0], &fs_1_5 }, - { &sub_data[ 1], &fs_1_5 }, - { &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 }, + { + .subvendor = 0x110a, + .subdevice = 0xffff, + .name = &fs_1_5 + }, { + .subvendor = 0x110a, + .subdevice = 0x0000, + .name = &fs_1_5 + }, { + .subvendor = 0x13c2, + .subdevice = 0x0000, + .name = &fs_1_3 + }, { + .subvendor = 0x13c2, + .subdevice = 0x1002, + .name = &unkwn + }, { + .subvendor = 0x13c2, + .subdevice = 0x0001, + .name = &tt_1_6 + }, { + .subvendor = 0x13c2, + .subdevice = 0x0002, + .name = &tt_2_1 + }, { + .subvendor = 0x13c2, + .subdevice = 0x0003, + .name = &tt_2_1 + }, { + .subvendor = 0x13c2, + .subdevice = 0x0004, + .name = &tt_2_1 + }, { + .subvendor = 0x13c2, + .subdevice = 0x0006, + .name = &tt_1_6 + }, { + .subvendor = 0x13c2, + .subdevice = 0x0008, + .name = &tt_t + }, { + .subvendor = 0xffc2, + .subdevice = 0x0000, + .name = &unkwn + }, { + .subvendor = 0xffff, + .subdevice = 0xffff, + .name = NULL + } }; - -int av7110_probe(struct saa7146_dev* dev, unsigned int subvendor, unsigned int subdevice) +static +int av7110_attach (struct saa7146_dev* dev, struct saa7146_sub_info *info) { - av7110_t *av7110; - 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; - } - } + av7110_t *av7110 = NULL; + int ret = 0; if (!(av7110 = kmalloc (sizeof (struct av7110_s), GFP_KERNEL))) { printk ("%s: out of memory!\n", __FUNCTION__); return -ENOMEM; } memset(av7110, 0, sizeof(av7110_t)); - av7110->card_name = *match_data[i].card; + av7110->card_name = *info->name; (av7110_t*)dev->ext_priv = av7110; - return 0; -} - -static -int av7110_attach (struct saa7146_dev* dev) -{ - av7110_t *av7110 = (av7110_t*)dev->ext_priv; - int ret = 0; - DEB_EE(("dev: %p, av7110: %p\n",dev,av7110)); if( 0 != saa7146_vv_init(dev)) { ERR(("cannot init capture device. skipping.\n")); + kfree(av7110); 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); + kfree(av7110); return -1; } @@ -4267,6 +4262,7 @@ int av7110_attach (struct saa7146_dev* dev) saa7146_unregister_device(&av7110->vd, dev); saa7146_vv_release(dev); dvb_unregister_adapter (av7110->dvb_adapter); + kfree(av7110); return -ENOMEM; } saa7146_write(dev, PCI_BT_V1, 0x1c00101f); @@ -4402,6 +4398,9 @@ int av7110_attach (struct saa7146_dev* dev) return 0; err: + if( NULL != av7110 ) { + kfree(av7110); + } /* FIXME: error handling is totally bogus: memory does not get freed ... */ saa7146_unregister_device(&av7110->vd, dev); saa7146_vv_release(dev); @@ -4458,11 +4457,13 @@ void av7110_irq(struct saa7146_dev* dev, u32 *isr) DEB_EE(("dev: %p, av7110: %p\n",dev,av7110)); - if (*isr & MASK_19) + if (*isr & MASK_19) { tasklet_schedule (&av7110->debi_tasklet); - - if (*isr & MASK_03) + } + + if (*isr & MASK_03) { tasklet_schedule (&av7110->gpio_tasklet); + } } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) @@ -4517,7 +4518,6 @@ struct saa7146_extension av7110_extension = { #endif .preinit = av7110_preinit, - .probe = av7110_probe, .attach = av7110_attach, .detach = av7110_detach, diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c index 2c25aa644..6fff101af 100644 --- a/linux/drivers/media/video/mxb.c +++ b/linux/drivers/media/video/mxb.c @@ -469,7 +469,7 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask) */ /* this function only gets called when the probing was successful */ -static int mxb_attach(struct saa7146_dev* dev) +static int mxb_attach(struct saa7146_dev* dev, struct saa7146_sub_info *info) { struct mxb* mxb = (struct mxb*)dev->ext_priv; |