mirror of
https://github.com/torvalds/linux.git
synced 2024-11-13 23:51:39 +00:00
c4cd4c8bd7
With the new prepare_streaming op it is possible to move the ugly v4l_vb2q_enable_media_source() call in vb2_core_streamon to the driver. It was called incorrectly in vb2 as well: it was only called if sufficient buffers were queued at STREAMON time, but not if more buffers were queued later. This was not an issue with the au0828 driver since it never set min_buffers_needed. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
80 lines
2.1 KiB
C
80 lines
2.1 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
au0828-vbi.c - VBI driver for au0828
|
|
|
|
Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
|
|
|
|
This work was sponsored by GetWellNetwork Inc.
|
|
|
|
*/
|
|
|
|
#include "au0828.h"
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/init.h>
|
|
#include <linux/slab.h>
|
|
#include <media/v4l2-mc.h>
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
static int vbi_queue_setup(struct vb2_queue *vq,
|
|
unsigned int *nbuffers, unsigned int *nplanes,
|
|
unsigned int sizes[], struct device *alloc_devs[])
|
|
{
|
|
struct au0828_dev *dev = vb2_get_drv_priv(vq);
|
|
unsigned long size = dev->vbi_width * dev->vbi_height * 2;
|
|
|
|
if (*nplanes)
|
|
return sizes[0] < size ? -EINVAL : 0;
|
|
*nplanes = 1;
|
|
sizes[0] = size;
|
|
return 0;
|
|
}
|
|
|
|
static int vbi_buffer_prepare(struct vb2_buffer *vb)
|
|
{
|
|
struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
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(vb, 0, size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
vbi_buffer_queue(struct vb2_buffer *vb)
|
|
{
|
|
struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
|
struct au0828_buffer *buf =
|
|
container_of(vbuf, struct au0828_buffer, vb);
|
|
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);
|
|
}
|
|
|
|
const struct vb2_ops au0828_vbi_qops = {
|
|
.queue_setup = vbi_queue_setup,
|
|
.buf_prepare = vbi_buffer_prepare,
|
|
.buf_queue = vbi_buffer_queue,
|
|
.prepare_streaming = v4l_vb2q_enable_media_source,
|
|
.start_streaming = au0828_start_analog_streaming,
|
|
.stop_streaming = au0828_stop_vbi_streaming,
|
|
.wait_prepare = vb2_ops_wait_prepare,
|
|
.wait_finish = vb2_ops_wait_finish,
|
|
};
|