Commit 643e8350 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

media: cx18: convert to vb2



This patch converts cx18 from the old deprecated videobuf framework
to the 'new' vb2 framework.

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 5f225889
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ config VIDEO_CX18
	tristate "Conexant cx23418 MPEG encoder support"
	depends on VIDEO_DEV && DVB_CORE && PCI && I2C
	select I2C_ALGOBIT
	select VIDEOBUF_VMALLOC
	select VIDEOBUF2_VMALLOC
	depends on RC_CORE
	select VIDEO_TUNER
	select VIDEO_TVEEPROM
+12 −12
Original line number Diff line number Diff line
@@ -48,9 +48,8 @@
#include <media/dvb_net.h>
#include <media/dvbdev.h>

/* Videobuf / YUV support */
#include <media/videobuf-core.h>
#include <media/videobuf-vmalloc.h>
/* vb2 YUV support */
#include <media/videobuf2-vmalloc.h>

#ifndef CONFIG_PCI
#  error "This driver requires kernel PCI support."
@@ -284,6 +283,14 @@ struct cx18_options {
#define list_entry_is_past_end(pos, head, member) \
	(&pos->member == (head))

struct cx18_vb2_buffer {
	/* Common video buffer sub-system struct */
	struct vb2_v4l2_buffer vb;
	struct list_head list;
	v4l2_std_id tvnorm; /* selected tv norm */
	u32 bytes_used;
};

struct cx18_buffer {
	struct list_head list;
	dma_addr_t dma_handle;
@@ -399,19 +406,12 @@ struct cx18_stream {
	struct list_head vb_capture;    /* video capture queue */
	spinlock_t vb_lock;
	struct timer_list vb_timeout;
	u32 sequence;

	struct videobuf_queue vbuf_q;
	spinlock_t vbuf_q_lock; /* Protect vbuf_q */
	struct vb2_queue vidq;
	enum v4l2_buf_type vb_type;
};

struct cx18_videobuf_buffer {
	/* Common video buffer sub-system struct */
	struct videobuf_buffer vb;
	v4l2_std_id tvnorm; /* selected tv norm */
	u32 bytes_used;
};

struct cx18_open_id {
	struct v4l2_fh fh;
	u32 open_id;
+16 −69
Original line number Diff line number Diff line
@@ -584,12 +584,6 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
	if (rc)
		return rc;

	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
		return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
			filp->f_flags & O_NONBLOCK);
	}

	return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
}

@@ -618,17 +612,6 @@ __poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
		CX18_DEBUG_FILE("Encoder poll started capture\n");
	}

	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
		__poll_t videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);

		if (v4l2_event_pending(&id->fh))
			res |= EPOLLPRI;
		if (eof && videobuf_poll == EPOLLERR)
			return res | EPOLLHUP;
		return res | videobuf_poll;
	}

	/* add stream's waitq to the poll list */
	CX18_DEBUG_HI_FILE("Encoder poll\n");
	if (v4l2_event_pending(&id->fh))
@@ -643,62 +626,20 @@ __poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
	return res;
}

int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
	int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);

	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {

		/* Start a capture if there is none */
		if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
			int rc;

			mutex_lock(&cx->serialize_lock);
			rc = cx18_start_capture(id);
			mutex_unlock(&cx->serialize_lock);
			if (rc) {
				CX18_DEBUG_INFO(
					"Could not start capture for %s (%d)\n",
					s->name, rc);
				return -EINVAL;
			}
			CX18_DEBUG_FILE("Encoder mmap started capture\n");
		}

		return videobuf_mmap_mapper(&s->vbuf_q, vma);
	}

	return -EINVAL;
}

void cx18_vb_timeout(struct timer_list *t)
{
	struct cx18_stream *s = from_timer(s, t, vb_timeout);
	struct cx18_videobuf_buffer *buf;
	unsigned long flags;

	/* Return all of the buffers in error state, so the vbi/vid inode
	/*
	 * Return all of the buffers in error state, so the vbi/vid inode
	 * can return from blocking.
	 */
	spin_lock_irqsave(&s->vb_lock, flags);
	while (!list_empty(&s->vb_capture)) {
		buf = list_entry(s->vb_capture.next,
			struct cx18_videobuf_buffer, vb.queue);
		list_del(&buf->vb.queue);
		buf->vb.state = VIDEOBUF_ERROR;
		wake_up(&buf->vb.done);
	}
	spin_unlock_irqrestore(&s->vb_lock, flags);
	cx18_clear_queue(s, VB2_BUF_STATE_ERROR);
}

void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
void cx18_stop_capture(struct cx18_stream *s, int gop_end)
{
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
	struct cx18 *cx = s->cx;
	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
	struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];

@@ -709,7 +650,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
	/* Stop capturing */
	if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
		CX18_DEBUG_INFO("close stopping capture\n");
		if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
		if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
			/* Stop internal use associated VBI and IDX streams */
			if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
