[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:
		
							parent
							
								
									2a221d34b6
								
							
						
					
					
						commit
						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,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -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 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user