i2c: Discard the i2c algo del_bus wrappers
[safe/jmp/linux-2.6] / drivers / media / video / cx88 / cx88-core.c
index 9975be1..453af5e 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
+#include <linux/mutex.h>
 
 #include "cx88.h"
 #include <media/v4l2-common.h>
@@ -75,7 +76,7 @@ MODULE_PARM_DESC(nocomb,"disable comb filter");
 
 static unsigned int cx88_devcount;
 static LIST_HEAD(cx88_devlist);
-static DECLARE_MUTEX(devlist);
+static DEFINE_MUTEX(devlist);
 
 #define NO_SYNC_LINE (-1U)
 
@@ -104,7 +105,7 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
                        *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
                        offset+=bpl;
                } else {
-                       /* scanline needs to be splitted */
+                       /* scanline needs to be split */
                        todo = bpl;
                        *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
                                            (sg_dma_len(sg)-offset));
@@ -145,9 +146,11 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
                fields++;
 
        /* estimate risc mem: worst case is one write per page border +
-          one write per scan line + syncs + jump (all 2 dwords) */
-       instructions  = (bpl * lines * fields) / PAGE_SIZE + lines * fields;
-       instructions += 3 + 4;
+          one write per scan line + syncs + jump (all 2 dwords).  Padding
+          can cause next bpl to start close to a page border.  First DMA
+          region may be smaller than PAGE_SIZE */
+       instructions  = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
+       instructions += 2;
        if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
                return rc;
 
@@ -162,7 +165,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
-       BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
        return 0;
 }
 
@@ -175,9 +178,11 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
        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;
+          one write per scan line + syncs + jump (all 2 dwords).  Here
+          there is no padding and no sync.  First DMA region may be smaller
+          than PAGE_SIZE */
+       instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
+       instructions += 1;
        if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
                return rc;
 
@@ -187,7 +192,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
-       BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
        return 0;
 }
 
@@ -212,14 +217,13 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
 }
 
 void
-cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
+cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
 {
-       if (in_interrupt())
-               BUG();
+       BUG_ON(in_interrupt());
        videobuf_waiton(&buf->vb,0,0);
-       videobuf_dma_pci_unmap(pci, &buf->vb.dma);
+       videobuf_dma_unmap(q, &buf->vb.dma);
        videobuf_dma_free(&buf->vb.dma);
-       btcx_riscmem_free(pci, &buf->risc);
+       btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
        buf->vb.state = STATE_NEEDS_INIT;
 }
 
@@ -654,13 +658,6 @@ static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
        return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
 }
 
-static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
-{
-       return (norm->id & V4L2_STD_625_50)
-               ? HLNotchFilter135PAL
-               : HLNotchFilter135NTSC;
-}
-
 static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
 {
        /* Should always be Line Draw Time / (4*FSC) */
@@ -673,7 +670,7 @@ static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
 
 static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
 {
-       return (norm->id & V4L2_STD_625_50) ? 511 : 288;
+       return (norm->id & V4L2_STD_625_50) ? 511 : 400;
 }
 
 int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
@@ -786,20 +783,32 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
 
 int cx88_start_audio_dma(struct cx88_core *core)
 {
+       /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
+       int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
+
+       /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
+       if (cx_read(MO_AUD_DMACNTRL) & 0x10)
+               return 0;
+
        /* setup fifo + format */
-       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_CH25], bpl, 0);
+       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
 
-       cx_write(MO_AUDD_LNGTH,    128); /* fifo bpl size */
-       cx_write(MO_AUDR_LNGTH,    128); /* fifo bpl size */
+       cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
+       cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
 
        /* start dma */
        cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
