Skip to content

Commit

Permalink
[media] em28xx: convert to videobuf2
Browse files Browse the repository at this point in the history
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: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed Jan 5, 2013
1 parent 2a221d3 commit d3829fa
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 589 deletions.
3 changes: 1 addition & 2 deletions drivers/media/usb/em28xx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 6 additions & 1 deletion drivers/media/usb/em28xx/em28xx-cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion drivers/media/usb/em28xx/em28xx-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
123 changes: 45 additions & 78 deletions drivers/media/usb/em28xx/em28xx-vbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
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_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 em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
free_buffer(q, buf);
struct em28xx_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 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,
};
Loading

0 comments on commit d3829fa

Please sign in to comment.