@@ -721,7 +662,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
				cx18_stop_v4l2_encode_stream(s_idx, 0);
			}
		}
		if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
		if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
		    test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
			/* Also used internally, don't stop capturing */
			s->id = -1;
@@ -741,6 +682,7 @@ int cx18_v4l2_close(struct file *filp)
	struct cx18_open_id *id = fh2id(fh);
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
	struct video_device *vdev = &s->video_dev;

	CX18_DEBUG_IOCTL("close() of %s\n", s->name);

@@ -766,12 +708,17 @@ int cx18_v4l2_close(struct file *filp)
		cx18_unmute(cx);
	}

	if (id->type == CX18_ENC_STREAM_TYPE_YUV &&
	    filp->private_data == vdev->queue->owner) {
		vb2_queue_release(vdev->queue);
		vdev->queue->owner = NULL;
	}
	v4l2_fh_del(fh);
	v4l2_fh_exit(fh);

	/* 'Unclaim' this stream */
	if (s->id == id->open_id)
		cx18_stop_capture(id, 0);
	if (id->type != CX18_ENC_STREAM_TYPE_YUV && s->id == id->open_id)
		cx18_stop_capture(s, 0);
	kfree(id);
	mutex_unlock(&cx->serialize_lock);
	return 0;
+2 −1
Original line number Diff line number Diff line
@@ -16,10 +16,11 @@ ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count,
int cx18_v4l2_close(struct file *filp);
__poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait);
int cx18_start_capture(struct cx18_open_id *id);
void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
void cx18_stop_capture(struct cx18_stream *s, int gop_end);
void cx18_mute(struct cx18 *cx);
void cx18_unmute(struct cx18 *cx);
int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma);
void cx18_clear_queue(struct cx18_stream *s, enum vb2_buffer_state state);
void cx18_vb_timeout(struct timer_list *t);

/* Shared with cx18-alsa module */
+10 −118
Original line number Diff line number Diff line
@@ -803,117 +803,6 @@ static int cx18_g_enc_index(struct file *file, void *fh,
	return 0;
}

static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
{
	struct videobuf_queue *q = NULL;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	switch (s->vb_type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
		q = &s->vbuf_q;
		break;
	case V4L2_BUF_TYPE_VBI_CAPTURE:
		break;
	default:
		break;
	}
	return q;
}

static int cx18_streamon(struct file *file, void *priv,
	enum v4l2_buf_type type)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	/* Start the hardware only if we're the video device */
	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
		return -EINVAL;

	if (id->type != CX18_ENC_STREAM_TYPE_YUV)
		return -EINVAL;

	/* Establish a buffer timeout */
	mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);

	return videobuf_streamon(cx18_vb_queue(id));
}

static int cx18_streamoff(struct file *file, void *priv,
	enum v4l2_buf_type type)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	/* Start the hardware only if we're the video device */
	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
		return -EINVAL;

	if (id->type != CX18_ENC_STREAM_TYPE_YUV)
		return -EINVAL;

	return videobuf_streamoff(cx18_vb_queue(id));
}

static int cx18_reqbufs(struct file *file, void *priv,
	struct v4l2_requestbuffers *rb)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
		return -EINVAL;

	return videobuf_reqbufs(cx18_vb_queue(id), rb);
}

static int cx18_querybuf(struct file *file, void *priv,
	struct v4l2_buffer *b)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
		return -EINVAL;

	return videobuf_querybuf(cx18_vb_queue(id), b);
}

static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
		return -EINVAL;

	return videobuf_qbuf(cx18_vb_queue(id), b);
}

static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
		return -EINVAL;

	return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
}

static int cx18_encoder_cmd(struct file *file, void *fh,
				struct v4l2_encoder_cmd *enc)
{
@@ -930,7 +819,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh,
	case V4L2_ENC_CMD_STOP:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
		enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
		cx18_stop_capture(id,
		cx18_stop_capture(&cx->streams[id->type],
				  enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
		break;

@@ -1106,12 +995,15 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
	.vidioc_s_register              = cx18_s_register,
#endif
	.vidioc_default                 = cx18_default,
	.vidioc_streamon                = cx18_streamon,
	.vidioc_streamoff               = cx18_streamoff,
	.vidioc_reqbufs                 = cx18_reqbufs,
	.vidioc_querybuf                = cx18_querybuf,
	.vidioc_qbuf                    = cx18_qbuf,
	.vidioc_dqbuf                   = cx18_dqbuf,

	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
	.vidioc_querybuf		= vb2_ioctl_querybuf,
	.vidioc_qbuf			= vb2_ioctl_qbuf,
	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
	.vidioc_streamon		= vb2_ioctl_streamon,
	.vidioc_streamoff		= vb2_ioctl_streamoff,
	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
};
Loading