diff options
Diffstat (limited to 'linux/drivers/media/dvb/ttpci')
-rw-r--r-- | linux/drivers/media/dvb/ttpci/Kconfig | 25 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.c | 148 |
2 files changed, 94 insertions, 79 deletions
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, |