+
        return 0;
 }
 
 int cx88_stop_audio_dma(struct cx88_core *core)
 {
+       /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
+       if (cx_read(MO_AUD_DMACNTRL) & 0x10)
+               return 0;
+
        /* stop dma */
        cx_write(MO_AUD_DMACNTRL, 0x0000);
 
@@ -921,14 +930,14 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
        // htotal
        tmp64 = norm_htotal(norm) * (u64)vdec_clock;
        do_div(tmp64, fsc8);
-       htotal = (u32)tmp64 | (norm_notchfilter(norm) << 11);
+       htotal = (u32)tmp64 | (HLNotchFilter4xFsc << 11);
        dprintk(1,"set_tvnorm: MO_HTOTAL        0x%08x [old=0x%08x,htotal=%d]\n",
                htotal, cx_read(MO_HTOTAL), (u32)tmp64);
        cx_write(MO_HTOTAL, htotal);
 
-       // vbi stuff
-       cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm)   << 11) | */
-                                norm_vbipack(norm)));
+       // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
+       // the effective vbi offset ~244 samples, the same as the Bt8x8
+       cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
 
        // this is needed as well to set all tvnorm parameter
        cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
@@ -1025,8 +1034,8 @@ static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
                               pci_resource_len(pci,0),
                               core->name))
                return 0;
-       printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
-              core->name,pci_resource_start(pci,0));
+       printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
+              core->name,(unsigned long long)pci_resource_start(pci,0));
        return -EBUSY;
 }
 
@@ -1036,7 +1045,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
        struct list_head *item;
        int i;
 
-       down(&devlist);
+       mutex_lock(&devlist);
        list_for_each(item,&cx88_devlist) {
                core = list_entry(item, struct cx88_core, devlist);
                if (pci->bus->number != core->pci_bus)
@@ -1047,19 +1056,18 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
                if (0 != get_ressources(core,pci))
                        goto fail_unlock;
                atomic_inc(&core->refcount);
-               up(&devlist);
+               mutex_unlock(&devlist);
                return core;
        }
-       core = kmalloc(sizeof(*core),GFP_KERNEL);
+       core = kzalloc(sizeof(*core),GFP_KERNEL);
        if (NULL == core)
                goto fail_unlock;
 
-       memset(core,0,sizeof(*core));
        atomic_inc(&core->refcount);
        core->pci_bus  = pci->bus->number;
        core->pci_slot = PCI_SLOT(pci->devfn);
        core->pci_irqmask = 0x00fc00;
-       init_MUTEX(&core->lock);
+       mutex_init(&core->lock);
 
        core->nr = cx88_devcount++;
        sprintf(core->name,"cx88[%d]",core->nr);
@@ -1118,18 +1126,19 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
 
        /* init hardware */
        cx88_reset(core);
+       cx88_card_setup_pre_i2c(core);
        cx88_i2c_init(core,pci);
        cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
        cx88_card_setup(core);
        cx88_ir_init(core,pci);
 
-       up(&devlist);
+       mutex_unlock(&devlist);
        return core;
 
 fail_free:
        kfree(core);
 fail_unlock:
-       up(&devlist);
+       mutex_unlock(&devlist);
        return NULL;
 }
 
@@ -1141,14 +1150,14 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
        if (!atomic_dec_and_test(&core->refcount))
                return;
 
-       down(&devlist);
+       mutex_lock(&devlist);
        cx88_ir_fini(core);
        if (0 == core->i2c_rc)
-               i2c_bit_del_bus(&core->i2c_adap);
+               i2c_del_adapter(&core->i2c_adap);
        list_del(&core->devlist);
        iounmap(core->lmmio);
        cx88_devcount--;
-       up(&devlist);
+       mutex_unlock(&devlist);
        kfree(core);
 }
 
@@ -1176,8 +1185,6 @@ EXPORT_SYMBOL(cx88_set_scale);
 EXPORT_SYMBOL(cx88_vdev_init);
 EXPORT_SYMBOL(cx88_core_get);
 EXPORT_SYMBOL(cx88_core_put);
-EXPORT_SYMBOL(cx88_start_audio_dma);
-EXPORT_SYMBOL(cx88_stop_audio_dma);
 
 /*
  * Local variables: