summaryrefslogtreecommitdiffstats
path: root/drivers/media/pci/saa7134/saa7134-vbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/pci/saa7134/saa7134-vbi.c')
-rw-r--r--drivers/media/pci/saa7134/saa7134-vbi.c175
1 files changed, 79 insertions, 96 deletions
diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c
index d4da18d..c06dbe1 100644
--- a/drivers/media/pci/saa7134/saa7134-vbi.c
+++ b/drivers/media/pci/saa7134/saa7134-vbi.c
@@ -67,10 +67,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task), 0x00);
saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
- saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width & 0xff);
- saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width >> 8);
- saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height & 0xff);
- saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height >> 8);
+ saa_writeb(SAA7134_VBI_H_LEN1(task), dev->vbi_hlen & 0xff);
+ saa_writeb(SAA7134_VBI_H_LEN2(task), dev->vbi_hlen >> 8);
+ saa_writeb(SAA7134_VBI_V_LEN1(task), dev->vbi_vlen & 0xff);
+ saa_writeb(SAA7134_VBI_V_LEN2(task), dev->vbi_vlen >> 8);
saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
}
@@ -81,14 +81,14 @@ static int buffer_activate(struct saa7134_dev *dev,
struct saa7134_buf *buf,
struct saa7134_buf *next)
{
- unsigned long control,base;
+ struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv;
+ unsigned long control, base;
- dprintk("buffer_activate [%p]\n",buf);
- buf->vb.state = VIDEOBUF_ACTIVE;
+ dprintk("buffer_activate [%p]\n", buf);
buf->top_seen = 0;
- task_init(dev,buf,TASK_A);
- task_init(dev,buf,TASK_B);
+ task_init(dev, buf, TASK_A);
+ task_init(dev, buf, TASK_B);
saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
@@ -96,107 +96,99 @@ static int buffer_activate(struct saa7134_dev *dev,
base = saa7134_buffer_base(buf);
control = SAA7134_RS_CONTROL_BURST_16 |
SAA7134_RS_CONTROL_ME |
- (buf->pt->dma >> 12);
- saa_writel(SAA7134_RS_BA1(2),base);
- saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2);
- saa_writel(SAA7134_RS_PITCH(2),buf->vb.width);
- saa_writel(SAA7134_RS_CONTROL(2),control);
- saa_writel(SAA7134_RS_BA1(3),base);
- saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2);
- saa_writel(SAA7134_RS_PITCH(3),buf->vb.width);
- saa_writel(SAA7134_RS_CONTROL(3),control);
+ (dmaq->pt.dma >> 12);
+ saa_writel(SAA7134_RS_BA1(2), base);
+ saa_writel(SAA7134_RS_BA2(2), base + dev->vbi_hlen * dev->vbi_vlen);
+ saa_writel(SAA7134_RS_PITCH(2), dev->vbi_hlen);
+ saa_writel(SAA7134_RS_CONTROL(2), control);
+ saa_writel(SAA7134_RS_BA1(3), base);
+ saa_writel(SAA7134_RS_BA2(3), base + dev->vbi_hlen * dev->vbi_vlen);
+ saa_writel(SAA7134_RS_PITCH(3), dev->vbi_hlen);
+ saa_writel(SAA7134_RS_CONTROL(3), control);
/* start DMA */
saa7134_set_dmabits(dev);
- mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
+ mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT);
return 0;
}
-static int buffer_prepare(struct videobuf_queue *q,
- struct videobuf_buffer *vb,
- enum v4l2_field field)
+static int buffer_prepare(struct vb2_buffer *vb2)
{
- struct saa7134_dev *dev = q->priv_data;
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
- struct saa7134_tvnorm *norm = dev->tvnorm;
- unsigned int lines, llength, size;
- int err;
-
- lines = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
- if (lines > VBI_LINE_COUNT)
- lines = VBI_LINE_COUNT;
- llength = VBI_LINE_LENGTH;
- size = lines * llength * 2;
- if (0 != buf->vb.baddr && buf->vb.bsize < size)
+ struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+ struct saa7134_dev *dev = dmaq->dev;
+ struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+ struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
+ unsigned int size;
+ int ret;
+
+ if (dma->sgl->offset) {
+ pr_err("The buffer is not page-aligned\n");
return -EINVAL;
-
- if (buf->vb.size != size)
- saa7134_dma_free(q,buf);
-
- if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
- struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
- buf->vb.width = llength;
- buf->vb.height = lines;
- buf->vb.size = size;
- buf->pt = &dev->pt_vbi;
-
- err = videobuf_iolock(q,&buf->vb,NULL);
- if (err)
- goto oops;
- err = saa7134_pgtable_build(dev->pci,buf->pt,
- dma->sglist,
- dma->sglen,
- saa7134_buffer_startpage(buf));
- if (err)
- goto oops;
}
- buf->vb.state = VIDEOBUF_PREPARED;
- buf->activate = buffer_activate;
- buf->vb.field = field;
- return 0;
+ size = dev->vbi_hlen * dev->vbi_vlen * 2;
+ if (vb2_plane_size(vb2, 0) < size)
+ return -EINVAL;
+
+ vb2_set_plane_payload(vb2, 0, size);
- oops:
- saa7134_dma_free(q,buf);
- return err;
+ ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
+ if (!ret)
+ return -EIO;
+ return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
+ saa7134_buffer_startpage(buf));
}
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], void *alloc_ctxs[])
{
- struct saa7134_dev *dev = q->priv_data;
- int llength,lines;
-
- lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
- llength = VBI_LINE_LENGTH;
- *size = lines * llength * 2;
- if (0 == *count)
- *count = vbibufs;
- *count = saa7134_buffer_count(*size,*count);
+ struct saa7134_dmaqueue *dmaq = q->drv_priv;
+ struct saa7134_dev *dev = dmaq->dev;
+ unsigned int size;
+
+ dev->vbi_vlen = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 + 1;
+ if (dev->vbi_vlen > VBI_LINE_COUNT)
+ dev->vbi_vlen = VBI_LINE_COUNT;
+ dev->vbi_hlen = VBI_LINE_LENGTH;
+ size = dev->vbi_hlen * dev->vbi_vlen * 2;
+
+ *nbuffers = saa7134_buffer_count(size, *nbuffers);
+ *nplanes = 1;
+ sizes[0] = size;
return 0;
}
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+static int buffer_init(struct vb2_buffer *vb2)
{
- struct saa7134_dev *dev = q->priv_data;
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
+ struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+ struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
- saa7134_buffer_queue(dev,&dev->vbi_q,buf);
+ dmaq->curr = NULL;
+ buf->activate = buffer_activate;
+ return 0;
}
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb2)
{
- struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
+ struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+ struct saa7134_dev *dev = dmaq->dev;
+ struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+ struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
- saa7134_dma_free(q,buf);
+ dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
}
-struct videobuf_queue_ops saa7134_vbi_qops = {
- .buf_setup = buffer_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = buffer_release,
+struct vb2_ops saa7134_vbi_qops = {
+ .queue_setup = queue_setup,
+ .buf_init = buffer_init,
+ .buf_prepare = buffer_prepare,
+ .buf_finish = buffer_finish,
+ .buf_queue = saa7134_vb2_buffer_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = saa7134_vb2_start_streaming,
+ .stop_streaming = saa7134_vb2_stop_streaming,
};
/* ------------------------------------------------------------------ */
@@ -226,7 +218,6 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
{
spin_lock(&dev->slock);
if (dev->vbi_q.curr) {
- dev->vbi_fieldcount++;
/* make sure we have seen both fields */
if ((status & 0x10) == 0x00) {
dev->vbi_q.curr->top_seen = 1;
@@ -235,18 +226,10 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
if (!dev->vbi_q.curr->top_seen)
goto done;
- dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
- saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE);
+ saa7134_buffer_finish(dev, &dev->vbi_q, VB2_BUF_STATE_DONE);
}
- saa7134_buffer_next(dev,&dev->vbi_q);
+ saa7134_buffer_next(dev, &dev->vbi_q);
done:
spin_unlock(&dev->slock);
}
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
OpenPOWER on IntegriCloud