mirror of
https://github.com/torvalds/linux.git
synced 2024-11-13 07:31:45 +00:00
[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: Shuah Khan <shuahkh@osg.samsung.com> Reviewed-by: Lad, Prabhakar <prabhakar.csengg@gmail.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
9bc1022f51
commit
05439b1a36
@ -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
|
||||
|
@ -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 = dev->vbi_width * dev->vbi_height * 2;
|
||||
|
||||
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)
|
||||
{
|
||||
struct au0828_fh *fh = q->priv_data;
|
||||
struct au0828_dev *dev = fh->dev;
|
||||
struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
|
||||
int rc = 0;
|
||||
|
||||
buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
|
||||
|
||||
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
|
||||
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;
|
||||
|
||||
buf->vb.width = dev->vbi_width;
|
||||
buf->vb.height = dev->vbi_height;
|
||||
buf->vb.field = field;
|
||||
*nplanes = 1;
|
||||
sizes[0] = size;
|
||||
|
||||
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
||||
rc = videobuf_iolock(q, &buf->vb, NULL);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
buf->vb.state = VIDEOBUF_PREPARED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fail:
|
||||
free_buffer(q, buf);
|
||||
return rc;
|
||||
static int vbi_buffer_prepare(struct vb2_buffer *vb)
|
||||
{
|
||||
struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
|
||||
unsigned long size;
|
||||
|
||||
size = dev->vbi_width * dev->vbi_height * 2;
|
||||
|
||||
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;
|
||||
}
|
||||
vb2_set_plane_payload(&buf->vb, 0, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
vbi_queue(struct videobuf_queue *vq, struct videobuf_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_dmaqueue *vbiq = &dev->vbiq;
|
||||
|
||||
buf->vb.state = VIDEOBUF_QUEUED;
|
||||
list_add_tail(&buf->vb.queue, &vbiq->active);
|
||||
}
|
||||
|
||||
static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
vbi_buffer_queue(struct vb2_buffer *vb)
|
||||
{
|
||||
struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
|
||||
free_buffer(q, buf);
|
||||
struct au0828_dmaqueue *vbiq = &dev->vbiq;
|
||||
unsigned long flags = 0;
|
||||
|
||||
buf->mem = vb2_plane_vaddr(vb, 0);
|
||||
buf->length = vb2_plane_size(vb, 0);
|
||||
|
||||
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,
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,7 +28,7 @@
|
||||
|
||||
/* Analog */
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/videobuf-vmalloc.h>
|
||||
#include <media/videobuf2-vmalloc.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-fh.h>
|
||||
@ -126,17 +126,7 @@ enum au0828_dev_state {
|
||||
DEV_MISCONFIGURED = 0x04
|
||||
};
|
||||
|
||||
struct au0828_fh {
|
||||
/* must be the first field of this struct! */
|
||||
struct v4l2_fh fh;
|
||||
|
||||
struct au0828_dev *dev;
|
||||
unsigned int resources;
|
||||
|
||||
struct videobuf_queue vb_vidq;
|
||||
struct videobuf_queue vb_vbiq;
|
||||
enum v4l2_buf_type type;
|
||||
};
|
||||
struct au0828_dev;
|
||||
|
||||
struct au0828_usb_isoc_ctl {
|
||||
/* max packet size of isoc transaction */
|
||||
@ -177,21 +167,20 @@ struct au0828_usb_isoc_ctl {
|
||||
/* buffer for one video frame */
|
||||
struct au0828_buffer {
|
||||
/* common v4l buffer stuff -- must be first */
|
||||
struct videobuf_buffer vb;
|
||||
struct vb2_buffer vb;
|
||||
struct list_head list;
|
||||
|
||||
struct list_head frame;
|
||||
void *mem;
|
||||
unsigned long length;
|
||||
int top_field;
|
||||
int receiving;
|
||||
/* pointer to vmalloc memory address in vb */
|
||||
char *vb_buf;
|
||||
};
|
||||
|
||||
struct au0828_dmaqueue {
|
||||
struct list_head active;
|
||||
struct list_head queued;
|
||||
|
||||
wait_queue_head_t wq;
|
||||
|
||||
/* Counters to control buffer fill */
|
||||
int pos;
|
||||
int pos;
|
||||
};
|
||||
|
||||
struct au0828_dev {
|
||||
@ -220,14 +209,26 @@ struct au0828_dev {
|
||||
struct au0828_rc *ir;
|
||||
#endif
|
||||
|
||||
int users;
|
||||
unsigned int resources; /* resources in use */
|
||||
struct video_device *vdev;
|
||||
struct video_device *vbi_dev;
|
||||
|
||||
/* Videobuf2 */
|
||||
struct vb2_queue vb_vidq;
|
||||
struct vb2_queue vb_vbiq;
|
||||
struct mutex vb_queue_lock;
|
||||
struct mutex vb_vbi_queue_lock;
|
||||
|
||||
unsigned int frame_count;
|
||||
unsigned int vbi_frame_count;
|
||||
|
||||
struct timer_list vid_timeout;
|
||||
int vid_timeout_running;
|
||||
struct timer_list vbi_timeout;
|
||||
int vbi_timeout_running;
|
||||
|
||||
int users;
|
||||
int streaming_users;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int vbi_width;
|
||||
@ -242,7 +243,6 @@ struct au0828_dev {
|
||||
__u8 isoc_in_endpointaddr;
|
||||
u8 isoc_init_ok;
|
||||
int greenscreen_detected;
|
||||
unsigned int frame_count;
|
||||
int ctrl_freq;
|
||||
int input_type;
|
||||
int std_set_in_tuner_core;
|
||||
@ -277,6 +277,7 @@ struct au0828_dev {
|
||||
char *dig_transfer_buffer[URB_COUNT];
|
||||
};
|
||||
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
#define au0828_read(dev, reg) au0828_readreg(dev, reg)
|
||||
#define au0828_write(dev, reg, value) au0828_writereg(dev, reg, value)
|
||||
@ -309,13 +310,15 @@ extern int au0828_i2c_unregister(struct au0828_dev *dev);
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
/* au0828-video.c */
|
||||
int au0828_analog_register(struct au0828_dev *dev,
|
||||
extern int au0828_analog_register(struct au0828_dev *dev,
|
||||
struct usb_interface *interface);
|
||||
int au0828_analog_stream_disable(struct au0828_dev *d);
|
||||
void au0828_analog_unregister(struct au0828_dev *dev);
|
||||
extern void au0828_analog_unregister(struct au0828_dev *dev);
|
||||
extern int au0828_start_analog_streaming(struct vb2_queue *vq,
|
||||
unsigned int count);
|
||||
extern void au0828_stop_vbi_streaming(struct vb2_queue *vq);
|
||||
#ifdef CONFIG_VIDEO_AU0828_V4L2
|
||||
void au0828_v4l2_suspend(struct au0828_dev *dev);
|
||||
void au0828_v4l2_resume(struct au0828_dev *dev);
|
||||
extern void au0828_v4l2_suspend(struct au0828_dev *dev);
|
||||
extern void au0828_v4l2_resume(struct au0828_dev *dev);
|
||||
#else
|
||||
static inline void au0828_v4l2_suspend(struct au0828_dev *dev) { };
|
||||
static inline void au0828_v4l2_resume(struct au0828_dev *dev) { };
|
||||
@ -329,7 +332,7 @@ void au0828_dvb_suspend(struct au0828_dev *dev);
|
||||
void au0828_dvb_resume(struct au0828_dev *dev);
|
||||
|
||||
/* au0828-vbi.c */
|
||||
extern struct videobuf_queue_ops au0828_vbi_qops;
|
||||
extern struct vb2_ops au0828_vbi_qops;
|
||||
|
||||
#define dprintk(level, fmt, arg...)\
|
||||
do { if (au0828_debug & level)\
|
||||
|
Loading…
Reference in New Issue
Block a user