mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	[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
	 Devin Heitmueller
						Devin Heitmueller