Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 164070
b: refs/heads/master
c: 28abf08
h: refs/heads/master
v: v3
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed Sep 19, 2009
1 parent d4aee0f commit 4686e65
Show file tree
Hide file tree
Showing 7 changed files with 431 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: da52a55cff643b8e0b346b9894adf5b93946040d
refs/heads/master: 28abf083d356bc4ec459ded7a95b6a22a20f6c3d
2 changes: 1 addition & 1 deletion trunk/drivers/media/video/em28xx/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
em28xx-input.o
em28xx-input.o em28xx-vbi.o

em28xx-alsa-objs := em28xx-audio.o

Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx-cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -2590,6 +2590,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
/* init video dma queues */
INIT_LIST_HEAD(&dev->vidq.active);
INIT_LIST_HEAD(&dev->vidq.queued);
INIT_LIST_HEAD(&dev->vbiq.active);
INIT_LIST_HEAD(&dev->vbiq.queued);


if (dev->board.has_msp34xx) {
Expand Down
5 changes: 4 additions & 1 deletion trunk/drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
int (*isoc_copy) (struct em28xx *dev, struct urb *urb))
{
struct em28xx_dmaqueue *dma_q = &dev->vidq;
struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
int i;
int sb_size, pipe;
struct urb *urb;
Expand Down Expand Up @@ -993,7 +994,8 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
}

dev->isoc_ctl.max_pkt_size = max_pkt_size;
dev->isoc_ctl.buf = NULL;
dev->isoc_ctl.vid_buf = NULL;
dev->isoc_ctl.vbi_buf = NULL;

sb_size = max_packets * dev->isoc_ctl.max_pkt_size;

Expand Down Expand Up @@ -1043,6 +1045,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
}

init_waitqueue_head(&dma_q->wq);
init_waitqueue_head(&vbi_dma_q->wq);

em28xx_capture_start(dev, 1);

Expand Down
150 changes: 150 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx-vbi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
em28xx-vbi.c - VBI driver for em28xx
Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
This work was sponsored by EyeMagnet Limited.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>

#include "em28xx.h"

static unsigned int vbibufs = 5;
module_param(vbibufs,int,0644);
MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");

static unsigned int vbi_debug;
module_param(vbi_debug,int,0644);
MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");

#define dprintk(level,fmt, arg...) if (vbi_debug >= level) \
printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)

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

static void
free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
{
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->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)
{
*size = 720 * 12 * 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 em28xx_fh *fh = q->priv_data;
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
int rc = 0;
unsigned int size;

size = 720 * 12 * 2;

buf->vb.size = size;

if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
return -EINVAL;

buf->vb.width = 720;
buf->vb.height = 12;
buf->vb.field = field;

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 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)
{
struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
free_buffer(q, buf);
}

struct videobuf_queue_ops em28xx_vbi_qops = {
.buf_setup = vbi_setup,
.buf_prepare = vbi_prepare,
.buf_queue = vbi_queue,
.buf_release = vbi_release,
};

/* ------------------------------------------------------------------ */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/
Loading

0 comments on commit 4686e65

Please sign in to comment.