Commit 7c617138 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: cx231xx: convert to the vb2 framework

This patch converts the cx231xx driver to the vb2 framework.
Since you can't do a partial conversion this is a big-bang patch,
i.e. large and hard to review. I never found a way around this.
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Co-developed-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 7e86efa2
...@@ -4,7 +4,7 @@ config VIDEO_CX231XX ...@@ -4,7 +4,7 @@ config VIDEO_CX231XX
depends on VIDEO_DEV && I2C && I2C_MUX depends on VIDEO_DEV && I2C && I2C_MUX
select VIDEO_TUNER select VIDEO_TUNER
select VIDEO_TVEEPROM select VIDEO_TVEEPROM
select VIDEOBUF_VMALLOC select VIDEOBUF2_VMALLOC
select VIDEO_CX25840 select VIDEO_CX25840
select VIDEO_CX2341X select VIDEO_CX2341X
......
This diff is collapsed.
...@@ -1479,13 +1479,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, ...@@ -1479,13 +1479,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
goto err_dev_init; goto err_dev_init;
} }
/* init video dma queues */ /* init video dma queue */
INIT_LIST_HEAD(&dev->video_mode.vidq.active); INIT_LIST_HEAD(&dev->video_mode.vidq.active);
INIT_LIST_HEAD(&dev->video_mode.vidq.queued);
/* init vbi dma queues */ /* init vbi dma queue */
INIT_LIST_HEAD(&dev->vbi_mode.vidq.active); INIT_LIST_HEAD(&dev->vbi_mode.vidq.active);
INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued);
/* Reset other chips required if they are tied up with GPIO pins */ /* Reset other chips required if they are tied up with GPIO pins */
cx231xx_add_into_devlist(dev); cx231xx_add_into_devlist(dev);
......
...@@ -153,131 +153,98 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb) ...@@ -153,131 +153,98 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
Vbi buf operations Vbi buf operations
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
static int static int vbi_queue_setup(struct vb2_queue *vq,
vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *nbuffers, unsigned int *nplanes,
unsigned int *size) unsigned int sizes[], struct device *alloc_devs[])
{ {
struct cx231xx_fh *fh = vq->priv_data; struct cx231xx *dev = vb2_get_drv_priv(vq);
struct cx231xx *dev = fh->dev;
u32 height = 0; u32 height = 0;
height = ((dev->norm & V4L2_STD_625_50) ? height = ((dev->norm & V4L2_STD_625_50) ?
PAL_VBI_LINES : NTSC_VBI_LINES); PAL_VBI_LINES : NTSC_VBI_LINES);
*size = (dev->width * height * 2 * 2); *nplanes = 1;
if (0 == *count) sizes[0] = (dev->width * height * 2 * 2);
*count = CX231XX_DEF_VBI_BUF;
if (*count < CX231XX_MIN_BUF)
*count = CX231XX_MIN_BUF;
return 0; return 0;
} }
/* This is called *without* dev->slock held; please keep it that way */ /* This is called *without* dev->slock held; please keep it that way */
static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) static int vbi_buf_prepare(struct vb2_buffer *vb)
{
struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx *dev = fh->dev;
unsigned long flags = 0;
BUG_ON(in_interrupt());
/* 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->vbi_mode.slock, flags);
if (dev->vbi_mode.bulk_ctl.buf == buf)
dev->vbi_mode.bulk_ctl.buf = NULL;
spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
videobuf_vmalloc_free(&buf->vb);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
}
static int
vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
enum v4l2_field field)
{ {
struct cx231xx_fh *fh = vq->priv_data; struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue);
struct cx231xx_buffer *buf =
container_of(vb, struct cx231xx_buffer, vb);
struct cx231xx *dev = fh->dev;
int rc = 0, urb_init = 0;
u32 height = 0; u32 height = 0;
u32 size;
height = ((dev->norm & V4L2_STD_625_50) ? height = ((dev->norm & V4L2_STD_625_50) ?
PAL_VBI_LINES : NTSC_VBI_LINES); PAL_VBI_LINES : NTSC_VBI_LINES);
buf->vb.size = ((dev->width << 1) * height * 2); size = ((dev->width << 1) * height * 2);
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) if (vb2_plane_size(vb, 0) < size)
return -EINVAL; return -EINVAL;
vb2_set_plane_payload(vb, 0, size);
buf->vb.width = dev->width;
buf->vb.height = height;
buf->vb.field = field;
buf->vb.field = V4L2_FIELD_SEQ_TB;
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
rc = videobuf_iolock(vq, &buf->vb, NULL);
if (rc < 0)
goto fail;
}
if (!dev->vbi_mode.bulk_ctl.num_bufs)
urb_init = 1;
if (urb_init) {
rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
CX231XX_NUM_VBI_BUFS,
dev->vbi_mode.alt_max_pkt_size[0],
cx231xx_isoc_vbi_copy);
if (rc < 0)
goto fail;
}
buf->vb.state = VIDEOBUF_PREPARED;
return 0; return 0;
fail:
free_buffer(vq, buf);
return rc;
} }
static void static void vbi_buf_queue(struct vb2_buffer *vb)
vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{ {
struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue);
struct cx231xx_buffer *buf = struct cx231xx_buffer *buf =
container_of(vb, struct cx231xx_buffer, vb); container_of(vb, struct cx231xx_buffer, vb.vb2_buf);
struct cx231xx_fh *fh = vq->priv_data;
struct cx231xx *dev = fh->dev;
struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq; struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
unsigned long flags;
buf->vb.state = VIDEOBUF_QUEUED; spin_lock_irqsave(&dev->vbi_mode.slock, flags);
list_add_tail(&buf->vb.queue, &vidq->active); list_add_tail(&buf->list, &vidq->active);
spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
}
static void return_all_buffers(struct cx231xx *dev,
enum vb2_buffer_state state)
{
struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
struct cx231xx_buffer *buf, *node;
unsigned long flags;
spin_lock_irqsave(&dev->vbi_mode.slock, flags);
dev->vbi_mode.bulk_ctl.buf = NULL;
list_for_each_entry_safe(buf, node, &vidq->active, list) {
list_del(&buf->list);
vb2_buffer_done(&buf->vb.vb2_buf, state);
}
spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
} }
static void vbi_buffer_release(struct videobuf_queue *vq, static int vbi_start_streaming(struct vb2_queue *vq, unsigned int count)
struct videobuf_buffer *vb)
{ {
struct cx231xx_buffer *buf = struct cx231xx *dev = vb2_get_drv_priv(vq);
container_of(vb, struct cx231xx_buffer, vb); struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
int ret;
vidq->sequence = 0;
ret = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
CX231XX_NUM_VBI_BUFS,
dev->vbi_mode.alt_max_pkt_size[0],
cx231xx_isoc_vbi_copy);
if (ret)
return_all_buffers(dev, VB2_BUF_STATE_QUEUED);
return ret;
}
static void vbi_stop_streaming(struct vb2_queue *vq)
{
struct cx231xx *dev = vb2_get_drv_priv(vq);
free_buffer(vq, buf); return_all_buffers(dev, VB2_BUF_STATE_ERROR);
} }
const struct videobuf_queue_ops cx231xx_vbi_qops = { struct vb2_ops cx231xx_vbi_qops = {
.buf_setup = vbi_buffer_setup, .queue_setup = vbi_queue_setup,
.buf_prepare = vbi_buffer_prepare, .buf_prepare = vbi_buf_prepare,
.buf_queue = vbi_buffer_queue, .buf_queue = vbi_buf_queue,
.buf_release = vbi_buffer_release, .start_streaming = vbi_start_streaming,
.stop_streaming = vbi_stop_streaming,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
}; };
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
...@@ -512,16 +479,15 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, ...@@ -512,16 +479,15 @@ static inline void vbi_buffer_filled(struct cx231xx *dev,
struct cx231xx_buffer *buf) struct cx231xx_buffer *buf)
{ {
/* Advice that buffer was filled */ /* Advice that buffer was filled */
/* dev_dbg(dev->dev, "[%p/%d] wakeup\n", buf, buf->vb.i); */ /* dev_dbg(dev->dev, "[%p/%d] wakeup\n", buf, buf->vb.index); */
buf->vb.state = VIDEOBUF_DONE; buf->vb.sequence = dma_q->sequence++;
buf->vb.field_count++; buf->vb.vb2_buf.timestamp = ktime_get_ns();
buf->vb.ts = ktime_get_ns();
dev->vbi_mode.bulk_ctl.buf = NULL; dev->vbi_mode.bulk_ctl.buf = NULL;
list_del(&buf->vb.queue); list_del(&buf->list);
wake_up(&buf->vb.done); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
} }
u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
...@@ -611,11 +577,11 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, ...@@ -611,11 +577,11 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
} }
/* Get the next buffer */ /* Get the next buffer */
*buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue); *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, list);
/* Cleans up buffer - Useful for testing for frame/URB loss */ /* Cleans up buffer - Useful for testing for frame/URB loss */
outp = videobuf_to_vmalloc(&(*buf)->vb); outp = vb2_plane_vaddr(&(*buf)->vb.vb2_buf, 0);
memset(outp, 0, (*buf)->vb.size); memset(outp, 0, vb2_plane_size(&(*buf)->vb.vb2_buf, 0));
dev->vbi_mode.bulk_ctl.buf = *buf; dev->vbi_mode.bulk_ctl.buf = *buf;
...@@ -656,7 +622,7 @@ int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, ...@@ -656,7 +622,7 @@ int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
if (buf == NULL) if (buf == NULL)
return -EINVAL; return -EINVAL;
p_out_buffer = videobuf_to_vmalloc(&buf->vb); p_out_buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
if (dma_q->bytes_left_in_line != _line_size) { if (dma_q->bytes_left_in_line != _line_size) {
current_line_bytes_copied = current_line_bytes_copied =
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#ifndef _CX231XX_VBI_H #ifndef _CX231XX_VBI_H
#define _CX231XX_VBI_H #define _CX231XX_VBI_H
extern const struct videobuf_queue_ops cx231xx_vbi_qops; extern struct vb2_ops cx231xx_vbi_qops;
#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */ #define NTSC_VBI_START_LINE 10 /* line 10 - 21 */
#define NTSC_VBI_END_LINE 21 #define NTSC_VBI_END_LINE 21
......
This diff is collapsed.
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <media/drv-intf/cx2341x.h> #include <media/drv-intf/cx2341x.h>
#include <media/videobuf-vmalloc.h> #include <media/videobuf2-vmalloc.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h> #include <media/v4l2-fh.h>
...@@ -223,8 +223,8 @@ struct cx231xx_fmt { ...@@ -223,8 +223,8 @@ struct cx231xx_fmt {
/* buffer for one video frame */ /* buffer for one video frame */
struct cx231xx_buffer { struct cx231xx_buffer {
/* common v4l buffer stuff -- must be first */ /* common v4l buffer stuff -- must be first */
struct videobuf_buffer vb; struct vb2_v4l2_buffer vb;
struct list_head list;
struct list_head frame; struct list_head frame;
int top_field; int top_field;
int receiving; int receiving;
...@@ -237,7 +237,6 @@ enum ps_package_head { ...@@ -237,7 +237,6 @@ enum ps_package_head {
struct cx231xx_dmaqueue { struct cx231xx_dmaqueue {
struct list_head active; struct list_head active;
struct list_head queued;
wait_queue_head_t wq; wait_queue_head_t wq;
...@@ -251,6 +250,7 @@ struct cx231xx_dmaqueue { ...@@ -251,6 +250,7 @@ struct cx231xx_dmaqueue {
u32 lines_completed; u32 lines_completed;
u8 field1_done; u8 field1_done;
u32 lines_per_field; u32 lines_per_field;
u32 sequence;
/*Mpeg2 control buffer*/ /*Mpeg2 control buffer*/
u8 *p_left_data; u8 *p_left_data;
...@@ -427,23 +427,6 @@ struct cx231xx_audio { ...@@ -427,23 +427,6 @@ struct cx231xx_audio {
struct cx231xx; struct cx231xx;
struct cx231xx_fh {
struct v4l2_fh fh;
struct cx231xx *dev;
unsigned int stream_on:1; /* Locks streams */
enum v4l2_buf_type type;
struct videobuf_queue vb_vidq;
/* vbi capture */
struct videobuf_queue vidq;
struct videobuf_queue vbiq;
/* MPEG Encoder specifics ONLY */
atomic_t v4l_reading;
};
/*****************************************************************/ /*****************************************************************/
/* set/get i2c */ /* set/get i2c */
/* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */ /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
...@@ -634,6 +617,7 @@ struct cx231xx { ...@@ -634,6 +617,7 @@ struct cx231xx {
int width; /* current frame width */ int width; /* current frame width */
int height; /* current frame height */ int height; /* current frame height */
int interlaced; /* 1=interlace fields, 0=just top fields */ int interlaced; /* 1=interlace fields, 0=just top fields */
unsigned int size;
struct cx231xx_audio adev; struct cx231xx_audio adev;
...@@ -657,6 +641,9 @@ struct cx231xx { ...@@ -657,6 +641,9 @@ struct cx231xx {
struct media_pad input_pad[MAX_CX231XX_INPUT]; struct media_pad input_pad[MAX_CX231XX_INPUT];
#endif #endif
struct vb2_queue vidq;
struct vb2_queue vbiq;
unsigned char eedata[256]; unsigned char eedata[256];
struct cx231xx_video_mode video_mode; struct cx231xx_video_mode video_mode;
...@@ -717,6 +704,7 @@ struct cx231xx { ...@@ -717,6 +704,7 @@ struct cx231xx {
u8 USE_ISO; u8 USE_ISO;
struct cx231xx_tvnorm encodernorm; struct cx231xx_tvnorm encodernorm;
struct cx231xx_tsport ts1, ts2; struct cx231xx_tsport ts1, ts2;
struct vb2_queue mpegq;
struct video_device v4l_device; struct video_device v4l_device;
atomic_t v4l_reader_count; atomic_t v4l_reader_count;
u32 freq; u32 freq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment