Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3829fad authored by Devin Heitmueller's avatar Devin Heitmueller Committed by Mauro Carvalho Chehab
Browse files

[media] em28xx: convert to videobuf2



This patch converts the em28xx driver over to videobuf2.  It is
likely that em28xx_fh can go away entirely, but that will come in
a separate patch.

[mchehab@redhat.com: fix a non-trivial merge conflict with some VBI
 patches; CodingStyle fixes]

Signed-off-by: default avatarDevin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2a221d34
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ config VIDEO_EM28XX
	depends on VIDEO_DEV && I2C
	select VIDEO_TUNER
	select VIDEO_TVEEPROM
	select VIDEOBUF_VMALLOC
	select VIDEOBUF2_VMALLOC
	select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
	select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT
	select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT
@@ -48,7 +48,6 @@ config VIDEO_EM28XX_DVB
	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
	select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
	select VIDEOBUF_DVB
	---help---
	  This adds support for DVB cards based on the
	  Empiatech em28xx chips.
+6 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ module_param(disable_usb_speed_check, int, 0444);
MODULE_PARM_DESC(disable_usb_speed_check,
		 "override min bandwidth requirement of 480M bps");

static unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
static unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
module_param_array(card,  int, NULL, 0444);
MODULE_PARM_DESC(card,     "card type");

@@ -2965,6 +2965,8 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
	const char *chip_name = default_chip_name;

	dev->udev = udev;
	mutex_init(&dev->vb_queue_lock);
	mutex_init(&dev->vb_vbi_queue_lock);
	mutex_init(&dev->ctrl_urb_lock);
	spin_lock_init(&dev->slock);

@@ -3411,6 +3413,9 @@ static int em28xx_usb_probe(struct usb_interface *interface,
	/* save our data pointer in this interface device */
	usb_set_intfdata(interface, dev);

	/* initialize videobuf2 stuff */
	em28xx_vb2_setup(dev);

	/* allocate device struct */
	mutex_init(&dev->lock);
	mutex_lock(&dev->lock);
+3 −1
Original line number Diff line number Diff line
@@ -27,7 +27,9 @@

#include "em28xx.h"
#include <media/v4l2-common.h>
#include <media/videobuf-vmalloc.h>
#include <dvb_demux.h>
#include <dvb_net.h>
#include <dmxdev.h>
#include <media/tuner.h>
#include "tuner-simple.h"
#include <linux/gpio.h>
+45 −78
Original line number Diff line number Diff line
@@ -41,105 +41,72 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");

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

static void
free_buffer(struct videobuf_queue *vq, struct em28xx_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 em28xx_fh     *fh  = vq->priv_data;
	struct em28xx        *dev = fh->dev;
	unsigned long flags = 0;
	if (in_interrupt())
		BUG();

	/* 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->usb_ctl.vbi_buf == buf)
		dev->usb_ctl.vbi_buf = NULL;
	spin_unlock_irqrestore(&dev->slock, flags);
	struct em28xx *dev = vb2_get_drv_priv(vq);
	unsigned long size;

	videobuf_vmalloc_free(&buf->vb);
	buf->vb.state = VIDEOBUF_NEEDS_INIT;
}
	if (fmt)
		size = fmt->fmt.pix.sizeimage;
	else
		size = dev->vbi_width * dev->vbi_height * 2;

static int
vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
{
	struct em28xx_fh     *fh  = q->priv_data;
	struct em28xx        *dev = fh->dev;
	if (0 == *nbuffers)
		*nbuffers = 32;
	if (*nbuffers < 2)
		*nbuffers = 2;
	if (*nbuffers > 32)
		*nbuffers = 32;

	*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 em28xx_fh     *fh  = q->priv_data;
	struct em28xx        *dev = fh->dev;
	struct em28xx        *dev = vb2_get_drv_priv(vb->vb2_queue);
	struct em28xx_buffer *buf = container_of(vb, struct em28xx_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) {
		printk(KERN_INFO "%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 em28xx_buffer    *buf     = container_of(vb,
							struct em28xx_buffer,
							vb);
	struct em28xx_fh        *fh      = vq->priv_data;
	struct em28xx           *dev     = fh->dev;
	struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
	struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
	struct em28xx_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 em28xx_buffer *buf = container_of(vb, struct em28xx_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 em28xx_vbi_qops = {
	.buf_setup    = vbi_setup,
	.buf_prepare  = vbi_prepare,
	.buf_queue    = vbi_queue,
	.buf_release  = vbi_release,

struct vb2_ops em28xx_vbi_qops = {
	.queue_setup    = vbi_queue_setup,
	.buf_prepare    = vbi_buffer_prepare,
	.buf_queue      = vbi_buffer_queue,
	.start_streaming = em28xx_start_analog_streaming,
	.stop_streaming = em28xx_stop_vbi_streaming,
	.wait_prepare   = vb2_ops_wait_prepare,
	.wait_finish    = vb2_ops_wait_finish,
};
+264 −496

File changed.

Preview size limit exceeded, changes collapsed.

Loading