Commit 05439b1a authored by Shuah Khan's avatar Shuah Khan Committed by Mauro Carvalho Chehab
Browse files

[media] media: au0828 - convert to use videobuf2



Convert au0828 to use videobuf2. Tested with NTSC.
Tested video and vbi devices with xawtv, tvtime,
and vlc. Ran v4l2-compliance to ensure there are
no failures.

Video compliance test results summary:
Total: 75, Succeeded: 75, Failed: 0, Warnings: 18

Vbi compliance test results summary:
Total: 75, Succeeded: 75, Failed: 0, Warnings: 0

Signed-off-by: default avatarShuah Khan <shuahkh@osg.samsung.com>
Reviewed-by: default avatarLad, Prabhakar <prabhakar.csengg@gmail.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 9bc1022f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ config VIDEO_AU0828
	depends on I2C && INPUT && DVB_CORE && USB
	select I2C_ALGOBIT
	select VIDEO_TVEEPROM
	select VIDEOBUF_VMALLOC
	select VIDEOBUF2_VMALLOC
	select DVB_AU8522_DTV if MEDIA_SUBDRV_AUTOSELECT
	select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
	select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
+39 −83
Original line number Diff line number Diff line
@@ -28,111 +28,67 @@
#include <linux/init.h>
#include <linux/slab.h>

static unsigned int vbibufs = 5;
module_param(vbibufs, int, 0644);
MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");

/* ------------------------------------------------------------------ */

static void
free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
			   unsigned int *nbuffers, unsigned int *nplanes,
			   unsigned int sizes[], void *alloc_ctxs[])
{
	struct au0828_fh     *fh  = vq->priv_data;
	struct au0828_dev    *dev = fh->dev;
	unsigned long flags = 0;
	if (in_interrupt())
		BUG();
	struct au0828_dev *dev = vb2_get_drv_priv(vq);
	unsigned long img_size = dev->vbi_width * dev->vbi_height * 2;
	unsigned long size;

	/* We used to wait for the buffer to finish here, but this didn't work
	   because, as we were keeping the state as VIDEOBUF_QUEUED,
	   videobuf_queue_cancel marked it as finished for us.
	   (Also, it could wedge forever if the hardware was misconfigured.)

	   This should be safe; by the time we get here, the buffer isn't
	   queued anymore. If we ever start marking the buffers as
	   VIDEOBUF_ACTIVE, it won't be, though.
	*/
	spin_lock_irqsave(&dev->slock, flags);
	if (dev->isoc_ctl.vbi_buf == buf)
		dev->isoc_ctl.vbi_buf = NULL;
	spin_unlock_irqrestore(&dev->slock, flags);

	videobuf_vmalloc_free(&buf->vb);
	buf->vb.state = VIDEOBUF_NEEDS_INIT;
}

static int
vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
{
	struct au0828_fh     *fh  = q->priv_data;
	struct au0828_dev    *dev = fh->dev;
	size = fmt ? (fmt->fmt.vbi.samples_per_line *
		(fmt->fmt.vbi.count[0] + fmt->fmt.vbi.count[1])) : img_size;
	if (size < img_size)
		return -EINVAL;

	*size = dev->vbi_width * dev->vbi_height * 2;
	*nplanes = 1;
	sizes[0] = size;

	if (0 == *count)
		*count = vbibufs;
	if (*count < 2)
		*count = 2;
	if (*count > 32)
		*count = 32;
	return 0;
}

static int
vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
	    enum v4l2_field field)
static int vbi_buffer_prepare(struct vb2_buffer *vb)
{
	struct au0828_fh     *fh  = q->priv_data;
	struct au0828_dev    *dev = fh->dev;
	struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
	struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
	int                  rc = 0;
	unsigned long size;

	buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
	size = dev->vbi_width * dev->vbi_height * 2;

	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
	if (vb2_plane_size(vb, 0) < size) {
		pr_err("%s data will not fit into plane (%lu < %lu)\n",
			__func__, vb2_plane_size(vb, 0), size);
		return -EINVAL;

	buf->vb.width  = dev->vbi_width;
	buf->vb.height = dev->vbi_height;
	buf->vb.field  = field;

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		rc = videobuf_iolock(q, &buf->vb, NULL);
		if (rc < 0)
			goto fail;
	}
	vb2_set_plane_payload(&buf->vb, 0, size);

	buf->vb.state = VIDEOBUF_PREPARED;
	return 0;

fail:
	free_buffer(q, buf);
	return rc;
}

static void
vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
vbi_buffer_queue(struct vb2_buffer *vb)
{
	struct au0828_buffer    *buf     = container_of(vb,
							struct au0828_buffer,
							vb);
	struct au0828_fh        *fh      = vq->priv_data;
	struct au0828_dev       *dev     = fh->dev;
	struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
	struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
	struct au0828_dmaqueue *vbiq = &dev->vbiq;
	unsigned long flags = 0;

	buf->vb.state = VIDEOBUF_QUEUED;
	list_add_tail(&buf->vb.queue, &vbiq->active);
}
	buf->mem = vb2_plane_vaddr(vb, 0);
	buf->length = vb2_plane_size(vb, 0);

static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
	struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
	free_buffer(q, buf);
	spin_lock_irqsave(&dev->slock, flags);
	list_add_tail(&buf->list, &vbiq->active);
	spin_unlock_irqrestore(&dev->slock, flags);
}

struct videobuf_queue_ops au0828_vbi_qops = {
	.buf_setup    = vbi_setup,
	.buf_prepare  = vbi_prepare,
	.buf_queue    = vbi_queue,
	.buf_release  = vbi_release,
struct vb2_ops au0828_vbi_qops = {
	.queue_setup     = vbi_queue_setup,
	.buf_prepare     = vbi_buffer_prepare,
	.buf_queue       = vbi_buffer_queue,
	.start_streaming = au0828_start_analog_streaming,
	.stop_streaming  = au0828_stop_vbi_streaming,
	.wait_prepare    = vb2_ops_wait_prepare,
	.wait_finish     = vb2_ops_wait_finish,
};