[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: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Родитель
2a221d34b6
Коммит
d3829fadc4
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
struct em28xx *dev = vb2_get_drv_priv(vq);
|
||||
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.)
|
||||
if (fmt)
|
||||
size = fmt->fmt.pix.sizeimage;
|
||||
else
|
||||
size = dev->vbi_width * dev->vbi_height * 2;
|
||||
|
||||
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);
|
||||
if (0 == *nbuffers)
|
||||
*nbuffers = 32;
|
||||
if (*nbuffers < 2)
|
||||
*nbuffers = 2;
|
||||
if (*nbuffers > 32)
|
||||
*nbuffers = 32;
|
||||
|
||||
videobuf_vmalloc_free(&buf->vb);
|
||||
buf->vb.state = VIDEOBUF_NEEDS_INIT;
|
||||
}
|
||||
*nplanes = 1;
|
||||
sizes[0] = size;
|
||||
|
||||
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;
|
||||
|
||||
*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)
|
||||
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,
|
||||
};
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -31,15 +31,12 @@
|
|||
#include <linux/mutex.h>
|
||||
#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>
|
||||
#include <media/ir-kbd-i2c.h>
|
||||
#include <media/rc-core.h>
|
||||
#if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE)
|
||||
#include <media/videobuf-dvb.h>
|
||||
#endif
|
||||
#include "tuner-xc2028.h"
|
||||
#include "xc5000.h"
|
||||
#include "em28xx-reg.h"
|
||||
|
@ -252,8 +249,11 @@ struct em28xx_fmt {
|
|||
/* buffer for one video frame */
|
||||
struct em28xx_buffer {
|
||||
/* common v4l buffer stuff -- must be first */
|
||||
struct videobuf_buffer vb;
|
||||
struct vb2_buffer vb;
|
||||
struct list_head list;
|
||||
|
||||
void *mem;
|
||||
unsigned int length;
|
||||
int top_field;
|
||||
|
||||
/* counter to control buffer fill */
|
||||
|
@ -480,11 +480,6 @@ struct em28xx;
|
|||
struct em28xx_fh {
|
||||
struct v4l2_fh fh;
|
||||
struct em28xx *dev;
|
||||
int radio;
|
||||
unsigned int resources;
|
||||
|
||||
struct videobuf_queue vb_vidq;
|
||||
struct videobuf_queue vb_vbiq;
|
||||
|
||||
enum v4l2_buf_type type;
|
||||
};
|
||||
|
@ -545,6 +540,7 @@ struct em28xx {
|
|||
struct i2c_client i2c_client;
|
||||
/* video for linux */
|
||||
int users; /* user count for exclusive use */
|
||||
int streaming_users; /* Number of actively streaming users */
|
||||
struct video_device *vdev; /* video for linux device struct */
|
||||
v4l2_std_id norm; /* selected tv norm */
|
||||
int ctl_freq; /* selected frequency */
|
||||
|
@ -587,6 +583,12 @@ struct em28xx {
|
|||
struct video_device *vbi_dev;
|
||||
struct video_device *radio_dev;
|
||||
|
||||
/* Videobuf2 */
|
||||
struct vb2_queue vb_vidq;
|
||||
struct vb2_queue vb_vbiq;
|
||||
struct mutex vb_queue_lock;
|
||||
struct mutex vb_vbi_queue_lock;
|
||||
|
||||
/* resources in use */
|
||||
unsigned int resources;
|
||||
|
||||
|
@ -598,6 +600,9 @@ struct em28xx {
|
|||
struct em28xx_usb_ctl usb_ctl;
|
||||
spinlock_t slock;
|
||||
|
||||
unsigned int field_count;
|
||||
unsigned int vbi_field_count;
|
||||
|
||||
/* usb transfer */
|
||||
struct usb_device *udev; /* the usb device */
|
||||
u8 analog_ep_isoc; /* address of isoc endpoint for analog */
|
||||
|
@ -709,9 +714,12 @@ void em28xx_init_extension(struct em28xx *dev);
|
|||
void em28xx_close_extension(struct em28xx *dev);
|
||||
|
||||
/* Provided by em28xx-video.c */
|
||||
int em28xx_vb2_setup(struct em28xx *dev);
|
||||
int em28xx_register_analog_devices(struct em28xx *dev);
|
||||
void em28xx_release_analog_resources(struct em28xx *dev);
|
||||
void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv);
|
||||
int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count);
|
||||
int em28xx_stop_vbi_streaming(struct vb2_queue *vq);
|
||||
extern const struct v4l2_ctrl_ops em28xx_ctrl_ops;
|
||||
|
||||
/* Provided by em28xx-cards.c */
|
||||
|
@ -723,7 +731,7 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
|
|||
void em28xx_release_resources(struct em28xx *dev);
|
||||
|
||||
/* Provided by em28xx-vbi.c */
|
||||
extern struct videobuf_queue_ops em28xx_vbi_qops;
|
||||
extern struct vb2_ops em28xx_vbi_qops;
|
||||
|
||||
/* printk macros */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче