diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drivers/media/video/bttv-driver.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-blackbird.c | 6 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-cards.c | 14 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-core.c | 44 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-dvb.c | 78 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-i2c.c | 56 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-mpeg.c | 67 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-vbi.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-video.c | 5 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88.h | 16 |
10 files changed, 204 insertions, 86 deletions
diff --git a/linux/drivers/media/video/bttv-driver.c b/linux/drivers/media/video/bttv-driver.c index f332ee8fa..c0cda0be5 100644 --- a/linux/drivers/media/video/bttv-driver.c +++ b/linux/drivers/media/video/bttv-driver.c @@ -1863,6 +1863,8 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, if (NULL == fh->ovfmt) return -EINVAL; + if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) + return -EINVAL; retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup); if (0 != retval) return retval; diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c index 51f4b1e9a..218b2805f 100644 --- a/linux/drivers/media/video/cx88/cx88-blackbird.c +++ b/linux/drivers/media/video/cx88/cx88-blackbird.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-blackbird.c,v 1.5 2004/08/25 14:47:53 kraxel Exp $ + * $Id: cx88-blackbird.c,v 1.6 2004/08/31 11:58:53 kraxel Exp $ * * Support for a cx23416 mpeg encoder via cx2388x host port. * "blackbird" reference design. @@ -848,8 +848,6 @@ static void __devexit blackbird_remove(struct pci_dev *pci_dev) /* common */ cx8802_fini_common(dev); - cx88_core_put(dev->core,dev->pci); - kfree(dev); } static struct pci_device_id cx8802_pci_tbl[] = { @@ -865,7 +863,7 @@ static struct pci_device_id cx8802_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); static struct pci_driver blackbird_pci_driver = { - .name = "cx8802", + .name = "cx88-blackbird", .id_table = cx8802_pci_tbl, .probe = blackbird_probe, .remove = blackbird_remove, diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index c8f44c472..25fe03d86 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -22,6 +22,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/delay.h> #include "cx88.h" @@ -316,12 +317,6 @@ struct cx88_board cx88_boards[] = { .gpio0 = 0x000027df, }}, .dvb = 1, -#if 0 - .ts = { - .type = CX88_TS, - .gpio0 = 0x00000101, /* Hooked to tuner reset bit */ - } -#endif }, [CX88_BOARD_KWORLD_LTV883] = { .name = "KWorld LTV883RF", @@ -720,6 +715,13 @@ void cx88_card_setup(struct cx88_core *core) case CX88_BOARD_KWORLD_LTV883: core->has_radio = 1; break; + case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: + /* Tuner reset is hooked to the tuner out of reset */ + cx_set(MO_GP0_IO, 0x00000101); + cx_clear(MO_GP0_IO, 0x00000001); + msleep(1); + cx_set(MO_GP0_IO, 0x00000101); + break; } } diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c index 0c338a944..eaee42b9d 100644 --- a/linux/drivers/media/video/cx88/cx88-core.c +++ b/linux/drivers/media/video/cx88/cx88-core.c @@ -121,6 +121,7 @@ void cx88_print_ioctl(char *name, unsigned int cmd) } /* ------------------------------------------------------------------ */ +#define NO_SYNC_LINE (-1U) static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, unsigned int offset, u32 sync_line, @@ -131,7 +132,8 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, unsigned int line,todo; /* sync instruction */ - *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); + if (sync_line != NO_SYNC_LINE) + *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); /* scan lines */ sg = sglist; @@ -207,6 +209,30 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, return 0; } +int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, + struct scatterlist *sglist, unsigned int bpl, + unsigned int lines) +{ + u32 instructions; + u32 *rp; + int rc; + + /* estimate risc mem: worst case is one write per page border + + one write per scan line + syncs + jump (all 2 dwords) */ + instructions = (bpl * lines) / PAGE_SIZE + lines; + instructions += 3 + 4; + if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0) + return rc; + + /* write risc instructions */ + rp = risc->cpu; + rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines); + + /* save pointer to jmp instruction address */ + risc->jmp = rp; + return 0; +} + int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, u32 reg, u32 mask, u32 value) { @@ -536,7 +562,10 @@ void cx88_print_irqbits(char *name, char *tag, char **strings, for (i = 0; i < 32; i++) { if (!(bits & (1 << i))) continue; - printk(" %s",strings[i]); + if (strings[i]) + printk(" %s", strings[i]); + else + printk(" %d", i); if (!(mask & (1 << i))) continue; printk("*"); @@ -556,8 +585,9 @@ void cx88_wakeup(struct cx88_core *core, struct cx88_dmaqueue *q, u32 count) { struct cx88_buffer *buf; + int bc; - for (;;) { + for (bc = 0;; bc++) { if (list_empty(&q->active)) break; buf = list_entry(q->active.next, @@ -576,6 +606,8 @@ void cx88_wakeup(struct cx88_core *core, } else { mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); } + if (bc != 1) + printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); } void cx88_shutdown(struct cx88_core *core) @@ -590,7 +622,7 @@ void cx88_shutdown(struct cx88_core *core) cx_write(MO_VIP_DMACNTRL, 0x0); cx_write(MO_GPHST_DMACNTRL, 0x0); - /* stop interupts */ + /* stop interrupts */ cx_write(MO_PCI_INTMSK, 0x0); cx_write(MO_VID_INTMSK, 0x0); cx_write(MO_AUD_INTMSK, 0x0); @@ -622,7 +654,7 @@ int cx88_reset(struct cx88_core *core) cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0); cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); - cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 512, 0); + cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0); /* misc init ... */ cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable @@ -1142,6 +1174,7 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) EXPORT_SYMBOL(cx88_print_ioctl); EXPORT_SYMBOL(cx88_pci_irqs); EXPORT_SYMBOL(cx88_vid_irqs); +EXPORT_SYMBOL(cx88_mpeg_irqs); EXPORT_SYMBOL(cx88_print_irqbits); EXPORT_SYMBOL(cx88_irq); @@ -1150,6 +1183,7 @@ EXPORT_SYMBOL(cx88_reset); EXPORT_SYMBOL(cx88_shutdown); EXPORT_SYMBOL(cx88_risc_buffer); +EXPORT_SYMBOL(cx88_risc_databuffer); EXPORT_SYMBOL(cx88_risc_stopper); EXPORT_SYMBOL(cx88_free_buffer); diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c index 398fbbd16..03969ebc1 100644 --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -88,7 +88,7 @@ static int dvb_thread(void *data) unsigned long flags; int err; - dprintk(1,"cx88: dvb thread started\n"); + dprintk(1,"dvb thread started\n"); file = get_empty_filp(); file->private_data = dev; videobuf_read_start(file, &dev->dvbq); @@ -113,11 +113,19 @@ static int dvb_thread(void *data) spin_lock_irqsave(dev->dvbq.irqlock,flags); dev->dvbq.ops->buf_queue(file,buf); spin_unlock_irqrestore(dev->dvbq.irqlock,flags); + + /* log errors if any */ + if (dev->error_count || dev->stopper_count) { + printk("%s: error=%d stopper=%d\n", + dev->core->name, dev->error_count, dev->stopper_count); + dev->error_count = 0; + dev->stopper_count = 0; + } } videobuf_read_stop(file, &dev->dvbq); put_filp(file); - dprintk(1,"cx88: dvb thread stopped\n"); + dprintk(1,"dvb thread stopped\n"); return 0; } @@ -127,20 +135,26 @@ static int dvb_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct cx8802_dev *dev = demux->priv; - int rc = 0; - - dprintk(2, "dvb_cx8800_start_feed\n"); + int rc; if (!demux->dmx.frontend) return -EINVAL; - if (dev->dvb_thread) - return -EINVAL; + down(&dev->lock); + dev->nfeeds++; + rc = dev->nfeeds; + + if (NULL != dev->dvb_thread) + goto out; dev->dvb_thread = kthread_run(dvb_thread, dev, "%s dvb", dev->core->name); if (IS_ERR(dev->dvb_thread)) { rc = PTR_ERR(dev->dvb_thread); dev->dvb_thread = NULL; } + +out: + up(&dev->lock); + dprintk(2, "dvb_cx8800_start_feed rc=%d\n",rc); return rc; } @@ -148,24 +162,29 @@ static int dvb_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct cx8802_dev *dev = demux->priv; - int err; + int err = 0; dprintk(2, "dvb_cx8800_stop_feed\n"); - if (NULL == dev->dvb_thread) - return -EINVAL; - err = kthread_stop(dev->dvb_thread); - dev->dvb_thread = NULL; + down(&dev->lock); + dev->nfeeds--; + if (0 == dev->nfeeds && NULL != dev->dvb_thread) { + err = kthread_stop(dev->dvb_thread); + dev->dvb_thread = NULL; + } + up(&dev->lock); return err; } static void dvb_unregister(struct cx8802_dev *dev) { #if 1 /* really needed? */ + down(&dev->lock); if (NULL != dev->dvb_thread) { kthread_stop(dev->dvb_thread); BUG(); } + up(&dev->lock); #endif dvb_net_release(&dev->dvbnet); @@ -173,7 +192,8 @@ static void dvb_unregister(struct cx8802_dev *dev) dev->demux.dmx.remove_frontend(&dev->demux.dmx, &dev->fe_hw); dvb_dmxdev_release(&dev->dmxdev); dvb_dmx_release(&dev->demux); - dvb_unregister_adapter(dev->dvb_adapter); + dvb_unregister_adapter(dev->core->dvb_adapter); + dev->core->dvb_adapter = NULL; return; } @@ -181,15 +201,7 @@ static int dvb_register(struct cx8802_dev *dev) { int result; -#if 0 /* hmm, this is board specific I guess? move to cx88-cards.c? */ - /* Take DVB hardware out of reset */ - cx_set(MO_GP0_IO, cx88_boards[dev->board].ts.gpio0); - cx_clear(MO_GP0_IO, cx88_boards[dev->board].ts.gpio0 & 0xff); - msleep(1); - cx_set(MO_GP0_IO, cx88_boards[dev->board].ts.gpio0); -#endif - - result = dvb_register_adapter(&dev->dvb_adapter, dev->core->name, + result = dvb_register_adapter(&dev->core->dvb_adapter, dev->core->name, THIS_MODULE); if (result < 0) { printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", @@ -215,7 +227,7 @@ static int dvb_register(struct cx8802_dev *dev) dev->dmxdev.filternum = 256; dev->dmxdev.demux = &dev->demux.dmx; dev->dmxdev.capabilities = 0; - result = dvb_dmxdev_init(&dev->dmxdev, dev->dvb_adapter); + result = dvb_dmxdev_init(&dev->dmxdev, dev->core->dvb_adapter); if (result < 0) { printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", dev->core->name, result); @@ -233,19 +245,19 @@ static int dvb_register(struct cx8802_dev *dev) dev->fe_mem.source = DMX_MEMORY_FE; result = dev->demux.dmx.add_frontend(&dev->demux.dmx, &dev->fe_mem); if (result < 0) { - printk(KERN_WARNING "%s: add_frontent failed (DMX_MEMORY_FE, errno = %d)\n", + printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", dev->core->name, result); goto fail5; } result = dev->demux.dmx.connect_frontend(&dev->demux.dmx, &dev->fe_hw); if (result < 0) { - printk(KERN_WARNING "%s: connect_frontent failed (errno = %d)\n", + printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", dev->core->name, result); goto fail6; } - dvb_net_init(dev->dvb_adapter, &dev->dvbnet, &dev->demux.dmx); + dvb_net_init(dev->core->dvb_adapter, &dev->dvbnet, &dev->demux.dmx); return 0; fail6: @@ -257,7 +269,7 @@ fail4: fail3: dvb_dmx_release(&dev->demux); fail2: - dvb_unregister_adapter(dev->dvb_adapter); + dvb_unregister_adapter(dev->core->dvb_adapter); fail1: return result; } @@ -293,15 +305,17 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, goto fail_free; /* dvb stuff */ - printk("%s/2: cx23416 based dvb card\n", core->name); + printk("%s/2: cx2388x based dvb card\n", core->name); videobuf_queue_init(&dev->dvbq, &dvb_qops, dev->pci, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx88_buffer)); init_MUTEX(&dev->dvbq.lock); - dvb_register(dev); - + + err = dvb_register(dev); + if (0 != err) + goto fail_free; return 0; fail_free: @@ -317,7 +331,7 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev) /* dvb */ dvb_unregister(dev); - + /* common */ cx8802_fini_common(dev); cx88_core_put(dev->core,dev->pci); @@ -337,7 +351,7 @@ static struct pci_device_id cx8802_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); static struct pci_driver dvb_pci_driver = { - .name = "cx8802", + .name = "cx88-dvb", .id_table = cx8802_pci_tbl, .probe = dvb_probe, .remove = dvb_remove, diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c index 02595d86c..ef04a431d 100644 --- a/linux/drivers/media/video/cx88/cx88-i2c.c +++ b/linux/drivers/media/video/cx88/cx88-i2c.c @@ -29,6 +29,19 @@ #include "cx88.h" +static unsigned int i2c_debug = 0; +MODULE_PARM(i2c_debug,"i"); +MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]"); + +#define dprintk(level,fmt, arg...) if (i2c_debug >= level) \ + printk(KERN_DEBUG "%s: " fmt, core->name , ## arg) + +/* temporary here until new dvb-kernel code is merged ... */ +#ifndef FE_REGISTER +# define FE_REGISTER _IO ('v', 84) +# define FE_UNREGISTER _IO ('v', 85) +#endif + /* ----------------------------------------------------------------------- */ void cx8800_bit_setscl(void *data, int state) @@ -89,17 +102,43 @@ static void cx8800_dec_use(struct i2c_adapter *adap) static int attach_inform(struct i2c_client *client) { - struct cx88_core *core = i2c_get_adapdata(client->adapter); + struct cx88_core *core = i2c_get_adapdata(client->adapter); if (core->tuner_type != UNSET) cx88_call_i2c_clients(core,TUNER_SET_TYPE,&core->tuner_type); if (core->tda9887_conf) cx88_call_i2c_clients(core,TDA9887_SET_CONFIG,&core->tda9887_conf); - if (1 /* fixme: debug */) - printk("%s: i2c attach [client=%s]\n", - core->name, i2c_clientname(client)); - return 0; +#if 1 + /* FIXME: should switch to cx88_call_i2c_clients */ + if (core->dvb_adapter && client->driver->command) { + dprintk(1, "i2c attach [client=%s] dvb_adapter %p\n", + i2c_clientname(client), core->dvb_adapter); + return client->driver->command(client, FE_REGISTER, core->dvb_adapter); + } +#endif + + dprintk(1, "i2c attach [client=%s]\n", i2c_clientname(client)); + return 0; +} + +static int detach_inform(struct i2c_client *client) +{ + struct cx88_core *core = i2c_get_adapdata(client->adapter); + +#if 1 + /* FIXME: should switch to cx88_call_i2c_clients */ + /* FIXME: drop FE_UNREGISTER altogether in favor of using + * i2c_driver->detach_client() ??? */ + if (core->dvb_adapter && client->driver->command) { + dprintk(1, "i2c detach [client=%s] dvb_adapter %p\n", + i2c_clientname(client), core->dvb_adapter); + return client->driver->command(client, FE_UNREGISTER, core->dvb_adapter); + } +#endif + + dprintk(1, "i2c detach [client=%s]\n", i2c_clientname(client)); + return 0; } void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) @@ -134,6 +173,7 @@ static struct i2c_adapter cx8800_i2c_adap_template = { I2C_DEVNAME("cx2388x"), .id = I2C_HW_B_BT848, .client_register = attach_inform, + .client_unregister = detach_inform, }; static struct i2c_client cx8800_i2c_client_template = { @@ -164,8 +204,10 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) cx8800_bit_setsda(core,1); core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap); - printk("%s: i2c register %s\n", core->name, - (0 == core->i2c_rc) ? "ok" : "FAILED"); + if (0 != core->i2c_rc) + printk("%s: i2c register FAILED\n", core->name); + else + dprintk(1, "i2c register ok\n"); return core->i2c_rc; } diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index 735356325..a0445baf5 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -1,10 +1,11 @@ /* - * $Id: cx88-mpeg.c,v 1.5 2004/08/25 14:47:53 kraxel Exp $ + * $Id: cx88-mpeg.c,v 1.6 2004/08/31 11:58:53 kraxel Exp $ * * Support for the mpeg transport stream transfers * PCI function #2 of the cx2388x. * * (c) 2004 Jelle Foks <jelle@foks.8m.com> + * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au> * (c) 2004 Gerd Knorr <kraxel@bytesex.org> * * This program is free software; you can redistribute it and/or modify @@ -34,6 +35,7 @@ MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards"); MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); +MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -58,6 +60,9 @@ int cx8802_start_dma(struct cx8802_dev *dev, cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], dev->ts_packet_size, buf->risc.dma); + /* write TS length to chip */ + cx_write(MO_TS_LNGTH, buf->vb.width); + #if 1 /* FIXME: this needs a review. * also: move to cx88-blackbird + cx88-dvb source files? */ @@ -65,19 +70,13 @@ int cx8802_start_dma(struct cx8802_dev *dev, if (cx88_boards[core->board].dvb) { /* Setup TS portion of chip */ cx_write(TS_GEN_CNTRL, 0x0c); - - /* write TS length to chip */ - cx_write(MO_TS_LNGTH, buf->bpl); } if (cx88_boards[core->board].blackbird) { cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ - // cx_write(TS_F2_CMD_STAT_MM, 0x2900106); /* F2_CMD_STAT_MM defaults + master + memory space */ cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ - // cx_write(MO_TS_LNGTH, MD_TS_LNGHT_VAL); - udelay(100); cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */ @@ -95,14 +94,30 @@ int cx8802_start_dma(struct cx8802_dev *dev, /* enable irqs */ cx_set(MO_PCI_INTMSK, 0x00fc04); - cx_set(MO_TS_INTMSK, 0x1f0011); + cx_write(MO_TS_INTMSK, 0x1f0011); /* start dma */ - cx_set(MO_DEV_CNTRL2, (1<<5)); - cx_set(MO_TS_DMACNTRL, 0x11); + cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */ + cx_write(MO_TS_DMACNTRL, 0x11); return 0; } +void cx8802_shutdown(struct cx8802_dev *dev) +{ + struct cx88_core *core = dev->core; + + /* disable and clear irqs */ + cx_write(MO_TS_INTMSK, 0x0); + cx_write(MO_TS_INTSTAT, 0x1f1111); + + /* stop dma */ + cx_clear(MO_TS_DMACNTRL, 0x11); + cx_write(MO_DEV_CNTRL2, 0); /* FIXME: affects other pci functions ??? */ + + /* Reset the controller */ + cx_write(TS_GEN_CNTRL, 0xcd); +} + int cx8802_restart_queue(struct cx8802_dev *dev, struct cx88_dmaqueue *q) { @@ -143,11 +158,9 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) goto fail; - cx88_risc_buffer(dev->pci, &buf->risc, - buf->vb.dma.sglist, - 0, UNSET, - buf->vb.width, 0, - buf->vb.height); + cx88_risc_databuffer(dev->pci, &buf->risc, + buf->vb.dma.sglist, + buf->vb.width, buf->vb.height); } buf->vb.state = STATE_PREPARED; return 0; @@ -186,12 +199,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) } } -void cx8802_buf_release(struct cx8802_dev *dev, struct cx88_buffer *buf) -{ - dprintk(1, "%s: %p\n", __FUNCTION__, buf); - -} - /* ----------------------------------------------------------- */ static void cx8802_timeout(unsigned long data) @@ -238,7 +245,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) cx_write(MO_TS_INTSTAT, status); if (debug || (status & mask & ~0xff)) cx88_print_irqbits(core->name, "irq mpeg ", - cx88_vid_irqs, status, mask); + cx88_mpeg_irqs, status, mask); /* risc op code error */ if (status & (1 << 16)) { @@ -256,11 +263,21 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) } /* risc2 y */ - if (status & 0x10) { /* I don't know what this does/when it's needed */ + if (status & 0x10) { spin_lock(&dev->slock); + dev->stopper_count++; cx8802_restart_queue(dev,&dev->mpegq); spin_unlock(&dev->slock); } + + /* other general errors */ + if (status & 0x1f0100) { + spin_lock(&dev->slock); + dev->error_count++; + cx8802_shutdown(dev); + cx8802_restart_queue(dev,&dev->mpegq); + spin_unlock(&dev->slock); + } } static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) @@ -355,9 +372,7 @@ int cx8802_init_common(struct cx8802_dev *dev) void cx8802_fini_common(struct cx8802_dev *dev) { -#if 0 cx8802_shutdown(dev); -#endif pci_disable_device(dev->pci); /* unregister stuff */ @@ -366,8 +381,6 @@ void cx8802_fini_common(struct cx8802_dev *dev) /* free memory */ btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); - cx88_core_put(dev->core,dev->pci); - kfree(dev); } /* ----------------------------------------------------------- */ diff --git a/linux/drivers/media/video/cx88/cx88-vbi.c b/linux/drivers/media/video/cx88/cx88-vbi.c index 09829a10f..7651ca890 100644 --- a/linux/drivers/media/video/cx88/cx88-vbi.c +++ b/linux/drivers/media/video/cx88/cx88-vbi.c @@ -11,7 +11,7 @@ MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32"); static unsigned int vbi_debug = 0; MODULE_PARM(vbi_debug,"i"); -MODULE_PARM_DESC(vbi_debug,"enable debug messages [video]"); +MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]"); #define dprintk(level,fmt, arg...) if (vbi_debug >= level) \ printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg) diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 8d2de17a1..f425d73f3 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-video.c,v 1.33 2004/08/26 10:59:39 kraxel Exp $ + * $Id: cx88-video.c,v 1.34 2004/08/31 11:58:53 kraxel Exp $ * * device driver for Conexant 2388x based TV cards * video4linux video interface @@ -2079,7 +2079,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, up(&dev->lock); /* start tvaudio thread */ - core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); + if (core->tuner_type != TUNER_ABSENT) + core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); return 0; fail_unreg: diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index 4abb91649..9db2c04df 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -1,5 +1,5 @@ /* - * $Id: cx88.h,v 1.26 2004/08/26 10:59:39 kraxel Exp $ + * $Id: cx88.h,v 1.27 2004/08/31 11:58:53 kraxel Exp $ * * v4l2 device driver for cx2388x based TV cards * @@ -266,6 +266,9 @@ struct cx88_core { u32 tvaudio; u32 input; u32 astat; + + /* used by cx88-dvb -- i2c code needs access to this for FE register */ + struct dvb_adapter *dvb_adapter; }; struct cx8800_dev; @@ -365,6 +368,10 @@ struct cx8802_dev { u32 ts_packet_size; u32 ts_packet_count; + /* error stats */ + u32 stopper_count; + u32 error_count; + /* for blackbird only */ struct list_head devlist; struct video_device *mpeg_dev; @@ -373,12 +380,12 @@ struct cx8802_dev { /* for dvb only */ struct videobuf_queue dvbq; struct task_struct *dvb_thread; - struct dvb_adapter *dvb_adapter; struct dvb_demux demux; struct dmxdev dmxdev; struct dmx_frontend fe_hw; struct dmx_frontend fe_mem; struct dvb_net dvbnet; + int nfeeds; }; /* ----------------------------------------------------------- */ @@ -409,6 +416,7 @@ struct cx8802_dev { extern char *cx88_pci_irqs[32]; extern char *cx88_vid_irqs[32]; +extern char *cx88_mpeg_irqs[32]; extern void cx88_print_irqbits(char *name, char *tag, char **strings, u32 bits, u32 mask); extern void cx88_print_ioctl(char *name, unsigned int cmd); @@ -425,6 +433,10 @@ cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, unsigned int top_offset, unsigned int bottom_offset, unsigned int bpl, unsigned int padding, unsigned int lines); extern int +cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, + struct scatterlist *sglist, unsigned int bpl, + unsigned int lines); +extern int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, u32 reg, u32 mask, u32 value); extern void |