All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks
@ 2014-08-14  9:53 Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 01/20] cx23885: fix querycap Hans Verkuil
                   ` (19 more replies)
  0 siblings, 20 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth

This patch series converts the cx23885 driver to the latest V4L2 core
frameworks, removing about 1000 lines in the process.

It now passes the v4l2-compliance tests and, frankly, feels much more
robust.

I have tested this with my HVR-1800 board with video (compressed and
uncompressed), vbi, dvb and alsa.

As usual, the vb2 conversion is a beast of a patch. But the vb2 conversion
affected video, vbi, dvb and alsa, so it's all over the place. And it is
all or nothing. See the commit log of that patch for some more information.

Since the cx23885 code resembles the cx88 and cx25821 code closely, I will
probably try to do the same for those drivers in the near future. And in
fact I have already started on the cx88.

Changes since v1:

- Added patch 20/20 which adds vb2_is_busy checks.
- altera-ci.c still included the videobuf headers for no reason. Fixed in
  patch 15/20.
- In buffer_prepare in cx23885-video.c the buf->bpl field was used before
  it was set. Fixed in patch 15/20.

Regards,

	Hans


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCHv2 01/20] cx23885: fix querycap
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 02/20] cx23885: fix audio input handling Hans Verkuil
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Set device_caps to fix the v4l2-compliance QUERYCAP complaints.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 91e4cb4..2666ac4 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -1146,19 +1146,22 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_querycap(struct file *file, void  *priv,
 	struct v4l2_capability *cap)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct cx23885_dev *dev  = ((struct cx23885_fh *)priv)->dev;
 
 	strcpy(cap->driver, "cx23885");
 	strlcpy(cap->card, cx23885_boards[dev->board].name,
 		sizeof(cap->card));
 	sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
-	cap->capabilities =
-		V4L2_CAP_VIDEO_CAPTURE |
-		V4L2_CAP_READWRITE     |
-		V4L2_CAP_STREAMING     |
-		V4L2_CAP_VBI_CAPTURE;
+	cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
 	if (dev->tuner_type != TUNER_ABSENT)
-		cap->capabilities |= V4L2_CAP_TUNER;
+		cap->device_caps |= V4L2_CAP_TUNER;
+	if (vdev->vfl_type == VFL_TYPE_VBI)
+		cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
+	else
+		cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
+	cap->capabilities = cap->device_caps | V4L2_CAP_VBI_CAPTURE |
+		V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 02/20] cx23885: fix audio input handling
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 01/20] cx23885: fix querycap Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 03/20] cx23885: support v4l2_fh and g/s_priority Hans Verkuil
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Fix a bunch of v4l2-compliance errors relating to audio input handling.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 2666ac4..79de4ac 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -1153,7 +1153,7 @@ static int vidioc_querycap(struct file *file, void  *priv,
 	strlcpy(cap->card, cx23885_boards[dev->board].name,
 		sizeof(cap->card));
 	sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
-	cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+	cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO;
 	if (dev->tuner_type != TUNER_ABSENT)
 		cap->device_caps |= V4L2_CAP_TUNER;
 	if (vdev->vfl_type == VFL_TYPE_VBI)
@@ -1302,16 +1302,16 @@ int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
 	i->index = n;
 	i->type  = V4L2_INPUT_TYPE_CAMERA;
 	strcpy(i->name, iname[INPUT(n)->type]);
+	i->std = CX23885_NORMS;
 	if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) ||
 		(CX23885_VMUX_CABLE == INPUT(n)->type)) {
 		i->type = V4L2_INPUT_TYPE_TUNER;
-		i->std = CX23885_NORMS;
+		i->audioset = 4;
+	} else {
+		/* Two selectable audio inputs for non-tv inputs */
+		i->audioset = 3;
 	}
 
-	/* Two selectable audio inputs for non-tv inputs */
-	if (INPUT(n)->type != CX23885_VMUX_TELEVISION)
-		i->audioset = 0x3;
-
 	if (dev->input == n) {
 		/* enum'd input matches our configured input.
 		 * Ask the video decoder to process the call
@@ -1397,19 +1397,19 @@ static int cx23885_query_audinput(struct file *file, void *priv,
 	static const char *iname[] = {
 		[0] = "Baseband L/R 1",
 		[1] = "Baseband L/R 2",
+		[2] = "TV",
 	};
 	unsigned int n;
 	dprintk(1, "%s()\n", __func__);
 
 	n = i->index;
-	if (n >= 2)
+	if (n >= 3)
 		return -EINVAL;
 
 	memset(i, 0, sizeof(*i));
 	i->index = n;
 	strcpy(i->name, iname[n]);
-	i->capability  = V4L2_AUDCAP_STEREO;
-	i->mode  = V4L2_AUDMODE_AVL;
+	i->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 
 }
@@ -1425,7 +1425,11 @@ static int vidioc_g_audinput(struct file *file, void *priv,
 {
 	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
 
-	i->index = dev->audinput;
+	if ((CX23885_VMUX_TELEVISION == INPUT(dev->input)->type) ||
+		(CX23885_VMUX_CABLE == INPUT(dev->input)->type))
+		i->index = 2;
+	else
+		i->index = dev->audinput;
 	dprintk(1, "%s(input=%d)\n", __func__, i->index);
 
 	return cx23885_query_audinput(file, priv, i);
@@ -1435,7 +1439,12 @@ static int vidioc_s_audinput(struct file *file, void *priv,
 	const struct v4l2_audio *i)
 {
 	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-	if (i->index >= 2)
+
+	if ((CX23885_VMUX_TELEVISION == INPUT(dev->input)->type) ||
+		(CX23885_VMUX_CABLE == INPUT(dev->input)->type)) {
+		return i->index != 2 ? -EINVAL : 0;
+	}
+	if (i->index > 1)
 		return -EINVAL;
 
 	dprintk(1, "%s(%d)\n", __func__, i->index);
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 03/20] cx23885: support v4l2_fh and g/s_priority
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 01/20] cx23885: fix querycap Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 02/20] cx23885: fix audio input handling Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 04/20] cx23885: use core locking, switch to unlocked_ioctl Hans Verkuil
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Add support for struct v4l2_fh and priority handling.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-417.c   | 5 +++++
 drivers/media/pci/cx23885/cx23885-video.c | 6 +++++-
 drivers/media/pci/cx23885/cx23885.h       | 2 ++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index bf89fc8..b65de33 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1550,6 +1550,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
 
 static int mpeg_open(struct file *file)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh;
 
@@ -1560,6 +1561,7 @@ static int mpeg_open(struct file *file)
 	if (!fh)
 		return -ENOMEM;
 
+	v4l2_fh_init(&fh->fh, vdev);
 	file->private_data = fh;
 	fh->dev      = dev;
 
@@ -1569,6 +1571,7 @@ static int mpeg_open(struct file *file)
 			    V4L2_FIELD_INTERLACED,
 			    sizeof(struct cx23885_buffer),
 			    fh, NULL);
+	v4l2_fh_add(&fh->fh);
 	return 0;
 }
 
@@ -1601,6 +1604,8 @@ static int mpeg_release(struct file *file)
 		videobuf_read_stop(&fh->mpegq);
 
 	videobuf_mmap_free(&fh->mpegq);
+	v4l2_fh_del(&fh->fh);
+	v4l2_fh_exit(&fh->fh);
 	file->private_data = NULL;
 	kfree(fh);
 
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 79de4ac..d575bfc 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -883,7 +883,8 @@ static int video_open(struct file *file)
 	if (NULL == fh)
 		return -ENOMEM;
 
-	file->private_data = fh;
+	v4l2_fh_init(&fh->fh, vdev);
+	file->private_data = &fh->fh;
 	fh->dev      = dev;
 	fh->radio    = radio;
 	fh->type     = type;
@@ -905,6 +906,7 @@ static int video_open(struct file *file)
 		sizeof(struct cx23885_buffer),
 		fh, NULL);
 
+	v4l2_fh_add(&fh->fh);
 
 	dprintk(1, "post videobuf_queue_init()\n");
 
@@ -1003,6 +1005,8 @@ static int video_release(struct file *file)
 	videobuf_mmap_free(&fh->vidq);
 	videobuf_mmap_free(&fh->vbiq);
 
+	v4l2_fh_del(&fh->fh);
+	v4l2_fh_exit(&fh->fh);
 	file->private_data = NULL;
 	kfree(fh);
 
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 0e086c0..de164c9 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 
 #include <media/v4l2-device.h>
+#include <media/v4l2-fh.h>
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
@@ -147,6 +148,7 @@ struct cx23885_tvnorm {
 };
 
 struct cx23885_fh {
+	struct v4l2_fh		   fh;
 	struct cx23885_dev         *dev;
 	enum v4l2_buf_type         type;
 	int                        radio;
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 04/20] cx23885: use core locking, switch to unlocked_ioctl.
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (2 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 03/20] cx23885: support v4l2_fh and g/s_priority Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 05/20] cx23885: convert to the control framework Hans Verkuil
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Enable core locking which allows us to safely switch to unlocked_ioctl.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-417.c   |  5 ++--
 drivers/media/pci/cx23885/cx23885-video.c | 43 +++++++------------------------
 2 files changed, 12 insertions(+), 36 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index b65de33..395f7a9 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1235,9 +1235,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
 	dev->encodernorm = cx23885_tvnorms[i];
 
 	/* Have the drier core notify the subdevices */
-	mutex_lock(&dev->lock);
 	cx23885_set_tvnorm(dev, id);
-	mutex_unlock(&dev->lock);
 
 	return 0;
 }
@@ -1661,7 +1659,7 @@ static struct v4l2_file_operations mpeg_fops = {
 	.read	       = mpeg_read,
 	.poll          = mpeg_poll,
 	.mmap	       = mpeg_mmap,
-	.ioctl	       = video_ioctl2,
+	.unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
@@ -1770,6 +1768,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
 	dev->v4l_device = cx23885_video_dev_alloc(tsport,
 		dev->pci, &cx23885_mpeg_template, "mpeg");
 	video_set_drvdata(dev->v4l_device, dev);
+	dev->v4l_device->lock = &dev->lock;
 	err = video_register_device(dev->v4l_device,
 		VFL_TYPE_GRABBER, -1);
 	if (err < 0) {
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index d575bfc..ba93e29 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -345,6 +345,7 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
 	*vfd = *template;
 	vfd->v4l2_dev = &dev->v4l2_dev;
 	vfd->release = video_device_release;
+	vfd->lock = &dev->lock;
 	snprintf(vfd->name, sizeof(vfd->name), "%s (%s)",
 		 cx23885_boards[dev->board].name, type);
 	video_set_drvdata(vfd, dev);
@@ -381,17 +382,14 @@ static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh,
 		return 1;
 
 	/* is it free? */
-	mutex_lock(&dev->lock);
 	if (dev->resources & bit) {
 		/* no, someone else uses it */
-		mutex_unlock(&dev->lock);
 		return 0;
 	}
 	/* it's free, grab it */
 	fh->resources  |= bit;
 	dev->resources |= bit;
 	dprintk(1, "res: get %d\n", bit);
-	mutex_unlock(&dev->lock);
 	return 1;
 }
 
@@ -411,11 +409,9 @@ static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
 	BUG_ON((fh->resources & bits) != bits);
 	dprintk(1, "%s()\n", __func__);
 
-	mutex_lock(&dev->lock);
 	fh->resources  &= ~bits;
 	dev->resources &= ~bits;
 	dprintk(1, "res: put %d\n", bits);
-	mutex_unlock(&dev->lock);
 }
 
 int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data)
@@ -1272,9 +1268,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
 	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
 	dprintk(1, "%s()\n", __func__);
 
-	mutex_lock(&dev->lock);
 	cx23885_set_tvnorm(dev, tvnorms);
-	mutex_unlock(&dev->lock);
 
 	return 0;
 }
@@ -1364,13 +1358,11 @@ int cx23885_set_input(struct file *file, void *priv, unsigned int i)
 	if (INPUT(i)->type == 0)
 		return -EINVAL;
 
-	mutex_lock(&dev->lock);
 	cx23885_video_mux(dev, i);
 
 	/* By default establish the default audio input for the card also */
 	/* Caller is free to use VIDIOC_S_AUDIO to override afterwards */
 	cx23885_audio_mux(dev, i);
-	mutex_unlock(&dev->lock);
 	return 0;
 }
 
@@ -1544,7 +1536,6 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency
 	if (unlikely(f->tuner != 0))
 		return -EINVAL;
 
-	mutex_lock(&dev->lock);
 	dev->freq = f->frequency;
 
 	/* I need to mute audio here */
@@ -1561,8 +1552,6 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency
 	ctrl.value = 0;
 	cx23885_set_control(dev, &ctrl);
 
-	mutex_unlock(&dev->lock);
-
 	return 0;
 }
 
@@ -1580,7 +1569,6 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 		.frequency = f->frequency
 	};
 
-	mutex_lock(&dev->lock);
 	dev->freq = f->frequency;
 
 	/* I need to mute audio here */
@@ -1594,7 +1582,6 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 
 	vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1);
 	if (!vfe) {
-		mutex_unlock(&dev->lock);
 		return -EINVAL;
 	}
 
@@ -1619,8 +1606,6 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 	ctrl.value = 0;
 	cx23885_set_control(dev, &ctrl);
 
-	mutex_unlock(&dev->lock);
-
 	return 0;
 }
 
@@ -1742,7 +1727,7 @@ static const struct v4l2_file_operations video_fops = {
 	.read	       = video_read,
 	.poll          = video_poll,
 	.mmap	       = video_mmap,
-	.ioctl	       = video_ioctl2,
+	.unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1791,14 +1776,6 @@ static struct video_device cx23885_video_template = {
 	.tvnorms              = CX23885_NORMS,
 };
 
-static const struct v4l2_file_operations radio_fops = {
-	.owner         = THIS_MODULE,
-	.open          = video_open,
-	.release       = video_release,
-	.ioctl         = video_ioctl2,
-};
-
-
 void cx23885_video_unregister(struct cx23885_dev *dev)
 {
 	dprintk(1, "%s()\n", __func__);
@@ -1909,6 +1886,14 @@ int cx23885_video_register(struct cx23885_dev *dev)
 		}
 	}
 
+	/* initial device configuration */
+	mutex_lock(&dev->lock);
+	cx23885_set_tvnorm(dev, dev->tvnorm);
+	init_controls(dev);
+	cx23885_video_mux(dev, 0);
+	cx23885_audio_mux(dev, 0);
+	mutex_unlock(&dev->lock);
+
 	/* register Video device */
 	dev->video_dev = cx23885_vdev_init(dev, dev->pci,
 		&cx23885_video_template, "video");
@@ -1938,14 +1923,6 @@ int cx23885_video_register(struct cx23885_dev *dev)
 	/* Register ALSA audio device */
 	dev->audio_dev = cx23885_audio_register(dev);
 
-	/* initial device configuration */
-	mutex_lock(&dev->lock);
-	cx23885_set_tvnorm(dev, dev->tvnorm);
-	init_controls(dev);
-	cx23885_video_mux(dev, 0);
-	cx23885_audio_mux(dev, 0);
-	mutex_unlock(&dev->lock);
-
 	return 0;
 
 fail_unreg:
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 05/20] cx23885: convert to the control framework
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (3 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 04/20] cx23885: use core locking, switch to unlocked_ioctl Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 06/20] cx23885: convert 417 " Hans Verkuil
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

This is part 1, converting the uncompressed video/vbi nodes to use
the control framework.

The next patch converts the compressed video node as well.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-417.c   |  20 ---
 drivers/media/pci/cx23885/cx23885-core.c  |  17 ++-
 drivers/media/pci/cx23885/cx23885-video.c | 246 +++++-------------------------
 drivers/media/pci/cx23885/cx23885.h       |  12 +-
 4 files changed, 51 insertions(+), 244 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index 395f7a9..d44395c 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1313,22 +1313,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 	return cx23885_set_frequency(file, priv, f);
 }
 
-static int vidioc_g_ctrl(struct file *file, void *priv,
-	struct v4l2_control *ctl)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
-	return cx23885_get_control(dev, ctl);
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-	struct v4l2_control *ctl)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
-	return cx23885_set_control(dev, ctl);
-}
-
 static int vidioc_querycap(struct file *file, void  *priv,
 				struct v4l2_capability *cap)
 {
@@ -1672,8 +1656,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_s_tuner		 = vidioc_s_tuner,
 	.vidioc_g_frequency	 = vidioc_g_frequency,
 	.vidioc_s_frequency	 = vidioc_s_frequency,
-	.vidioc_s_ctrl		 = vidioc_s_ctrl,
-	.vidioc_g_ctrl		 = vidioc_g_ctrl,
 	.vidioc_querycap	 = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap	 = vidioc_g_fmt_vid_cap,
@@ -1689,8 +1671,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
 	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
 	.vidioc_log_status	 = vidioc_log_status,
-	.vidioc_querymenu	 = vidioc_querymenu,
-	.vidioc_queryctrl	 = vidioc_queryctrl,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_chip_info	 = cx23885_g_chip_info,
 	.vidioc_g_register	 = cx23885_g_register,
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index edcd79d..075b28e 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -2087,6 +2087,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
 			   const struct pci_device_id *pci_id)
 {
 	struct cx23885_dev *dev;
+	struct v4l2_ctrl_handler *hdl;
 	int err;
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -2097,6 +2098,14 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
 	if (err < 0)
 		goto fail_free;
 
+	hdl = &dev->ctrl_handler;
+	v4l2_ctrl_handler_init(hdl, 6);
+	if (hdl->error) {
+		err = hdl->error;
+		goto fail_ctrl;
+	}
+	dev->v4l2_dev.ctrl_handler = hdl;
+
 	/* Prepare to handle notifications from subdevices */
 	cx23885_v4l2_dev_notify_init(dev);
 
@@ -2104,12 +2113,12 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
 	dev->pci = pci_dev;
 	if (pci_enable_device(pci_dev)) {
 		err = -EIO;
-		goto fail_unreg;
+		goto fail_ctrl;
 	}
 
 	if (cx23885_dev_setup(dev) < 0) {
 		err = -EINVAL;
-		goto fail_unreg;
+		goto fail_ctrl;
 	}
 
 	/* print pci info */
@@ -2157,7 +2166,8 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
 
 fail_irq:
 	cx23885_dev_unregister(dev);
-fail_unreg:
+fail_ctrl:
+	v4l2_ctrl_handler_free(hdl);
 	v4l2_device_unregister(&dev->v4l2_dev);
 fail_free:
 	kfree(dev);
@@ -2180,6 +2190,7 @@ static void cx23885_finidev(struct pci_dev *pci_dev)
 	free_irq(pci_dev->irq, dev);
 
 	cx23885_dev_unregister(dev);
+	v4l2_ctrl_handler_free(&dev->ctrl_handler);
 	v4l2_device_unregister(v4l2_dev);
 	kfree(dev);
 }
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ba93e29..090d48b 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -35,6 +35,7 @@
 #include "cx23885-video.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
 #include "cx23885-ioctl.h"
 #include "tuner-xc2028.h"
 
@@ -170,119 +171,6 @@ static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc)
 
 /* ------------------------------------------------------------------- */
 
-static const struct v4l2_queryctrl no_ctl = {
-	.name  = "42",
-	.flags = V4L2_CTRL_FLAG_DISABLED,
-};
-
-static struct cx23885_ctrl cx23885_ctls[] = {
-	/* --- video --- */
-	{
-		.v = {
-			.id            = V4L2_CID_BRIGHTNESS,
-			.name          = "Brightness",
-			.minimum       = 0x00,
-			.maximum       = 0xff,
-			.step          = 1,
-			.default_value = 0x7f,
-			.type          = V4L2_CTRL_TYPE_INTEGER,
-		},
-		.off                   = 128,
-		.reg                   = LUMA_CTRL,
-		.mask                  = 0x00ff,
-		.shift                 = 0,
-	}, {
-		.v = {
-			.id            = V4L2_CID_CONTRAST,
-			.name          = "Contrast",
-			.minimum       = 0,
-			.maximum       = 0x7f,
-			.step          = 1,
-			.default_value = 0x3f,
-			.type          = V4L2_CTRL_TYPE_INTEGER,
-		},
-		.off                   = 0,
-		.reg                   = LUMA_CTRL,
-		.mask                  = 0xff00,
-		.shift                 = 8,
-	}, {
-		.v = {
-			.id            = V4L2_CID_HUE,
-			.name          = "Hue",
-			.minimum       = -127,
-			.maximum       = 128,
-			.step          = 1,
-			.default_value = 0x0,
-			.type          = V4L2_CTRL_TYPE_INTEGER,
-		},
-		.off                   = 128,
-		.reg                   = CHROMA_CTRL,
-		.mask                  = 0xff0000,
-		.shift                 = 16,
-	}, {
-		/* strictly, this only describes only U saturation.
-		 * V saturation is handled specially through code.
-		 */
-		.v = {
-			.id            = V4L2_CID_SATURATION,
-			.name          = "Saturation",
-			.minimum       = 0,
-			.maximum       = 0x7f,
-			.step          = 1,
-			.default_value = 0x3f,
-			.type          = V4L2_CTRL_TYPE_INTEGER,
-		},
-		.off                   = 0,
-		.reg                   = CHROMA_CTRL,
-		.mask                  = 0x00ff,
-		.shift                 = 0,
-	}, {
-	/* --- audio --- */
-		.v = {
-			.id            = V4L2_CID_AUDIO_MUTE,
-			.name          = "Mute",
-			.minimum       = 0,
-			.maximum       = 1,
-			.default_value = 1,
-			.type          = V4L2_CTRL_TYPE_BOOLEAN,
-		},
-		.reg                   = PATH1_CTL1,
-		.mask                  = (0x1f << 24),
-		.shift                 = 24,
-	}, {
-		.v = {
-			.id            = V4L2_CID_AUDIO_VOLUME,
-			.name          = "Volume",
-			.minimum       = 0,
-			.maximum       = 65535,
-			.step          = 65535 / 100,
-			.default_value = 65535,
-			.type          = V4L2_CTRL_TYPE_INTEGER,
-		},
-		.reg                   = PATH1_VOL_CTL,
-		.mask                  = 0xff,
-		.shift                 = 0,
-	}
-};
-static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls);
-
-/* Must be sorted from low to high control ID! */
-static const u32 cx23885_user_ctrls[] = {
-	V4L2_CID_USER_CLASS,
-	V4L2_CID_BRIGHTNESS,
-	V4L2_CID_CONTRAST,
-	V4L2_CID_SATURATION,
-	V4L2_CID_HUE,
-	V4L2_CID_AUDIO_VOLUME,
-	V4L2_CID_AUDIO_MUTE,
-	0
-};
-
-static const u32 *ctrl_classes[] = {
-	cx23885_user_ctrls,
-	NULL
-};
-
 void cx23885_video_wakeup(struct cx23885_dev *dev,
 	struct cx23885_dmaqueue *q, u32 count)
 {
@@ -352,24 +240,6 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
 	return vfd;
 }
 
-static int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl)
-{
-	int i;
-
-	if (qctrl->id < V4L2_CID_BASE ||
-	    qctrl->id >= V4L2_CID_LASTP1)
-		return -EINVAL;
-	for (i = 0; i < CX23885_CTLS; i++)
-		if (cx23885_ctls[i].v.id == qctrl->id)
-			break;
-	if (i == CX23885_CTLS) {
-		*qctrl = no_ctl;
-		return 0;
-	}
-	*qctrl = cx23885_ctls[i].v;
-	return 0;
-}
-
 /* ------------------------------------------------------------------- */
 /* resource management                                                 */
 
@@ -936,12 +806,20 @@ static unsigned int video_poll(struct file *file,
 {
 	struct cx23885_fh *fh = file->private_data;
 	struct cx23885_buffer *buf;
-	unsigned int rc = POLLERR;
+	unsigned long req_events = poll_requested_events(wait);
+	unsigned int rc = 0;
+
+	if (v4l2_event_pending(&fh->fh))
+		rc = POLLPRI;
+	else
+		poll_wait(file, &fh->fh.wait, wait);
+	if (!(req_events & (POLLIN | POLLRDNORM)))
+		return rc;
 
 	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
 		if (!res_get(fh->dev, fh, RESOURCE_VBI))
-			return POLLERR;
-		return videobuf_poll_stream(file, &fh->vbiq, wait);
+			return rc | POLLERR;
+		return rc | videobuf_poll_stream(file, &fh->vbiq, wait);
 	}
 
 	mutex_lock(&fh->vidq.vb_lock);
@@ -960,9 +838,7 @@ static unsigned int video_poll(struct file *file,
 	poll_wait(file, &buf->vb.done, wait);
 	if (buf->vb.state == VIDEOBUF_DONE ||
 	    buf->vb.state == VIDEOBUF_ERROR)
-		rc =  POLLIN|POLLRDNORM;
-	else
-		rc = 0;
+		rc |= POLLIN | POLLRDNORM;
 done:
 	mutex_unlock(&fh->vidq.vb_lock);
 	return rc;
@@ -1022,39 +898,6 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma)
 }
 
 /* ------------------------------------------------------------------ */
-/* VIDEO CTRL IOCTLS                                                  */
-
-int cx23885_get_control(struct cx23885_dev *dev,
-	struct v4l2_control *ctl)
-{
-	dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
-	call_all(dev, core, g_ctrl, ctl);
-	return 0;
-}
-
-int cx23885_set_control(struct cx23885_dev *dev,
-	struct v4l2_control *ctl)
-{
-	dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)\n", __func__);
-	call_all(dev, core, s_ctrl, ctl);
-
-	return 0;
-}
-
-static void init_controls(struct cx23885_dev *dev)
-{
-	struct v4l2_control ctrl;
-	int i;
-
-	for (i = 0; i < CX23885_CTLS; i++) {
-		ctrl.id = cx23885_ctls[i].v.id;
-		ctrl.value = cx23885_ctls[i].v.default_value;
-
-		cx23885_set_control(dev, &ctrl);
-	}
-}
-
-/* ------------------------------------------------------------------ */
 /* VIDEO IOCTLS                                                       */
 
 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
@@ -1453,31 +1296,6 @@ static int vidioc_s_audinput(struct file *file, void *priv,
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-				struct v4l2_queryctrl *qctrl)
-{
-	qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
-	if (unlikely(qctrl->id == 0))
-		return -EINVAL;
-	return cx23885_ctrl_query(qctrl);
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctl)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
-	return cx23885_get_control(dev, ctl);
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctl)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
-	return cx23885_set_control(dev, ctl);
-}
-
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *t)
 {
@@ -1529,7 +1347,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
 
 static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency *f)
 {
-	struct v4l2_control ctrl;
+	struct v4l2_ctrl *mute;
+	int old_mute_val = 1;
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1539,9 +1358,12 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency
 	dev->freq = f->frequency;
 
 	/* I need to mute audio here */
-	ctrl.id = V4L2_CID_AUDIO_MUTE;
-	ctrl.value = 1;
-	cx23885_set_control(dev, &ctrl);
+	mute = v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_AUDIO_MUTE);
+	if (mute) {
+		old_mute_val = v4l2_ctrl_g_ctrl(mute);
+		if (!old_mute_val)
+			v4l2_ctrl_s_ctrl(mute, 1);
+	}
 
 	call_all(dev, tuner, s_frequency, f);
 
@@ -1549,8 +1371,8 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency
 	msleep(100);
 
 	/* I need to unmute audio here */
-	ctrl.value = 0;
-	cx23885_set_control(dev, &ctrl);
+	if (old_mute_val == 0)
+		v4l2_ctrl_s_ctrl(mute, old_mute_val);
 
 	return 0;
 }
@@ -1558,7 +1380,8 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency
 static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 	const struct v4l2_frequency *f)
 {
-	struct v4l2_control ctrl;
+	struct v4l2_ctrl *mute;
+	int old_mute_val = 1;
 	struct videobuf_dvb_frontend *vfe;
 	struct dvb_frontend *fe;
 
@@ -1572,9 +1395,12 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 	dev->freq = f->frequency;
 
 	/* I need to mute audio here */
-	ctrl.id = V4L2_CID_AUDIO_MUTE;
-	ctrl.value = 1;
-	cx23885_set_control(dev, &ctrl);
+	mute = v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_AUDIO_MUTE);
+	if (mute) {
+		old_mute_val = v4l2_ctrl_g_ctrl(mute);
+		if (!old_mute_val)
+			v4l2_ctrl_s_ctrl(mute, 1);
+	}
 
 	/* If HVR1850 */
 	dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__,
@@ -1603,8 +1429,8 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 	msleep(100);
 
 	/* I need to unmute audio here */
-	ctrl.value = 0;
-	cx23885_set_control(dev, &ctrl);
+	if (old_mute_val == 0)
+		v4l2_ctrl_s_ctrl(mute, old_mute_val);
 
 	return 0;
 }
@@ -1749,9 +1575,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_g_input       = vidioc_g_input,
 	.vidioc_s_input       = vidioc_s_input,
 	.vidioc_log_status    = vidioc_log_status,
-	.vidioc_queryctrl     = vidioc_queryctrl,
-	.vidioc_g_ctrl        = vidioc_g_ctrl,
-	.vidioc_s_ctrl        = vidioc_s_ctrl,
 	.vidioc_streamon      = vidioc_streamon,
 	.vidioc_streamoff     = vidioc_streamoff,
 	.vidioc_g_tuner       = vidioc_g_tuner,
@@ -1766,6 +1589,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_enumaudio     = vidioc_enum_audinput,
 	.vidioc_g_audio       = vidioc_g_audinput,
 	.vidioc_s_audio       = vidioc_s_audinput,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 static struct video_device cx23885_vbi_template;
@@ -1889,7 +1714,6 @@ int cx23885_video_register(struct cx23885_dev *dev)
 	/* initial device configuration */
 	mutex_lock(&dev->lock);
 	cx23885_set_tvnorm(dev, dev->tvnorm);
-	init_controls(dev);
 	cx23885_video_mux(dev, 0);
 	cx23885_audio_mux(dev, 0);
 	mutex_unlock(&dev->lock);
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index de164c9..516435c 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -26,6 +26,7 @@
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-fh.h>
+#include <media/v4l2-ctrls.h>
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
@@ -132,14 +133,6 @@ struct cx23885_fmt {
 	u32   cxformat;
 };
 
-struct cx23885_ctrl {
-	struct v4l2_queryctrl v;
-	u32                   off;
-	u32                   reg;
-	u32                   mask;
-	u32                   shift;
-};
-
 struct cx23885_tvnorm {
 	char		*name;
 	v4l2_std_id	id;
@@ -370,6 +363,7 @@ struct cx23885_audio_dev {
 struct cx23885_dev {
 	atomic_t                   refcount;
 	struct v4l2_device 	   v4l2_dev;
+	struct v4l2_ctrl_handler   ctrl_handler;
 
 	/* pci stuff */
 	struct pci_dev             *pci;
@@ -597,8 +591,6 @@ int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i);
 int cx23885_set_input(struct file *file, void *priv, unsigned int i);
 int cx23885_get_input(struct file *file, void *priv, unsigned int *i);
 int cx23885_set_frequency(struct file *file, void *priv, const struct v4l2_frequency *f);
-int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl);
-int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl);
 int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm);
 
 /* ----------------------------------------------------------- */
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 06/20] cx23885: convert 417 to the control framework
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (4 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 05/20] cx23885: convert to the control framework Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 07/20] cx23885: fix format colorspace compliance error Hans Verkuil
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Convert the -417 source to the control framework as well.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-417.c   | 133 +++++-------------------------
 drivers/media/pci/cx23885/cx23885-video.c |   6 --
 drivers/media/pci/cx23885/cx23885.h       |   2 +-
 3 files changed, 20 insertions(+), 121 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index d44395c..4142c15 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -865,6 +865,11 @@ static int cx23885_api_cmd(struct cx23885_dev *dev,
 	return err;
 }
 
+static int cx23885_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
+{
+	return cx23885_mbox_func(priv, cmd, in, out, data);
+}
+
 static int cx23885_find_mailbox(struct cx23885_dev *dev)
 {
 	u32 signature[4] = {
@@ -1033,12 +1038,12 @@ static void cx23885_codec_settings(struct cx23885_dev *dev)
 	cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
 				dev->ts1.height, dev->ts1.width);
 
-	dev->mpeg_params.width = dev->ts1.width;
-	dev->mpeg_params.height = dev->ts1.height;
-	dev->mpeg_params.is_50hz =
+	dev->cxhdl.width = dev->ts1.width;
+	dev->cxhdl.height = dev->ts1.height;
+	dev->cxhdl.is_50hz =
 		(dev->encodernorm.id & V4L2_STD_625_50) != 0;
 
-	cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params);
+	cx2341x_handler_setup(&dev->cxhdl);
 
 	cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
 	cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
@@ -1182,36 +1187,6 @@ static struct videobuf_queue_ops cx23885_qops = {
 
 /* ------------------------------------------------------------------ */
 
-static const u32 *ctrl_classes[] = {
-	cx2341x_mpeg_ctrls,
-	NULL
-};
-
-static int cx23885_queryctrl(struct cx23885_dev *dev,
-	struct v4l2_queryctrl *qctrl)
-{
-	qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
-	if (qctrl->id == 0)
-		return -EINVAL;
-
-	/* MPEG V4L2 controls */
-	if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl))
-		qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
-
-	return 0;
-}
-
-static int cx23885_querymenu(struct cx23885_dev *dev,
-	struct v4l2_querymenu *qmenu)
-{
-	struct v4l2_queryctrl qctrl;
-
-	qctrl.id = qmenu->id;
-	cx23885_queryctrl(dev, &qctrl);
-	return v4l2_ctrl_query_menu(qmenu, &qctrl,
-		cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));
-}
-
 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 {
 	struct cx23885_fh  *fh  = file->private_data;
@@ -1445,55 +1420,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 	return videobuf_streamoff(&fh->mpegq);
 }
 
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
-				struct v4l2_ext_controls *f)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-
-	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-	return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS);
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
-				struct v4l2_ext_controls *f)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-	struct cx2341x_mpeg_params p;
-	int err;
-
-	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-
-	p = dev->mpeg_params;
-	err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
-
-	if (err == 0) {
-		err = cx2341x_update(dev, cx23885_mbox_func,
-			&dev->mpeg_params, &p);
-		dev->mpeg_params = p;
-	}
-	return err;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
-				struct v4l2_ext_controls *f)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-	struct cx2341x_mpeg_params p;
-	int err;
-
-	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-
-	p = dev->mpeg_params;
-	err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
-	return err;
-}
-
 static int vidioc_log_status(struct file *file, void *priv)
 {
 	struct cx23885_fh  *fh  = priv;
@@ -1501,35 +1427,11 @@ static int vidioc_log_status(struct file *file, void *priv)
 	char name[32 + 2];
 
 	snprintf(name, sizeof(name), "%s/2", dev->name);
-	printk(KERN_INFO
-		"%s/2: ============  START LOG STATUS  ============\n",
-	       dev->name);
 	call_all(dev, core, log_status);
-	cx2341x_log_status(&dev->mpeg_params, name);
-	printk(KERN_INFO
-		"%s/2: =============  END LOG STATUS  =============\n",
-	       dev->name);
+	v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name);
 	return 0;
 }
 
-static int vidioc_querymenu(struct file *file, void *priv,
-				struct v4l2_querymenu *a)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-
-	return cx23885_querymenu(dev, a);
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
-				struct v4l2_queryctrl *c)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-
-	return cx23885_queryctrl(dev, c);
-}
-
 static int mpeg_open(struct file *file)
 {
 	struct video_device *vdev = video_devdata(file);
@@ -1667,9 +1569,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_dqbuf		 = vidioc_dqbuf,
 	.vidioc_streamon	 = vidioc_streamon,
 	.vidioc_streamoff	 = vidioc_streamoff,
-	.vidioc_g_ext_ctrls	 = vidioc_g_ext_ctrls,
-	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
-	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
 	.vidioc_log_status	 = vidioc_log_status,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_chip_info	 = cx23885_g_chip_info,
@@ -1694,6 +1593,7 @@ void cx23885_417_unregister(struct cx23885_dev *dev)
 			video_unregister_device(dev->v4l_device);
 		else
 			video_device_release(dev->v4l_device);
+		v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
 		dev->v4l_device = NULL;
 	}
 }
@@ -1740,9 +1640,14 @@ int cx23885_417_register(struct cx23885_dev *dev)
 		tsport->height = 576;
 
 	tsport->width = 720;
-	cx2341x_fill_defaults(&dev->mpeg_params);
-
-	dev->mpeg_params.port = CX2341X_PORT_SERIAL;
+	dev->cxhdl.port = CX2341X_PORT_SERIAL;
+	err = cx2341x_handler_init(&dev->cxhdl, 50);
+	if (err)
+		return err;
+	dev->cxhdl.priv = dev;
+	dev->cxhdl.func = cx23885_api_func;
+	cx2341x_handler_set_50hz(&dev->cxhdl, tsport->height == 576);
+	v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL);
 
 	/* Allocate and initialize V4L video device */
 	dev->v4l_device = cx23885_video_dev_alloc(tsport,
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 090d48b..116ce34 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -1219,13 +1219,7 @@ static int vidioc_log_status(struct file *file, void *priv)
 	struct cx23885_fh  *fh  = priv;
 	struct cx23885_dev *dev = fh->dev;
 
-	printk(KERN_INFO
-		"%s/0: ============  START LOG STATUS  ============\n",
-		dev->name);
 	call_all(dev, core, log_status);
-	printk(KERN_INFO
-		"%s/0: =============  END LOG STATUS  =============\n",
-		dev->name);
 	return 0;
 }
 
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 516435c..2d57af7 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -439,7 +439,7 @@ struct cx23885_dev {
 
 	/* MPEG Encoder ONLY settings */
 	u32                        cx23417_mailbox;
-	struct cx2341x_mpeg_params mpeg_params;
+	struct cx2341x_handler     cxhdl;
 	struct video_device        *v4l_device;
 	atomic_t                   v4l_reader_count;
 	struct cx23885_tvnorm      encodernorm;
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 07/20] cx23885: fix format colorspace compliance error
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (5 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 06/20] cx23885: convert 417 " Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 08/20] cx23885: map invalid fields to a valid field Hans Verkuil
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Fix v4l2-compliance failure relating to formatting.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 116ce34..ad02912 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -913,6 +913,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 		(f->fmt.pix.width * fh->fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
 		f->fmt.pix.height * f->fmt.pix.bytesperline;
+	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
 
 	return 0;
 }
@@ -957,6 +958,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 		(f->fmt.pix.width * fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
 		f->fmt.pix.height * f->fmt.pix.bytesperline;
+	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
 	return 0;
 }
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 08/20] cx23885: map invalid fields to a valid field.
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (6 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 07/20] cx23885: fix format colorspace compliance error Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 09/20] cx23885: drop radio-related dead code Hans Verkuil
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ad02912..9bb19fd 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -948,7 +948,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	case V4L2_FIELD_INTERLACED:
 		break;
 	default:
-		return -EINVAL;
+		field = V4L2_FIELD_INTERLACED;
+		break;
 	}
 
 	f->fmt.pix.field = field;
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 09/20] cx23885: drop radio-related dead code
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (7 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 08/20] cx23885: map invalid fields to a valid field Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 10/20] cx23885: drop type field from struct cx23885_fh Hans Verkuil
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Currently no radio device nodes are ever created, so remove the dead radio
code.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 15 +++------------
 drivers/media/pci/cx23885/cx23885.h       |  3 ---
 2 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 9bb19fd..50694c6 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -49,15 +49,12 @@ MODULE_LICENSE("GPL");
 
 static unsigned int video_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
 static unsigned int vbi_nr[]   = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
 
 module_param_array(video_nr, int, NULL, 0444);
 module_param_array(vbi_nr,   int, NULL, 0444);
-module_param_array(radio_nr, int, NULL, 0444);
 
 MODULE_PARM_DESC(video_nr, "video device numbers");
 MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
-MODULE_PARM_DESC(radio_nr, "radio device numbers");
 
 static unsigned int video_debug;
 module_param(video_debug, int, 0644);
@@ -727,7 +724,6 @@ static int video_open(struct file *file)
 	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh;
 	enum v4l2_buf_type type = 0;
-	int radio = 0;
 
 	switch (vdev->vfl_type) {
 	case VFL_TYPE_GRABBER:
@@ -736,13 +732,10 @@ static int video_open(struct file *file)
 	case VFL_TYPE_VBI:
 		type = V4L2_BUF_TYPE_VBI_CAPTURE;
 		break;
-	case VFL_TYPE_RADIO:
-		radio = 1;
-		break;
 	}
 
-	dprintk(1, "open dev=%s radio=%d type=%s\n",
-		video_device_node_name(vdev), radio, v4l2_type_names[type]);
+	dprintk(1, "open dev=%s type=%s\n",
+		video_device_node_name(vdev), v4l2_type_names[type]);
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
@@ -752,7 +745,6 @@ static int video_open(struct file *file)
 	v4l2_fh_init(&fh->fh, vdev);
 	file->private_data = &fh->fh;
 	fh->dev      = dev;
-	fh->radio    = radio;
 	fh->type     = type;
 	fh->width    = 320;
 	fh->height   = 240;
@@ -1333,8 +1325,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
 
-	/* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
-	f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+	f->type = V4L2_TUNER_ANALOG_TV;
 	f->frequency = dev->freq;
 
 	call_all(dev, tuner, g_frequency, f);
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 2d57af7..94ab000 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -144,7 +144,6 @@ struct cx23885_fh {
 	struct v4l2_fh		   fh;
 	struct cx23885_dev         *dev;
 	enum v4l2_buf_type         type;
-	int                        radio;
 	u32                        resources;
 
 	/* video overlay */
@@ -413,7 +412,6 @@ struct cx23885_dev {
 	unsigned int               tuner_bus;
 	unsigned int               radio_type;
 	unsigned char              radio_addr;
-	unsigned int               has_radio;
 	struct v4l2_subdev 	   *sd_cx25840;
 	struct work_struct	   cx25840_work;
 
@@ -431,7 +429,6 @@ struct cx23885_dev {
 	u32                        freq;
 	struct video_device        *video_dev;
 	struct video_device        *vbi_dev;
-	struct video_device        *radio_dev;
 
 	struct cx23885_dmaqueue    vidq;
 	struct cx23885_dmaqueue    vbiq;
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 10/20] cx23885: drop type field from struct cx23885_fh
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (8 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 09/20] cx23885: drop radio-related dead code Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 11/20] cx23885: drop unused clip fields " Hans Verkuil
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

This information is available elsewhere as well.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 89 ++++++++++++++-----------------
 drivers/media/pci/cx23885/cx23885.h       |  1 -
 2 files changed, 40 insertions(+), 50 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 50694c6..a68ab59 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -692,28 +692,31 @@ static struct videobuf_queue_ops cx23885_video_qops = {
 	.buf_release  = buffer_release,
 };
 
-static struct videobuf_queue *get_queue(struct cx23885_fh *fh)
+static struct videobuf_queue *get_queue(struct file *file)
 {
-	switch (fh->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	struct video_device *vdev = video_devdata(file);
+	struct cx23885_fh *fh = file->private_data;
+
+	switch (vdev->vfl_type) {
+	case VFL_TYPE_GRABBER:
 		return &fh->vidq;
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
+	case VFL_TYPE_VBI:
 		return &fh->vbiq;
 	default:
-		BUG();
+		WARN_ON(1);
 		return NULL;
 	}
 }
 
-static int get_resource(struct cx23885_fh *fh)
+static int get_resource(u32 type)
 {
-	switch (fh->type) {
+	switch (type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		return RESOURCE_VIDEO;
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
 		return RESOURCE_VBI;
 	default:
-		BUG();
+		WARN_ON(1);
 		return 0;
 	}
 }
@@ -723,19 +726,9 @@ static int video_open(struct file *file)
 	struct video_device *vdev = video_devdata(file);
 	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh;
-	enum v4l2_buf_type type = 0;
 
-	switch (vdev->vfl_type) {
-	case VFL_TYPE_GRABBER:
-		type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		break;
-	case VFL_TYPE_VBI:
-		type = V4L2_BUF_TYPE_VBI_CAPTURE;
-		break;
-	}
-
-	dprintk(1, "open dev=%s type=%s\n",
-		video_device_node_name(vdev), v4l2_type_names[type]);
+	dprintk(1, "open dev=%s\n",
+		video_device_node_name(vdev));
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
@@ -745,7 +738,6 @@ static int video_open(struct file *file)
 	v4l2_fh_init(&fh->fh, vdev);
 	file->private_data = &fh->fh;
 	fh->dev      = dev;
-	fh->type     = type;
 	fh->width    = 320;
 	fh->height   = 240;
 	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_YUYV);
@@ -774,28 +766,29 @@ static int video_open(struct file *file)
 static ssize_t video_read(struct file *file, char __user *data,
 	size_t count, loff_t *ppos)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct cx23885_fh *fh = file->private_data;
 
-	switch (fh->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	switch (vdev->vfl_type) {
+	case VFL_TYPE_GRABBER:
 		if (res_locked(fh->dev, RESOURCE_VIDEO))
 			return -EBUSY;
 		return videobuf_read_one(&fh->vidq, data, count, ppos,
 					 file->f_flags & O_NONBLOCK);
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
+	case VFL_TYPE_VBI:
 		if (!res_get(fh->dev, fh, RESOURCE_VBI))
 			return -EBUSY;
 		return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1,
 					    file->f_flags & O_NONBLOCK);
 	default:
-		BUG();
-		return 0;
+		return -EINVAL;
 	}
 }
 
 static unsigned int video_poll(struct file *file,
 	struct poll_table_struct *wait)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct cx23885_fh *fh = file->private_data;
 	struct cx23885_buffer *buf;
 	unsigned long req_events = poll_requested_events(wait);
@@ -808,7 +801,7 @@ static unsigned int video_poll(struct file *file,
 	if (!(req_events & (POLLIN | POLLRDNORM)))
 		return rc;
 
-	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
+	if (vdev->vfl_type == VFL_TYPE_VBI) {
 		if (!res_get(fh->dev, fh, RESOURCE_VBI))
 			return rc | POLLERR;
 		return rc | videobuf_poll_stream(file, &fh->vbiq, wait);
@@ -884,9 +877,7 @@ static int video_release(struct file *file)
 
 static int video_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct cx23885_fh *fh = file->private_data;
-
-	return videobuf_mmap_mapper(get_queue(fh), vma);
+	return videobuf_mmap_mapper(get_queue(file), vma);
 }
 
 /* ------------------------------------------------------------------ */
@@ -1019,73 +1010,73 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int vidioc_reqbufs(struct file *file, void *priv,
 	struct v4l2_requestbuffers *p)
 {
-	struct cx23885_fh *fh = priv;
-	return videobuf_reqbufs(get_queue(fh), p);
+	return videobuf_reqbufs(get_queue(file), p);
 }
 
 static int vidioc_querybuf(struct file *file, void *priv,
 	struct v4l2_buffer *p)
 {
-	struct cx23885_fh *fh = priv;
-	return videobuf_querybuf(get_queue(fh), p);
+	return videobuf_querybuf(get_queue(file), p);
 }
 
 static int vidioc_qbuf(struct file *file, void *priv,
 	struct v4l2_buffer *p)
 {
-	struct cx23885_fh *fh = priv;
-	return videobuf_qbuf(get_queue(fh), p);
+	return videobuf_qbuf(get_queue(file), p);
 }
 
 static int vidioc_dqbuf(struct file *file, void *priv,
 	struct v4l2_buffer *p)
 {
-	struct cx23885_fh *fh = priv;
-	return videobuf_dqbuf(get_queue(fh), p,
+	return videobuf_dqbuf(get_queue(file), p,
 				file->f_flags & O_NONBLOCK);
 }
 
 static int vidioc_streamon(struct file *file, void *priv,
 	enum v4l2_buf_type i)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct cx23885_fh *fh = priv;
 	struct cx23885_dev *dev = fh->dev;
 	dprintk(1, "%s()\n", __func__);
 
-	if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
-		(fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
+	if (vdev->vfl_type == VFL_TYPE_VBI &&
+	    i != V4L2_BUF_TYPE_VBI_CAPTURE)
 		return -EINVAL;
-	if (unlikely(i != fh->type))
+	if (vdev->vfl_type == VFL_TYPE_GRABBER &&
+	    i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	if (unlikely(!res_get(dev, fh, get_resource(fh))))
+	if (unlikely(!res_get(dev, fh, get_resource(i))))
 		return -EBUSY;
 
 	/* Don't start VBI streaming unless vida streaming
 	 * has already started.
 	 */
-	if ((fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) &&
+	if ((i == V4L2_BUF_TYPE_VBI_CAPTURE) &&
 		((cx_read(VID_A_DMA_CTL) & 0x11) == 0))
 		return -EINVAL;
 
-	return videobuf_streamon(get_queue(fh));
+	return videobuf_streamon(get_queue(file));
 }
 
 static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct cx23885_fh *fh = priv;
 	struct cx23885_dev *dev = fh->dev;
 	int err, res;
 	dprintk(1, "%s()\n", __func__);
 
-	if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
-		(fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
+	if (vdev->vfl_type == VFL_TYPE_VBI &&
+	    i != V4L2_BUF_TYPE_VBI_CAPTURE)
 		return -EINVAL;
-	if (i != fh->type)
+	if (vdev->vfl_type == VFL_TYPE_GRABBER &&
+	    i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	res = get_resource(fh);
-	err = videobuf_streamoff(get_queue(fh));
+	res = get_resource(i);
+	err = videobuf_streamoff(get_queue(file));
 	if (err < 0)
 		return err;
 	res_free(dev, fh, res);
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 94ab000..aba1e6a 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -143,7 +143,6 @@ struct cx23885_tvnorm {
 struct cx23885_fh {
 	struct v4l2_fh		   fh;
 	struct cx23885_dev         *dev;
-	enum v4l2_buf_type         type;
 	u32                        resources;
 
 	/* video overlay */
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 11/20] cx23885: drop unused clip fields from struct cx23885_fh
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (9 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 10/20] cx23885: drop type field from struct cx23885_fh Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 12/20] cx23885: fmt, width and height are global, not per-fh Hans Verkuil
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

There is no overlay support, so drop these unused fields.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index aba1e6a..a88e951 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -145,11 +145,6 @@ struct cx23885_fh {
 	struct cx23885_dev         *dev;
 	u32                        resources;
 
-	/* video overlay */
-	struct v4l2_window         win;
-	struct v4l2_clip           *clips;
-	unsigned int               nclips;
-
 	/* video capture */
 	struct cx23885_fmt         *fmt;
 	unsigned int               width, height;
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 12/20] cx23885: fmt, width and height are global, not per-fh.
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (10 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 11/20] cx23885: drop unused clip fields " Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 13/20] cx23885: drop videobuf abuse in cx23885-alsa Hans Verkuil
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Move these fields from cx23885_fh to cx23885_dev.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 125 +++++++-----------------------
 drivers/media/pci/cx23885/cx23885.h       |   8 +-
 2 files changed, 34 insertions(+), 99 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index a68ab59..3dcee0a 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -77,77 +77,14 @@ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
 /* static data                                                         */
 
 #define FORMAT_FLAGS_PACKED       0x01
-#if 0
 static struct cx23885_fmt formats[] = {
 	{
-		.name     = "8 bpp, gray",
-		.fourcc   = V4L2_PIX_FMT_GREY,
-		.depth    = 8,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "15 bpp RGB, le",
-		.fourcc   = V4L2_PIX_FMT_RGB555,
-		.depth    = 16,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "15 bpp RGB, be",
-		.fourcc   = V4L2_PIX_FMT_RGB555X,
-		.depth    = 16,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "16 bpp RGB, le",
-		.fourcc   = V4L2_PIX_FMT_RGB565,
-		.depth    = 16,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "16 bpp RGB, be",
-		.fourcc   = V4L2_PIX_FMT_RGB565X,
-		.depth    = 16,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "24 bpp RGB, le",
-		.fourcc   = V4L2_PIX_FMT_BGR24,
-		.depth    = 24,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "32 bpp RGB, le",
-		.fourcc   = V4L2_PIX_FMT_BGR32,
-		.depth    = 32,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "32 bpp RGB, be",
-		.fourcc   = V4L2_PIX_FMT_RGB32,
-		.depth    = 32,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "4:2:2, packed, YUYV",
-		.fourcc   = V4L2_PIX_FMT_YUYV,
-		.depth    = 16,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-		.name     = "4:2:2, packed, UYVY",
-		.fourcc   = V4L2_PIX_FMT_UYVY,
-		.depth    = 16,
-		.flags    = FORMAT_FLAGS_PACKED,
-	},
-};
-#else
-static struct cx23885_fmt formats[] = {
-	{
-#if 0
-		.name     = "4:2:2, packed, UYVY",
-		.fourcc   = V4L2_PIX_FMT_UYVY,
-		.depth    = 16,
-		.flags    = FORMAT_FLAGS_PACKED,
-	}, {
-#endif
 		.name     = "4:2:2, packed, YUYV",
 		.fourcc   = V4L2_PIX_FMT_YUYV,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}
 };
-#endif
 
 static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc)
 {
@@ -156,13 +93,6 @@ static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc)
 	for (i = 0; i < ARRAY_SIZE(formats); i++)
 		if (formats[i].fourcc == fourcc)
 			return formats+i;
-
-	printk(KERN_ERR "%s(%c%c%c%c) NOT FOUND\n", __func__,
-		(fourcc & 0xff),
-		((fourcc >> 8) & 0xff),
-		((fourcc >> 16) & 0xff),
-		((fourcc >> 24) & 0xff)
-		);
 	return NULL;
 }
 
@@ -502,8 +432,9 @@ static int buffer_setup(struct videobuf_queue *q, unsigned int *count,
 	unsigned int *size)
 {
 	struct cx23885_fh *fh = q->priv_data;
+	struct cx23885_dev *dev = fh->dev;
 
-	*size = fh->fmt->depth*fh->width*fh->height >> 3;
+	*size = (dev->fmt->depth * dev->width * dev->height) >> 3;
 	if (0 == *count)
 		*count = 32;
 	if (*size * *count > vid_limit * 1024 * 1024)
@@ -523,21 +454,23 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
 	int field_tff;
 
-	BUG_ON(NULL == fh->fmt);
-	if (fh->width  < 48 || fh->width  > norm_maxw(dev->tvnorm) ||
-	    fh->height < 32 || fh->height > norm_maxh(dev->tvnorm))
+	if (WARN_ON(NULL == dev->fmt))
+		return -EINVAL;
+
+	if (dev->width  < 48 || dev->width  > norm_maxw(dev->tvnorm) ||
+	    dev->height < 32 || dev->height > norm_maxh(dev->tvnorm))
 		return -EINVAL;
-	buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+	buf->vb.size = (dev->width * dev->height * dev->fmt->depth) >> 3;
 	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
 		return -EINVAL;
 
-	if (buf->fmt       != fh->fmt    ||
-	    buf->vb.width  != fh->width  ||
-	    buf->vb.height != fh->height ||
+	if (buf->fmt       != dev->fmt    ||
+	    buf->vb.width  != dev->width  ||
+	    buf->vb.height != dev->height ||
 	    buf->vb.field  != field) {
-		buf->fmt       = fh->fmt;
-		buf->vb.width  = fh->width;
-		buf->vb.height = fh->height;
+		buf->fmt       = dev->fmt;
+		buf->vb.width  = dev->width;
+		buf->vb.height = dev->height;
 		buf->vb.field  = field;
 		init_buffer = 1;
 	}
@@ -612,7 +545,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 	}
 	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
 		buf, buf->vb.i,
-		fh->width, fh->height, fh->fmt->depth, fh->fmt->name,
+		dev->width, dev->height, dev->fmt->depth, dev->fmt->name,
 		(unsigned long)buf->risc.dma);
 
 	buf->vb.state = VIDEOBUF_PREPARED;
@@ -738,9 +671,6 @@ static int video_open(struct file *file)
 	v4l2_fh_init(&fh->fh, vdev);
 	file->private_data = &fh->fh;
 	fh->dev      = dev;
-	fh->width    = 320;
-	fh->height   = 240;
-	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_YUYV);
 
 	videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops,
 			    &dev->pci->dev, &dev->slock,
@@ -887,13 +817,14 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
 	struct cx23885_fh *fh   = priv;
+	struct cx23885_dev *dev = fh->dev;
 
-	f->fmt.pix.width        = fh->width;
-	f->fmt.pix.height       = fh->height;
+	f->fmt.pix.width        = dev->width;
+	f->fmt.pix.height       = dev->height;
 	f->fmt.pix.field        = fh->vidq.field;
-	f->fmt.pix.pixelformat  = fh->fmt->fourcc;
+	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
 	f->fmt.pix.bytesperline =
-		(f->fmt.pix.width * fh->fmt->depth) >> 3;
+		(f->fmt.pix.width * dev->fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
 		f->fmt.pix.height * f->fmt.pix.bytesperline;
 	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
@@ -951,7 +882,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
 	struct cx23885_fh *fh = priv;
-	struct cx23885_dev *dev  = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev  = fh->dev;
 	struct v4l2_mbus_framefmt mbus_fmt;
 	int err;
 
@@ -960,12 +891,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 
 	if (0 != err)
 		return err;
-	fh->fmt        = format_by_fourcc(f->fmt.pix.pixelformat);
-	fh->width      = f->fmt.pix.width;
-	fh->height     = f->fmt.pix.height;
+	dev->fmt        = format_by_fourcc(f->fmt.pix.pixelformat);
+	dev->width      = f->fmt.pix.width;
+	dev->height     = f->fmt.pix.height;
 	fh->vidq.field = f->fmt.pix.field;
 	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
-		fh->width, fh->height, fh->vidq.field);
+		dev->width, dev->height, fh->vidq.field);
 	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
 	call_all(dev, video, s_mbus_fmt, &mbus_fmt);
 	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
@@ -976,7 +907,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
 	struct v4l2_capability *cap)
 {
 	struct video_device *vdev = video_devdata(file);
-	struct cx23885_dev *dev  = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_fh *fh = priv;
+	struct cx23885_dev *dev = fh->dev;
 
 	strcpy(cap->driver, "cx23885");
 	strlcpy(cap->card, cx23885_boards[dev->board].name,
@@ -1619,6 +1551,9 @@ int cx23885_video_register(struct cx23885_dev *dev)
 	strcpy(cx23885_vbi_template.name, "cx23885-vbi");
 
 	dev->tvnorm = V4L2_STD_NTSC_M;
+	dev->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
+	dev->width = norm_maxw(dev->tvnorm);
+	dev->height = norm_maxh(dev->tvnorm);
 
 	/* init video dma queues */
 	INIT_LIST_HEAD(&dev->vidq.active);
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index a88e951..260d177 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -145,10 +145,6 @@ struct cx23885_fh {
 	struct cx23885_dev         *dev;
 	u32                        resources;
 
-	/* video capture */
-	struct cx23885_fmt         *fmt;
-	unsigned int               width, height;
-
 	/* vbi capture */
 	struct videobuf_queue      vidq;
 	struct videobuf_queue      vbiq;
@@ -424,6 +420,10 @@ struct cx23885_dev {
 	struct video_device        *video_dev;
 	struct video_device        *vbi_dev;
 
+	/* video capture */
+	struct cx23885_fmt         *fmt;
+	unsigned int               width, height;
+
 	struct cx23885_dmaqueue    vidq;
 	struct cx23885_dmaqueue    vbiq;
 	spinlock_t                 slock;
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 13/20] cx23885: drop videobuf abuse in cx23885-alsa
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (11 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 12/20] cx23885: fmt, width and height are global, not per-fh Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:53 ` [PATCHv2 14/20] cx23885: use video_drvdata to get cx23885_dev pointer Hans Verkuil
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

The alsa driver uses videobuf low-level functions that are not
available in vb2, so replace them by driver-specific functions.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-alsa.c | 96 ++++++++++++++++++++++++++++----
 drivers/media/pci/cx23885/cx23885.h      |  7 ++-
 2 files changed, 88 insertions(+), 15 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c
index 554798d..31dbf0c 100644
--- a/drivers/media/pci/cx23885/cx23885-alsa.c
+++ b/drivers/media/pci/cx23885/cx23885-alsa.c
@@ -84,6 +84,82 @@ MODULE_PARM_DESC(audio_debug, "enable debug messages [analog audio]");
 #define AUD_INT_MCHG_IRQ        (1 << 21)
 #define GP_COUNT_CONTROL_RESET	0x3
 
+static int cx23885_alsa_dma_init(struct cx23885_audio_dev *chip, int nr_pages)
+{
+	struct cx23885_audio_buffer *buf = chip->buf;
+	struct page *pg;
+	int i;
+
+	buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
+	if (NULL == buf->vaddr) {
+		dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
+		return -ENOMEM;
+	}
+
+	dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
+				(unsigned long)buf->vaddr,
+				nr_pages << PAGE_SHIFT);
+
+	memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT);
+	buf->nr_pages = nr_pages;
+
+	buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist));
+	if (NULL == buf->sglist)
+		goto vzalloc_err;
+
+	sg_init_table(buf->sglist, buf->nr_pages);
+	for (i = 0; i < buf->nr_pages; i++) {
+		pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE);
+		if (NULL == pg)
+			goto vmalloc_to_page_err;
+		sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0);
+	}
+	return 0;
+
+vmalloc_to_page_err:
+	vfree(buf->sglist);
+	buf->sglist = NULL;
+vzalloc_err:
+	vfree(buf->vaddr);
+	buf->vaddr = NULL;
+	return -ENOMEM;
+}
+
+static int cx23885_alsa_dma_map(struct cx23885_audio_dev *dev)
+{
+	struct cx23885_audio_buffer *buf = dev->buf;
+
+	buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist,
+			buf->nr_pages, PCI_DMA_FROMDEVICE);
+
+	if (0 == buf->sglen) {
+		pr_warn("%s: cx23885_alsa_map_sg failed\n", __func__);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int cx23885_alsa_dma_unmap(struct cx23885_audio_dev *dev)
+{
+	struct cx23885_audio_buffer *buf = dev->buf;
+
+	if (!buf->sglen)
+		return 0;
+
+	dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE);
+	buf->sglen = 0;
+	return 0;
+}
+
+static int cx23885_alsa_dma_free(struct cx23885_audio_buffer *buf)
+{
+	vfree(buf->sglist);
+	buf->sglist = NULL;
+	vfree(buf->vaddr);
+	buf->vaddr = NULL;
+	return 0;
+}
+
 /*
  * BOARD Specific: Sets audio DMA
  */
@@ -201,12 +277,12 @@ static int dsp_buffer_free(struct cx23885_audio_dev *chip)
 	BUG_ON(!chip->dma_size);
 
 	dprintk(2, "Freeing buffer\n");
-	videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc);
-	videobuf_dma_free(chip->dma_risc);
+	cx23885_alsa_dma_unmap(chip);
+	cx23885_alsa_dma_free(chip->buf);
 	btcx_riscmem_free(chip->pci, &chip->buf->risc);
 	kfree(chip->buf);
 
-	chip->dma_risc = NULL;
+	chip->buf = NULL;
 	chip->dma_size = 0;
 
 	return 0;
@@ -289,6 +365,7 @@ static int snd_cx23885_close(struct snd_pcm_substream *substream)
 	return 0;
 }
 
+
 /*
  * hw_params callback
  */
@@ -296,8 +373,6 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 			      struct snd_pcm_hw_params *hw_params)
 {
 	struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
-	struct videobuf_dmabuf *dma;
-
 	struct cx23885_audio_buffer *buf;
 	int ret;
 
@@ -319,18 +394,16 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 
 	buf->bpl = chip->period_size;
 
-	dma = &buf->dma;
-	videobuf_dma_init(dma);
-	ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
+	ret = cx23885_alsa_dma_init(chip,
 			(PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
 	if (ret < 0)
 		goto error;
 
-	ret = videobuf_dma_map(&chip->pci->dev, dma);
+	ret = cx23885_alsa_dma_map(chip);
 	if (ret < 0)
 		goto error;
 
-	ret = cx23885_risc_databuffer(chip->pci, &buf->risc, dma->sglist,
+	ret = cx23885_risc_databuffer(chip->pci, &buf->risc, buf->sglist,
 				   chip->period_size, chip->num_periods, 1);
 	if (ret < 0)
 		goto error;
@@ -341,9 +414,8 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
 
 	chip->buf = buf;
-	chip->dma_risc = dma;
 
-	substream->runtime->dma_area = chip->dma_risc->vaddr;
+	substream->runtime->dma_area = chip->buf->vaddr;
 	substream->runtime->dma_bytes = chip->dma_size;
 	substream->runtime->dma_addr = 0;
 
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 260d177..9cd2b1b 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -324,7 +324,10 @@ struct cx23885_kernel_ir {
 struct cx23885_audio_buffer {
 	unsigned int		bpl;
 	struct btcx_riscmem	risc;
-	struct videobuf_dmabuf	dma;
+	void			*vaddr;
+	struct scatterlist	*sglist;
+	int                     sglen;
+	int                     nr_pages;
 };
 
 struct cx23885_audio_dev {
@@ -342,8 +345,6 @@ struct cx23885_audio_dev {
 	unsigned int		period_size;
 	unsigned int		num_periods;
 
-	struct videobuf_dmabuf	*dma_risc;
-
 	struct cx23885_audio_buffer   *buf;
 
 	struct snd_pcm_substream *substream;
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 14/20] cx23885: use video_drvdata to get cx23885_dev pointer
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (12 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 13/20] cx23885: drop videobuf abuse in cx23885-alsa Hans Verkuil
@ 2014-08-14  9:53 ` Hans Verkuil
  2014-08-14  9:54 ` [PATCHv2 15/20] cx23885: convert to vb2 Hans Verkuil
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:53 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Use video_drvdata(file) instead of fh->dev to get the cx23885_dev
pointer. This prepares for the vb2 conversion where fh->dev (renamed
to fh->q_dev in this patch) will be removed completely.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-417.c   | 56 +++++++++++++----------------
 drivers/media/pci/cx23885/cx23885-ioctl.c |  6 ++--
 drivers/media/pci/cx23885/cx23885-vbi.c   |  7 ++--
 drivers/media/pci/cx23885/cx23885-video.c | 60 +++++++++++++++----------------
 drivers/media/pci/cx23885/cx23885.h       |  2 +-
 5 files changed, 60 insertions(+), 71 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index 4142c15..0948b44 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1147,10 +1147,10 @@ static int bb_buf_setup(struct videobuf_queue *q,
 {
 	struct cx23885_fh *fh = q->priv_data;
 
-	fh->dev->ts1.ts_packet_size  = mpeglinesize;
-	fh->dev->ts1.ts_packet_count = mpeglines;
+	fh->q_dev->ts1.ts_packet_size  = mpeglinesize;
+	fh->q_dev->ts1.ts_packet_count = mpeglines;
 
-	*size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;
+	*size = fh->q_dev->ts1.ts_packet_size * fh->q_dev->ts1.ts_packet_count;
 	*count = mpegbufs;
 
 	return 0;
@@ -1160,7 +1160,7 @@ static int bb_buf_prepare(struct videobuf_queue *q,
 	struct videobuf_buffer *vb, enum v4l2_field field)
 {
 	struct cx23885_fh *fh = q->priv_data;
-	return cx23885_buf_prepare(q, &fh->dev->ts1,
+	return cx23885_buf_prepare(q, &fh->q_dev->ts1,
 		(struct cx23885_buffer *)vb,
 		field);
 }
@@ -1169,7 +1169,7 @@ static void bb_buf_queue(struct videobuf_queue *q,
 	struct videobuf_buffer *vb)
 {
 	struct cx23885_fh *fh = q->priv_data;
-	cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb);
+	cx23885_buf_queue(&fh->q_dev->ts1, (struct cx23885_buffer *)vb);
 }
 
 static void bb_buf_release(struct videobuf_queue *q,
@@ -1189,8 +1189,7 @@ static struct videobuf_queue_ops cx23885_qops = {
 
 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	*id = dev->tvnorm;
 	return 0;
@@ -1198,8 +1197,7 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
@@ -1218,7 +1216,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
 static int vidioc_enum_input(struct file *file, void *priv,
 	struct v4l2_input *i)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	dprintk(1, "%s()\n", __func__);
 	return cx23885_enum_input(dev, i);
 }
@@ -1236,8 +1234,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *t)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1254,8 +1251,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 static int vidioc_s_tuner(struct file *file, void *priv,
 				const struct v4l2_tuner *t)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1269,8 +1265,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1291,8 +1286,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 static int vidioc_querycap(struct file *file, void  *priv,
 				struct v4l2_capability *cap)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_tsport  *tsport = &dev->ts1;
 
 	strlcpy(cap->driver, dev->name, sizeof(cap->driver));
@@ -1325,8 +1319,8 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
@@ -1344,8 +1338,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
@@ -1360,8 +1354,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
@@ -1422,8 +1415,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 
 static int vidioc_log_status(struct file *file, void *priv)
 {
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	char name[32 + 2];
 
 	snprintf(name, sizeof(name), "%s/2", dev->name);
@@ -1434,8 +1426,8 @@ static int vidioc_log_status(struct file *file, void *priv)
 
 static int mpeg_open(struct file *file)
 {
-	struct video_device *vdev = video_devdata(file);
 	struct cx23885_dev *dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
 	struct cx23885_fh *fh;
 
 	dprintk(2, "%s()\n", __func__);
@@ -1447,7 +1439,7 @@ static int mpeg_open(struct file *file)
 
 	v4l2_fh_init(&fh->fh, vdev);
 	file->private_data = fh;
-	fh->dev      = dev;
+	fh->q_dev      = dev;
 
 	videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops,
 			    &dev->pci->dev, &dev->ts1.slock,
@@ -1461,8 +1453,8 @@ static int mpeg_open(struct file *file)
 
 static int mpeg_release(struct file *file)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
 
 	dprintk(2, "%s()\n", __func__);
 
@@ -1471,14 +1463,14 @@ static int mpeg_release(struct file *file)
 	if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
 		if (atomic_dec_return(&dev->v4l_reader_count) == 0) {
 			/* stop mpeg capture */
-			cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
+			cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
 				CX23885_END_NOW, CX23885_MPEG_CAPTURE,
 				CX23885_RAW_BITS_NONE);
 
 			msleep(500);
 			cx23885_417_check_encoder(dev);
 
-			cx23885_cancel_buffers(&fh->dev->ts1);
+			cx23885_cancel_buffers(&dev->ts1);
 		}
 	}
 
@@ -1499,8 +1491,8 @@ static int mpeg_release(struct file *file)
 static ssize_t mpeg_read(struct file *file, char __user *data,
 	size_t count, loff_t *ppos)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
 
 	dprintk(2, "%s()\n", __func__);
 
@@ -1520,8 +1512,8 @@ static ssize_t mpeg_read(struct file *file, char __user *data,
 static unsigned int mpeg_poll(struct file *file,
 	struct poll_table_struct *wait)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
 
 	dprintk(2, "%s\n", __func__);
 
@@ -1530,8 +1522,8 @@ static unsigned int mpeg_poll(struct file *file,
 
 static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
 
 	dprintk(2, "%s()\n", __func__);
 
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.c b/drivers/media/pci/cx23885/cx23885-ioctl.c
index 271d69d..9c16786 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.c
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.c
@@ -28,7 +28,7 @@
 int cx23885_g_chip_info(struct file *file, void *fh,
 			 struct v4l2_dbg_chip_info *chip)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (chip->match.addr > 1)
 		return -EINVAL;
@@ -64,7 +64,7 @@ static int cx23417_g_register(struct cx23885_dev *dev,
 int cx23885_g_register(struct file *file, void *fh,
 		       struct v4l2_dbg_register *reg)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (reg->match.addr > 1)
 		return -EINVAL;
@@ -96,7 +96,7 @@ static int cx23417_s_register(struct cx23885_dev *dev,
 int cx23885_s_register(struct file *file, void *fh,
 		       const struct v4l2_dbg_register *reg)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (reg->match.addr > 1)
 		return -EINVAL;
diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
index a1154f0..1cb67d3 100644
--- a/drivers/media/pci/cx23885/cx23885-vbi.c
+++ b/drivers/media/pci/cx23885/cx23885-vbi.c
@@ -50,8 +50,7 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
 int cx23885_vbi_fmt(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
-	struct cx23885_fh *fh = priv;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tvnorm & V4L2_STD_525_60) {
 		/* ntsc */
@@ -201,7 +200,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 	    enum v4l2_field field)
 {
 	struct cx23885_fh *fh  = q->priv_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = fh->q_dev;
 	struct cx23885_buffer *buf = container_of(vb,
 		struct cx23885_buffer, vb);
 	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
@@ -242,7 +241,7 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 		container_of(vb, struct cx23885_buffer, vb);
 	struct cx23885_buffer   *prev;
 	struct cx23885_fh       *fh   = vq->priv_data;
-	struct cx23885_dev      *dev  = fh->dev;
+	struct cx23885_dev      *dev  = fh->q_dev;
 	struct cx23885_dmaqueue *q    = &dev->vbiq;
 
 	/* add jump to stopper */
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 3dcee0a..b374003 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -432,7 +432,7 @@ static int buffer_setup(struct videobuf_queue *q, unsigned int *count,
 	unsigned int *size)
 {
 	struct cx23885_fh *fh = q->priv_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = fh->q_dev;
 
 	*size = (dev->fmt->depth * dev->width * dev->height) >> 3;
 	if (0 == *count)
@@ -446,7 +446,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 	       enum v4l2_field field)
 {
 	struct cx23885_fh *fh  = q->priv_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = fh->q_dev;
 	struct cx23885_buffer *buf =
 		container_of(vb, struct cx23885_buffer, vb);
 	int rc, init_buffer = 0;
@@ -562,7 +562,7 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 		struct cx23885_buffer, vb);
 	struct cx23885_buffer   *prev;
 	struct cx23885_fh       *fh   = vq->priv_data;
-	struct cx23885_dev      *dev  = fh->dev;
+	struct cx23885_dev      *dev  = fh->q_dev;
 	struct cx23885_dmaqueue *q    = &dev->vidq;
 
 	/* add jump to stopper */
@@ -670,7 +670,7 @@ static int video_open(struct file *file)
 
 	v4l2_fh_init(&fh->fh, vdev);
 	file->private_data = &fh->fh;
-	fh->dev      = dev;
+	fh->q_dev      = dev;
 
 	videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops,
 			    &dev->pci->dev, &dev->slock,
@@ -697,16 +697,17 @@ static ssize_t video_read(struct file *file, char __user *data,
 	size_t count, loff_t *ppos)
 {
 	struct video_device *vdev = video_devdata(file);
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh = file->private_data;
 
 	switch (vdev->vfl_type) {
 	case VFL_TYPE_GRABBER:
-		if (res_locked(fh->dev, RESOURCE_VIDEO))
+		if (res_locked(dev, RESOURCE_VIDEO))
 			return -EBUSY;
 		return videobuf_read_one(&fh->vidq, data, count, ppos,
 					 file->f_flags & O_NONBLOCK);
 	case VFL_TYPE_VBI:
-		if (!res_get(fh->dev, fh, RESOURCE_VBI))
+		if (!res_get(dev, fh, RESOURCE_VBI))
 			return -EBUSY;
 		return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1,
 					    file->f_flags & O_NONBLOCK);
@@ -719,6 +720,7 @@ static unsigned int video_poll(struct file *file,
 	struct poll_table_struct *wait)
 {
 	struct video_device *vdev = video_devdata(file);
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh = file->private_data;
 	struct cx23885_buffer *buf;
 	unsigned long req_events = poll_requested_events(wait);
@@ -732,7 +734,7 @@ static unsigned int video_poll(struct file *file,
 		return rc;
 
 	if (vdev->vfl_type == VFL_TYPE_VBI) {
-		if (!res_get(fh->dev, fh, RESOURCE_VBI))
+		if (!res_get(dev, fh, RESOURCE_VBI))
 			return rc | POLLERR;
 		return rc | videobuf_poll_stream(file, &fh->vbiq, wait);
 	}
@@ -761,8 +763,8 @@ done:
 
 static int video_release(struct file *file)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
 
 	/* turn off overlay */
 	if (res_check(fh, RESOURCE_OVERLAY)) {
@@ -816,8 +818,8 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma)
 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh   = priv;
-	struct cx23885_dev *dev = fh->dev;
 
 	f->fmt.pix.width        = dev->width;
 	f->fmt.pix.height       = dev->height;
@@ -835,7 +837,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fmt *fmt;
 	enum v4l2_field   field;
 	unsigned int      maxw, maxh;
@@ -881,8 +883,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_fh *fh = priv;
-	struct cx23885_dev *dev  = fh->dev;
 	struct v4l2_mbus_framefmt mbus_fmt;
 	int err;
 
@@ -906,9 +908,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_querycap(struct file *file, void  *priv,
 	struct v4l2_capability *cap)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct video_device *vdev = video_devdata(file);
-	struct cx23885_fh *fh = priv;
-	struct cx23885_dev *dev = fh->dev;
 
 	strcpy(cap->driver, "cx23885");
 	strlcpy(cap->card, cx23885_boards[dev->board].name,
@@ -967,9 +968,9 @@ static int vidioc_dqbuf(struct file *file, void *priv,
 static int vidioc_streamon(struct file *file, void *priv,
 	enum v4l2_buf_type i)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct video_device *vdev = video_devdata(file);
 	struct cx23885_fh *fh = priv;
-	struct cx23885_dev *dev = fh->dev;
 	dprintk(1, "%s()\n", __func__);
 
 	if (vdev->vfl_type == VFL_TYPE_VBI &&
@@ -994,9 +995,9 @@ static int vidioc_streamon(struct file *file, void *priv,
 
 static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 {
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct video_device *vdev = video_devdata(file);
 	struct cx23885_fh *fh = priv;
-	struct cx23885_dev *dev = fh->dev;
 	int err, res;
 	dprintk(1, "%s()\n", __func__);
 
@@ -1017,7 +1018,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 
 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	dprintk(1, "%s()\n", __func__);
 
 	*id = dev->tvnorm;
@@ -1026,7 +1027,7 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	dprintk(1, "%s()\n", __func__);
 
 	cx23885_set_tvnorm(dev, tvnorms);
@@ -1086,14 +1087,14 @@ int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
 static int vidioc_enum_input(struct file *file, void *priv,
 				struct v4l2_input *i)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	dprintk(1, "%s()\n", __func__);
 	return cx23885_enum_input(dev, i);
 }
 
 int cx23885_get_input(struct file *file, void *priv, unsigned int *i)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	*i = dev->input;
 	dprintk(1, "%s() returns %d\n", __func__, *i);
@@ -1107,7 +1108,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
 
 int cx23885_set_input(struct file *file, void *priv, unsigned int i)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	dprintk(1, "%s(%d)\n", __func__, i);
 
@@ -1134,8 +1135,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 
 static int vidioc_log_status(struct file *file, void *priv)
 {
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	call_all(dev, core, log_status);
 	return 0;
@@ -1144,7 +1144,7 @@ static int vidioc_log_status(struct file *file, void *priv)
 static int cx23885_query_audinput(struct file *file, void *priv,
 	struct v4l2_audio *i)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	static const char *iname[] = {
 		[0] = "Baseband L/R 1",
 		[1] = "Baseband L/R 2",
@@ -1174,7 +1174,7 @@ static int vidioc_enum_audinput(struct file *file, void *priv,
 static int vidioc_g_audinput(struct file *file, void *priv,
 	struct v4l2_audio *i)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if ((CX23885_VMUX_TELEVISION == INPUT(dev->input)->type) ||
 		(CX23885_VMUX_CABLE == INPUT(dev->input)->type))
@@ -1189,7 +1189,7 @@ static int vidioc_g_audinput(struct file *file, void *priv,
 static int vidioc_s_audinput(struct file *file, void *priv,
 	const struct v4l2_audio *i)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if ((CX23885_VMUX_TELEVISION == INPUT(dev->input)->type) ||
 		(CX23885_VMUX_CABLE == INPUT(dev->input)->type)) {
@@ -1211,7 +1211,7 @@ static int vidioc_s_audinput(struct file *file, void *priv,
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *t)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1227,7 +1227,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 static int vidioc_s_tuner(struct file *file, void *priv,
 				const struct v4l2_tuner *t)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1242,8 +1242,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct cx23885_fh *fh = priv;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1349,8 +1348,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 int cx23885_set_frequency(struct file *file, void *priv,
 	const struct v4l2_frequency *f)
 {
-	struct cx23885_fh *fh = priv;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	int ret;
 
 	switch (dev->board) {
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 9cd2b1b..95f8c42 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -142,8 +142,8 @@ struct cx23885_tvnorm {
 
 struct cx23885_fh {
 	struct v4l2_fh		   fh;
-	struct cx23885_dev         *dev;
 	u32                        resources;
+	struct cx23885_dev         *q_dev;
 
 	/* vbi capture */
 	struct videobuf_queue      vidq;
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 15/20] cx23885: convert to vb2
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (13 preceding siblings ...)
  2014-08-14  9:53 ` [PATCHv2 14/20] cx23885: use video_drvdata to get cx23885_dev pointer Hans Verkuil
@ 2014-08-14  9:54 ` Hans Verkuil
  2014-09-03 11:32   ` Mauro Carvalho Chehab
  2014-08-14  9:54 ` [PATCHv2 16/20] cx23885: fix field handling Hans Verkuil
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:54 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

As usual, this patch is very large due to the fact that half a vb2 conversion
isn't possible. And since this affects 417, alsa, core, dvb, vbi and video the
changes are all over.

What made this more difficult was the peculiar way the risc program was setup.
The driver allowed for running out of buffers in which case the DMA would stop
and restart when the next buffer was queued. There was also a complicated
timeout system for when buffers weren't filled. This was replaced by a much
simpler scheme where there is always one buffer around and the DMA will just
cycle that buffer until a new buffer is queued. In that case the previous
buffer will be chained to the new buffer. An interrupt is generated at the
start of the new buffer telling the driver that the previous buffer can be
passed on to userspace.

Much simpler and more robust. The old code seems to be copied from the
cx88 driver. But it didn't fit the vb2 ops very well and replacing it with
the new scheme made the code easier to understand. Not to mention that this
patch removes 600 lines of code.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/Kconfig         |   4 +-
 drivers/media/pci/cx23885/altera-ci.c     |   4 +-
 drivers/media/pci/cx23885/cx23885-417.c   | 312 +++++-------
 drivers/media/pci/cx23885/cx23885-alsa.c  |   4 +-
 drivers/media/pci/cx23885/cx23885-core.c  | 309 ++++--------
 drivers/media/pci/cx23885/cx23885-dvb.c   | 131 +++--
 drivers/media/pci/cx23885/cx23885-vbi.c   | 275 +++++-----
 drivers/media/pci/cx23885/cx23885-video.c | 810 ++++++++----------------------
 drivers/media/pci/cx23885/cx23885.h       |  61 +--
 9 files changed, 657 insertions(+), 1253 deletions(-)

diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig
index e12c006..38c3b7b 100644
--- a/drivers/media/pci/cx23885/Kconfig
+++ b/drivers/media/pci/cx23885/Kconfig
@@ -7,8 +7,8 @@ config VIDEO_CX23885
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	depends on RC_CORE
-	select VIDEOBUF_DVB
-	select VIDEOBUF_DMA_SG
+	select VIDEOBUF2_DVB
+	select VIDEOBUF2_DMA_SG
 	select VIDEO_CX25840
 	select VIDEO_CX2341X
 	select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c
index 2926f7f..f57b333 100644
--- a/drivers/media/pci/cx23885/altera-ci.c
+++ b/drivers/media/pci/cx23885/altera-ci.c
@@ -52,8 +52,8 @@
  * |  DATA7|  DATA6|  DATA5|  DATA4|  DATA3|  DATA2|  DATA1|  DATA0|
  * +-------+-------+-------+-------+-------+-------+-------+-------+
  */
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
 #include "altera-ci.h"
 #include "dvb_ca_en50221.h"
 
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index 0948b44..a17238a 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1142,47 +1142,100 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder)
 
 /* ------------------------------------------------------------------ */
 
-static int bb_buf_setup(struct videobuf_queue *q,
-	unsigned int *count, unsigned int *size)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *num_buffers, unsigned int *num_planes,
+			   unsigned int sizes[], void *alloc_ctxs[])
 {
-	struct cx23885_fh *fh = q->priv_data;
+	struct cx23885_dev *dev = q->drv_priv;
 
-	fh->q_dev->ts1.ts_packet_size  = mpeglinesize;
-	fh->q_dev->ts1.ts_packet_count = mpeglines;
+	dev->ts1.ts_packet_size  = mpeglinesize;
+	dev->ts1.ts_packet_count = mpeglines;
+	*num_planes = 1;
+	sizes[0] = mpeglinesize * mpeglines;
+	*num_buffers = mpegbufs;
+	return 0;
+}
 
-	*size = fh->q_dev->ts1.ts_packet_size * fh->q_dev->ts1.ts_packet_count;
-	*count = mpegbufs;
+static int buffer_prepare(struct vb2_buffer *vb)
+{
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer *buf =
+		container_of(vb, struct cx23885_buffer, vb);
 
-	return 0;
+	return cx23885_buf_prepare(buf, &dev->ts1);
 }
 
-static int bb_buf_prepare(struct videobuf_queue *q,
-	struct videobuf_buffer *vb, enum v4l2_field field)
+static void buffer_finish(struct vb2_buffer *vb)
 {
-	struct cx23885_fh *fh = q->priv_data;
-	return cx23885_buf_prepare(q, &fh->q_dev->ts1,
-		(struct cx23885_buffer *)vb,
-		field);
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer *buf = container_of(vb,
+		struct cx23885_buffer, vb);
+	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+
+	cx23885_free_buffer(dev, buf);
+
+	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
 }
 
-static void bb_buf_queue(struct videobuf_queue *q,
-	struct videobuf_buffer *vb)
+static void buffer_queue(struct vb2_buffer *vb)
 {
-	struct cx23885_fh *fh = q->priv_data;
-	cx23885_buf_queue(&fh->q_dev->ts1, (struct cx23885_buffer *)vb);
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer   *buf = container_of(vb,
+		struct cx23885_buffer, vb);
+
+	cx23885_buf_queue(&dev->ts1, buf);
+}
+
+static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct cx23885_dev *dev = q->drv_priv;
+	struct cx23885_dmaqueue *dmaq = &dev->ts1.mpegq;
+	unsigned long flags;
+	int ret;
+
+	ret = cx23885_initialize_codec(dev, 1);
+	if (ret == 0) {
+		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
+
+		cx23885_start_dma(&dev->ts1, dmaq, buf);
+		return 0;
+	}
+	spin_lock_irqsave(&dev->slock, flags);
+	while (!list_empty(&dmaq->active)) {
+		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
+
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+	}
+	spin_unlock_irqrestore(&dev->slock, flags);
+	return ret;
 }
 
-static void bb_buf_release(struct videobuf_queue *q,
-	struct videobuf_buffer *vb)
+static void cx23885_stop_streaming(struct vb2_queue *q)
 {
-	cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
+	struct cx23885_dev *dev = q->drv_priv;
+
+	/* stop mpeg capture */
+	cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
+			CX23885_END_NOW, CX23885_MPEG_CAPTURE,
+			CX23885_RAW_BITS_NONE);
+
+	msleep(500);
+	cx23885_417_check_encoder(dev);
+	cx23885_cancel_buffers(&dev->ts1);
 }
 
-static struct videobuf_queue_ops cx23885_qops = {
-	.buf_setup    = bb_buf_setup,
-	.buf_prepare  = bb_buf_prepare,
-	.buf_queue    = bb_buf_queue,
-	.buf_release  = bb_buf_release,
+static struct vb2_ops cx23885_qops = {
+	.queue_setup    = queue_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_finish = buffer_finish,
+	.buf_queue    = buffer_queue,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = cx23885_start_streaming,
+	.stop_streaming = cx23885_stop_streaming,
 };
 
 /* ------------------------------------------------------------------ */
@@ -1320,7 +1373,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
 	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh  *fh  = file->private_data;
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
@@ -1329,9 +1381,9 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 	f->fmt.pix.colorspace   = 0;
 	f->fmt.pix.width        = dev->ts1.width;
 	f->fmt.pix.height       = dev->ts1.height;
-	f->fmt.pix.field        = fh->mpegq.field;
-	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
-		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
+	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
+	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
+		dev->ts1.width, dev->ts1.height);
 	return 0;
 }
 
@@ -1339,15 +1391,15 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
 	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh  *fh  = file->private_data;
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    =
 		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
 	f->fmt.pix.colorspace   = 0;
-	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
-		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
+	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
+	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
+		dev->ts1.width, dev->ts1.height);
 	return 0;
 }
 
@@ -1361,58 +1413,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	f->fmt.pix.sizeimage    =
 		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
 	f->fmt.pix.colorspace   = 0;
+	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
 	dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
 		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
 	return 0;
 }
 
-static int vidioc_reqbufs(struct file *file, void *priv,
-				struct v4l2_requestbuffers *p)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_reqbufs(&fh->mpegq, p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
-				struct v4l2_buffer *p)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_querybuf(&fh->mpegq, p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv,
-				struct v4l2_buffer *p)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_qbuf(&fh->mpegq, p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
-	struct cx23885_fh  *fh  = priv;
-
-	return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK);
-}
-
-
-static int vidioc_streamon(struct file *file, void *priv,
-				enum v4l2_buf_type i)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_streamon(&fh->mpegq);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_streamoff(&fh->mpegq);
-}
-
 static int vidioc_log_status(struct file *file, void *priv)
 {
 	struct cx23885_dev *dev = video_drvdata(file);
@@ -1424,120 +1430,14 @@ static int vidioc_log_status(struct file *file, void *priv)
 	return 0;
 }
 
-static int mpeg_open(struct file *file)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-	struct cx23885_fh *fh;
-
-	dprintk(2, "%s()\n", __func__);
-
-	/* allocate + initialize per filehandle data */
-	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-	if (!fh)
-		return -ENOMEM;
-
-	v4l2_fh_init(&fh->fh, vdev);
-	file->private_data = fh;
-	fh->q_dev      = dev;
-
-	videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops,
-			    &dev->pci->dev, &dev->ts1.slock,
-			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			    V4L2_FIELD_INTERLACED,
-			    sizeof(struct cx23885_buffer),
-			    fh, NULL);
-	v4l2_fh_add(&fh->fh);
-	return 0;
-}
-
-static int mpeg_release(struct file *file)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh  *fh  = file->private_data;
-
-	dprintk(2, "%s()\n", __func__);
-
-	/* FIXME: Review this crap */
-	/* Shut device down on last close */
-	if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
-		if (atomic_dec_return(&dev->v4l_reader_count) == 0) {
-			/* stop mpeg capture */
-			cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
-				CX23885_END_NOW, CX23885_MPEG_CAPTURE,
-				CX23885_RAW_BITS_NONE);
-
-			msleep(500);
-			cx23885_417_check_encoder(dev);
-
-			cx23885_cancel_buffers(&dev->ts1);
-		}
-	}
-
-	if (fh->mpegq.streaming)
-		videobuf_streamoff(&fh->mpegq);
-	if (fh->mpegq.reading)
-		videobuf_read_stop(&fh->mpegq);
-
-	videobuf_mmap_free(&fh->mpegq);
-	v4l2_fh_del(&fh->fh);
-	v4l2_fh_exit(&fh->fh);
-	file->private_data = NULL;
-	kfree(fh);
-
-	return 0;
-}
-
-static ssize_t mpeg_read(struct file *file, char __user *data,
-	size_t count, loff_t *ppos)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh = file->private_data;
-
-	dprintk(2, "%s()\n", __func__);
-
-	/* Deal w/ A/V decoder * and mpeg encoder sync issues. */
-	/* Start mpeg encoder on first read. */
-	if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
-		if (atomic_inc_return(&dev->v4l_reader_count) == 1) {
-			if (cx23885_initialize_codec(dev, 1) < 0)
-				return -EINVAL;
-		}
-	}
-
-	return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
-				    file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int mpeg_poll(struct file *file,
-	struct poll_table_struct *wait)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh = file->private_data;
-
-	dprintk(2, "%s\n", __func__);
-
-	return videobuf_poll_stream(file, &fh->mpegq, wait);
-}
-
-static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh = file->private_data;
-
-	dprintk(2, "%s()\n", __func__);
-
-	return videobuf_mmap_mapper(&fh->mpegq, vma);
-}
-
 static struct v4l2_file_operations mpeg_fops = {
 	.owner	       = THIS_MODULE,
-	.open	       = mpeg_open,
-	.release       = mpeg_release,
-	.read	       = mpeg_read,
-	.poll          = mpeg_poll,
-	.mmap	       = mpeg_mmap,
+	.open           = v4l2_fh_open,
+	.release        = vb2_fop_release,
+	.read           = vb2_fop_read,
+	.poll		= vb2_fop_poll,
 	.unlocked_ioctl = video_ioctl2,
+	.mmap           = vb2_fop_mmap,
 };
 
 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
@@ -1555,12 +1455,13 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_g_fmt_vid_cap	 = vidioc_g_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap	 = vidioc_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap	 = vidioc_s_fmt_vid_cap,
-	.vidioc_reqbufs		 = vidioc_reqbufs,
-	.vidioc_querybuf	 = vidioc_querybuf,
-	.vidioc_qbuf		 = vidioc_qbuf,
-	.vidioc_dqbuf		 = vidioc_dqbuf,
-	.vidioc_streamon	 = vidioc_streamon,
-	.vidioc_streamoff	 = vidioc_streamoff,
+	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
+	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf      = vb2_ioctl_querybuf,
+	.vidioc_qbuf          = vb2_ioctl_qbuf,
+	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
+	.vidioc_streamon      = vb2_ioctl_streamon,
+	.vidioc_streamoff     = vb2_ioctl_streamoff,
 	.vidioc_log_status	 = vidioc_log_status,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_chip_info	 = cx23885_g_chip_info,
@@ -1617,6 +1518,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
 	/* FIXME: Port1 hardcoded here */
 	int err = -ENODEV;
 	struct cx23885_tsport *tsport = &dev->ts1;
+	struct vb2_queue *q;
 
 	dprintk(1, "%s()\n", __func__);
 
@@ -1644,8 +1546,24 @@ int cx23885_417_register(struct cx23885_dev *dev)
 	/* Allocate and initialize V4L video device */
 	dev->v4l_device = cx23885_video_dev_alloc(tsport,
 		dev->pci, &cx23885_mpeg_template, "mpeg");
+	q = &dev->vb2_mpegq;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+	q->gfp_flags = GFP_DMA32;
+	q->min_buffers_needed = 2;
+	q->drv_priv = dev;
+	q->buf_struct_size = sizeof(struct cx23885_buffer);
+	q->ops = &cx23885_qops;
+	q->mem_ops = &vb2_dma_sg_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->lock;
+
+	err = vb2_queue_init(q);
+	if (err < 0)
+		return err;
 	video_set_drvdata(dev->v4l_device, dev);
 	dev->v4l_device->lock = &dev->lock;
+	dev->v4l_device->queue = q;
 	err = video_register_device(dev->v4l_device,
 		VFL_TYPE_GRABBER, -1);
 	if (err < 0) {
diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c
index 31dbf0c..cbbf9ad 100644
--- a/drivers/media/pci/cx23885/cx23885-alsa.c
+++ b/drivers/media/pci/cx23885/cx23885-alsa.c
@@ -393,6 +393,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 		return -ENOMEM;
 
 	buf->bpl = chip->period_size;
+	chip->buf = buf;
 
 	ret = cx23885_alsa_dma_init(chip,
 			(PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
@@ -413,8 +414,6 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
 
-	chip->buf = buf;
-
 	substream->runtime->dma_area = chip->buf->vaddr;
 	substream->runtime->dma_bytes = chip->dma_size;
 	substream->runtime->dma_addr = 0;
@@ -423,6 +422,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 
 error:
 	kfree(buf);
+	chip->buf = NULL;
 	return ret;
 }
 
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index 075b28e..2599af1 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -420,39 +420,23 @@ static int cx23885_risc_decode(u32 risc)
 	return incr[risc >> 28] ? incr[risc >> 28] : 1;
 }
 
-void cx23885_wakeup(struct cx23885_tsport *port,
+static void cx23885_wakeup(struct cx23885_tsport *port,
 			   struct cx23885_dmaqueue *q, u32 count)
 {
 	struct cx23885_dev *dev = port->dev;
 	struct cx23885_buffer *buf;
-	int bc;
 
-	for (bc = 0;; bc++) {
-		if (list_empty(&q->active))
-			break;
-		buf = list_entry(q->active.next,
-				 struct cx23885_buffer, vb.queue);
-
-		/* count comes from the hw and is is 16bit wide --
-		 * this trick handles wrap-arounds correctly for
-		 * up to 32767 buffers in flight... */
-		if ((s16) (count - buf->count) < 0)
-			break;
-
-		v4l2_get_timestamp(&buf->vb.ts);
-		dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i,
-			count, buf->count);
-		buf->vb.state = VIDEOBUF_DONE;
-		list_del(&buf->vb.queue);
-		wake_up(&buf->vb.done);
-	}
 	if (list_empty(&q->active))
-		del_timer(&q->timeout);
-	else
-		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
-	if (bc != 1)
-		printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n",
-		       __func__, bc);
+		return;
+	buf = list_entry(q->active.next,
+			 struct cx23885_buffer, queue);
+
+	v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+	buf->vb.v4l2_buf.sequence = q->count++;
+	dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index,
+		count, q->count);
+	list_del(&buf->queue);
+	vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
 }
 
 int cx23885_sram_channel_setup(struct cx23885_dev *dev,
@@ -482,8 +466,8 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
 		lines = 6;
 	BUG_ON(lines < 2);
 
-	cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
-	cx_write(8 + 4, 8);
+	cx_write(8 + 0, RISC_JUMP | RISC_CNT_RESET);
+	cx_write(8 + 4, 12);
 	cx_write(8 + 8, 0);
 
 	/* write CDT */
@@ -699,10 +683,6 @@ static int get_resources(struct cx23885_dev *dev)
 	return -EBUSY;
 }
 
-static void cx23885_timeout(unsigned long data);
-int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
-				u32 reg, u32 mask, u32 value);
-
 static int cx23885_init_tsport(struct cx23885_dev *dev,
 	struct cx23885_tsport *port, int portno)
 {
@@ -719,11 +699,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
 	port->nr = portno;
 
 	INIT_LIST_HEAD(&port->mpegq.active);
-	INIT_LIST_HEAD(&port->mpegq.queued);
-	port->mpegq.timeout.function = cx23885_timeout;
-	port->mpegq.timeout.data = (unsigned long)port;
-	init_timer(&port->mpegq.timeout);
-
 	mutex_init(&port->frontends.lock);
 	INIT_LIST_HEAD(&port->frontends.felist);
 	port->frontends.active_fe_id = 0;
@@ -776,9 +751,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
 		BUG();
 	}
 
-	cx23885_risc_stopper(dev->pci, &port->mpegq.stopper,
-		     port->reg_dma_ctl, port->dma_ctl_val, 0x00);
-
 	return 0;
 }
 
@@ -1089,11 +1061,18 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
 static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
 			       unsigned int offset, u32 sync_line,
 			       unsigned int bpl, unsigned int padding,
-			       unsigned int lines,  unsigned int lpi)
+			       unsigned int lines,  unsigned int lpi, bool jump)
 {
 	struct scatterlist *sg;
 	unsigned int line, todo, sol;
 
+
+	if (jump) {
+		*(rp++) = cpu_to_le32(RISC_JUMP);
+		*(rp++) = cpu_to_le32(0);
+		*(rp++) = cpu_to_le32(0); /* bits 63-32 */
+	}
+
 	/* sync instruction */
 	if (sync_line != NO_SYNC_LINE)
 		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
@@ -1168,7 +1147,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 	/* write and jump need and extra dword */
 	instructions  = fields * (1 + ((bpl + padding) * lines)
 		/ PAGE_SIZE + lines);
-	instructions += 2;
+	instructions += 5;
 	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
 	if (rc < 0)
 		return rc;
@@ -1177,10 +1156,10 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 	rp = risc->cpu;
 	if (UNSET != top_offset)
 		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
-					bpl, padding, lines, 0);
+					bpl, padding, lines, 0, true);
 	if (UNSET != bottom_offset)
 		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
-					bpl, padding, lines, 0);
+					bpl, padding, lines, 0, UNSET == top_offset);
 
 	/* save pointer to jmp instruction address */
 	risc->jmp = rp;
@@ -1204,7 +1183,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
 	   than PAGE_SIZE */
 	/* Jump and write need an extra dword */
 	instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
-	instructions += 1;
+	instructions += 4;
 
 	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
 	if (rc < 0)
@@ -1213,7 +1192,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
 	/* write risc instructions */
 	rp = risc->cpu;
 	rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE,
-				bpl, 0, lines, lpi);
+				bpl, 0, lines, lpi, lpi == 0);
 
 	/* save pointer to jmp instruction address */
 	risc->jmp = rp;
@@ -1243,7 +1222,7 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 	/* write and jump need and extra dword */
 	instructions  = fields * (1 + ((bpl + padding) * lines)
 		/ PAGE_SIZE + lines);
-	instructions += 2;
+	instructions += 5;
 	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
 	if (rc < 0)
 		return rc;
@@ -1253,12 +1232,12 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 	/* Sync to line 6, so US CC line 21 will appear in line '12'
 	 * in the userland vbi payload */
 	if (UNSET != top_offset)
-		rp = cx23885_risc_field(rp, sglist, top_offset, 6,
-					bpl, padding, lines, 0);
+		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
+					bpl, padding, lines, 0, true);
 
 	if (UNSET != bottom_offset)
-		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207,
-					bpl, padding, lines, 0);
+		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
+					bpl, padding, lines, 0, UNSET == top_offset);
 
 
 
@@ -1269,38 +1248,10 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 }
 
 
-int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
-				u32 reg, u32 mask, u32 value)
+void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf)
 {
-	__le32 *rp;
-	int rc;
-
-	rc = btcx_riscmem_alloc(pci, risc, 4*16);
-	if (rc < 0)
-		return rc;
-
-	/* write risc instructions */
-	rp = risc->cpu;
-	*(rp++) = cpu_to_le32(RISC_WRITECR  | RISC_IRQ2);
-	*(rp++) = cpu_to_le32(reg);
-	*(rp++) = cpu_to_le32(value);
-	*(rp++) = cpu_to_le32(mask);
-	*(rp++) = cpu_to_le32(RISC_JUMP);
-	*(rp++) = cpu_to_le32(risc->dma);
-	*(rp++) = cpu_to_le32(0); /* bits 63-32 */
-	return 0;
-}
-
-void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
-{
-	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
-
 	BUG_ON(in_interrupt());
-	videobuf_waiton(q, &buf->vb, 0, 0);
-	videobuf_dma_unmap(q->dev, dma);
-	videobuf_dma_free(dma);
-	btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
-	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+	btcx_riscmem_free(dev->pci, &buf->risc);
 }
 
 static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
@@ -1355,7 +1306,7 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
 		port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk));
 }
 
-static int cx23885_start_dma(struct cx23885_tsport *port,
+int cx23885_start_dma(struct cx23885_tsport *port,
 			     struct cx23885_dmaqueue *q,
 			     struct cx23885_buffer   *buf)
 {
@@ -1363,7 +1314,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 	u32 reg;
 
 	dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__,
-		buf->vb.width, buf->vb.height, buf->vb.field);
+		dev->width, dev->height, dev->field);
 
 	/* Stop the fifo and risc engine for this port */
 	cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
@@ -1379,7 +1330,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 	}
 
 	/* write TS length to chip */
-	cx_write(port->reg_lngth, buf->vb.width);
+	cx_write(port->reg_lngth, port->ts_packet_size);
 
 	if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
 		(!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) {
@@ -1408,7 +1359,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 	/* NOTE: this is 2 (reserved) for portb, does it matter? */
 	/* reset counter to zero */
 	cx_write(port->reg_gpcnt_ctl, 3);
-	q->count = 1;
+	q->count = 0;
 
 	/* Set VIDB pins to input */
 	if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
@@ -1497,134 +1448,83 @@ static int cx23885_stop_dma(struct cx23885_tsport *port)
 	return 0;
 }
 
-int cx23885_restart_queue(struct cx23885_tsport *port,
-				struct cx23885_dmaqueue *q)
-{
-	struct cx23885_dev *dev = port->dev;
-	struct cx23885_buffer *buf;
-
-	dprintk(5, "%s()\n", __func__);
-	if (list_empty(&q->active)) {
-		struct cx23885_buffer *prev;
-		prev = NULL;
-
-		dprintk(5, "%s() queue is empty\n", __func__);
-
-		for (;;) {
-			if (list_empty(&q->queued))
-				return 0;
-			buf = list_entry(q->queued.next, struct cx23885_buffer,
-					 vb.queue);
-			if (NULL == prev) {
-				list_move_tail(&buf->vb.queue, &q->active);
-				cx23885_start_dma(port, q, buf);
-				buf->vb.state = VIDEOBUF_ACTIVE;
-				buf->count    = q->count++;
-				mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
-				dprintk(5, "[%p/%d] restart_queue - f/active\n",
-					buf, buf->vb.i);
-
-			} else if (prev->vb.width  == buf->vb.width  &&
-				   prev->vb.height == buf->vb.height &&
-				   prev->fmt       == buf->fmt) {
-				list_move_tail(&buf->vb.queue, &q->active);
-				buf->vb.state = VIDEOBUF_ACTIVE;
-				buf->count    = q->count++;
-				prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-				/* 64 bit bits 63-32 */
-				prev->risc.jmp[2] = cpu_to_le32(0);
-				dprintk(5, "[%p/%d] restart_queue - m/active\n",
-					buf, buf->vb.i);
-			} else {
-				return 0;
-			}
-			prev = buf;
-		}
-		return 0;
-	}
-
-	buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
-	dprintk(2, "restart_queue [%p/%d]: restart dma\n",
-		buf, buf->vb.i);
-	cx23885_start_dma(port, q, buf);
-	list_for_each_entry(buf, &q->active, vb.queue)
-		buf->count = q->count++;
-	mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
-	return 0;
-}
-
 /* ------------------------------------------------------------------ */
 
-int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
-			struct cx23885_buffer *buf, enum v4l2_field field)
+int cx23885_buf_prepare(struct cx23885_buffer *buf, struct cx23885_tsport *port)
 {
 	struct cx23885_dev *dev = port->dev;
 	int size = port->ts_packet_size * port->ts_packet_count;
+	struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0);
 	int rc;
 
 	dprintk(1, "%s: %p\n", __func__, buf);
-	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
+	if (vb2_plane_size(&buf->vb, 0) < size)
 		return -EINVAL;
+	vb2_set_plane_payload(&buf->vb, 0, size);
 
-	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-		buf->vb.width  = port->ts_packet_size;
-		buf->vb.height = port->ts_packet_count;
-		buf->vb.size   = size;
-		buf->vb.field  = field /*V4L2_FIELD_TOP*/;
-
-		rc = videobuf_iolock(q, &buf->vb, NULL);
-		if (0 != rc)
-			goto fail;
-		cx23885_risc_databuffer(dev->pci, &buf->risc,
-					videobuf_to_dma(&buf->vb)->sglist,
-					buf->vb.width, buf->vb.height, 0);
-	}
-	buf->vb.state = VIDEOBUF_PREPARED;
-	return 0;
+	rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
+	if (!rc)
+		return -EIO;
 
- fail:
-	cx23885_free_buffer(q, buf);
-	return rc;
+	cx23885_risc_databuffer(dev->pci, &buf->risc,
+				sgt->sgl,
+				port->ts_packet_size, port->ts_packet_count, 0);
+	return 0;
 }
 
+/*
+ * The risc program for each buffer works as follows: it starts with a simple
+ * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
+ * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
+ * the initial JUMP).
+ *
+ * This is the risc program of the first buffer to be queued if the active list
+ * is empty and it just keeps DMAing this buffer without generating any
+ * interrupts.
+ *
+ * If a new buffer is added then the initial JUMP in the code for that buffer
+ * will generate an interrupt which signals that the previous buffer has been
+ * DMAed successfully and that it can be returned to userspace.
+ *
+ * It also sets the final jump of the previous buffer to the start of the new
+ * buffer, thus chaining the new buffer into the DMA chain. This is a single
+ * atomic u32 write, so there is no race condition.
+ *
+ * The end-result of all this that you only get an interrupt when a buffer
+ * is ready, so the control flow is very easy.
+ */
 void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
 {
 	struct cx23885_buffer    *prev;
 	struct cx23885_dev *dev = port->dev;
 	struct cx23885_dmaqueue  *cx88q = &port->mpegq;
+	unsigned long flags;
 
-	/* add jump to stopper */
-	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
-	buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
+	buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
 	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
 
+	spin_lock_irqsave(&dev->slock, flags);
 	if (list_empty(&cx88q->active)) {
-		dprintk(1, "queue is empty - first active\n");
-		list_add_tail(&buf->vb.queue, &cx88q->active);
-		cx23885_start_dma(port, cx88q, buf);
-		buf->vb.state = VIDEOBUF_ACTIVE;
-		buf->count    = cx88q->count++;
-		mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT);
+		list_add_tail(&buf->queue, &cx88q->active);
 		dprintk(1, "[%p/%d] %s - first active\n",
-			buf, buf->vb.i, __func__);
+			buf, buf->vb.v4l2_buf.index, __func__);
 	} else {
-		dprintk(1, "queue is not empty - append to active\n");
+		buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
 		prev = list_entry(cx88q->active.prev, struct cx23885_buffer,
-				  vb.queue);
-		list_add_tail(&buf->vb.queue, &cx88q->active);
-		buf->vb.state = VIDEOBUF_ACTIVE;
-		buf->count    = cx88q->count++;
+				  queue);
+		list_add_tail(&buf->queue, &cx88q->active);
 		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-		prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
 		dprintk(1, "[%p/%d] %s - append to active\n",
-			 buf, buf->vb.i, __func__);
+			 buf, buf->vb.v4l2_buf.index, __func__);
 	}
+	spin_unlock_irqrestore(&dev->slock, flags);
 }
 
 /* ----------------------------------------------------------- */
 
-static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
-			      int restart)
+static void do_cancel_buffers(struct cx23885_tsport *port, char *reason)
 {
 	struct cx23885_dev *dev = port->dev;
 	struct cx23885_dmaqueue *q = &port->mpegq;
@@ -1634,16 +1534,11 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
 	spin_lock_irqsave(&port->slock, flags);
 	while (!list_empty(&q->active)) {
 		buf = list_entry(q->active.next, struct cx23885_buffer,
-				 vb.queue);
-		list_del(&buf->vb.queue);
-		buf->vb.state = VIDEOBUF_ERROR;
-		wake_up(&buf->vb.done);
+				 queue);
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
 		dprintk(1, "[%p/%d] %s - dma=0x%08lx\n",
-			buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
-	}
-	if (restart) {
-		dprintk(1, "restarting queue\n");
-		cx23885_restart_queue(port, q);
+			buf, buf->vb.v4l2_buf.index, reason, (unsigned long)buf->risc.dma);
 	}
 	spin_unlock_irqrestore(&port->slock, flags);
 }
@@ -1651,27 +1546,10 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
 void cx23885_cancel_buffers(struct cx23885_tsport *port)
 {
 	struct cx23885_dev *dev = port->dev;
-	struct cx23885_dmaqueue *q = &port->mpegq;
 
 	dprintk(1, "%s()\n", __func__);
-	del_timer_sync(&q->timeout);
 	cx23885_stop_dma(port);
-	do_cancel_buffers(port, "cancel", 0);
-}
-
-static void cx23885_timeout(unsigned long data)
-{
-	struct cx23885_tsport *port = (struct cx23885_tsport *)data;
-	struct cx23885_dev *dev = port->dev;
-
-	dprintk(1, "%s()\n", __func__);
-
-	if (debug > 5)
-		cx23885_sram_channel_dump(dev,
-			&dev->sram_channels[port->sram_chno]);
-
-	cx23885_stop_dma(port);
-	do_cancel_buffers(port, "timeout", 1);
+	do_cancel_buffers(port, "cancel");
 }
 
 int cx23885_irq_417(struct cx23885_dev *dev, u32 status)
@@ -1721,11 +1599,6 @@ int cx23885_irq_417(struct cx23885_dev *dev, u32 status)
 		spin_lock(&port->slock);
 		cx23885_wakeup(port, &port->mpegq, count);
 		spin_unlock(&port->slock);
-	} else if (status & VID_B_MSK_RISCI2) {
-		dprintk(7, "        VID_B_MSK_RISCI2\n");
-		spin_lock(&port->slock);
-		cx23885_restart_queue(port, &port->mpegq);
-		spin_unlock(&port->slock);
 	}
 	if (status) {
 		cx_write(port->reg_ts_int_stat, status);
@@ -1777,14 +1650,6 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
 		cx23885_wakeup(port, &port->mpegq, count);
 		spin_unlock(&port->slock);
 
-	} else if (status & VID_BC_MSK_RISCI2) {
-
-		dprintk(7, " (RISCI2            0x%08x)\n", VID_BC_MSK_RISCI2);
-
-		spin_lock(&port->slock);
-		cx23885_restart_queue(port, &port->mpegq);
-		spin_unlock(&port->slock);
-
 	}
 	if (status) {
 		cx_write(port->reg_ts_int_stat, status);
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index 968fecc..376b0a6 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -91,59 +91,95 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 /* ------------------------------------------------------------------ */
 
-static int dvb_buf_setup(struct videobuf_queue *q,
-			 unsigned int *count, unsigned int *size)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *num_buffers, unsigned int *num_planes,
+			   unsigned int sizes[], void *alloc_ctxs[])
 {
-	struct cx23885_tsport *port = q->priv_data;
+	struct cx23885_tsport *port = q->drv_priv;
 
 	port->ts_packet_size  = 188 * 4;
 	port->ts_packet_count = 32;
-
-	*size  = port->ts_packet_size * port->ts_packet_count;
-	*count = 32;
+	*num_planes = 1;
+	sizes[0] = port->ts_packet_size * port->ts_packet_count;
+	*num_buffers = 32;
 	return 0;
 }
 
-static int dvb_buf_prepare(struct videobuf_queue *q,
-			   struct videobuf_buffer *vb, enum v4l2_field field)
+
+static int buffer_prepare(struct vb2_buffer *vb)
 {
-	struct cx23885_tsport *port = q->priv_data;
-	return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field);
+	struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer *buf =
+		container_of(vb, struct cx23885_buffer, vb);
+
+	return cx23885_buf_prepare(buf, port);
 }
 
-static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb)
 {
-	struct cx23885_tsport *port = q->priv_data;
-	cx23885_buf_queue(port, (struct cx23885_buffer *)vb);
+	struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
+	struct cx23885_dev *dev = port->dev;
+	struct cx23885_buffer *buf = container_of(vb,
+		struct cx23885_buffer, vb);
+	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+
+	cx23885_free_buffer(dev, buf);
+
+	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
 }
 
-static void dvb_buf_release(struct videobuf_queue *q,
-			    struct videobuf_buffer *vb)
+static void buffer_queue(struct vb2_buffer *vb)
 {
-	cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
+	struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer   *buf = container_of(vb,
+		struct cx23885_buffer, vb);
+
+	cx23885_buf_queue(port, buf);
 }
 
 static void cx23885_dvb_gate_ctrl(struct cx23885_tsport  *port, int open)
 {
-	struct videobuf_dvb_frontends *f;
-	struct videobuf_dvb_frontend *fe;
+	struct vb2_dvb_frontends *f;
+	struct vb2_dvb_frontend *fe;
 
 	f = &port->frontends;
 
 	if (f->gate <= 1) /* undefined or fe0 */
-		fe = videobuf_dvb_get_frontend(f, 1);
+		fe = vb2_dvb_get_frontend(f, 1);
 	else
-		fe = videobuf_dvb_get_frontend(f, f->gate);
+		fe = vb2_dvb_get_frontend(f, f->gate);
 
 	if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
 		fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
 }
 
-static struct videobuf_queue_ops dvb_qops = {
-	.buf_setup    = dvb_buf_setup,
-	.buf_prepare  = dvb_buf_prepare,
-	.buf_queue    = dvb_buf_queue,
-	.buf_release  = dvb_buf_release,
+static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct cx23885_tsport *port = q->drv_priv;
+	struct cx23885_dmaqueue *dmaq = &port->mpegq;
+	struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
+
+	cx23885_start_dma(port, dmaq, buf);
+	return 0;
+}
+
+static void cx23885_stop_streaming(struct vb2_queue *q)
+{
+	struct cx23885_tsport *port = q->drv_priv;
+
+	cx23885_cancel_buffers(port);
+}
+
+static struct vb2_ops dvb_qops = {
+	.queue_setup    = queue_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_finish = buffer_finish,
+	.buf_queue    = buffer_queue,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = cx23885_start_streaming,
+	.stop_streaming = cx23885_stop_streaming,
 };
 
 static struct s5h1409_config hauppauge_generic_config = {
@@ -863,16 +899,16 @@ static int dvb_register(struct cx23885_tsport *port)
 	struct dib7000p_ops dib7000p_ops;
 	struct cx23885_dev *dev = port->dev;
 	struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
-	struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+	struct vb2_dvb_frontend *fe0, *fe1 = NULL;
 	int mfe_shared = 0; /* bus not shared by default */
 	int ret;
 
 	/* Get the first frontend */
-	fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+	fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
 	if (!fe0)
 		return -EINVAL;
 
-	/* init struct videobuf_dvb */
+	/* init struct vb2_dvb */
 	fe0->dvb.name = dev->name;
 
 	/* multi-frontend gate control is undefined or defaults to fe0 */
@@ -1392,7 +1428,7 @@ static int dvb_register(struct cx23885_tsport *port)
 			fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend);
 		}
 		/* MFE frontend 2 */
-		fe1 = videobuf_dvb_get_frontend(&port->frontends, 2);
+		fe1 = vb2_dvb_get_frontend(&port->frontends, 2);
 		if (fe1 == NULL)
 			goto frontend_detach;
 		/* DVB-C init */
@@ -1532,7 +1568,7 @@ static int dvb_register(struct cx23885_tsport *port)
 		fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
 
 	/* register everything */
-	ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+	ret = vb2_dvb_register_bus(&port->frontends, THIS_MODULE, port,
 					&dev->pci->dev, adapter_nr, mfe_shared);
 	if (ret)
 		goto frontend_detach;
@@ -1581,14 +1617,14 @@ static int dvb_register(struct cx23885_tsport *port)
 
 frontend_detach:
 	port->gate_ctrl = NULL;
-	videobuf_dvb_dealloc_frontends(&port->frontends);
+	vb2_dvb_dealloc_frontends(&port->frontends);
 	return -EINVAL;
 }
 
 int cx23885_dvb_register(struct cx23885_tsport *port)
 {
 
-	struct videobuf_dvb_frontend *fe0;
+	struct vb2_dvb_frontend *fe0;
 	struct cx23885_dev *dev = port->dev;
 	int err, i;
 
@@ -1605,13 +1641,15 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
 		port->num_frontends);
 
 	for (i = 1; i <= port->num_frontends; i++) {
-		if (videobuf_dvb_alloc_frontend(
+		struct vb2_queue *q;
+
+		if (vb2_dvb_alloc_frontend(
 			&port->frontends, i) == NULL) {
 			printk(KERN_ERR "%s() failed to alloc\n", __func__);
 			return -ENOMEM;
 		}
 
-		fe0 = videobuf_dvb_get_frontend(&port->frontends, i);
+		fe0 = vb2_dvb_get_frontend(&port->frontends, i);
 		if (!fe0)
 			err = -EINVAL;
 
@@ -1627,10 +1665,21 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
 		/* dvb stuff */
 		/* We have to init the queue for each frontend on a port. */
 		printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name);
-		videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops,
-			    &dev->pci->dev, &port->slock,
-			    V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
-			    sizeof(struct cx23885_buffer), port, NULL);
+		q = &fe0->dvb.dvbq;
+		q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+		q->gfp_flags = GFP_DMA32;
+		q->min_buffers_needed = 2;
+		q->drv_priv = port;
+		q->buf_struct_size = sizeof(struct cx23885_buffer);
+		q->ops = &dvb_qops;
+		q->mem_ops = &vb2_dma_sg_memops;
+		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+		q->lock = &dev->lock;
+
+		err = vb2_queue_init(q);
+		if (err < 0)
+			return err;
 	}
 	err = dvb_register(port);
 	if (err != 0)
@@ -1642,7 +1691,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
 
 int cx23885_dvb_unregister(struct cx23885_tsport *port)
 {
-	struct videobuf_dvb_frontend *fe0;
+	struct vb2_dvb_frontend *fe0;
 
 	/* FIXME: in an error condition where the we have
 	 * an expected number of frontends (attach problem)
@@ -1651,9 +1700,9 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
 	 * This comment only applies to future boards IF they
 	 * implement MFE support.
 	 */
-	fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+	fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
 	if (fe0 && fe0->dvb.frontend)
-		videobuf_dvb_unregister_bus(&port->frontends);
+		vb2_dvb_unregister_bus(&port->frontends);
 
 	switch (port->dev->board) {
 	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
index 1cb67d3..358776e 100644
--- a/drivers/media/pci/cx23885/cx23885-vbi.c
+++ b/drivers/media/pci/cx23885/cx23885-vbi.c
@@ -42,9 +42,8 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
 /* ------------------------------------------------------------------ */
 
 #define VBI_LINE_LENGTH 1440
-#define NTSC_VBI_START_LINE 10        /* line 10 - 21 */
-#define NTSC_VBI_END_LINE   21
-#define NTSC_VBI_LINES      (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1)
+#define VBI_NTSC_LINE_COUNT 12
+#define VBI_PAL_LINE_COUNT 18
 
 
 int cx23885_vbi_fmt(struct file *file, void *priv,
@@ -52,22 +51,23 @@ int cx23885_vbi_fmt(struct file *file, void *priv,
 {
 	struct cx23885_dev *dev = video_drvdata(file);
 
+	f->fmt.vbi.sampling_rate = 27000000;
+	f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
+	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+	f->fmt.vbi.offset = 0;
+	f->fmt.vbi.flags = 0;
 	if (dev->tvnorm & V4L2_STD_525_60) {
 		/* ntsc */
-		f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
-		f->fmt.vbi.sampling_rate = 27000000;
-		f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
-		f->fmt.vbi.offset = 0;
-		f->fmt.vbi.flags = 0;
 		f->fmt.vbi.start[0] = 10;
-		f->fmt.vbi.count[0] = 17;
-		f->fmt.vbi.start[1] = 263 + 10 + 1;
-		f->fmt.vbi.count[1] = 17;
+		f->fmt.vbi.start[1] = 272;
+		f->fmt.vbi.count[0] = VBI_NTSC_LINE_COUNT;
+		f->fmt.vbi.count[1] = VBI_NTSC_LINE_COUNT;
 	} else if (dev->tvnorm & V4L2_STD_625_50) {
 		/* pal */
-		f->fmt.vbi.sampling_rate = 35468950;
-		f->fmt.vbi.start[0] = 7 - 1;
-		f->fmt.vbi.start[1] = 319 - 1;
+		f->fmt.vbi.start[0] = 6;
+		f->fmt.vbi.start[1] = 318;
+		f->fmt.vbi.count[0] = VBI_PAL_LINE_COUNT;
+		f->fmt.vbi.count[1] = VBI_PAL_LINE_COUNT;
 	}
 
 	return 0;
@@ -93,15 +93,6 @@ int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status)
 		handled++;
 	}
 
-	if (status & VID_BC_MSK_VBI_RISCI2) {
-		dprintk(1, "%s() VID_BC_MSK_VBI_RISCI2\n", __func__);
-		dprintk(2, "stopper vbi\n");
-		spin_lock(&dev->slock);
-		cx23885_restart_vbi_queue(dev, &dev->vbiq);
-		spin_unlock(&dev->slock);
-		handled++;
-	}
-
 	return handled;
 }
 
@@ -113,13 +104,13 @@ static int cx23885_start_vbi_dma(struct cx23885_dev    *dev,
 
 	/* setup fifo + format */
 	cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02],
-				buf->vb.width, buf->risc.dma);
+				VBI_LINE_LENGTH, buf->risc.dma);
 
 	/* reset counter */
 	cx_write(VID_A_GPCNT_CTL, 3);
 	cx_write(VID_A_VBI_CTRL, 3);
 	cx_write(VBI_A_GPCNT_CTL, 3);
-	q->count = 1;
+	q->count = 0;
 
 	/* enable irq */
 	cx23885_irq_add_enable(dev, 0x01);
@@ -132,163 +123,153 @@ static int cx23885_start_vbi_dma(struct cx23885_dev    *dev,
 	return 0;
 }
 
+/* ------------------------------------------------------------------ */
 
-int cx23885_restart_vbi_queue(struct cx23885_dev    *dev,
-			     struct cx23885_dmaqueue *q)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *num_buffers, unsigned int *num_planes,
+			   unsigned int sizes[], void *alloc_ctxs[])
 {
-	struct cx23885_buffer *buf;
-	struct list_head *item;
-
-	if (list_empty(&q->active))
-		return 0;
-
-	buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
-	dprintk(2, "restart_queue [%p/%d]: restart dma\n",
-		buf, buf->vb.i);
-	cx23885_start_vbi_dma(dev, q, buf);
-	list_for_each(item, &q->active) {
-		buf = list_entry(item, struct cx23885_buffer, vb.queue);
-		buf->count = q->count++;
-	}
-	mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30));
+	struct cx23885_dev *dev = q->drv_priv;
+	unsigned lines = VBI_PAL_LINE_COUNT;
+
+	if (dev->tvnorm & V4L2_STD_525_60)
+		lines = VBI_NTSC_LINE_COUNT;
+	*num_planes = 1;
+	sizes[0] = lines * VBI_LINE_LENGTH * 2;
 	return 0;
 }
 
-void cx23885_vbi_timeout(unsigned long data)
+static int buffer_prepare(struct vb2_buffer *vb)
 {
-	struct cx23885_dev *dev = (struct cx23885_dev *)data;
-	struct cx23885_dmaqueue *q = &dev->vbiq;
-	struct cx23885_buffer *buf;
-	unsigned long flags;
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer *buf = container_of(vb,
+		struct cx23885_buffer, vb);
+	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+	unsigned lines = VBI_PAL_LINE_COUNT;
+	int ret;
 
-	/* Stop the VBI engine */
-	cx_clear(VID_A_DMA_CTL, 0x22);
+	if (dev->tvnorm & V4L2_STD_525_60)
+		lines = VBI_NTSC_LINE_COUNT;
 
-	spin_lock_irqsave(&dev->slock, flags);
-	while (!list_empty(&q->active)) {
-		buf = list_entry(q->active.next, struct cx23885_buffer,
-			vb.queue);
-		list_del(&buf->vb.queue);
-		buf->vb.state = VIDEOBUF_ERROR;
-		wake_up(&buf->vb.done);
-		printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->name,
-		       buf, buf->vb.i, (unsigned long)buf->risc.dma);
-	}
-	cx23885_restart_vbi_queue(dev, q);
-	spin_unlock_irqrestore(&dev->slock, flags);
-}
+	if (vb2_plane_size(vb, 0) < lines * VBI_LINE_LENGTH * 2)
+		return -EINVAL;
+	vb2_set_plane_payload(vb, 0, lines * VBI_LINE_LENGTH * 2);
 
-/* ------------------------------------------------------------------ */
-#define VBI_LINE_LENGTH 1440
-#define VBI_LINE_COUNT 17
+	ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
+	if (!ret)
+		return -EIO;
 
-static int
-vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
-{
-	*size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
-	if (0 == *count)
-		*count = vbibufs;
-	if (*count < 2)
-		*count = 2;
-	if (*count > 32)
-		*count = 32;
+	cx23885_risc_vbibuffer(dev->pci, &buf->risc,
+			 sgt->sgl,
+			 0, VBI_LINE_LENGTH * lines,
+			 VBI_LINE_LENGTH, 0,
+			 lines);
 	return 0;
 }
 
-static int
-vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
-	    enum v4l2_field field)
+static void buffer_finish(struct vb2_buffer *vb)
 {
-	struct cx23885_fh *fh  = q->priv_data;
-	struct cx23885_dev *dev = fh->q_dev;
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
 	struct cx23885_buffer *buf = container_of(vb,
 		struct cx23885_buffer, vb);
-	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
-	unsigned int size;
-	int rc;
-
-	size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
-	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
-		return -EINVAL;
+	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
 
-	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-		buf->vb.width  = VBI_LINE_LENGTH;
-		buf->vb.height = VBI_LINE_COUNT;
-		buf->vb.size   = size;
-		buf->vb.field  = V4L2_FIELD_SEQ_TB;
-
-		rc = videobuf_iolock(q, &buf->vb, NULL);
-		if (0 != rc)
-			goto fail;
-		cx23885_risc_vbibuffer(dev->pci, &buf->risc,
-				 dma->sglist,
-				 0, buf->vb.width * buf->vb.height,
-				 buf->vb.width, 0,
-				 buf->vb.height);
-	}
-	buf->vb.state = VIDEOBUF_PREPARED;
-	return 0;
+	cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
 
- fail:
-	cx23885_free_buffer(q, buf);
-	return rc;
+	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
 }
 
-static void
-vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+/*
+ * The risc program for each buffer works as follows: it starts with a simple
+ * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
+ * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
+ * the initial JUMP).
+ *
+ * This is the risc program of the first buffer to be queued if the active list
+ * is empty and it just keeps DMAing this buffer without generating any
+ * interrupts.
+ *
+ * If a new buffer is added then the initial JUMP in the code for that buffer
+ * will generate an interrupt which signals that the previous buffer has been
+ * DMAed successfully and that it can be returned to userspace.
+ *
+ * It also sets the final jump of the previous buffer to the start of the new
+ * buffer, thus chaining the new buffer into the DMA chain. This is a single
+ * atomic u32 write, so there is no race condition.
+ *
+ * The end-result of all this that you only get an interrupt when a buffer
+ * is ready, so the control flow is very easy.
+ */
+static void buffer_queue(struct vb2_buffer *vb)
 {
-	struct cx23885_buffer   *buf =
-		container_of(vb, struct cx23885_buffer, vb);
-	struct cx23885_buffer   *prev;
-	struct cx23885_fh       *fh   = vq->priv_data;
-	struct cx23885_dev      *dev  = fh->q_dev;
-	struct cx23885_dmaqueue *q    = &dev->vbiq;
-
-	/* add jump to stopper */
-	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
-	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb);
+	struct cx23885_buffer *prev;
+	struct cx23885_dmaqueue *q = &dev->vbiq;
+	unsigned long flags;
+
+	buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
 	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
 
 	if (list_empty(&q->active)) {
-		list_add_tail(&buf->vb.queue, &q->active);
-		cx23885_start_vbi_dma(dev, q, buf);
-		buf->vb.state = VIDEOBUF_ACTIVE;
-		buf->count    = q->count++;
-		mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30));
+		spin_lock_irqsave(&dev->slock, flags);
+		list_add_tail(&buf->queue, &q->active);
+		spin_unlock_irqrestore(&dev->slock, flags);
 		dprintk(2, "[%p/%d] vbi_queue - first active\n",
-			buf, buf->vb.i);
+			buf, buf->vb.v4l2_buf.index);
 
 	} else {
+		buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
 		prev = list_entry(q->active.prev, struct cx23885_buffer,
-			vb.queue);
-		list_add_tail(&buf->vb.queue, &q->active);
-		buf->vb.state = VIDEOBUF_ACTIVE;
-		buf->count    = q->count++;
+			queue);
+		spin_lock_irqsave(&dev->slock, flags);
+		list_add_tail(&buf->queue, &q->active);
+		spin_unlock_irqrestore(&dev->slock, flags);
 		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-		prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63-32 */
 		dprintk(2, "[%p/%d] buffer_queue - append to active\n",
-			buf, buf->vb.i);
+			buf, buf->vb.v4l2_buf.index);
 	}
 }
 
-static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
 {
-	struct cx23885_buffer *buf =
-		container_of(vb, struct cx23885_buffer, vb);
+	struct cx23885_dev *dev = q->drv_priv;
+	struct cx23885_dmaqueue *dmaq = &dev->vbiq;
+	struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
 
-	cx23885_free_buffer(q, buf);
+	cx23885_start_vbi_dma(dev, dmaq, buf);
+	return 0;
 }
 
-struct videobuf_queue_ops cx23885_vbi_qops = {
-	.buf_setup    = vbi_setup,
-	.buf_prepare  = vbi_prepare,
-	.buf_queue    = vbi_queue,
-	.buf_release  = vbi_release,
-};
+static void cx23885_stop_streaming(struct vb2_queue *q)
+{
+	struct cx23885_dev *dev = q->drv_priv;
+	struct cx23885_dmaqueue *dmaq = &dev->vbiq;
+	unsigned long flags;
 
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
+	cx_clear(VID_A_DMA_CTL, 0x22); /* FIFO and RISC enable */
+	spin_lock_irqsave(&dev->slock, flags);
+	while (!list_empty(&dmaq->active)) {
+		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
+
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+	}
+	spin_unlock_irqrestore(&dev->slock, flags);
+}
+
+
+struct vb2_ops cx23885_vbi_qops = {
+	.queue_setup    = queue_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_finish = buffer_finish,
+	.buf_queue    = buffer_queue,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = cx23885_start_streaming,
+	.stop_streaming = cx23885_stop_streaming,
+};
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index b374003..16fcdfc 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -102,34 +102,18 @@ void cx23885_video_wakeup(struct cx23885_dev *dev,
 	struct cx23885_dmaqueue *q, u32 count)
 {
 	struct cx23885_buffer *buf;
-	int bc;
-
-	for (bc = 0;; bc++) {
-		if (list_empty(&q->active))
-			break;
-		buf = list_entry(q->active.next,
-				 struct cx23885_buffer, vb.queue);
-
-		/* count comes from the hw and is is 16bit wide --
-		 * this trick handles wrap-arounds correctly for
-		 * up to 32767 buffers in flight... */
-		if ((s16) (count - buf->count) < 0)
-			break;
-
-		v4l2_get_timestamp(&buf->vb.ts);
-		dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i,
-			count, buf->count);
-		buf->vb.state = VIDEOBUF_DONE;
-		list_del(&buf->vb.queue);
-		wake_up(&buf->vb.done);
-	}
+
 	if (list_empty(&q->active))
-		del_timer(&q->timeout);
-	else
-		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
-	if (bc != 1)
-		printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
-			__func__, bc);
+		return;
+	buf = list_entry(q->active.next,
+			struct cx23885_buffer, queue);
+
+	buf->vb.v4l2_buf.sequence = q->count++;
+	v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+	dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index,
+			count, q->count);
+	list_del(&buf->queue);
+	vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
 }
 
 int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
@@ -167,50 +151,6 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
 	return vfd;
 }
 
-/* ------------------------------------------------------------------- */
-/* resource management                                                 */
-
-static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh,
-	unsigned int bit)
-{
-	dprintk(1, "%s()\n", __func__);
-	if (fh->resources & bit)
-		/* have it already allocated */
-		return 1;
-
-	/* is it free? */
-	if (dev->resources & bit) {
-		/* no, someone else uses it */
-		return 0;
-	}
-	/* it's free, grab it */
-	fh->resources  |= bit;
-	dev->resources |= bit;
-	dprintk(1, "res: get %d\n", bit);
-	return 1;
-}
-
-static int res_check(struct cx23885_fh *fh, unsigned int bit)
-{
-	return fh->resources & bit;
-}
-
-static int res_locked(struct cx23885_dev *dev, unsigned int bit)
-{
-	return dev->resources & bit;
-}
-
-static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
-	unsigned int bits)
-{
-	BUG_ON((fh->resources & bits) != bits);
-	dprintk(1, "%s()\n", __func__);
-
-	fh->resources  &= ~bits;
-	dev->resources &= ~bits;
-	dprintk(1, "res: put %d\n", bits);
-}
-
 int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data)
 {
 	/* 8 bit registers, 8 bit values */
@@ -360,7 +300,7 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev,
 
 	/* reset counter */
 	cx_write(VID_A_GPCNT_CTL, 3);
-	q->count = 1;
+	q->count = 0;
 
 	/* enable irq */
 	cx23885_irq_add_enable(dev, 0x01);
@@ -373,444 +313,206 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev,
 	return 0;
 }
 
-
-static int cx23885_restart_video_queue(struct cx23885_dev *dev,
-			       struct cx23885_dmaqueue *q)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *num_buffers, unsigned int *num_planes,
+			   unsigned int sizes[], void *alloc_ctxs[])
 {
-	struct cx23885_buffer *buf, *prev;
-	struct list_head *item;
-	dprintk(1, "%s()\n", __func__);
-
-	if (!list_empty(&q->active)) {
-		buf = list_entry(q->active.next, struct cx23885_buffer,
-			vb.queue);
-		dprintk(2, "restart_queue [%p/%d]: restart dma\n",
-			buf, buf->vb.i);
-		cx23885_start_video_dma(dev, q, buf);
-		list_for_each(item, &q->active) {
-			buf = list_entry(item, struct cx23885_buffer,
-				vb.queue);
-			buf->count    = q->count++;
-		}
-		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
-		return 0;
-	}
+	struct cx23885_dev *dev = q->drv_priv;
 
-	prev = NULL;
-	for (;;) {
-		if (list_empty(&q->queued))
-			return 0;
-		buf = list_entry(q->queued.next, struct cx23885_buffer,
-			vb.queue);
-		if (NULL == prev) {
-			list_move_tail(&buf->vb.queue, &q->active);
-			cx23885_start_video_dma(dev, q, buf);
-			buf->vb.state = VIDEOBUF_ACTIVE;
-			buf->count    = q->count++;
-			mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
-			dprintk(2, "[%p/%d] restart_queue - first active\n",
-				buf, buf->vb.i);
-
-		} else if (prev->vb.width  == buf->vb.width  &&
-			   prev->vb.height == buf->vb.height &&
-			   prev->fmt       == buf->fmt) {
-			list_move_tail(&buf->vb.queue, &q->active);
-			buf->vb.state = VIDEOBUF_ACTIVE;
-			buf->count    = q->count++;
-			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-			prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
-			dprintk(2, "[%p/%d] restart_queue - move to active\n",
-				buf, buf->vb.i);
-		} else {
-			return 0;
-		}
-		prev = buf;
-	}
-}
-
-static int buffer_setup(struct videobuf_queue *q, unsigned int *count,
-	unsigned int *size)
-{
-	struct cx23885_fh *fh = q->priv_data;
-	struct cx23885_dev *dev = fh->q_dev;
-
-	*size = (dev->fmt->depth * dev->width * dev->height) >> 3;
-	if (0 == *count)
-		*count = 32;
-	if (*size * *count > vid_limit * 1024 * 1024)
-		*count = (vid_limit * 1024 * 1024) / *size;
+	*num_planes = 1;
+	sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3;
 	return 0;
 }
 
-static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
-	       enum v4l2_field field)
+static int buffer_prepare(struct vb2_buffer *vb)
 {
-	struct cx23885_fh *fh  = q->priv_data;
-	struct cx23885_dev *dev = fh->q_dev;
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
 	struct cx23885_buffer *buf =
 		container_of(vb, struct cx23885_buffer, vb);
-	int rc, init_buffer = 0;
 	u32 line0_offset, line1_offset;
-	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
+	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
 	int field_tff;
+	int ret;
 
-	if (WARN_ON(NULL == dev->fmt))
-		return -EINVAL;
+	buf->bpl = (dev->width * dev->fmt->depth) >> 3;
 
-	if (dev->width  < 48 || dev->width  > norm_maxw(dev->tvnorm) ||
-	    dev->height < 32 || dev->height > norm_maxh(dev->tvnorm))
-		return -EINVAL;
-	buf->vb.size = (dev->width * dev->height * dev->fmt->depth) >> 3;
-	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
+	if (vb2_plane_size(vb, 0) < dev->height * buf->bpl)
 		return -EINVAL;
+	vb2_set_plane_payload(vb, 0, dev->height * buf->bpl);
 
-	if (buf->fmt       != dev->fmt    ||
-	    buf->vb.width  != dev->width  ||
-	    buf->vb.height != dev->height ||
-	    buf->vb.field  != field) {
-		buf->fmt       = dev->fmt;
-		buf->vb.width  = dev->width;
-		buf->vb.height = dev->height;
-		buf->vb.field  = field;
-		init_buffer = 1;
-	}
+	ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
+	if (!ret)
+		return -EIO;
 
-	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-		init_buffer = 1;
-		rc = videobuf_iolock(q, &buf->vb, NULL);
-		if (0 != rc)
-			goto fail;
-	}
+	switch (dev->field) {
+	case V4L2_FIELD_TOP:
+		cx23885_risc_buffer(dev->pci, &buf->risc,
+				sgt->sgl, 0, UNSET,
+				buf->bpl, 0, dev->height);
+		break;
+	case V4L2_FIELD_BOTTOM:
+		cx23885_risc_buffer(dev->pci, &buf->risc,
+				sgt->sgl, UNSET, 0,
+				buf->bpl, 0, dev->height);
+		break;
+	case V4L2_FIELD_INTERLACED:
+		if (dev->tvnorm & V4L2_STD_NTSC)
+			/* NTSC or  */
+			field_tff = 1;
+		else
+			field_tff = 0;
+
+		if (cx23885_boards[dev->board].force_bff)
+			/* PAL / SECAM OR 888 in NTSC MODE */
+			field_tff = 0;
 
-	if (init_buffer) {
-		buf->bpl = buf->vb.width * buf->fmt->depth >> 3;
-		switch (buf->vb.field) {
-		case V4L2_FIELD_TOP:
-			cx23885_risc_buffer(dev->pci, &buf->risc,
-					 dma->sglist, 0, UNSET,
-					 buf->bpl, 0, buf->vb.height);
-			break;
-		case V4L2_FIELD_BOTTOM:
-			cx23885_risc_buffer(dev->pci, &buf->risc,
-					 dma->sglist, UNSET, 0,
-					 buf->bpl, 0, buf->vb.height);
-			break;
-		case V4L2_FIELD_INTERLACED:
-			if (dev->tvnorm & V4L2_STD_NTSC)
-				/* NTSC or  */
-				field_tff = 1;
-			else
-				field_tff = 0;
-
-			if (cx23885_boards[dev->board].force_bff)
-				/* PAL / SECAM OR 888 in NTSC MODE */
-				field_tff = 0;
-
-			if (field_tff) {
-				/* cx25840 transmits NTSC bottom field first */
-				dprintk(1, "%s() Creating TFF/NTSC risc\n",
+		if (field_tff) {
+			/* cx25840 transmits NTSC bottom field first */
+			dprintk(1, "%s() Creating TFF/NTSC risc\n",
 					__func__);
-				line0_offset = buf->bpl;
-				line1_offset = 0;
-			} else {
-				/* All other formats are top field first */
-				dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n",
+			line0_offset = buf->bpl;
+			line1_offset = 0;
+		} else {
+			/* All other formats are top field first */
+			dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n",
 					__func__);
-				line0_offset = 0;
-				line1_offset = buf->bpl;
-			}
-			cx23885_risc_buffer(dev->pci, &buf->risc,
-					dma->sglist, line0_offset,
-					line1_offset,
-					buf->bpl, buf->bpl,
-					buf->vb.height >> 1);
-			break;
-		case V4L2_FIELD_SEQ_TB:
-			cx23885_risc_buffer(dev->pci, &buf->risc,
-					 dma->sglist,
-					 0, buf->bpl * (buf->vb.height >> 1),
-					 buf->bpl, 0,
-					 buf->vb.height >> 1);
-			break;
-		case V4L2_FIELD_SEQ_BT:
-			cx23885_risc_buffer(dev->pci, &buf->risc,
-					 dma->sglist,
-					 buf->bpl * (buf->vb.height >> 1), 0,
-					 buf->bpl, 0,
-					 buf->vb.height >> 1);
-			break;
-		default:
-			BUG();
+			line0_offset = 0;
+			line1_offset = buf->bpl;
 		}
+		cx23885_risc_buffer(dev->pci, &buf->risc,
+				sgt->sgl, line0_offset,
+				line1_offset,
+				buf->bpl, buf->bpl,
+				dev->height >> 1);
+		break;
+	case V4L2_FIELD_SEQ_TB:
+		cx23885_risc_buffer(dev->pci, &buf->risc,
+				sgt->sgl,
+				0, buf->bpl * (dev->height >> 1),
+				buf->bpl, 0,
+				dev->height >> 1);
+		break;
+	case V4L2_FIELD_SEQ_BT:
+		cx23885_risc_buffer(dev->pci, &buf->risc,
+				sgt->sgl,
+				buf->bpl * (dev->height >> 1), 0,
+				buf->bpl, 0,
+				dev->height >> 1);
+		break;
+	default:
+		BUG();
 	}
-	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
-		buf, buf->vb.i,
+	dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
+		buf, buf->vb.v4l2_buf.index,
 		dev->width, dev->height, dev->fmt->depth, dev->fmt->name,
 		(unsigned long)buf->risc.dma);
-
-	buf->vb.state = VIDEOBUF_PREPARED;
 	return 0;
+}
 
- fail:
-	cx23885_free_buffer(q, buf);
-	return rc;
+static void buffer_finish(struct vb2_buffer *vb)
+{
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer *buf = container_of(vb,
+		struct cx23885_buffer, vb);
+	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+
+	cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
+
+	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
 }
 
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+/*
+ * The risc program for each buffer works as follows: it starts with a simple
+ * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
+ * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
+ * the initial JUMP).
+ *
+ * This is the risc program of the first buffer to be queued if the active list
+ * is empty and it just keeps DMAing this buffer without generating any
+ * interrupts.
+ *
+ * If a new buffer is added then the initial JUMP in the code for that buffer
+ * will generate an interrupt which signals that the previous buffer has been
+ * DMAed successfully and that it can be returned to userspace.
+ *
+ * It also sets the final jump of the previous buffer to the start of the new
+ * buffer, thus chaining the new buffer into the DMA chain. This is a single
+ * atomic u32 write, so there is no race condition.
+ *
+ * The end-result of all this that you only get an interrupt when a buffer
+ * is ready, so the control flow is very easy.
+ */
+static void buffer_queue(struct vb2_buffer *vb)
 {
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
 	struct cx23885_buffer   *buf = container_of(vb,
 		struct cx23885_buffer, vb);
 	struct cx23885_buffer   *prev;
-	struct cx23885_fh       *fh   = vq->priv_data;
-	struct cx23885_dev      *dev  = fh->q_dev;
 	struct cx23885_dmaqueue *q    = &dev->vidq;
+	unsigned long flags;
 
-	/* add jump to stopper */
-	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
-	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	/* add jump to start */
+	buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
 	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
 
-	if (!list_empty(&q->queued)) {
-		list_add_tail(&buf->vb.queue, &q->queued);
-		buf->vb.state = VIDEOBUF_QUEUED;
-		dprintk(2, "[%p/%d] buffer_queue - append to queued\n",
-			buf, buf->vb.i);
-
-	} else if (list_empty(&q->active)) {
-		list_add_tail(&buf->vb.queue, &q->active);
-		cx23885_start_video_dma(dev, q, buf);
-		buf->vb.state = VIDEOBUF_ACTIVE;
-		buf->count    = q->count++;
-		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
+	spin_lock_irqsave(&dev->slock, flags);
+	if (list_empty(&q->active)) {
+		list_add_tail(&buf->queue, &q->active);
 		dprintk(2, "[%p/%d] buffer_queue - first active\n",
-			buf, buf->vb.i);
-
+			buf, buf->vb.v4l2_buf.index);
 	} else {
+		buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
 		prev = list_entry(q->active.prev, struct cx23885_buffer,
-			vb.queue);
-		if (prev->vb.width  == buf->vb.width  &&
-		    prev->vb.height == buf->vb.height &&
-		    prev->fmt       == buf->fmt) {
-			list_add_tail(&buf->vb.queue, &q->active);
-			buf->vb.state = VIDEOBUF_ACTIVE;
-			buf->count    = q->count++;
-			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-			/* 64 bit bits 63-32 */
-			prev->risc.jmp[2] = cpu_to_le32(0);
-			dprintk(2, "[%p/%d] buffer_queue - append to active\n",
-				buf, buf->vb.i);
-
-		} else {
-			list_add_tail(&buf->vb.queue, &q->queued);
-			buf->vb.state = VIDEOBUF_QUEUED;
-			dprintk(2, "[%p/%d] buffer_queue - first queued\n",
-				buf, buf->vb.i);
-		}
-	}
-}
-
-static void buffer_release(struct videobuf_queue *q,
-	struct videobuf_buffer *vb)
-{
-	struct cx23885_buffer *buf = container_of(vb,
-		struct cx23885_buffer, vb);
-
-	cx23885_free_buffer(q, buf);
-}
-
-static struct videobuf_queue_ops cx23885_video_qops = {
-	.buf_setup    = buffer_setup,
-	.buf_prepare  = buffer_prepare,
-	.buf_queue    = buffer_queue,
-	.buf_release  = buffer_release,
-};
-
-static struct videobuf_queue *get_queue(struct file *file)
-{
-	struct video_device *vdev = video_devdata(file);
-	struct cx23885_fh *fh = file->private_data;
-
-	switch (vdev->vfl_type) {
-	case VFL_TYPE_GRABBER:
-		return &fh->vidq;
-	case VFL_TYPE_VBI:
-		return &fh->vbiq;
-	default:
-		WARN_ON(1);
-		return NULL;
-	}
-}
-
-static int get_resource(u32 type)
-{
-	switch (type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		return RESOURCE_VIDEO;
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
-		return RESOURCE_VBI;
-	default:
-		WARN_ON(1);
-		return 0;
+			queue);
+		list_add_tail(&buf->queue, &q->active);
+		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+		dprintk(2, "[%p/%d] buffer_queue - append to active\n",
+				buf, buf->vb.v4l2_buf.index);
 	}
+	spin_unlock_irqrestore(&dev->slock, flags);
 }
 
-static int video_open(struct file *file)
+static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
 {
-	struct video_device *vdev = video_devdata(file);
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh;
-
-	dprintk(1, "open dev=%s\n",
-		video_device_node_name(vdev));
-
-	/* allocate + initialize per filehandle data */
-	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-	if (NULL == fh)
-		return -ENOMEM;
-
-	v4l2_fh_init(&fh->fh, vdev);
-	file->private_data = &fh->fh;
-	fh->q_dev      = dev;
-
-	videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops,
-			    &dev->pci->dev, &dev->slock,
-			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			    V4L2_FIELD_INTERLACED,
-			    sizeof(struct cx23885_buffer),
-			    fh, NULL);
-
-	videobuf_queue_sg_init(&fh->vbiq, &cx23885_vbi_qops,
-		&dev->pci->dev, &dev->slock,
-		V4L2_BUF_TYPE_VBI_CAPTURE,
-		V4L2_FIELD_SEQ_TB,
-		sizeof(struct cx23885_buffer),
-		fh, NULL);
-
-	v4l2_fh_add(&fh->fh);
-
-	dprintk(1, "post videobuf_queue_init()\n");
+	struct cx23885_dev *dev = q->drv_priv;
+	struct cx23885_dmaqueue *dmaq = &dev->vidq;
+	struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
 
+	cx23885_start_video_dma(dev, dmaq, buf);
 	return 0;
 }
 
-static ssize_t video_read(struct file *file, char __user *data,
-	size_t count, loff_t *ppos)
+static void cx23885_stop_streaming(struct vb2_queue *q)
 {
-	struct video_device *vdev = video_devdata(file);
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh = file->private_data;
-
-	switch (vdev->vfl_type) {
-	case VFL_TYPE_GRABBER:
-		if (res_locked(dev, RESOURCE_VIDEO))
-			return -EBUSY;
-		return videobuf_read_one(&fh->vidq, data, count, ppos,
-					 file->f_flags & O_NONBLOCK);
-	case VFL_TYPE_VBI:
-		if (!res_get(dev, fh, RESOURCE_VBI))
-			return -EBUSY;
-		return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1,
-					    file->f_flags & O_NONBLOCK);
-	default:
-		return -EINVAL;
-	}
-}
-
-static unsigned int video_poll(struct file *file,
-	struct poll_table_struct *wait)
-{
-	struct video_device *vdev = video_devdata(file);
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh = file->private_data;
-	struct cx23885_buffer *buf;
-	unsigned long req_events = poll_requested_events(wait);
-	unsigned int rc = 0;
-
-	if (v4l2_event_pending(&fh->fh))
-		rc = POLLPRI;
-	else
-		poll_wait(file, &fh->fh.wait, wait);
-	if (!(req_events & (POLLIN | POLLRDNORM)))
-		return rc;
-
-	if (vdev->vfl_type == VFL_TYPE_VBI) {
-		if (!res_get(dev, fh, RESOURCE_VBI))
-			return rc | POLLERR;
-		return rc | videobuf_poll_stream(file, &fh->vbiq, wait);
-	}
-
-	mutex_lock(&fh->vidq.vb_lock);
-	if (res_check(fh, RESOURCE_VIDEO)) {
-		/* streaming capture */
-		if (list_empty(&fh->vidq.stream))
-			goto done;
-		buf = list_entry(fh->vidq.stream.next,
-			struct cx23885_buffer, vb.stream);
-	} else {
-		/* read() capture */
-		buf = (struct cx23885_buffer *)fh->vidq.read_buf;
-		if (NULL == buf)
-			goto done;
-	}
-	poll_wait(file, &buf->vb.done, wait);
-	if (buf->vb.state == VIDEOBUF_DONE ||
-	    buf->vb.state == VIDEOBUF_ERROR)
-		rc |= POLLIN | POLLRDNORM;
-done:
-	mutex_unlock(&fh->vidq.vb_lock);
-	return rc;
-}
-
-static int video_release(struct file *file)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh = file->private_data;
-
-	/* turn off overlay */
-	if (res_check(fh, RESOURCE_OVERLAY)) {
-		/* FIXME */
-		res_free(dev, fh, RESOURCE_OVERLAY);
-	}
+	struct cx23885_dev *dev = q->drv_priv;
+	struct cx23885_dmaqueue *dmaq = &dev->vidq;
+	unsigned long flags;
 
-	/* stop video capture */
-	if (res_check(fh, RESOURCE_VIDEO)) {
-		videobuf_queue_cancel(&fh->vidq);
-		res_free(dev, fh, RESOURCE_VIDEO);
-	}
-	if (fh->vidq.read_buf) {
-		buffer_release(&fh->vidq, fh->vidq.read_buf);
-		kfree(fh->vidq.read_buf);
-	}
+	cx_clear(VID_A_DMA_CTL, 0x11);
+	spin_lock_irqsave(&dev->slock, flags);
+	while (!list_empty(&dmaq->active)) {
+		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
 
-	/* stop vbi capture */
-	if (res_check(fh, RESOURCE_VBI)) {
-		if (fh->vbiq.streaming)
-			videobuf_streamoff(&fh->vbiq);
-		if (fh->vbiq.reading)
-			videobuf_read_stop(&fh->vbiq);
-		res_free(dev, fh, RESOURCE_VBI);
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
 	}
-
-	videobuf_mmap_free(&fh->vidq);
-	videobuf_mmap_free(&fh->vbiq);
-
-	v4l2_fh_del(&fh->fh);
-	v4l2_fh_exit(&fh->fh);
-	file->private_data = NULL;
-	kfree(fh);
-
-	/* We are not putting the tuner to sleep here on exit, because
-	 * we want to use the mpeg encoder in another session to capture
-	 * tuner video. Closing this will result in no video to the encoder.
-	 */
-
-	return 0;
+	spin_unlock_irqrestore(&dev->slock, flags);
 }
 
-static int video_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	return videobuf_mmap_mapper(get_queue(file), vma);
-}
+static struct vb2_ops cx23885_video_qops = {
+	.queue_setup    = queue_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_finish = buffer_finish,
+	.buf_queue    = buffer_queue,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = cx23885_start_streaming,
+	.stop_streaming = cx23885_stop_streaming,
+};
 
 /* ------------------------------------------------------------------ */
 /* VIDEO IOCTLS                                                       */
@@ -819,11 +521,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
 	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh   = priv;
 
 	f->fmt.pix.width        = dev->width;
 	f->fmt.pix.height       = dev->height;
-	f->fmt.pix.field        = fh->vidq.field;
+	f->fmt.pix.field        = dev->field;
 	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
 	f->fmt.pix.bytesperline =
 		(f->fmt.pix.width * dev->fmt->depth) >> 3;
@@ -884,7 +585,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
 	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh = priv;
 	struct v4l2_mbus_framefmt mbus_fmt;
 	int err;
 
@@ -896,9 +596,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	dev->fmt        = format_by_fourcc(f->fmt.pix.pixelformat);
 	dev->width      = f->fmt.pix.width;
 	dev->height     = f->fmt.pix.height;
-	fh->vidq.field = f->fmt.pix.field;
+	dev->field	= f->fmt.pix.field;
 	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
-		dev->width, dev->height, fh->vidq.field);
+		dev->width, dev->height, dev->field);
 	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
 	call_all(dev, video, s_mbus_fmt, &mbus_fmt);
 	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
@@ -940,82 +640,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 	return 0;
 }
 
-static int vidioc_reqbufs(struct file *file, void *priv,
-	struct v4l2_requestbuffers *p)
-{
-	return videobuf_reqbufs(get_queue(file), p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
-	struct v4l2_buffer *p)
-{
-	return videobuf_querybuf(get_queue(file), p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv,
-	struct v4l2_buffer *p)
-{
-	return videobuf_qbuf(get_queue(file), p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv,
-	struct v4l2_buffer *p)
-{
-	return videobuf_dqbuf(get_queue(file), p,
-				file->f_flags & O_NONBLOCK);
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
-	enum v4l2_buf_type i)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-	struct cx23885_fh *fh = priv;
-	dprintk(1, "%s()\n", __func__);
-
-	if (vdev->vfl_type == VFL_TYPE_VBI &&
-	    i != V4L2_BUF_TYPE_VBI_CAPTURE)
-		return -EINVAL;
-	if (vdev->vfl_type == VFL_TYPE_GRABBER &&
-	    i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	if (unlikely(!res_get(dev, fh, get_resource(i))))
-		return -EBUSY;
-
-	/* Don't start VBI streaming unless vida streaming
-	 * has already started.
-	 */
-	if ((i == V4L2_BUF_TYPE_VBI_CAPTURE) &&
-		((cx_read(VID_A_DMA_CTL) & 0x11) == 0))
-		return -EINVAL;
-
-	return videobuf_streamon(get_queue(file));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct video_device *vdev = video_devdata(file);
-	struct cx23885_fh *fh = priv;
-	int err, res;
-	dprintk(1, "%s()\n", __func__);
-
-	if (vdev->vfl_type == VFL_TYPE_VBI &&
-	    i != V4L2_BUF_TYPE_VBI_CAPTURE)
-		return -EINVAL;
-	if (vdev->vfl_type == VFL_TYPE_GRABBER &&
-	    i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	res = get_resource(i);
-	err = videobuf_streamoff(get_queue(file));
-	if (err < 0)
-		return err;
-	res_free(dev, fh, res);
-	return 0;
-}
-
 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 {
 	struct cx23885_dev *dev = video_drvdata(file);
@@ -1292,7 +916,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 {
 	struct v4l2_ctrl *mute;
 	int old_mute_val = 1;
-	struct videobuf_dvb_frontend *vfe;
+	struct vb2_dvb_frontend *vfe;
 	struct dvb_frontend *fe;
 
 	struct analog_parameters params = {
@@ -1316,7 +940,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 	dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__,
 		params.frequency, f->tuner, params.std);
 
-	vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1);
+	vfe = vb2_dvb_get_frontend(&dev->ts2.frontends, 1);
 	if (!vfe) {
 		return -EINVAL;
 	}
@@ -1372,28 +996,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 
 /* ----------------------------------------------------------- */
 
-static void cx23885_vid_timeout(unsigned long data)
-{
-	struct cx23885_dev *dev = (struct cx23885_dev *)data;
-	struct cx23885_dmaqueue *q = &dev->vidq;
-	struct cx23885_buffer *buf;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev->slock, flags);
-	while (!list_empty(&q->active)) {
-		buf = list_entry(q->active.next,
-			struct cx23885_buffer, vb.queue);
-		list_del(&buf->vb.queue);
-		buf->vb.state = VIDEOBUF_ERROR;
-		wake_up(&buf->vb.done);
-		printk(KERN_ERR "%s: [%p/%d] timeout - dma=0x%08lx\n",
-			dev->name, buf, buf->vb.i,
-			(unsigned long)buf->risc.dma);
-	}
-	cx23885_restart_video_queue(dev, q);
-	spin_unlock_irqrestore(&dev->slock, flags);
-}
-
 int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
 {
 	u32 mask, count;
@@ -1438,13 +1040,6 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
 		spin_unlock(&dev->slock);
 		handled++;
 	}
-	if (status & VID_BC_MSK_RISCI2) {
-		dprintk(2, "stopper video\n");
-		spin_lock(&dev->slock);
-		cx23885_restart_video_queue(dev, &dev->vidq);
-		spin_unlock(&dev->slock);
-		handled++;
-	}
 
 	/* Allow the VBI framework to process it's payload */
 	handled += cx23885_vbi_irq(dev, status);
@@ -1457,12 +1052,12 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
 
 static const struct v4l2_file_operations video_fops = {
 	.owner	       = THIS_MODULE,
-	.open	       = video_open,
-	.release       = video_release,
-	.read	       = video_read,
-	.poll          = video_poll,
-	.mmap	       = video_mmap,
+	.open           = v4l2_fh_open,
+	.release        = vb2_fop_release,
+	.read           = vb2_fop_read,
+	.poll		= vb2_fop_poll,
 	.unlocked_ioctl = video_ioctl2,
+	.mmap           = vb2_fop_mmap,
 };
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1474,18 +1069,19 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_g_fmt_vbi_cap     = cx23885_vbi_fmt,
 	.vidioc_try_fmt_vbi_cap   = cx23885_vbi_fmt,
 	.vidioc_s_fmt_vbi_cap     = cx23885_vbi_fmt,
-	.vidioc_reqbufs       = vidioc_reqbufs,
-	.vidioc_querybuf      = vidioc_querybuf,
-	.vidioc_qbuf          = vidioc_qbuf,
-	.vidioc_dqbuf         = vidioc_dqbuf,
+	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
+	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf      = vb2_ioctl_querybuf,
+	.vidioc_qbuf          = vb2_ioctl_qbuf,
+	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
+	.vidioc_streamon      = vb2_ioctl_streamon,
+	.vidioc_streamoff     = vb2_ioctl_streamoff,
 	.vidioc_s_std         = vidioc_s_std,
 	.vidioc_g_std         = vidioc_g_std,
 	.vidioc_enum_input    = vidioc_enum_input,
 	.vidioc_g_input       = vidioc_g_input,
 	.vidioc_s_input       = vidioc_s_input,
 	.vidioc_log_status    = vidioc_log_status,
-	.vidioc_streamon      = vidioc_streamon,
-	.vidioc_streamoff     = vidioc_streamoff,
 	.vidioc_g_tuner       = vidioc_g_tuner,
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_g_frequency   = vidioc_g_frequency,
@@ -1521,7 +1117,6 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
 		else
 			video_device_release(dev->vbi_dev);
 		dev->vbi_dev = NULL;
-		btcx_riscmem_free(dev->pci, &dev->vbiq.stopper);
 	}
 	if (dev->video_dev) {
 		if (video_is_registered(dev->video_dev))
@@ -1529,8 +1124,6 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
 		else
 			video_device_release(dev->video_dev);
 		dev->video_dev = NULL;
-
-		btcx_riscmem_free(dev->pci, &dev->vidq.stopper);
 	}
 
 	if (dev->audio_dev)
@@ -1539,6 +1132,7 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
 
 int cx23885_video_register(struct cx23885_dev *dev)
 {
+	struct vb2_queue *q;
 	int err;
 
 	dprintk(1, "%s()\n", __func__);
@@ -1555,21 +1149,9 @@ int cx23885_video_register(struct cx23885_dev *dev)
 
 	/* init video dma queues */
 	INIT_LIST_HEAD(&dev->vidq.active);
-	INIT_LIST_HEAD(&dev->vidq.queued);
-	dev->vidq.timeout.function = cx23885_vid_timeout;
-	dev->vidq.timeout.data = (unsigned long)dev;
-	init_timer(&dev->vidq.timeout);
-	cx23885_risc_stopper(dev->pci, &dev->vidq.stopper,
-		VID_A_DMA_CTL, 0x11, 0x00);
 
 	/* init vbi dma queues */
 	INIT_LIST_HEAD(&dev->vbiq.active);
-	INIT_LIST_HEAD(&dev->vbiq.queued);
-	dev->vbiq.timeout.function = cx23885_vbi_timeout;
-	dev->vbiq.timeout.data = (unsigned long)dev;
-	init_timer(&dev->vbiq.timeout);
-	cx23885_risc_stopper(dev->pci, &dev->vbiq.stopper,
-		VID_A_DMA_CTL, 0x22, 0x00);
 
 	cx23885_irq_add_enable(dev, 0x01);
 
@@ -1630,9 +1212,42 @@ int cx23885_video_register(struct cx23885_dev *dev)
 	cx23885_audio_mux(dev, 0);
 	mutex_unlock(&dev->lock);
 
+	q = &dev->vb2_vidq;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+	q->gfp_flags = GFP_DMA32;
+	q->min_buffers_needed = 2;
+	q->drv_priv = dev;
+	q->buf_struct_size = sizeof(struct cx23885_buffer);
+	q->ops = &cx23885_video_qops;
+	q->mem_ops = &vb2_dma_sg_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->lock;
+
+	err = vb2_queue_init(q);
+	if (err < 0)
+		goto fail_unreg;
+
+	q = &dev->vb2_vbiq;
+	q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+	q->gfp_flags = GFP_DMA32;
+	q->min_buffers_needed = 2;
+	q->drv_priv = dev;
+	q->buf_struct_size = sizeof(struct cx23885_buffer);
+	q->ops = &cx23885_vbi_qops;
+	q->mem_ops = &vb2_dma_sg_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->lock;
+
+	err = vb2_queue_init(q);
+	if (err < 0)
+		goto fail_unreg;
+
 	/* register Video device */
 	dev->video_dev = cx23885_vdev_init(dev, dev->pci,
 		&cx23885_video_template, "video");
+	dev->video_dev->queue = &dev->vb2_vidq;
 	err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,
 				    video_nr[dev->nr]);
 	if (err < 0) {
@@ -1646,6 +1261,7 @@ int cx23885_video_register(struct cx23885_dev *dev)
 	/* register VBI device */
 	dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
 		&cx23885_vbi_template, "vbi");
+	dev->vbi_dev->queue = &dev->vb2_vbiq;
 	err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
 				    vbi_nr[dev->nr]);
 	if (err < 0) {
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 95f8c42..99a5fe0 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -29,8 +29,8 @@
 #include <media/v4l2-ctrls.h>
 #include <media/tuner.h>
 #include <media/tveeprom.h>
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
+#include <media/videobuf2-dma-sg.h>
+#include <media/videobuf2-dvb.h>
 #include <media/rc-core.h>
 
 #include "btcx-risc.h"
@@ -39,7 +39,7 @@
 
 #include <linux/mutex.h>
 
-#define CX23885_VERSION "0.0.3"
+#define CX23885_VERSION "0.0.4"
 
 #define UNSET (-1U)
 
@@ -48,9 +48,6 @@
 /* Max number of inputs by card */
 #define MAX_CX23885_INPUT 8
 #define INPUT(nr) (&cx23885_boards[dev->board].input[nr])
-#define RESOURCE_OVERLAY       1
-#define RESOURCE_VIDEO         2
-#define RESOURCE_VBI           4
 
 #define BUFFER_TIMEOUT     (HZ)  /* 0.5 seconds */
 
@@ -140,20 +137,6 @@ struct cx23885_tvnorm {
 	u32		cxoformat;
 };
 
-struct cx23885_fh {
-	struct v4l2_fh		   fh;
-	u32                        resources;
-	struct cx23885_dev         *q_dev;
-
-	/* vbi capture */
-	struct videobuf_queue      vidq;
-	struct videobuf_queue      vbiq;
-
-	/* MPEG Encoder specifics ONLY */
-	struct videobuf_queue      mpegq;
-	atomic_t                   v4l_reading;
-};
-
 enum cx23885_itype {
 	CX23885_VMUX_COMPOSITE1 = 1,
 	CX23885_VMUX_COMPOSITE2,
@@ -176,7 +159,8 @@ enum cx23885_src_sel_type {
 /* buffer for one video frame */
 struct cx23885_buffer {
 	/* common v4l buffer stuff -- must be first */
-	struct videobuf_buffer vb;
+	struct vb2_buffer vb;
+	struct list_head queue;
 
 	/* cx23885 specific */
 	unsigned int           bpl;
@@ -252,9 +236,6 @@ struct cx23885_i2c {
 
 struct cx23885_dmaqueue {
 	struct list_head       active;
-	struct list_head       queued;
-	struct timer_list      timeout;
-	struct btcx_riscmem    stopper;
 	u32                    count;
 };
 
@@ -264,7 +245,7 @@ struct cx23885_tsport {
 	int                        nr;
 	int                        sram_chno;
 
-	struct videobuf_dvb_frontends frontends;
+	struct vb2_dvb_frontends   frontends;
 
 	/* dma queues */
 	struct cx23885_dmaqueue    mpegq;
@@ -393,7 +374,6 @@ struct cx23885_dev {
 	} bridge;
 
 	/* Analog video */
-	u32                        resources;
 	unsigned int               input;
 	unsigned int               audinput; /* Selectable audio input */
 	u32                        tvaudio;
@@ -424,16 +404,20 @@ struct cx23885_dev {
 	/* video capture */
 	struct cx23885_fmt         *fmt;
 	unsigned int               width, height;
+	unsigned		   field;
 
 	struct cx23885_dmaqueue    vidq;
+	struct vb2_queue           vb2_vidq;
 	struct cx23885_dmaqueue    vbiq;
+	struct vb2_queue           vb2_vbiq;
+
 	spinlock_t                 slock;
 
 	/* MPEG Encoder ONLY settings */
 	u32                        cx23417_mailbox;
 	struct cx2341x_handler     cxhdl;
 	struct video_device        *v4l_device;
-	atomic_t                   v4l_reader_count;
+	struct vb2_queue           vb2_mpegq;
 	struct cx23885_tvnorm      encodernorm;
 
 	/* Analog raw audio */
@@ -509,9 +493,6 @@ extern int cx23885_sram_channel_setup(struct cx23885_dev *dev,
 extern void cx23885_sram_channel_dump(struct cx23885_dev *dev,
 	struct sram_channel *ch);
 
-extern int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
-	u32 reg, u32 mask, u32 value);
-
 extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 	struct scatterlist *sglist,
 	unsigned int top_offset, unsigned int bottom_offset,
@@ -522,13 +503,11 @@ extern int cx23885_risc_vbibuffer(struct pci_dev *pci,
 	unsigned int top_offset, unsigned int bottom_offset,
 	unsigned int bpl, unsigned int padding, unsigned int lines);
 
+int cx23885_start_dma(struct cx23885_tsport *port,
+			     struct cx23885_dmaqueue *q,
+			     struct cx23885_buffer   *buf);
 void cx23885_cancel_buffers(struct cx23885_tsport *port);
 
-extern int cx23885_restart_queue(struct cx23885_tsport *port,
-				struct cx23885_dmaqueue *q);
-
-extern void cx23885_wakeup(struct cx23885_tsport *port,
-			   struct cx23885_dmaqueue *q, u32 count);
 
 extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
 extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
@@ -562,13 +541,11 @@ extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
 extern int cx23885_dvb_register(struct cx23885_tsport *port);
 extern int cx23885_dvb_unregister(struct cx23885_tsport *port);
 
-extern int cx23885_buf_prepare(struct videobuf_queue *q,
-			       struct cx23885_tsport *port,
-			       struct cx23885_buffer *buf,
-			       enum v4l2_field field);
+extern int cx23885_buf_prepare(struct cx23885_buffer *buf,
+			       struct cx23885_tsport *port);
 extern void cx23885_buf_queue(struct cx23885_tsport *port,
 			      struct cx23885_buffer *buf);
-extern void cx23885_free_buffer(struct videobuf_queue *q,
+extern void cx23885_free_buffer(struct cx23885_dev *dev,
 				struct cx23885_buffer *buf);
 
 /* ----------------------------------------------------------- */
@@ -590,9 +567,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm);
 extern int cx23885_vbi_fmt(struct file *file, void *priv,
 	struct v4l2_format *f);
 extern void cx23885_vbi_timeout(unsigned long data);
-extern struct videobuf_queue_ops cx23885_vbi_qops;
-extern int cx23885_restart_vbi_queue(struct cx23885_dev *dev,
-	struct cx23885_dmaqueue *q);
+extern struct vb2_ops cx23885_vbi_qops;
 extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status);
 
 /* cx23885-i2c.c                                                */
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 16/20] cx23885: fix field handling
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (14 preceding siblings ...)
  2014-08-14  9:54 ` [PATCHv2 15/20] cx23885: convert to vb2 Hans Verkuil
@ 2014-08-14  9:54 ` Hans Verkuil
  2014-08-14  9:54 ` [PATCHv2 17/20] cx23885: fix weird sizes Hans Verkuil
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:54 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Add missing SEQ_BT/TB support, bottom field is first for all 60 Hz formats,
not just NTSC, restore an overwritten field value and initialize dev->field
correctly.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 16fcdfc..ff45417 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -356,7 +356,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
 				buf->bpl, 0, dev->height);
 		break;
 	case V4L2_FIELD_INTERLACED:
-		if (dev->tvnorm & V4L2_STD_NTSC)
+		if (dev->tvnorm & V4L2_STD_525_60)
 			/* NTSC or  */
 			field_tff = 1;
 		else
@@ -563,6 +563,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 		maxh = maxh / 2;
 		break;
 	case V4L2_FIELD_INTERLACED:
+	case V4L2_FIELD_SEQ_TB:
+	case V4L2_FIELD_SEQ_BT:
 		break;
 	default:
 		field = V4L2_FIELD_INTERLACED;
@@ -602,6 +604,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
 	call_all(dev, video, s_mbus_fmt, &mbus_fmt);
 	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
+	/* s_mbus_fmt overwrites f->fmt.pix.field, restore it */
+	f->fmt.pix.field = dev->field;
 	return 0;
 }
 
@@ -1144,6 +1148,7 @@ int cx23885_video_register(struct cx23885_dev *dev)
 
 	dev->tvnorm = V4L2_STD_NTSC_M;
 	dev->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
+	dev->field = V4L2_FIELD_INTERLACED;
 	dev->width = norm_maxw(dev->tvnorm);
 	dev->height = norm_maxh(dev->tvnorm);
 
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 17/20] cx23885: fix weird sizes.
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (15 preceding siblings ...)
  2014-08-14  9:54 ` [PATCHv2 16/20] cx23885: fix field handling Hans Verkuil
@ 2014-08-14  9:54 ` Hans Verkuil
  2014-09-03 11:46   ` Mauro Carvalho Chehab
  2014-08-14  9:54 ` [PATCHv2 18/20] cx23885: remove FSF address as per checkpatch Hans Verkuil
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:54 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

These values make no sense. All SDTV standards have the same width.
This seems to be copied from the cx88 driver. Just drop these weird
values.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 99a5fe0..f542ced 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -610,15 +610,15 @@ extern int cx23885_risc_databuffer(struct pci_dev *pci,
 
 static inline unsigned int norm_maxw(v4l2_std_id norm)
 {
-	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
+	return 720;
 }
 
 static inline unsigned int norm_maxh(v4l2_std_id norm)
 {
-	return (norm & V4L2_STD_625_50) ? 576 : 480;
+	return (norm & V4L2_STD_525_60) ? 480 : 576;
 }
 
 static inline unsigned int norm_swidth(v4l2_std_id norm)
 {
-	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
+	return 754;
 }
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 18/20] cx23885: remove FSF address as per checkpatch
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (16 preceding siblings ...)
  2014-08-14  9:54 ` [PATCHv2 17/20] cx23885: fix weird sizes Hans Verkuil
@ 2014-08-14  9:54 ` Hans Verkuil
  2014-08-14  9:54 ` [PATCHv2 19/20] cx23885: remove btcx-risc dependency Hans Verkuil
  2014-08-14  9:54 ` [PATCHv2 20/20] cx23885: Add busy checks before changing formats Hans Verkuil
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:54 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

These addresses are usually out-of-date and the top-level license will
always have the right address. So drop it from these sources.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/altera-ci.c     |  4 ----
 drivers/media/pci/cx23885/altera-ci.h     |  4 ----
 drivers/media/pci/cx23885/cimax2.c        |  4 ----
 drivers/media/pci/cx23885/cimax2.h        |  4 ----
 drivers/media/pci/cx23885/cx23885-417.c   |  4 ----
 drivers/media/pci/cx23885/cx23885-alsa.c  |  4 ----
 drivers/media/pci/cx23885/cx23885-av.c    |  5 -----
 drivers/media/pci/cx23885/cx23885-av.h    |  5 -----
 drivers/media/pci/cx23885/cx23885-cards.c |  6 ------
 drivers/media/pci/cx23885/cx23885-core.c  |  4 ----
 drivers/media/pci/cx23885/cx23885-dvb.c   |  5 -----
 drivers/media/pci/cx23885/cx23885-f300.c  |  4 ----
 drivers/media/pci/cx23885/cx23885-i2c.c   | 12 ------------
 drivers/media/pci/cx23885/cx23885-input.c |  5 -----
 drivers/media/pci/cx23885/cx23885-input.h |  5 -----
 drivers/media/pci/cx23885/cx23885-ioctl.c |  4 ----
 drivers/media/pci/cx23885/cx23885-ioctl.h |  4 ----
 drivers/media/pci/cx23885/cx23885-ir.c    |  5 -----
 drivers/media/pci/cx23885/cx23885-ir.h    |  5 -----
 drivers/media/pci/cx23885/cx23885-reg.h   |  4 ----
 drivers/media/pci/cx23885/cx23885-vbi.c   |  4 ----
 drivers/media/pci/cx23885/cx23885-video.c |  5 -----
 drivers/media/pci/cx23885/cx23885-video.h |  5 -----
 drivers/media/pci/cx23885/cx23885.h       |  4 ----
 drivers/media/pci/cx23885/cx23888-ir.c    |  5 -----
 drivers/media/pci/cx23885/cx23888-ir.h    |  5 -----
 drivers/media/pci/cx23885/netup-eeprom.c  |  4 ----
 drivers/media/pci/cx23885/netup-eeprom.h  |  4 ----
 drivers/media/pci/cx23885/netup-init.c    |  4 ----
 drivers/media/pci/cx23885/netup-init.h    |  4 ----
 30 files changed, 141 deletions(-)

diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c
index f57b333..2bbbf54 100644
--- a/drivers/media/pci/cx23885/altera-ci.c
+++ b/drivers/media/pci/cx23885/altera-ci.c
@@ -16,10 +16,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
diff --git a/drivers/media/pci/cx23885/altera-ci.h b/drivers/media/pci/cx23885/altera-ci.h
index 4998c96..5028f0c 100644
--- a/drivers/media/pci/cx23885/altera-ci.h
+++ b/drivers/media/pci/cx23885/altera-ci.h
@@ -16,10 +16,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #ifndef __ALTERA_CI_H
 #define __ALTERA_CI_H
diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c
index 16fa7ea..631e4f2 100644
--- a/drivers/media/pci/cx23885/cimax2.c
+++ b/drivers/media/pci/cx23885/cimax2.c
@@ -17,10 +17,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx23885.h"
diff --git a/drivers/media/pci/cx23885/cimax2.h b/drivers/media/pci/cx23885/cimax2.h
index 518744a..565e958 100644
--- a/drivers/media/pci/cx23885/cimax2.h
+++ b/drivers/media/pci/cx23885/cimax2.h
@@ -17,10 +17,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef CIMAX2_H
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index a17238a..f1ef901 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -18,10 +18,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c
index cbbf9ad..1b162ee 100644
--- a/drivers/media/pci/cx23885/cx23885-alsa.c
+++ b/drivers/media/pci/cx23885/cx23885-alsa.c
@@ -15,10 +15,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
diff --git a/drivers/media/pci/cx23885/cx23885-av.c b/drivers/media/pci/cx23885/cx23885-av.c
index c443b7a..877dad8 100644
--- a/drivers/media/pci/cx23885/cx23885-av.c
+++ b/drivers/media/pci/cx23885/cx23885-av.c
@@ -14,11 +14,6 @@
  *  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 "cx23885.h"
diff --git a/drivers/media/pci/cx23885/cx23885-av.h b/drivers/media/pci/cx23885/cx23885-av.h
index d2915c3..97f232f 100644
--- a/drivers/media/pci/cx23885/cx23885-av.h
+++ b/drivers/media/pci/cx23885/cx23885-av.h
@@ -14,11 +14,6 @@
  *  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.
  */
 
 #ifndef _CX23885_AV_H_
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index c2b6080..21e500b 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -13,10 +13,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/init.h>
@@ -1970,5 +1966,3 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	}
 	}
 }
-
-/* ------------------------------------------------------------------ */
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index 2599af1..8663f7b 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -13,10 +13,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/init.h>
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index 376b0a6..4f643ae 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -13,10 +13,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -1717,4 +1713,3 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
 
 	return 0;
 }
-
diff --git a/drivers/media/pci/cx23885/cx23885-f300.c b/drivers/media/pci/cx23885/cx23885-f300.c
index 5444cc5..6f817d8 100644
--- a/drivers/media/pci/cx23885/cx23885-f300.c
+++ b/drivers/media/pci/cx23885/cx23885-f300.c
@@ -22,10 +22,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx23885.h"
diff --git a/drivers/media/pci/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c
index 4887314..fd71306 100644
--- a/drivers/media/pci/cx23885/cx23885-i2c.c
+++ b/drivers/media/pci/cx23885/cx23885-i2c.c
@@ -13,10 +13,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -386,11 +382,3 @@ void cx23885_av_clk(struct cx23885_dev *dev, int enable)
 
 	i2c_xfer(&dev->i2c_bus[2].i2c_adap, &msg, 1);
 }
-
-/* ----------------------------------------------------------------------- */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
index 1940c18..9d37fe6 100644
--- a/drivers/media/pci/cx23885/cx23885-input.c
+++ b/drivers/media/pci/cx23885/cx23885-input.c
@@ -28,11 +28,6 @@
  *  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/slab.h>
diff --git a/drivers/media/pci/cx23885/cx23885-input.h b/drivers/media/pci/cx23885/cx23885-input.h
index 87dc44e..6199c7e 100644
--- a/drivers/media/pci/cx23885/cx23885-input.h
+++ b/drivers/media/pci/cx23885/cx23885-input.h
@@ -14,11 +14,6 @@
  *  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.
  */
 
 #ifndef _CX23885_INPUT_H_
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.c b/drivers/media/pci/cx23885/cx23885-ioctl.c
index 9c16786..d2cdd40 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.c
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.c
@@ -15,10 +15,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx23885.h"
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.h b/drivers/media/pci/cx23885/cx23885-ioctl.h
index 92d9f07..cc5dbb6 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.h
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.h
@@ -15,10 +15,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _CX23885_IOCTL_H_
diff --git a/drivers/media/pci/cx23885/cx23885-ir.c b/drivers/media/pci/cx23885/cx23885-ir.c
index bfef193..89dc4cc 100644
--- a/drivers/media/pci/cx23885/cx23885-ir.c
+++ b/drivers/media/pci/cx23885/cx23885-ir.c
@@ -14,11 +14,6 @@
  *  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 <media/v4l2-device.h>
diff --git a/drivers/media/pci/cx23885/cx23885-ir.h b/drivers/media/pci/cx23885/cx23885-ir.h
index 0c9d8bd..8e93d1f 100644
--- a/drivers/media/pci/cx23885/cx23885-ir.h
+++ b/drivers/media/pci/cx23885/cx23885-ir.h
@@ -14,11 +14,6 @@
  *  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.
  */
 
 #ifndef _CX23885_IR_H_
diff --git a/drivers/media/pci/cx23885/cx23885-reg.h b/drivers/media/pci/cx23885/cx23885-reg.h
index a99936e..2d3cbaf 100644
--- a/drivers/media/pci/cx23885/cx23885-reg.h
+++ b/drivers/media/pci/cx23885/cx23885-reg.h
@@ -13,10 +13,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef _CX23885_REG_H_
diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
index 358776e..67b71f9 100644
--- a/drivers/media/pci/cx23885/cx23885-vbi.c
+++ b/drivers/media/pci/cx23885/cx23885-vbi.c
@@ -13,10 +13,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ff45417..defdf74 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -13,10 +13,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/init.h>
@@ -1286,4 +1282,3 @@ fail_unreg:
 	cx23885_video_unregister(dev);
 	return err;
 }
-
diff --git a/drivers/media/pci/cx23885/cx23885-video.h b/drivers/media/pci/cx23885/cx23885-video.h
index c961a2b..291e8f3 100644
--- a/drivers/media/pci/cx23885/cx23885-video.h
+++ b/drivers/media/pci/cx23885/cx23885-video.h
@@ -12,11 +12,6 @@
  *  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.
  */
 
 #ifndef _CX23885_VIDEO_H_
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index f542ced..c306aa3 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -13,10 +13,6 @@
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/pci.h>
diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index 2c951de..8ac968b 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
@@ -14,11 +14,6 @@
  *  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/kfifo.h>
diff --git a/drivers/media/pci/cx23885/cx23888-ir.h b/drivers/media/pci/cx23885/cx23888-ir.h
index d2de41c..ff74a93 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.h
+++ b/drivers/media/pci/cx23885/cx23888-ir.h
@@ -14,11 +14,6 @@
  *  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.
  */
 
 #ifndef _CX23888_IR_H_
diff --git a/drivers/media/pci/cx23885/netup-eeprom.c b/drivers/media/pci/cx23885/netup-eeprom.c
index 98a48f5..b6542ee 100644
--- a/drivers/media/pci/cx23885/netup-eeprom.c
+++ b/drivers/media/pci/cx23885/netup-eeprom.c
@@ -17,10 +17,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #
diff --git a/drivers/media/pci/cx23885/netup-eeprom.h b/drivers/media/pci/cx23885/netup-eeprom.h
index 13926e1..90cac5b 100644
--- a/drivers/media/pci/cx23885/netup-eeprom.h
+++ b/drivers/media/pci/cx23885/netup-eeprom.h
@@ -16,10 +16,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef NETUP_EEPROM_H
diff --git a/drivers/media/pci/cx23885/netup-init.c b/drivers/media/pci/cx23885/netup-init.c
index 0044fef..76d9487 100644
--- a/drivers/media/pci/cx23885/netup-init.c
+++ b/drivers/media/pci/cx23885/netup-init.c
@@ -17,10 +17,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx23885.h"
diff --git a/drivers/media/pci/cx23885/netup-init.h b/drivers/media/pci/cx23885/netup-init.h
index d26ae4b..daaa212 100644
--- a/drivers/media/pci/cx23885/netup-init.h
+++ b/drivers/media/pci/cx23885/netup-init.h
@@ -17,9 +17,5 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 extern void netup_initialize(struct cx23885_dev *dev);
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 19/20] cx23885: remove btcx-risc dependency
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (17 preceding siblings ...)
  2014-08-14  9:54 ` [PATCHv2 18/20] cx23885: remove FSF address as per checkpatch Hans Verkuil
@ 2014-08-14  9:54 ` Hans Verkuil
  2014-08-14  9:54 ` [PATCHv2 20/20] cx23885: Add busy checks before changing formats Hans Verkuil
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:54 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

It's just as easy to do it in the driver. This dependency only uses a
fraction of the btcx-risc module and doing it directly in the driver
adds only a few lines. The btcx-risc module is really meant for the
bttv driver, not for other drivers.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/Kconfig        |  1 -
 drivers/media/pci/cx23885/Makefile       |  1 -
 drivers/media/pci/cx23885/cx23885-alsa.c |  5 ++++-
 drivers/media/pci/cx23885/cx23885-core.c | 36 +++++++++++++++++---------------
 drivers/media/pci/cx23885/cx23885.h      | 18 ++++++++++------
 5 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig
index 38c3b7b..a883ea4 100644
--- a/drivers/media/pci/cx23885/Kconfig
+++ b/drivers/media/pci/cx23885/Kconfig
@@ -3,7 +3,6 @@ config VIDEO_CX23885
 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
 	select SND_PCM
 	select I2C_ALGOBIT
-	select VIDEO_BTCX
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	depends on RC_CORE
diff --git a/drivers/media/pci/cx23885/Makefile b/drivers/media/pci/cx23885/Makefile
index 2a2cafb..a2cbdcf 100644
--- a/drivers/media/pci/cx23885/Makefile
+++ b/drivers/media/pci/cx23885/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
 obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
 
 ccflags-y += -Idrivers/media/i2c
-ccflags-y += -Idrivers/media/common
 ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c
index 1b162ee..ae7c2e8 100644
--- a/drivers/media/pci/cx23885/cx23885-alsa.c
+++ b/drivers/media/pci/cx23885/cx23885-alsa.c
@@ -270,12 +270,15 @@ int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask)
 
 static int dsp_buffer_free(struct cx23885_audio_dev *chip)
 {
+	struct cx23885_riscmem *risc;
+
 	BUG_ON(!chip->dma_size);
 
 	dprintk(2, "Freeing buffer\n");
 	cx23885_alsa_dma_unmap(chip);
 	cx23885_alsa_dma_free(chip->buf);
-	btcx_riscmem_free(chip->pci, &chip->buf->risc);
+	risc = &chip->buf->risc;
+	pci_free_consistent(chip->pci, risc->size, risc->cpu, risc->dma);
 	kfree(chip->buf);
 
 	chip->buf = NULL;
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index 8663f7b..331edda 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -570,7 +570,7 @@ void cx23885_sram_channel_dump(struct cx23885_dev *dev,
 }
 
 static void cx23885_risc_disasm(struct cx23885_tsport *port,
-				struct btcx_riscmem *risc)
+				struct cx23885_riscmem *risc)
 {
 	struct cx23885_dev *dev = port->dev;
 	unsigned int i, j, n;
@@ -1121,14 +1121,13 @@ static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
 	return rp;
 }
 
-int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+int cx23885_risc_buffer(struct pci_dev *pci, struct cx23885_riscmem *risc,
 			struct scatterlist *sglist, unsigned int top_offset,
 			unsigned int bottom_offset, unsigned int bpl,
 			unsigned int padding, unsigned int lines)
 {
 	u32 instructions, fields;
 	__le32 *rp;
-	int rc;
 
 	fields = 0;
 	if (UNSET != top_offset)
@@ -1144,9 +1143,10 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 	instructions  = fields * (1 + ((bpl + padding) * lines)
 		/ PAGE_SIZE + lines);
 	instructions += 5;
-	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
-	if (rc < 0)
-		return rc;
+	risc->size = instructions * 12;
+	risc->cpu = pci_alloc_consistent(pci, risc->size, &risc->dma);
+	if (risc->cpu == NULL)
+		return -ENOMEM;
 
 	/* write risc instructions */
 	rp = risc->cpu;
@@ -1164,14 +1164,13 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 }
 
 int cx23885_risc_databuffer(struct pci_dev *pci,
-				   struct btcx_riscmem *risc,
+				   struct cx23885_riscmem *risc,
 				   struct scatterlist *sglist,
 				   unsigned int bpl,
 				   unsigned int lines, unsigned int lpi)
 {
 	u32 instructions;
 	__le32 *rp;
-	int rc;
 
 	/* estimate risc mem: worst case is one write per page border +
 	   one write per scan line + syncs + jump (all 2 dwords).  Here
@@ -1181,9 +1180,10 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
 	instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
 	instructions += 4;
 
-	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
-	if (rc < 0)
-		return rc;
+	risc->size = instructions * 12;
+	risc->cpu = pci_alloc_consistent(pci, risc->size, &risc->dma);
+	if (risc->cpu == NULL)
+		return -ENOMEM;
 
 	/* write risc instructions */
 	rp = risc->cpu;
@@ -1196,14 +1196,13 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
 	return 0;
 }
 
-int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+int cx23885_risc_vbibuffer(struct pci_dev *pci, struct cx23885_riscmem *risc,
 			struct scatterlist *sglist, unsigned int top_offset,
 			unsigned int bottom_offset, unsigned int bpl,
 			unsigned int padding, unsigned int lines)
 {
 	u32 instructions, fields;
 	__le32 *rp;
-	int rc;
 
 	fields = 0;
 	if (UNSET != top_offset)
@@ -1219,9 +1218,10 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 	instructions  = fields * (1 + ((bpl + padding) * lines)
 		/ PAGE_SIZE + lines);
 	instructions += 5;
-	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
-	if (rc < 0)
-		return rc;
+	risc->size = instructions * 12;
+	risc->cpu = pci_alloc_consistent(pci, risc->size, &risc->dma);
+	if (risc->cpu == NULL)
+		return -ENOMEM;
 	/* write risc instructions */
 	rp = risc->cpu;
 
@@ -1246,8 +1246,10 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 
 void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf)
 {
+	struct cx23885_riscmem *risc = &buf->risc;
+
 	BUG_ON(in_interrupt());
-	btcx_riscmem_free(dev->pci, &buf->risc);
+	pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma);
 }
 
 static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index c306aa3..1ff86ba 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -29,7 +29,6 @@
 #include <media/videobuf2-dvb.h>
 #include <media/rc-core.h>
 
-#include "btcx-risc.h"
 #include "cx23885-reg.h"
 #include "media/cx2341x.h"
 
@@ -152,6 +151,13 @@ enum cx23885_src_sel_type {
 	CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO
 };
 
+struct cx23885_riscmem {
+	unsigned int   size;
+	__le32         *cpu;
+	__le32         *jmp;
+	dma_addr_t     dma;
+};
+
 /* buffer for one video frame */
 struct cx23885_buffer {
 	/* common v4l buffer stuff -- must be first */
@@ -160,7 +166,7 @@ struct cx23885_buffer {
 
 	/* cx23885 specific */
 	unsigned int           bpl;
-	struct btcx_riscmem    risc;
+	struct cx23885_riscmem risc;
 	struct cx23885_fmt     *fmt;
 	u32                    count;
 };
@@ -300,7 +306,7 @@ struct cx23885_kernel_ir {
 
 struct cx23885_audio_buffer {
 	unsigned int		bpl;
-	struct btcx_riscmem	risc;
+	struct cx23885_riscmem	risc;
 	void			*vaddr;
 	struct scatterlist	*sglist;
 	int                     sglen;
@@ -489,13 +495,13 @@ extern int cx23885_sram_channel_setup(struct cx23885_dev *dev,
 extern void cx23885_sram_channel_dump(struct cx23885_dev *dev,
 	struct sram_channel *ch);
 
-extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+extern int cx23885_risc_buffer(struct pci_dev *pci, struct cx23885_riscmem *risc,
 	struct scatterlist *sglist,
 	unsigned int top_offset, unsigned int bottom_offset,
 	unsigned int bpl, unsigned int padding, unsigned int lines);
 
 extern int cx23885_risc_vbibuffer(struct pci_dev *pci,
-	struct btcx_riscmem *risc, struct scatterlist *sglist,
+	struct cx23885_riscmem *risc, struct scatterlist *sglist,
 	unsigned int top_offset, unsigned int bottom_offset,
 	unsigned int bpl, unsigned int padding, unsigned int lines);
 
@@ -595,7 +601,7 @@ extern struct cx23885_audio_dev *cx23885_audio_register(
 extern void cx23885_audio_unregister(struct cx23885_dev *dev);
 extern int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask);
 extern int cx23885_risc_databuffer(struct pci_dev *pci,
-				   struct btcx_riscmem *risc,
+				   struct cx23885_riscmem *risc,
 				   struct scatterlist *sglist,
 				   unsigned int bpl,
 				   unsigned int lines,
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCHv2 20/20] cx23885: Add busy checks before changing formats
  2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
                   ` (18 preceding siblings ...)
  2014-08-14  9:54 ` [PATCHv2 19/20] cx23885: remove btcx-risc dependency Hans Verkuil
@ 2014-08-14  9:54 ` Hans Verkuil
  19 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-08-14  9:54 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Before you can change the standard or the capture format, make sure the
various vb2_queues aren't in use since you cannot change the buffer size from
underneath a a busy vb2_queue.

Also make sure that the return code of cx23885_set_tvnorm is returned
correctly, otherwise the -EBUSY will be lost.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-417.c   | 10 +++++-----
 drivers/media/pci/cx23885/cx23885-video.c | 15 ++++++++++++---
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index f1ef901..6973055 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1248,18 +1248,18 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
 {
 	struct cx23885_dev *dev = video_drvdata(file);
 	unsigned int i;
+	int ret;
 
 	for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
 		if (id & cx23885_tvnorms[i].id)
 			break;
 	if (i == ARRAY_SIZE(cx23885_tvnorms))
 		return -EINVAL;
-	dev->encodernorm = cx23885_tvnorms[i];
-
-	/* Have the drier core notify the subdevices */
-	cx23885_set_tvnorm(dev, id);
 
-	return 0;
+	ret = cx23885_set_tvnorm(dev, id);
+	if (!ret)
+		dev->encodernorm = cx23885_tvnorms[i];
+	return ret;
 }
 
 static int vidioc_enum_input(struct file *file, void *priv,
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index defdf74..f0ea904 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -119,6 +119,12 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
 		(unsigned int)norm,
 		v4l2_norm_to_name(norm));
 
+	if (dev->tvnorm != norm) {
+		if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
+		    vb2_is_busy(&dev->vb2_mpegq))
+			return -EBUSY;
+	}
+
 	dev->tvnorm = norm;
 
 	call_all(dev, video, s_std, norm);
@@ -591,6 +597,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 
 	if (0 != err)
 		return err;
+
+	if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
+	    vb2_is_busy(&dev->vb2_mpegq))
+		return -EBUSY;
+
 	dev->fmt        = format_by_fourcc(f->fmt.pix.pixelformat);
 	dev->width      = f->fmt.pix.width;
 	dev->height     = f->fmt.pix.height;
@@ -654,9 +665,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
 	struct cx23885_dev *dev = video_drvdata(file);
 	dprintk(1, "%s()\n", __func__);
 
-	cx23885_set_tvnorm(dev, tvnorms);
-
-	return 0;
+	return cx23885_set_tvnorm(dev, tvnorms);
 }
 
 int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
-- 
2.1.0.rc1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCHv2 15/20] cx23885: convert to vb2
  2014-08-14  9:54 ` [PATCHv2 15/20] cx23885: convert to vb2 Hans Verkuil
@ 2014-09-03 11:32   ` Mauro Carvalho Chehab
  2014-09-03 11:57     ` Hans Verkuil
  0 siblings, 1 reply; 28+ messages in thread
From: Mauro Carvalho Chehab @ 2014-09-03 11:32 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, stoth, Hans Verkuil

Em Thu, 14 Aug 2014 11:54:00 +0200
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> As usual, this patch is very large due to the fact that half a vb2 conversion
> isn't possible. And since this affects 417, alsa, core, dvb, vbi and video the
> changes are all over.
> 
> What made this more difficult was the peculiar way the risc program was setup.
> The driver allowed for running out of buffers in which case the DMA would stop
> and restart when the next buffer was queued. There was also a complicated
> timeout system for when buffers weren't filled. This was replaced by a much
> simpler scheme where there is always one buffer around and the DMA will just
> cycle that buffer until a new buffer is queued. In that case the previous
> buffer will be chained to the new buffer. An interrupt is generated at the
> start of the new buffer telling the driver that the previous buffer can be
> passed on to userspace.
> 
> Much simpler and more robust. The old code seems to be copied from the
> cx88 driver. But it didn't fit the vb2 ops very well and replacing it with
> the new scheme made the code easier to understand. Not to mention that this
> patch removes 600 lines of code.

Great job!

Still, there are some issue. In special, the RISC changes should go
to a separate patch, as such changes have the potential of causing
some regressions. See below.

> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/media/pci/cx23885/Kconfig         |   4 +-
>  drivers/media/pci/cx23885/altera-ci.c     |   4 +-
>  drivers/media/pci/cx23885/cx23885-417.c   | 312 +++++-------
>  drivers/media/pci/cx23885/cx23885-alsa.c  |   4 +-
>  drivers/media/pci/cx23885/cx23885-core.c  | 309 ++++--------
>  drivers/media/pci/cx23885/cx23885-dvb.c   | 131 +++--
>  drivers/media/pci/cx23885/cx23885-vbi.c   | 275 +++++-----
>  drivers/media/pci/cx23885/cx23885-video.c | 810 ++++++++----------------------
>  drivers/media/pci/cx23885/cx23885.h       |  61 +--
>  9 files changed, 657 insertions(+), 1253 deletions(-)
> 
> diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig
> index e12c006..38c3b7b 100644
> --- a/drivers/media/pci/cx23885/Kconfig
> +++ b/drivers/media/pci/cx23885/Kconfig
> @@ -7,8 +7,8 @@ config VIDEO_CX23885
>  	select VIDEO_TUNER
>  	select VIDEO_TVEEPROM
>  	depends on RC_CORE
> -	select VIDEOBUF_DVB
> -	select VIDEOBUF_DMA_SG
> +	select VIDEOBUF2_DVB
> +	select VIDEOBUF2_DMA_SG
>  	select VIDEO_CX25840
>  	select VIDEO_CX2341X
>  	select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
> diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c
> index 2926f7f..f57b333 100644
> --- a/drivers/media/pci/cx23885/altera-ci.c
> +++ b/drivers/media/pci/cx23885/altera-ci.c
> @@ -52,8 +52,8 @@
>   * |  DATA7|  DATA6|  DATA5|  DATA4|  DATA3|  DATA2|  DATA1|  DATA0|
>   * +-------+-------+-------+-------+-------+-------+-------+-------+
>   */
> -#include <media/videobuf-dma-sg.h>
> -#include <media/videobuf-dvb.h>
> +#include <dvb_demux.h>
> +#include <dvb_frontend.h>
>  #include "altera-ci.h"
>  #include "dvb_ca_en50221.h"
>  
> diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
> index 0948b44..a17238a 100644
> --- a/drivers/media/pci/cx23885/cx23885-417.c
> +++ b/drivers/media/pci/cx23885/cx23885-417.c
> @@ -1142,47 +1142,100 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder)
>  
>  /* ------------------------------------------------------------------ */
>  
> -static int bb_buf_setup(struct videobuf_queue *q,
> -	unsigned int *count, unsigned int *size)
> +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
> +			   unsigned int *num_buffers, unsigned int *num_planes,
> +			   unsigned int sizes[], void *alloc_ctxs[])
>  {
> -	struct cx23885_fh *fh = q->priv_data;
> +	struct cx23885_dev *dev = q->drv_priv;
>  
> -	fh->q_dev->ts1.ts_packet_size  = mpeglinesize;
> -	fh->q_dev->ts1.ts_packet_count = mpeglines;
> +	dev->ts1.ts_packet_size  = mpeglinesize;
> +	dev->ts1.ts_packet_count = mpeglines;
> +	*num_planes = 1;
> +	sizes[0] = mpeglinesize * mpeglines;
> +	*num_buffers = mpegbufs;
> +	return 0;
> +}
>  
> -	*size = fh->q_dev->ts1.ts_packet_size * fh->q_dev->ts1.ts_packet_count;
> -	*count = mpegbufs;
> +static int buffer_prepare(struct vb2_buffer *vb)
> +{
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
> +	struct cx23885_buffer *buf =
> +		container_of(vb, struct cx23885_buffer, vb);
>  
> -	return 0;
> +	return cx23885_buf_prepare(buf, &dev->ts1);
>  }
>  
> -static int bb_buf_prepare(struct videobuf_queue *q,
> -	struct videobuf_buffer *vb, enum v4l2_field field)
> +static void buffer_finish(struct vb2_buffer *vb)
>  {
> -	struct cx23885_fh *fh = q->priv_data;
> -	return cx23885_buf_prepare(q, &fh->q_dev->ts1,
> -		(struct cx23885_buffer *)vb,
> -		field);
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
> +	struct cx23885_buffer *buf = container_of(vb,
> +		struct cx23885_buffer, vb);
> +	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
> +
> +	cx23885_free_buffer(dev, buf);
> +
> +	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
>  }
>  
> -static void bb_buf_queue(struct videobuf_queue *q,
> -	struct videobuf_buffer *vb)
> +static void buffer_queue(struct vb2_buffer *vb)
>  {
> -	struct cx23885_fh *fh = q->priv_data;
> -	cx23885_buf_queue(&fh->q_dev->ts1, (struct cx23885_buffer *)vb);
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
> +	struct cx23885_buffer   *buf = container_of(vb,
> +		struct cx23885_buffer, vb);
> +
> +	cx23885_buf_queue(&dev->ts1, buf);
> +}
> +
> +static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
> +{
> +	struct cx23885_dev *dev = q->drv_priv;
> +	struct cx23885_dmaqueue *dmaq = &dev->ts1.mpegq;
> +	unsigned long flags;
> +	int ret;
> +
> +	ret = cx23885_initialize_codec(dev, 1);
> +	if (ret == 0) {
> +		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
> +			struct cx23885_buffer, queue);
> +
> +		cx23885_start_dma(&dev->ts1, dmaq, buf);
> +		return 0;
> +	}
> +	spin_lock_irqsave(&dev->slock, flags);
> +	while (!list_empty(&dmaq->active)) {
> +		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
> +			struct cx23885_buffer, queue);
> +
> +		list_del(&buf->queue);
> +		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
> +	}
> +	spin_unlock_irqrestore(&dev->slock, flags);
> +	return ret;
>  }
>  
> -static void bb_buf_release(struct videobuf_queue *q,
> -	struct videobuf_buffer *vb)
> +static void cx23885_stop_streaming(struct vb2_queue *q)
>  {
> -	cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
> +	struct cx23885_dev *dev = q->drv_priv;
> +
> +	/* stop mpeg capture */
> +	cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
> +			CX23885_END_NOW, CX23885_MPEG_CAPTURE,
> +			CX23885_RAW_BITS_NONE);
> +
> +	msleep(500);
> +	cx23885_417_check_encoder(dev);
> +	cx23885_cancel_buffers(&dev->ts1);
>  }
>  
> -static struct videobuf_queue_ops cx23885_qops = {
> -	.buf_setup    = bb_buf_setup,
> -	.buf_prepare  = bb_buf_prepare,
> -	.buf_queue    = bb_buf_queue,
> -	.buf_release  = bb_buf_release,
> +static struct vb2_ops cx23885_qops = {
> +	.queue_setup    = queue_setup,
> +	.buf_prepare  = buffer_prepare,
> +	.buf_finish = buffer_finish,
> +	.buf_queue    = buffer_queue,
> +	.wait_prepare = vb2_ops_wait_prepare,
> +	.wait_finish = vb2_ops_wait_finish,
> +	.start_streaming = cx23885_start_streaming,
> +	.stop_streaming = cx23885_stop_streaming,
>  };
>  
>  /* ------------------------------------------------------------------ */
> @@ -1320,7 +1373,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
>  				struct v4l2_format *f)
>  {
>  	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh  *fh  = file->private_data;
>  
>  	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
>  	f->fmt.pix.bytesperline = 0;
> @@ -1329,9 +1381,9 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
>  	f->fmt.pix.colorspace   = 0;
>  	f->fmt.pix.width        = dev->ts1.width;
>  	f->fmt.pix.height       = dev->ts1.height;
> -	f->fmt.pix.field        = fh->mpegq.field;
> -	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
> -		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
> +	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;

Why? There are other supported formats, right?

> +	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
> +		dev->ts1.width, dev->ts1.height);
>  	return 0;
>  }
>  
> @@ -1339,15 +1391,15 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
>  				struct v4l2_format *f)
>  {
>  	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh  *fh  = file->private_data;
>  
>  	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
>  	f->fmt.pix.bytesperline = 0;
>  	f->fmt.pix.sizeimage    =
>  		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
>  	f->fmt.pix.colorspace   = 0;
> -	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
> -		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
> +	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;

Why? There are other supported formats, right?

> +	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
> +		dev->ts1.width, dev->ts1.height);
>  	return 0;
>  }
>  
> @@ -1361,58 +1413,12 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
>  	f->fmt.pix.sizeimage    =
>  		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
>  	f->fmt.pix.colorspace   = 0;
> +	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
>  	dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
>  		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
>  	return 0;
>  }
>  
> -static int vidioc_reqbufs(struct file *file, void *priv,
> -				struct v4l2_requestbuffers *p)
> -{
> -	struct cx23885_fh  *fh  = file->private_data;
> -
> -	return videobuf_reqbufs(&fh->mpegq, p);
> -}
> -
> -static int vidioc_querybuf(struct file *file, void *priv,
> -				struct v4l2_buffer *p)
> -{
> -	struct cx23885_fh  *fh  = file->private_data;
> -
> -	return videobuf_querybuf(&fh->mpegq, p);
> -}
> -
> -static int vidioc_qbuf(struct file *file, void *priv,
> -				struct v4l2_buffer *p)
> -{
> -	struct cx23885_fh  *fh  = file->private_data;
> -
> -	return videobuf_qbuf(&fh->mpegq, p);
> -}
> -
> -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
> -{
> -	struct cx23885_fh  *fh  = priv;
> -
> -	return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK);
> -}
> -
> -
> -static int vidioc_streamon(struct file *file, void *priv,
> -				enum v4l2_buf_type i)
> -{
> -	struct cx23885_fh  *fh  = file->private_data;
> -
> -	return videobuf_streamon(&fh->mpegq);
> -}
> -
> -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
> -{
> -	struct cx23885_fh  *fh  = file->private_data;
> -
> -	return videobuf_streamoff(&fh->mpegq);
> -}
> -
>  static int vidioc_log_status(struct file *file, void *priv)
>  {
>  	struct cx23885_dev *dev = video_drvdata(file);
> @@ -1424,120 +1430,14 @@ static int vidioc_log_status(struct file *file, void *priv)
>  	return 0;
>  }
>  
> -static int mpeg_open(struct file *file)
> -{
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct video_device *vdev = video_devdata(file);
> -	struct cx23885_fh *fh;
> -
> -	dprintk(2, "%s()\n", __func__);
> -
> -	/* allocate + initialize per filehandle data */
> -	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
> -	if (!fh)
> -		return -ENOMEM;
> -
> -	v4l2_fh_init(&fh->fh, vdev);
> -	file->private_data = fh;
> -	fh->q_dev      = dev;
> -
> -	videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops,
> -			    &dev->pci->dev, &dev->ts1.slock,
> -			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
> -			    V4L2_FIELD_INTERLACED,
> -			    sizeof(struct cx23885_buffer),
> -			    fh, NULL);
> -	v4l2_fh_add(&fh->fh);
> -	return 0;
> -}
> -
> -static int mpeg_release(struct file *file)
> -{
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh  *fh  = file->private_data;
> -
> -	dprintk(2, "%s()\n", __func__);
> -
> -	/* FIXME: Review this crap */
> -	/* Shut device down on last close */
> -	if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
> -		if (atomic_dec_return(&dev->v4l_reader_count) == 0) {
> -			/* stop mpeg capture */
> -			cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
> -				CX23885_END_NOW, CX23885_MPEG_CAPTURE,
> -				CX23885_RAW_BITS_NONE);
> -
> -			msleep(500);
> -			cx23885_417_check_encoder(dev);
> -
> -			cx23885_cancel_buffers(&dev->ts1);
> -		}
> -	}
> -
> -	if (fh->mpegq.streaming)
> -		videobuf_streamoff(&fh->mpegq);
> -	if (fh->mpegq.reading)
> -		videobuf_read_stop(&fh->mpegq);
> -
> -	videobuf_mmap_free(&fh->mpegq);
> -	v4l2_fh_del(&fh->fh);
> -	v4l2_fh_exit(&fh->fh);
> -	file->private_data = NULL;
> -	kfree(fh);
> -
> -	return 0;
> -}
> -
> -static ssize_t mpeg_read(struct file *file, char __user *data,
> -	size_t count, loff_t *ppos)
> -{
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh = file->private_data;
> -
> -	dprintk(2, "%s()\n", __func__);
> -
> -	/* Deal w/ A/V decoder * and mpeg encoder sync issues. */
> -	/* Start mpeg encoder on first read. */
> -	if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
> -		if (atomic_inc_return(&dev->v4l_reader_count) == 1) {
> -			if (cx23885_initialize_codec(dev, 1) < 0)
> -				return -EINVAL;
> -		}
> -	}
> -
> -	return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
> -				    file->f_flags & O_NONBLOCK);
> -}
> -
> -static unsigned int mpeg_poll(struct file *file,
> -	struct poll_table_struct *wait)
> -{
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh = file->private_data;
> -
> -	dprintk(2, "%s\n", __func__);
> -
> -	return videobuf_poll_stream(file, &fh->mpegq, wait);
> -}
> -
> -static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
> -{
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh = file->private_data;
> -
> -	dprintk(2, "%s()\n", __func__);
> -
> -	return videobuf_mmap_mapper(&fh->mpegq, vma);
> -}
> -
>  static struct v4l2_file_operations mpeg_fops = {
>  	.owner	       = THIS_MODULE,
> -	.open	       = mpeg_open,
> -	.release       = mpeg_release,
> -	.read	       = mpeg_read,
> -	.poll          = mpeg_poll,
> -	.mmap	       = mpeg_mmap,
> +	.open           = v4l2_fh_open,
> +	.release        = vb2_fop_release,
> +	.read           = vb2_fop_read,
> +	.poll		= vb2_fop_poll,
>  	.unlocked_ioctl = video_ioctl2,
> +	.mmap           = vb2_fop_mmap,
>  };
>  
>  static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
> @@ -1555,12 +1455,13 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
>  	.vidioc_g_fmt_vid_cap	 = vidioc_g_fmt_vid_cap,
>  	.vidioc_try_fmt_vid_cap	 = vidioc_try_fmt_vid_cap,
>  	.vidioc_s_fmt_vid_cap	 = vidioc_s_fmt_vid_cap,
> -	.vidioc_reqbufs		 = vidioc_reqbufs,
> -	.vidioc_querybuf	 = vidioc_querybuf,
> -	.vidioc_qbuf		 = vidioc_qbuf,
> -	.vidioc_dqbuf		 = vidioc_dqbuf,
> -	.vidioc_streamon	 = vidioc_streamon,
> -	.vidioc_streamoff	 = vidioc_streamoff,
> +	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
> +	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
> +	.vidioc_querybuf      = vb2_ioctl_querybuf,
> +	.vidioc_qbuf          = vb2_ioctl_qbuf,
> +	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
> +	.vidioc_streamon      = vb2_ioctl_streamon,
> +	.vidioc_streamoff     = vb2_ioctl_streamoff,
>  	.vidioc_log_status	 = vidioc_log_status,
>  #ifdef CONFIG_VIDEO_ADV_DEBUG
>  	.vidioc_g_chip_info	 = cx23885_g_chip_info,
> @@ -1617,6 +1518,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
>  	/* FIXME: Port1 hardcoded here */
>  	int err = -ENODEV;
>  	struct cx23885_tsport *tsport = &dev->ts1;
> +	struct vb2_queue *q;
>  
>  	dprintk(1, "%s()\n", __func__);
>  
> @@ -1644,8 +1546,24 @@ int cx23885_417_register(struct cx23885_dev *dev)
>  	/* Allocate and initialize V4L video device */
>  	dev->v4l_device = cx23885_video_dev_alloc(tsport,
>  		dev->pci, &cx23885_mpeg_template, "mpeg");
> +	q = &dev->vb2_mpegq;
> +	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> +	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
> +	q->gfp_flags = GFP_DMA32;
> +	q->min_buffers_needed = 2;
> +	q->drv_priv = dev;
> +	q->buf_struct_size = sizeof(struct cx23885_buffer);
> +	q->ops = &cx23885_qops;
> +	q->mem_ops = &vb2_dma_sg_memops;
> +	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> +	q->lock = &dev->lock;
> +
> +	err = vb2_queue_init(q);
> +	if (err < 0)
> +		return err;
>  	video_set_drvdata(dev->v4l_device, dev);
>  	dev->v4l_device->lock = &dev->lock;
> +	dev->v4l_device->queue = q;
>  	err = video_register_device(dev->v4l_device,
>  		VFL_TYPE_GRABBER, -1);
>  	if (err < 0) {
> diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c
> index 31dbf0c..cbbf9ad 100644
> --- a/drivers/media/pci/cx23885/cx23885-alsa.c
> +++ b/drivers/media/pci/cx23885/cx23885-alsa.c
> @@ -393,6 +393,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
>  		return -ENOMEM;
>  
>  	buf->bpl = chip->period_size;
> +	chip->buf = buf;
>  
>  	ret = cx23885_alsa_dma_init(chip,
>  			(PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
> @@ -413,8 +414,6 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
>  	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
>  	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
>  
> -	chip->buf = buf;
> -
>  	substream->runtime->dma_area = chip->buf->vaddr;
>  	substream->runtime->dma_bytes = chip->dma_size;
>  	substream->runtime->dma_addr = 0;
> @@ -423,6 +422,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
>  
>  error:
>  	kfree(buf);
> +	chip->buf = NULL;
>  	return ret;
>  }
>  
> diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
> index 075b28e..2599af1 100644
> --- a/drivers/media/pci/cx23885/cx23885-core.c
> +++ b/drivers/media/pci/cx23885/cx23885-core.c
> @@ -420,39 +420,23 @@ static int cx23885_risc_decode(u32 risc)
>  	return incr[risc >> 28] ? incr[risc >> 28] : 1;
>  }
>  
> -void cx23885_wakeup(struct cx23885_tsport *port,
> +static void cx23885_wakeup(struct cx23885_tsport *port,
>  			   struct cx23885_dmaqueue *q, u32 count)
>  {
>  	struct cx23885_dev *dev = port->dev;
>  	struct cx23885_buffer *buf;
> -	int bc;
>  
> -	for (bc = 0;; bc++) {
> -		if (list_empty(&q->active))
> -			break;
> -		buf = list_entry(q->active.next,
> -				 struct cx23885_buffer, vb.queue);
> -
> -		/* count comes from the hw and is is 16bit wide --
> -		 * this trick handles wrap-arounds correctly for
> -		 * up to 32767 buffers in flight... */
> -		if ((s16) (count - buf->count) < 0)
> -			break;
> -
> -		v4l2_get_timestamp(&buf->vb.ts);
> -		dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i,
> -			count, buf->count);
> -		buf->vb.state = VIDEOBUF_DONE;
> -		list_del(&buf->vb.queue);
> -		wake_up(&buf->vb.done);
> -	}
>  	if (list_empty(&q->active))
> -		del_timer(&q->timeout);
> -	else
> -		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
> -	if (bc != 1)
> -		printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n",
> -		       __func__, bc);
> +		return;
> +	buf = list_entry(q->active.next,
> +			 struct cx23885_buffer, queue);
> +
> +	v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
> +	buf->vb.v4l2_buf.sequence = q->count++;
> +	dprintk(1, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index,
> +		count, q->count);
> +	list_del(&buf->queue);
> +	vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
>  }
>  
>  int cx23885_sram_channel_setup(struct cx23885_dev *dev,
> @@ -482,8 +466,8 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
>  		lines = 6;
>  	BUG_ON(lines < 2);
>  
> -	cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
> -	cx_write(8 + 4, 8);
> +	cx_write(8 + 0, RISC_JUMP | RISC_CNT_RESET);
> +	cx_write(8 + 4, 12);

The above doesn't sound as being a pure vb2 conversion, and might cause
regressions, as we're changing the channel setups. I would very much
prefer to have such changes on a separate changeset, as it makes easier
to do bisect if ever needed.

>  	cx_write(8 + 8, 0);
>  
>  	/* write CDT */
> @@ -699,10 +683,6 @@ static int get_resources(struct cx23885_dev *dev)
>  	return -EBUSY;
>  }
>  
> -static void cx23885_timeout(unsigned long data);
> -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
> -				u32 reg, u32 mask, u32 value);
> -
>  static int cx23885_init_tsport(struct cx23885_dev *dev,
>  	struct cx23885_tsport *port, int portno)
>  {
> @@ -719,11 +699,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
>  	port->nr = portno;
>  
>  	INIT_LIST_HEAD(&port->mpegq.active);
> -	INIT_LIST_HEAD(&port->mpegq.queued);
> -	port->mpegq.timeout.function = cx23885_timeout;
> -	port->mpegq.timeout.data = (unsigned long)port;
> -	init_timer(&port->mpegq.timeout);
> -
>  	mutex_init(&port->frontends.lock);
>  	INIT_LIST_HEAD(&port->frontends.felist);
>  	port->frontends.active_fe_id = 0;
> @@ -776,9 +751,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
>  		BUG();
>  	}
>  
> -	cx23885_risc_stopper(dev->pci, &port->mpegq.stopper,
> -		     port->reg_dma_ctl, port->dma_ctl_val, 0x00);
> -
>  	return 0;
>  }
>  
> @@ -1089,11 +1061,18 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
>  static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
>  			       unsigned int offset, u32 sync_line,
>  			       unsigned int bpl, unsigned int padding,
> -			       unsigned int lines,  unsigned int lpi)
> +			       unsigned int lines,  unsigned int lpi, bool jump)
>  {
>  	struct scatterlist *sg;
>  	unsigned int line, todo, sol;
>  
> +
> +	if (jump) {
> +		*(rp++) = cpu_to_le32(RISC_JUMP);
> +		*(rp++) = cpu_to_le32(0);
> +		*(rp++) = cpu_to_le32(0); /* bits 63-32 */
> +	}
> +

Here it seem clear: you're now adding a code to support different
frame interlacing layouts, but the best is to have such changes on
a separate changeset, as this is one thing that we may have troubles
in the future.

The way I see is that we might start having a flood of complains about
regressions, and all of them will point to this single patch, making
really hard to identify what part of the change broke it.

So, let's split those risc changes on a pre (or post) patch, making
easier if someone needs to report an issue, for us to track what
patch broke it.

>  	/* sync instruction */
>  	if (sync_line != NO_SYNC_LINE)
>  		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
> @@ -1168,7 +1147,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  	/* write and jump need and extra dword */
>  	instructions  = fields * (1 + ((bpl + padding) * lines)
>  		/ PAGE_SIZE + lines);
> -	instructions += 2;
> +	instructions += 5;
>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
>  	if (rc < 0)
>  		return rc;
> @@ -1177,10 +1156,10 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  	rp = risc->cpu;
>  	if (UNSET != top_offset)
>  		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
> -					bpl, padding, lines, 0);
> +					bpl, padding, lines, 0, true);
>  	if (UNSET != bottom_offset)
>  		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
> -					bpl, padding, lines, 0);
> +					bpl, padding, lines, 0, UNSET == top_offset);
>  
>  	/* save pointer to jmp instruction address */
>  	risc->jmp = rp;
> @@ -1204,7 +1183,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
>  	   than PAGE_SIZE */
>  	/* Jump and write need an extra dword */
>  	instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
> -	instructions += 1;
> +	instructions += 4;
>  
>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
>  	if (rc < 0)
> @@ -1213,7 +1192,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
>  	/* write risc instructions */
>  	rp = risc->cpu;
>  	rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE,
> -				bpl, 0, lines, lpi);
> +				bpl, 0, lines, lpi, lpi == 0);
>  
>  	/* save pointer to jmp instruction address */
>  	risc->jmp = rp;
> @@ -1243,7 +1222,7 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  	/* write and jump need and extra dword */
>  	instructions  = fields * (1 + ((bpl + padding) * lines)
>  		/ PAGE_SIZE + lines);
> -	instructions += 2;
> +	instructions += 5;
>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
>  	if (rc < 0)
>  		return rc;
> @@ -1253,12 +1232,12 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  	/* Sync to line 6, so US CC line 21 will appear in line '12'
>  	 * in the userland vbi payload */
>  	if (UNSET != top_offset)
> -		rp = cx23885_risc_field(rp, sglist, top_offset, 6,
> -					bpl, padding, lines, 0);
> +		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
> +					bpl, padding, lines, 0, true);
>  
>  	if (UNSET != bottom_offset)
> -		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207,
> -					bpl, padding, lines, 0);
> +		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
> +					bpl, padding, lines, 0, UNSET == top_offset);

Why to change the 4th argument of cx23885_risc_field() call?

>  
>  
>  
> @@ -1269,38 +1248,10 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  }
>  
>  
> -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
> -				u32 reg, u32 mask, u32 value)

What happened with this function?

> +void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf)
>  {
> -	__le32 *rp;
> -	int rc;
> -
> -	rc = btcx_riscmem_alloc(pci, risc, 4*16);
> -	if (rc < 0)
> -		return rc;
> -
> -	/* write risc instructions */
> -	rp = risc->cpu;
> -	*(rp++) = cpu_to_le32(RISC_WRITECR  | RISC_IRQ2);
> -	*(rp++) = cpu_to_le32(reg);
> -	*(rp++) = cpu_to_le32(value);
> -	*(rp++) = cpu_to_le32(mask);
> -	*(rp++) = cpu_to_le32(RISC_JUMP);
> -	*(rp++) = cpu_to_le32(risc->dma);
> -	*(rp++) = cpu_to_le32(0); /* bits 63-32 */
> -	return 0;
> -}
> -
> -void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
> -{
> -	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
> -
>  	BUG_ON(in_interrupt());
> -	videobuf_waiton(q, &buf->vb, 0, 0);
> -	videobuf_dma_unmap(q->dev, dma);
> -	videobuf_dma_free(dma);
> -	btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
> -	buf->vb.state = VIDEOBUF_NEEDS_INIT;
> +	btcx_riscmem_free(dev->pci, &buf->risc);
>  }
>  
>  static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
> @@ -1355,7 +1306,7 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
>  		port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk));
>  }
>  
> -static int cx23885_start_dma(struct cx23885_tsport *port,
> +int cx23885_start_dma(struct cx23885_tsport *port,
>  			     struct cx23885_dmaqueue *q,
>  			     struct cx23885_buffer   *buf)
>  {
> @@ -1363,7 +1314,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
>  	u32 reg;
>  
>  	dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__,
> -		buf->vb.width, buf->vb.height, buf->vb.field);
> +		dev->width, dev->height, dev->field);
>  
>  	/* Stop the fifo and risc engine for this port */
>  	cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
> @@ -1379,7 +1330,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
>  	}
>  
>  	/* write TS length to chip */
> -	cx_write(port->reg_lngth, buf->vb.width);
> +	cx_write(port->reg_lngth, port->ts_packet_size);
>  
>  	if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
>  		(!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) {
> @@ -1408,7 +1359,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
>  	/* NOTE: this is 2 (reserved) for portb, does it matter? */
>  	/* reset counter to zero */
>  	cx_write(port->reg_gpcnt_ctl, 3);
> -	q->count = 1;
> +	q->count = 0;
>  
>  	/* Set VIDB pins to input */
>  	if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
> @@ -1497,134 +1448,83 @@ static int cx23885_stop_dma(struct cx23885_tsport *port)
>  	return 0;
>  }
>  
> -int cx23885_restart_queue(struct cx23885_tsport *port,
> -				struct cx23885_dmaqueue *q)
> -{
> -	struct cx23885_dev *dev = port->dev;
> -	struct cx23885_buffer *buf;
> -
> -	dprintk(5, "%s()\n", __func__);
> -	if (list_empty(&q->active)) {
> -		struct cx23885_buffer *prev;
> -		prev = NULL;
> -
> -		dprintk(5, "%s() queue is empty\n", __func__);
> -
> -		for (;;) {
> -			if (list_empty(&q->queued))
> -				return 0;
> -			buf = list_entry(q->queued.next, struct cx23885_buffer,
> -					 vb.queue);
> -			if (NULL == prev) {
> -				list_move_tail(&buf->vb.queue, &q->active);
> -				cx23885_start_dma(port, q, buf);
> -				buf->vb.state = VIDEOBUF_ACTIVE;
> -				buf->count    = q->count++;
> -				mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
> -				dprintk(5, "[%p/%d] restart_queue - f/active\n",
> -					buf, buf->vb.i);
> -
> -			} else if (prev->vb.width  == buf->vb.width  &&
> -				   prev->vb.height == buf->vb.height &&
> -				   prev->fmt       == buf->fmt) {
> -				list_move_tail(&buf->vb.queue, &q->active);
> -				buf->vb.state = VIDEOBUF_ACTIVE;
> -				buf->count    = q->count++;
> -				prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
> -				/* 64 bit bits 63-32 */
> -				prev->risc.jmp[2] = cpu_to_le32(0);
> -				dprintk(5, "[%p/%d] restart_queue - m/active\n",
> -					buf, buf->vb.i);
> -			} else {
> -				return 0;
> -			}
> -			prev = buf;
> -		}
> -		return 0;
> -	}
> -
> -	buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
> -	dprintk(2, "restart_queue [%p/%d]: restart dma\n",
> -		buf, buf->vb.i);
> -	cx23885_start_dma(port, q, buf);
> -	list_for_each_entry(buf, &q->active, vb.queue)
> -		buf->count = q->count++;
> -	mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
> -	return 0;
> -}
> -
>  /* ------------------------------------------------------------------ */
>  
> -int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
> -			struct cx23885_buffer *buf, enum v4l2_field field)
> +int cx23885_buf_prepare(struct cx23885_buffer *buf, struct cx23885_tsport *port)
>  {
>  	struct cx23885_dev *dev = port->dev;
>  	int size = port->ts_packet_size * port->ts_packet_count;
> +	struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0);
>  	int rc;
>  
>  	dprintk(1, "%s: %p\n", __func__, buf);
> -	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
> +	if (vb2_plane_size(&buf->vb, 0) < size)
>  		return -EINVAL;
> +	vb2_set_plane_payload(&buf->vb, 0, size);
>  
> -	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
> -		buf->vb.width  = port->ts_packet_size;
> -		buf->vb.height = port->ts_packet_count;
> -		buf->vb.size   = size;
> -		buf->vb.field  = field /*V4L2_FIELD_TOP*/;
> -
> -		rc = videobuf_iolock(q, &buf->vb, NULL);
> -		if (0 != rc)
> -			goto fail;
> -		cx23885_risc_databuffer(dev->pci, &buf->risc,
> -					videobuf_to_dma(&buf->vb)->sglist,
> -					buf->vb.width, buf->vb.height, 0);
> -	}
> -	buf->vb.state = VIDEOBUF_PREPARED;
> -	return 0;
> +	rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
> +	if (!rc)
> +		return -EIO;
>  
> - fail:
> -	cx23885_free_buffer(q, buf);
> -	return rc;
> +	cx23885_risc_databuffer(dev->pci, &buf->risc,
> +				sgt->sgl,
> +				port->ts_packet_size, port->ts_packet_count, 0);
> +	return 0;
>  }
>  
> +/*
> + * The risc program for each buffer works as follows: it starts with a simple
> + * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
> + * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
> + * the initial JUMP).
> + *
> + * This is the risc program of the first buffer to be queued if the active list
> + * is empty and it just keeps DMAing this buffer without generating any
> + * interrupts.
> + *
> + * If a new buffer is added then the initial JUMP in the code for that buffer
> + * will generate an interrupt which signals that the previous buffer has been
> + * DMAed successfully and that it can be returned to userspace.
> + *
> + * It also sets the final jump of the previous buffer to the start of the new
> + * buffer, thus chaining the new buffer into the DMA chain. This is a single
> + * atomic u32 write, so there is no race condition.
> + *
> + * The end-result of all this that you only get an interrupt when a buffer
> + * is ready, so the control flow is very easy.
> + */
>  void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
>  {
>  	struct cx23885_buffer    *prev;
>  	struct cx23885_dev *dev = port->dev;
>  	struct cx23885_dmaqueue  *cx88q = &port->mpegq;
> +	unsigned long flags;
>  
> -	/* add jump to stopper */
> -	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
> -	buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
> +	buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
> +	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
> +	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
>  	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
>  
> +	spin_lock_irqsave(&dev->slock, flags);
>  	if (list_empty(&cx88q->active)) {
> -		dprintk(1, "queue is empty - first active\n");
> -		list_add_tail(&buf->vb.queue, &cx88q->active);
> -		cx23885_start_dma(port, cx88q, buf);
> -		buf->vb.state = VIDEOBUF_ACTIVE;
> -		buf->count    = cx88q->count++;
> -		mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT);
> +		list_add_tail(&buf->queue, &cx88q->active);
>  		dprintk(1, "[%p/%d] %s - first active\n",
> -			buf, buf->vb.i, __func__);
> +			buf, buf->vb.v4l2_buf.index, __func__);
>  	} else {
> -		dprintk(1, "queue is not empty - append to active\n");
> +		buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
>  		prev = list_entry(cx88q->active.prev, struct cx23885_buffer,
> -				  vb.queue);
> -		list_add_tail(&buf->vb.queue, &cx88q->active);
> -		buf->vb.state = VIDEOBUF_ACTIVE;
> -		buf->count    = cx88q->count++;
> +				  queue);
> +		list_add_tail(&buf->queue, &cx88q->active);
>  		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
> -		prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
>  		dprintk(1, "[%p/%d] %s - append to active\n",
> -			 buf, buf->vb.i, __func__);
> +			 buf, buf->vb.v4l2_buf.index, __func__);
>  	}
> +	spin_unlock_irqrestore(&dev->slock, flags);
>  }
>  
>  /* ----------------------------------------------------------- */
>  
> -static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
> -			      int restart)
> +static void do_cancel_buffers(struct cx23885_tsport *port, char *reason)
>  {
>  	struct cx23885_dev *dev = port->dev;
>  	struct cx23885_dmaqueue *q = &port->mpegq;
> @@ -1634,16 +1534,11 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
>  	spin_lock_irqsave(&port->slock, flags);
>  	while (!list_empty(&q->active)) {
>  		buf = list_entry(q->active.next, struct cx23885_buffer,
> -				 vb.queue);
> -		list_del(&buf->vb.queue);
> -		buf->vb.state = VIDEOBUF_ERROR;
> -		wake_up(&buf->vb.done);
> +				 queue);
> +		list_del(&buf->queue);
> +		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
>  		dprintk(1, "[%p/%d] %s - dma=0x%08lx\n",
> -			buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
> -	}
> -	if (restart) {
> -		dprintk(1, "restarting queue\n");
> -		cx23885_restart_queue(port, q);
> +			buf, buf->vb.v4l2_buf.index, reason, (unsigned long)buf->risc.dma);
>  	}
>  	spin_unlock_irqrestore(&port->slock, flags);
>  }
> @@ -1651,27 +1546,10 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
>  void cx23885_cancel_buffers(struct cx23885_tsport *port)
>  {
>  	struct cx23885_dev *dev = port->dev;
> -	struct cx23885_dmaqueue *q = &port->mpegq;
>  
>  	dprintk(1, "%s()\n", __func__);
> -	del_timer_sync(&q->timeout);
>  	cx23885_stop_dma(port);
> -	do_cancel_buffers(port, "cancel", 0);
> -}
> -
> -static void cx23885_timeout(unsigned long data)
> -{
> -	struct cx23885_tsport *port = (struct cx23885_tsport *)data;
> -	struct cx23885_dev *dev = port->dev;
> -
> -	dprintk(1, "%s()\n", __func__);
> -
> -	if (debug > 5)
> -		cx23885_sram_channel_dump(dev,
> -			&dev->sram_channels[port->sram_chno]);
> -
> -	cx23885_stop_dma(port);
> -	do_cancel_buffers(port, "timeout", 1);
> +	do_cancel_buffers(port, "cancel");
>  }
>  
>  int cx23885_irq_417(struct cx23885_dev *dev, u32 status)
> @@ -1721,11 +1599,6 @@ int cx23885_irq_417(struct cx23885_dev *dev, u32 status)
>  		spin_lock(&port->slock);
>  		cx23885_wakeup(port, &port->mpegq, count);
>  		spin_unlock(&port->slock);
> -	} else if (status & VID_B_MSK_RISCI2) {
> -		dprintk(7, "        VID_B_MSK_RISCI2\n");
> -		spin_lock(&port->slock);
> -		cx23885_restart_queue(port, &port->mpegq);
> -		spin_unlock(&port->slock);
>  	}
>  	if (status) {
>  		cx_write(port->reg_ts_int_stat, status);
> @@ -1777,14 +1650,6 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
>  		cx23885_wakeup(port, &port->mpegq, count);
>  		spin_unlock(&port->slock);
>  
> -	} else if (status & VID_BC_MSK_RISCI2) {
> -
> -		dprintk(7, " (RISCI2            0x%08x)\n", VID_BC_MSK_RISCI2);
> -
> -		spin_lock(&port->slock);
> -		cx23885_restart_queue(port, &port->mpegq);
> -		spin_unlock(&port->slock);
> -
>  	}
>  	if (status) {
>  		cx_write(port->reg_ts_int_stat, status);
> diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
> index 968fecc..376b0a6 100644
> --- a/drivers/media/pci/cx23885/cx23885-dvb.c
> +++ b/drivers/media/pci/cx23885/cx23885-dvb.c
> @@ -91,59 +91,95 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
>  
>  /* ------------------------------------------------------------------ */
>  
> -static int dvb_buf_setup(struct videobuf_queue *q,
> -			 unsigned int *count, unsigned int *size)
> +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
> +			   unsigned int *num_buffers, unsigned int *num_planes,
> +			   unsigned int sizes[], void *alloc_ctxs[])
>  {
> -	struct cx23885_tsport *port = q->priv_data;
> +	struct cx23885_tsport *port = q->drv_priv;
>  
>  	port->ts_packet_size  = 188 * 4;
>  	port->ts_packet_count = 32;
> -
> -	*size  = port->ts_packet_size * port->ts_packet_count;
> -	*count = 32;
> +	*num_planes = 1;
> +	sizes[0] = port->ts_packet_size * port->ts_packet_count;
> +	*num_buffers = 32;
>  	return 0;
>  }
>  
> -static int dvb_buf_prepare(struct videobuf_queue *q,
> -			   struct videobuf_buffer *vb, enum v4l2_field field)
> +
> +static int buffer_prepare(struct vb2_buffer *vb)
>  {
> -	struct cx23885_tsport *port = q->priv_data;
> -	return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field);
> +	struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
> +	struct cx23885_buffer *buf =
> +		container_of(vb, struct cx23885_buffer, vb);
> +
> +	return cx23885_buf_prepare(buf, port);
>  }
>  
> -static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
> +static void buffer_finish(struct vb2_buffer *vb)
>  {
> -	struct cx23885_tsport *port = q->priv_data;
> -	cx23885_buf_queue(port, (struct cx23885_buffer *)vb);
> +	struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
> +	struct cx23885_dev *dev = port->dev;
> +	struct cx23885_buffer *buf = container_of(vb,
> +		struct cx23885_buffer, vb);
> +	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
> +
> +	cx23885_free_buffer(dev, buf);
> +
> +	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
>  }
>  
> -static void dvb_buf_release(struct videobuf_queue *q,
> -			    struct videobuf_buffer *vb)
> +static void buffer_queue(struct vb2_buffer *vb)
>  {
> -	cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
> +	struct cx23885_tsport *port = vb->vb2_queue->drv_priv;
> +	struct cx23885_buffer   *buf = container_of(vb,
> +		struct cx23885_buffer, vb);
> +
> +	cx23885_buf_queue(port, buf);
>  }
>  
>  static void cx23885_dvb_gate_ctrl(struct cx23885_tsport  *port, int open)
>  {
> -	struct videobuf_dvb_frontends *f;
> -	struct videobuf_dvb_frontend *fe;
> +	struct vb2_dvb_frontends *f;
> +	struct vb2_dvb_frontend *fe;
>  
>  	f = &port->frontends;
>  
>  	if (f->gate <= 1) /* undefined or fe0 */
> -		fe = videobuf_dvb_get_frontend(f, 1);
> +		fe = vb2_dvb_get_frontend(f, 1);
>  	else
> -		fe = videobuf_dvb_get_frontend(f, f->gate);
> +		fe = vb2_dvb_get_frontend(f, f->gate);
>  
>  	if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
>  		fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
>  }
>  
> -static struct videobuf_queue_ops dvb_qops = {
> -	.buf_setup    = dvb_buf_setup,
> -	.buf_prepare  = dvb_buf_prepare,
> -	.buf_queue    = dvb_buf_queue,
> -	.buf_release  = dvb_buf_release,
> +static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
> +{
> +	struct cx23885_tsport *port = q->drv_priv;
> +	struct cx23885_dmaqueue *dmaq = &port->mpegq;
> +	struct cx23885_buffer *buf = list_entry(dmaq->active.next,
> +			struct cx23885_buffer, queue);
> +
> +	cx23885_start_dma(port, dmaq, buf);
> +	return 0;
> +}
> +
> +static void cx23885_stop_streaming(struct vb2_queue *q)
> +{
> +	struct cx23885_tsport *port = q->drv_priv;
> +
> +	cx23885_cancel_buffers(port);
> +}
> +
> +static struct vb2_ops dvb_qops = {
> +	.queue_setup    = queue_setup,
> +	.buf_prepare  = buffer_prepare,
> +	.buf_finish = buffer_finish,
> +	.buf_queue    = buffer_queue,
> +	.wait_prepare = vb2_ops_wait_prepare,
> +	.wait_finish = vb2_ops_wait_finish,
> +	.start_streaming = cx23885_start_streaming,
> +	.stop_streaming = cx23885_stop_streaming,
>  };
>  
>  static struct s5h1409_config hauppauge_generic_config = {
> @@ -863,16 +899,16 @@ static int dvb_register(struct cx23885_tsport *port)
>  	struct dib7000p_ops dib7000p_ops;
>  	struct cx23885_dev *dev = port->dev;
>  	struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
> -	struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
> +	struct vb2_dvb_frontend *fe0, *fe1 = NULL;
>  	int mfe_shared = 0; /* bus not shared by default */
>  	int ret;
>  
>  	/* Get the first frontend */
> -	fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
> +	fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
>  	if (!fe0)
>  		return -EINVAL;
>  
> -	/* init struct videobuf_dvb */
> +	/* init struct vb2_dvb */
>  	fe0->dvb.name = dev->name;
>  
>  	/* multi-frontend gate control is undefined or defaults to fe0 */
> @@ -1392,7 +1428,7 @@ static int dvb_register(struct cx23885_tsport *port)
>  			fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend);
>  		}
>  		/* MFE frontend 2 */
> -		fe1 = videobuf_dvb_get_frontend(&port->frontends, 2);
> +		fe1 = vb2_dvb_get_frontend(&port->frontends, 2);
>  		if (fe1 == NULL)
>  			goto frontend_detach;
>  		/* DVB-C init */
> @@ -1532,7 +1568,7 @@ static int dvb_register(struct cx23885_tsport *port)
>  		fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
>  
>  	/* register everything */
> -	ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
> +	ret = vb2_dvb_register_bus(&port->frontends, THIS_MODULE, port,
>  					&dev->pci->dev, adapter_nr, mfe_shared);
>  	if (ret)
>  		goto frontend_detach;
> @@ -1581,14 +1617,14 @@ static int dvb_register(struct cx23885_tsport *port)
>  
>  frontend_detach:
>  	port->gate_ctrl = NULL;
> -	videobuf_dvb_dealloc_frontends(&port->frontends);
> +	vb2_dvb_dealloc_frontends(&port->frontends);
>  	return -EINVAL;
>  }
>  
>  int cx23885_dvb_register(struct cx23885_tsport *port)
>  {
>  
> -	struct videobuf_dvb_frontend *fe0;
> +	struct vb2_dvb_frontend *fe0;
>  	struct cx23885_dev *dev = port->dev;
>  	int err, i;
>  
> @@ -1605,13 +1641,15 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
>  		port->num_frontends);
>  
>  	for (i = 1; i <= port->num_frontends; i++) {
> -		if (videobuf_dvb_alloc_frontend(
> +		struct vb2_queue *q;
> +
> +		if (vb2_dvb_alloc_frontend(
>  			&port->frontends, i) == NULL) {
>  			printk(KERN_ERR "%s() failed to alloc\n", __func__);
>  			return -ENOMEM;
>  		}
>  
> -		fe0 = videobuf_dvb_get_frontend(&port->frontends, i);
> +		fe0 = vb2_dvb_get_frontend(&port->frontends, i);
>  		if (!fe0)
>  			err = -EINVAL;
>  
> @@ -1627,10 +1665,21 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
>  		/* dvb stuff */
>  		/* We have to init the queue for each frontend on a port. */
>  		printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name);
> -		videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops,
> -			    &dev->pci->dev, &port->slock,
> -			    V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
> -			    sizeof(struct cx23885_buffer), port, NULL);
> +		q = &fe0->dvb.dvbq;
> +		q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> +		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
> +		q->gfp_flags = GFP_DMA32;
> +		q->min_buffers_needed = 2;
> +		q->drv_priv = port;
> +		q->buf_struct_size = sizeof(struct cx23885_buffer);
> +		q->ops = &dvb_qops;
> +		q->mem_ops = &vb2_dma_sg_memops;
> +		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> +		q->lock = &dev->lock;
> +
> +		err = vb2_queue_init(q);
> +		if (err < 0)
> +			return err;
>  	}
>  	err = dvb_register(port);
>  	if (err != 0)
> @@ -1642,7 +1691,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
>  
>  int cx23885_dvb_unregister(struct cx23885_tsport *port)
>  {
> -	struct videobuf_dvb_frontend *fe0;
> +	struct vb2_dvb_frontend *fe0;
>  
>  	/* FIXME: in an error condition where the we have
>  	 * an expected number of frontends (attach problem)
> @@ -1651,9 +1700,9 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
>  	 * This comment only applies to future boards IF they
>  	 * implement MFE support.
>  	 */
> -	fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
> +	fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
>  	if (fe0 && fe0->dvb.frontend)
> -		videobuf_dvb_unregister_bus(&port->frontends);
> +		vb2_dvb_unregister_bus(&port->frontends);
>  
>  	switch (port->dev->board) {
>  	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
> diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
> index 1cb67d3..358776e 100644
> --- a/drivers/media/pci/cx23885/cx23885-vbi.c
> +++ b/drivers/media/pci/cx23885/cx23885-vbi.c
> @@ -42,9 +42,8 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
>  /* ------------------------------------------------------------------ */
>  
>  #define VBI_LINE_LENGTH 1440
> -#define NTSC_VBI_START_LINE 10        /* line 10 - 21 */
> -#define NTSC_VBI_END_LINE   21
> -#define NTSC_VBI_LINES      (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1)
> +#define VBI_NTSC_LINE_COUNT 12
> +#define VBI_PAL_LINE_COUNT 18
>  
>  
>  int cx23885_vbi_fmt(struct file *file, void *priv,
> @@ -52,22 +51,23 @@ int cx23885_vbi_fmt(struct file *file, void *priv,
>  {
>  	struct cx23885_dev *dev = video_drvdata(file);
>  
> +	f->fmt.vbi.sampling_rate = 27000000;
> +	f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
> +	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
> +	f->fmt.vbi.offset = 0;
> +	f->fmt.vbi.flags = 0;
>  	if (dev->tvnorm & V4L2_STD_525_60) {
>  		/* ntsc */
> -		f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
> -		f->fmt.vbi.sampling_rate = 27000000;
> -		f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
> -		f->fmt.vbi.offset = 0;
> -		f->fmt.vbi.flags = 0;
>  		f->fmt.vbi.start[0] = 10;
> -		f->fmt.vbi.count[0] = 17;
> -		f->fmt.vbi.start[1] = 263 + 10 + 1;
> -		f->fmt.vbi.count[1] = 17;
> +		f->fmt.vbi.start[1] = 272;
> +		f->fmt.vbi.count[0] = VBI_NTSC_LINE_COUNT;
> +		f->fmt.vbi.count[1] = VBI_NTSC_LINE_COUNT;
>  	} else if (dev->tvnorm & V4L2_STD_625_50) {
>  		/* pal */
> -		f->fmt.vbi.sampling_rate = 35468950;
> -		f->fmt.vbi.start[0] = 7 - 1;
> -		f->fmt.vbi.start[1] = 319 - 1;
> +		f->fmt.vbi.start[0] = 6;
> +		f->fmt.vbi.start[1] = 318;
> +		f->fmt.vbi.count[0] = VBI_PAL_LINE_COUNT;
> +		f->fmt.vbi.count[1] = VBI_PAL_LINE_COUNT;
>  	}
>  
>  	return 0;
> @@ -93,15 +93,6 @@ int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status)
>  		handled++;
>  	}
>  
> -	if (status & VID_BC_MSK_VBI_RISCI2) {
> -		dprintk(1, "%s() VID_BC_MSK_VBI_RISCI2\n", __func__);
> -		dprintk(2, "stopper vbi\n");
> -		spin_lock(&dev->slock);
> -		cx23885_restart_vbi_queue(dev, &dev->vbiq);
> -		spin_unlock(&dev->slock);
> -		handled++;
> -	}
> -
>  	return handled;
>  }
>  
> @@ -113,13 +104,13 @@ static int cx23885_start_vbi_dma(struct cx23885_dev    *dev,
>  
>  	/* setup fifo + format */
>  	cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02],
> -				buf->vb.width, buf->risc.dma);
> +				VBI_LINE_LENGTH, buf->risc.dma);
>  
>  	/* reset counter */
>  	cx_write(VID_A_GPCNT_CTL, 3);
>  	cx_write(VID_A_VBI_CTRL, 3);
>  	cx_write(VBI_A_GPCNT_CTL, 3);
> -	q->count = 1;
> +	q->count = 0;
>  
>  	/* enable irq */
>  	cx23885_irq_add_enable(dev, 0x01);
> @@ -132,163 +123,153 @@ static int cx23885_start_vbi_dma(struct cx23885_dev    *dev,
>  	return 0;
>  }
>  
> +/* ------------------------------------------------------------------ */
>  
> -int cx23885_restart_vbi_queue(struct cx23885_dev    *dev,
> -			     struct cx23885_dmaqueue *q)
> +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
> +			   unsigned int *num_buffers, unsigned int *num_planes,
> +			   unsigned int sizes[], void *alloc_ctxs[])
>  {
> -	struct cx23885_buffer *buf;
> -	struct list_head *item;
> -
> -	if (list_empty(&q->active))
> -		return 0;
> -
> -	buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
> -	dprintk(2, "restart_queue [%p/%d]: restart dma\n",
> -		buf, buf->vb.i);
> -	cx23885_start_vbi_dma(dev, q, buf);
> -	list_for_each(item, &q->active) {
> -		buf = list_entry(item, struct cx23885_buffer, vb.queue);
> -		buf->count = q->count++;
> -	}
> -	mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30));
> +	struct cx23885_dev *dev = q->drv_priv;
> +	unsigned lines = VBI_PAL_LINE_COUNT;
> +
> +	if (dev->tvnorm & V4L2_STD_525_60)
> +		lines = VBI_NTSC_LINE_COUNT;
> +	*num_planes = 1;
> +	sizes[0] = lines * VBI_LINE_LENGTH * 2;
>  	return 0;
>  }
>  
> -void cx23885_vbi_timeout(unsigned long data)
> +static int buffer_prepare(struct vb2_buffer *vb)
>  {
> -	struct cx23885_dev *dev = (struct cx23885_dev *)data;
> -	struct cx23885_dmaqueue *q = &dev->vbiq;
> -	struct cx23885_buffer *buf;
> -	unsigned long flags;
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
> +	struct cx23885_buffer *buf = container_of(vb,
> +		struct cx23885_buffer, vb);
> +	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
> +	unsigned lines = VBI_PAL_LINE_COUNT;
> +	int ret;
>  
> -	/* Stop the VBI engine */
> -	cx_clear(VID_A_DMA_CTL, 0x22);
> +	if (dev->tvnorm & V4L2_STD_525_60)
> +		lines = VBI_NTSC_LINE_COUNT;
>  
> -	spin_lock_irqsave(&dev->slock, flags);
> -	while (!list_empty(&q->active)) {
> -		buf = list_entry(q->active.next, struct cx23885_buffer,
> -			vb.queue);
> -		list_del(&buf->vb.queue);
> -		buf->vb.state = VIDEOBUF_ERROR;
> -		wake_up(&buf->vb.done);
> -		printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->name,
> -		       buf, buf->vb.i, (unsigned long)buf->risc.dma);
> -	}
> -	cx23885_restart_vbi_queue(dev, q);
> -	spin_unlock_irqrestore(&dev->slock, flags);
> -}
> +	if (vb2_plane_size(vb, 0) < lines * VBI_LINE_LENGTH * 2)
> +		return -EINVAL;
> +	vb2_set_plane_payload(vb, 0, lines * VBI_LINE_LENGTH * 2);
>  
> -/* ------------------------------------------------------------------ */
> -#define VBI_LINE_LENGTH 1440
> -#define VBI_LINE_COUNT 17
> +	ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
> +	if (!ret)
> +		return -EIO;
>  
> -static int
> -vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
> -{
> -	*size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
> -	if (0 == *count)
> -		*count = vbibufs;
> -	if (*count < 2)
> -		*count = 2;
> -	if (*count > 32)
> -		*count = 32;
> +	cx23885_risc_vbibuffer(dev->pci, &buf->risc,
> +			 sgt->sgl,
> +			 0, VBI_LINE_LENGTH * lines,
> +			 VBI_LINE_LENGTH, 0,
> +			 lines);
>  	return 0;
>  }
>  
> -static int
> -vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
> -	    enum v4l2_field field)
> +static void buffer_finish(struct vb2_buffer *vb)
>  {
> -	struct cx23885_fh *fh  = q->priv_data;
> -	struct cx23885_dev *dev = fh->q_dev;
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
>  	struct cx23885_buffer *buf = container_of(vb,
>  		struct cx23885_buffer, vb);
> -	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
> -	unsigned int size;
> -	int rc;
> -
> -	size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
> -	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
> -		return -EINVAL;
> +	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
>  
> -	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
> -		buf->vb.width  = VBI_LINE_LENGTH;
> -		buf->vb.height = VBI_LINE_COUNT;
> -		buf->vb.size   = size;
> -		buf->vb.field  = V4L2_FIELD_SEQ_TB;
> -
> -		rc = videobuf_iolock(q, &buf->vb, NULL);
> -		if (0 != rc)
> -			goto fail;
> -		cx23885_risc_vbibuffer(dev->pci, &buf->risc,
> -				 dma->sglist,
> -				 0, buf->vb.width * buf->vb.height,
> -				 buf->vb.width, 0,
> -				 buf->vb.height);
> -	}
> -	buf->vb.state = VIDEOBUF_PREPARED;
> -	return 0;
> +	cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
>  
> - fail:
> -	cx23885_free_buffer(q, buf);
> -	return rc;
> +	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
>  }
>  
> -static void
> -vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
> +/*
> + * The risc program for each buffer works as follows: it starts with a simple
> + * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
> + * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
> + * the initial JUMP).
> + *
> + * This is the risc program of the first buffer to be queued if the active list
> + * is empty and it just keeps DMAing this buffer without generating any
> + * interrupts.
> + *
> + * If a new buffer is added then the initial JUMP in the code for that buffer
> + * will generate an interrupt which signals that the previous buffer has been
> + * DMAed successfully and that it can be returned to userspace.
> + *
> + * It also sets the final jump of the previous buffer to the start of the new
> + * buffer, thus chaining the new buffer into the DMA chain. This is a single
> + * atomic u32 write, so there is no race condition.
> + *
> + * The end-result of all this that you only get an interrupt when a buffer
> + * is ready, so the control flow is very easy.
> + */
> +static void buffer_queue(struct vb2_buffer *vb)
>  {
> -	struct cx23885_buffer   *buf =
> -		container_of(vb, struct cx23885_buffer, vb);
> -	struct cx23885_buffer   *prev;
> -	struct cx23885_fh       *fh   = vq->priv_data;
> -	struct cx23885_dev      *dev  = fh->q_dev;
> -	struct cx23885_dmaqueue *q    = &dev->vbiq;
> -
> -	/* add jump to stopper */
> -	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
> -	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
> +	struct cx23885_buffer *buf = container_of(vb, struct cx23885_buffer, vb);
> +	struct cx23885_buffer *prev;
> +	struct cx23885_dmaqueue *q = &dev->vbiq;
> +	unsigned long flags;
> +
> +	buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
> +	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
> +	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
>  	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
>  
>  	if (list_empty(&q->active)) {
> -		list_add_tail(&buf->vb.queue, &q->active);
> -		cx23885_start_vbi_dma(dev, q, buf);
> -		buf->vb.state = VIDEOBUF_ACTIVE;
> -		buf->count    = q->count++;
> -		mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30));
> +		spin_lock_irqsave(&dev->slock, flags);
> +		list_add_tail(&buf->queue, &q->active);
> +		spin_unlock_irqrestore(&dev->slock, flags);
>  		dprintk(2, "[%p/%d] vbi_queue - first active\n",
> -			buf, buf->vb.i);
> +			buf, buf->vb.v4l2_buf.index);
>  
>  	} else {
> +		buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
>  		prev = list_entry(q->active.prev, struct cx23885_buffer,
> -			vb.queue);
> -		list_add_tail(&buf->vb.queue, &q->active);
> -		buf->vb.state = VIDEOBUF_ACTIVE;
> -		buf->count    = q->count++;
> +			queue);
> +		spin_lock_irqsave(&dev->slock, flags);
> +		list_add_tail(&buf->queue, &q->active);
> +		spin_unlock_irqrestore(&dev->slock, flags);
>  		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
> -		prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63-32 */
>  		dprintk(2, "[%p/%d] buffer_queue - append to active\n",
> -			buf, buf->vb.i);
> +			buf, buf->vb.v4l2_buf.index);
>  	}
>  }
>  
> -static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
> +static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
>  {
> -	struct cx23885_buffer *buf =
> -		container_of(vb, struct cx23885_buffer, vb);
> +	struct cx23885_dev *dev = q->drv_priv;
> +	struct cx23885_dmaqueue *dmaq = &dev->vbiq;
> +	struct cx23885_buffer *buf = list_entry(dmaq->active.next,
> +			struct cx23885_buffer, queue);
>  
> -	cx23885_free_buffer(q, buf);
> +	cx23885_start_vbi_dma(dev, dmaq, buf);
> +	return 0;
>  }
>  
> -struct videobuf_queue_ops cx23885_vbi_qops = {
> -	.buf_setup    = vbi_setup,
> -	.buf_prepare  = vbi_prepare,
> -	.buf_queue    = vbi_queue,
> -	.buf_release  = vbi_release,
> -};
> +static void cx23885_stop_streaming(struct vb2_queue *q)
> +{
> +	struct cx23885_dev *dev = q->drv_priv;
> +	struct cx23885_dmaqueue *dmaq = &dev->vbiq;
> +	unsigned long flags;
>  
> -/* ------------------------------------------------------------------ */
> -/*
> - * Local variables:
> - * c-basic-offset: 8
> - * End:
> - */
> +	cx_clear(VID_A_DMA_CTL, 0x22); /* FIFO and RISC enable */
> +	spin_lock_irqsave(&dev->slock, flags);
> +	while (!list_empty(&dmaq->active)) {
> +		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
> +			struct cx23885_buffer, queue);
> +
> +		list_del(&buf->queue);
> +		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
> +	}
> +	spin_unlock_irqrestore(&dev->slock, flags);
> +}
> +
> +
> +struct vb2_ops cx23885_vbi_qops = {
> +	.queue_setup    = queue_setup,
> +	.buf_prepare  = buffer_prepare,
> +	.buf_finish = buffer_finish,
> +	.buf_queue    = buffer_queue,
> +	.wait_prepare = vb2_ops_wait_prepare,
> +	.wait_finish = vb2_ops_wait_finish,
> +	.start_streaming = cx23885_start_streaming,
> +	.stop_streaming = cx23885_stop_streaming,
> +};
> diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
> index b374003..16fcdfc 100644
> --- a/drivers/media/pci/cx23885/cx23885-video.c
> +++ b/drivers/media/pci/cx23885/cx23885-video.c
> @@ -102,34 +102,18 @@ void cx23885_video_wakeup(struct cx23885_dev *dev,
>  	struct cx23885_dmaqueue *q, u32 count)
>  {
>  	struct cx23885_buffer *buf;
> -	int bc;
> -
> -	for (bc = 0;; bc++) {
> -		if (list_empty(&q->active))
> -			break;
> -		buf = list_entry(q->active.next,
> -				 struct cx23885_buffer, vb.queue);
> -
> -		/* count comes from the hw and is is 16bit wide --
> -		 * this trick handles wrap-arounds correctly for
> -		 * up to 32767 buffers in flight... */
> -		if ((s16) (count - buf->count) < 0)
> -			break;
> -
> -		v4l2_get_timestamp(&buf->vb.ts);
> -		dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i,
> -			count, buf->count);
> -		buf->vb.state = VIDEOBUF_DONE;
> -		list_del(&buf->vb.queue);
> -		wake_up(&buf->vb.done);
> -	}
> +
>  	if (list_empty(&q->active))
> -		del_timer(&q->timeout);
> -	else
> -		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
> -	if (bc != 1)
> -		printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
> -			__func__, bc);
> +		return;
> +	buf = list_entry(q->active.next,
> +			struct cx23885_buffer, queue);
> +
> +	buf->vb.v4l2_buf.sequence = q->count++;
> +	v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
> +	dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.v4l2_buf.index,
> +			count, q->count);
> +	list_del(&buf->queue);
> +	vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
>  }
>  
>  int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
> @@ -167,50 +151,6 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
>  	return vfd;
>  }
>  
> -/* ------------------------------------------------------------------- */
> -/* resource management                                                 */
> -
> -static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh,
> -	unsigned int bit)
> -{
> -	dprintk(1, "%s()\n", __func__);
> -	if (fh->resources & bit)
> -		/* have it already allocated */
> -		return 1;
> -
> -	/* is it free? */
> -	if (dev->resources & bit) {
> -		/* no, someone else uses it */
> -		return 0;
> -	}
> -	/* it's free, grab it */
> -	fh->resources  |= bit;
> -	dev->resources |= bit;
> -	dprintk(1, "res: get %d\n", bit);
> -	return 1;
> -}
> -
> -static int res_check(struct cx23885_fh *fh, unsigned int bit)
> -{
> -	return fh->resources & bit;
> -}
> -
> -static int res_locked(struct cx23885_dev *dev, unsigned int bit)
> -{
> -	return dev->resources & bit;
> -}
> -
> -static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
> -	unsigned int bits)
> -{
> -	BUG_ON((fh->resources & bits) != bits);
> -	dprintk(1, "%s()\n", __func__);
> -
> -	fh->resources  &= ~bits;
> -	dev->resources &= ~bits;
> -	dprintk(1, "res: put %d\n", bits);
> -}
> -
>  int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data)
>  {
>  	/* 8 bit registers, 8 bit values */
> @@ -360,7 +300,7 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev,
>  
>  	/* reset counter */
>  	cx_write(VID_A_GPCNT_CTL, 3);
> -	q->count = 1;
> +	q->count = 0;
>  
>  	/* enable irq */
>  	cx23885_irq_add_enable(dev, 0x01);
> @@ -373,444 +313,206 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev,
>  	return 0;
>  }
>  
> -
> -static int cx23885_restart_video_queue(struct cx23885_dev *dev,
> -			       struct cx23885_dmaqueue *q)
> +static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
> +			   unsigned int *num_buffers, unsigned int *num_planes,
> +			   unsigned int sizes[], void *alloc_ctxs[])
>  {
> -	struct cx23885_buffer *buf, *prev;
> -	struct list_head *item;
> -	dprintk(1, "%s()\n", __func__);
> -
> -	if (!list_empty(&q->active)) {
> -		buf = list_entry(q->active.next, struct cx23885_buffer,
> -			vb.queue);
> -		dprintk(2, "restart_queue [%p/%d]: restart dma\n",
> -			buf, buf->vb.i);
> -		cx23885_start_video_dma(dev, q, buf);
> -		list_for_each(item, &q->active) {
> -			buf = list_entry(item, struct cx23885_buffer,
> -				vb.queue);
> -			buf->count    = q->count++;
> -		}
> -		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
> -		return 0;
> -	}
> +	struct cx23885_dev *dev = q->drv_priv;
>  
> -	prev = NULL;
> -	for (;;) {
> -		if (list_empty(&q->queued))
> -			return 0;
> -		buf = list_entry(q->queued.next, struct cx23885_buffer,
> -			vb.queue);
> -		if (NULL == prev) {
> -			list_move_tail(&buf->vb.queue, &q->active);
> -			cx23885_start_video_dma(dev, q, buf);
> -			buf->vb.state = VIDEOBUF_ACTIVE;
> -			buf->count    = q->count++;
> -			mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
> -			dprintk(2, "[%p/%d] restart_queue - first active\n",
> -				buf, buf->vb.i);
> -
> -		} else if (prev->vb.width  == buf->vb.width  &&
> -			   prev->vb.height == buf->vb.height &&
> -			   prev->fmt       == buf->fmt) {
> -			list_move_tail(&buf->vb.queue, &q->active);
> -			buf->vb.state = VIDEOBUF_ACTIVE;
> -			buf->count    = q->count++;
> -			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
> -			prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
> -			dprintk(2, "[%p/%d] restart_queue - move to active\n",
> -				buf, buf->vb.i);
> -		} else {
> -			return 0;
> -		}
> -		prev = buf;
> -	}
> -}
> -
> -static int buffer_setup(struct videobuf_queue *q, unsigned int *count,
> -	unsigned int *size)
> -{
> -	struct cx23885_fh *fh = q->priv_data;
> -	struct cx23885_dev *dev = fh->q_dev;
> -
> -	*size = (dev->fmt->depth * dev->width * dev->height) >> 3;
> -	if (0 == *count)
> -		*count = 32;
> -	if (*size * *count > vid_limit * 1024 * 1024)
> -		*count = (vid_limit * 1024 * 1024) / *size;
> +	*num_planes = 1;
> +	sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3;
>  	return 0;
>  }
>  
> -static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
> -	       enum v4l2_field field)
> +static int buffer_prepare(struct vb2_buffer *vb)
>  {
> -	struct cx23885_fh *fh  = q->priv_data;
> -	struct cx23885_dev *dev = fh->q_dev;
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
>  	struct cx23885_buffer *buf =
>  		container_of(vb, struct cx23885_buffer, vb);
> -	int rc, init_buffer = 0;
>  	u32 line0_offset, line1_offset;
> -	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
> +	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
>  	int field_tff;
> +	int ret;
>  
> -	if (WARN_ON(NULL == dev->fmt))
> -		return -EINVAL;
> +	buf->bpl = (dev->width * dev->fmt->depth) >> 3;
>  
> -	if (dev->width  < 48 || dev->width  > norm_maxw(dev->tvnorm) ||
> -	    dev->height < 32 || dev->height > norm_maxh(dev->tvnorm))
> -		return -EINVAL;
> -	buf->vb.size = (dev->width * dev->height * dev->fmt->depth) >> 3;
> -	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
> +	if (vb2_plane_size(vb, 0) < dev->height * buf->bpl)
>  		return -EINVAL;
> +	vb2_set_plane_payload(vb, 0, dev->height * buf->bpl);
>  
> -	if (buf->fmt       != dev->fmt    ||
> -	    buf->vb.width  != dev->width  ||
> -	    buf->vb.height != dev->height ||
> -	    buf->vb.field  != field) {
> -		buf->fmt       = dev->fmt;
> -		buf->vb.width  = dev->width;
> -		buf->vb.height = dev->height;
> -		buf->vb.field  = field;
> -		init_buffer = 1;
> -	}
> +	ret = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
> +	if (!ret)
> +		return -EIO;
>  
> -	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
> -		init_buffer = 1;
> -		rc = videobuf_iolock(q, &buf->vb, NULL);
> -		if (0 != rc)
> -			goto fail;
> -	}
> +	switch (dev->field) {
> +	case V4L2_FIELD_TOP:
> +		cx23885_risc_buffer(dev->pci, &buf->risc,
> +				sgt->sgl, 0, UNSET,
> +				buf->bpl, 0, dev->height);
> +		break;
> +	case V4L2_FIELD_BOTTOM:
> +		cx23885_risc_buffer(dev->pci, &buf->risc,
> +				sgt->sgl, UNSET, 0,
> +				buf->bpl, 0, dev->height);
> +		break;
> +	case V4L2_FIELD_INTERLACED:
> +		if (dev->tvnorm & V4L2_STD_NTSC)
> +			/* NTSC or  */
> +			field_tff = 1;
> +		else
> +			field_tff = 0;
> +
> +		if (cx23885_boards[dev->board].force_bff)
> +			/* PAL / SECAM OR 888 in NTSC MODE */
> +			field_tff = 0;
>  
> -	if (init_buffer) {
> -		buf->bpl = buf->vb.width * buf->fmt->depth >> 3;
> -		switch (buf->vb.field) {
> -		case V4L2_FIELD_TOP:
> -			cx23885_risc_buffer(dev->pci, &buf->risc,
> -					 dma->sglist, 0, UNSET,
> -					 buf->bpl, 0, buf->vb.height);
> -			break;
> -		case V4L2_FIELD_BOTTOM:
> -			cx23885_risc_buffer(dev->pci, &buf->risc,
> -					 dma->sglist, UNSET, 0,
> -					 buf->bpl, 0, buf->vb.height);
> -			break;
> -		case V4L2_FIELD_INTERLACED:
> -			if (dev->tvnorm & V4L2_STD_NTSC)
> -				/* NTSC or  */
> -				field_tff = 1;
> -			else
> -				field_tff = 0;
> -
> -			if (cx23885_boards[dev->board].force_bff)
> -				/* PAL / SECAM OR 888 in NTSC MODE */
> -				field_tff = 0;
> -
> -			if (field_tff) {
> -				/* cx25840 transmits NTSC bottom field first */
> -				dprintk(1, "%s() Creating TFF/NTSC risc\n",
> +		if (field_tff) {
> +			/* cx25840 transmits NTSC bottom field first */
> +			dprintk(1, "%s() Creating TFF/NTSC risc\n",
>  					__func__);
> -				line0_offset = buf->bpl;
> -				line1_offset = 0;
> -			} else {
> -				/* All other formats are top field first */
> -				dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n",
> +			line0_offset = buf->bpl;
> +			line1_offset = 0;
> +		} else {
> +			/* All other formats are top field first */
> +			dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n",
>  					__func__);
> -				line0_offset = 0;
> -				line1_offset = buf->bpl;
> -			}
> -			cx23885_risc_buffer(dev->pci, &buf->risc,
> -					dma->sglist, line0_offset,
> -					line1_offset,
> -					buf->bpl, buf->bpl,
> -					buf->vb.height >> 1);
> -			break;
> -		case V4L2_FIELD_SEQ_TB:
> -			cx23885_risc_buffer(dev->pci, &buf->risc,
> -					 dma->sglist,
> -					 0, buf->bpl * (buf->vb.height >> 1),
> -					 buf->bpl, 0,
> -					 buf->vb.height >> 1);
> -			break;
> -		case V4L2_FIELD_SEQ_BT:
> -			cx23885_risc_buffer(dev->pci, &buf->risc,
> -					 dma->sglist,
> -					 buf->bpl * (buf->vb.height >> 1), 0,
> -					 buf->bpl, 0,
> -					 buf->vb.height >> 1);
> -			break;
> -		default:
> -			BUG();
> +			line0_offset = 0;
> +			line1_offset = buf->bpl;
>  		}
> +		cx23885_risc_buffer(dev->pci, &buf->risc,
> +				sgt->sgl, line0_offset,
> +				line1_offset,
> +				buf->bpl, buf->bpl,
> +				dev->height >> 1);
> +		break;
> +	case V4L2_FIELD_SEQ_TB:
> +		cx23885_risc_buffer(dev->pci, &buf->risc,
> +				sgt->sgl,
> +				0, buf->bpl * (dev->height >> 1),
> +				buf->bpl, 0,
> +				dev->height >> 1);
> +		break;
> +	case V4L2_FIELD_SEQ_BT:
> +		cx23885_risc_buffer(dev->pci, &buf->risc,
> +				sgt->sgl,
> +				buf->bpl * (dev->height >> 1), 0,
> +				buf->bpl, 0,
> +				dev->height >> 1);
> +		break;
> +	default:
> +		BUG();
>  	}
> -	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
> -		buf, buf->vb.i,
> +	dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
> +		buf, buf->vb.v4l2_buf.index,
>  		dev->width, dev->height, dev->fmt->depth, dev->fmt->name,
>  		(unsigned long)buf->risc.dma);
> -
> -	buf->vb.state = VIDEOBUF_PREPARED;
>  	return 0;
> +}
>  
> - fail:
> -	cx23885_free_buffer(q, buf);
> -	return rc;
> +static void buffer_finish(struct vb2_buffer *vb)
> +{
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
> +	struct cx23885_buffer *buf = container_of(vb,
> +		struct cx23885_buffer, vb);
> +	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
> +
> +	cx23885_free_buffer(vb->vb2_queue->drv_priv, buf);
> +
> +	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
>  }
>  
> -static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
> +/*
> + * The risc program for each buffer works as follows: it starts with a simple
> + * 'JUMP to addr + 12', which is effectively a NOP. Then the code to DMA the
> + * buffer follows and at the end we have a JUMP back to the start + 12 (skipping
> + * the initial JUMP).
> + *
> + * This is the risc program of the first buffer to be queued if the active list
> + * is empty and it just keeps DMAing this buffer without generating any
> + * interrupts.
> + *
> + * If a new buffer is added then the initial JUMP in the code for that buffer
> + * will generate an interrupt which signals that the previous buffer has been
> + * DMAed successfully and that it can be returned to userspace.
> + *
> + * It also sets the final jump of the previous buffer to the start of the new
> + * buffer, thus chaining the new buffer into the DMA chain. This is a single
> + * atomic u32 write, so there is no race condition.
> + *
> + * The end-result of all this that you only get an interrupt when a buffer
> + * is ready, so the control flow is very easy.
> + */
> +static void buffer_queue(struct vb2_buffer *vb)
>  {
> +	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
>  	struct cx23885_buffer   *buf = container_of(vb,
>  		struct cx23885_buffer, vb);
>  	struct cx23885_buffer   *prev;
> -	struct cx23885_fh       *fh   = vq->priv_data;
> -	struct cx23885_dev      *dev  = fh->q_dev;
>  	struct cx23885_dmaqueue *q    = &dev->vidq;
> +	unsigned long flags;
>  
> -	/* add jump to stopper */
> -	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
> -	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
> +	/* add jump to start */
> +	buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 12);
> +	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
> +	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 12);
>  	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
>  
> -	if (!list_empty(&q->queued)) {
> -		list_add_tail(&buf->vb.queue, &q->queued);
> -		buf->vb.state = VIDEOBUF_QUEUED;
> -		dprintk(2, "[%p/%d] buffer_queue - append to queued\n",
> -			buf, buf->vb.i);
> -
> -	} else if (list_empty(&q->active)) {
> -		list_add_tail(&buf->vb.queue, &q->active);
> -		cx23885_start_video_dma(dev, q, buf);
> -		buf->vb.state = VIDEOBUF_ACTIVE;
> -		buf->count    = q->count++;
> -		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
> +	spin_lock_irqsave(&dev->slock, flags);
> +	if (list_empty(&q->active)) {
> +		list_add_tail(&buf->queue, &q->active);
>  		dprintk(2, "[%p/%d] buffer_queue - first active\n",
> -			buf, buf->vb.i);
> -
> +			buf, buf->vb.v4l2_buf.index);
>  	} else {
> +		buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
>  		prev = list_entry(q->active.prev, struct cx23885_buffer,
> -			vb.queue);
> -		if (prev->vb.width  == buf->vb.width  &&
> -		    prev->vb.height == buf->vb.height &&
> -		    prev->fmt       == buf->fmt) {
> -			list_add_tail(&buf->vb.queue, &q->active);
> -			buf->vb.state = VIDEOBUF_ACTIVE;
> -			buf->count    = q->count++;
> -			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
> -			/* 64 bit bits 63-32 */
> -			prev->risc.jmp[2] = cpu_to_le32(0);
> -			dprintk(2, "[%p/%d] buffer_queue - append to active\n",
> -				buf, buf->vb.i);
> -
> -		} else {
> -			list_add_tail(&buf->vb.queue, &q->queued);
> -			buf->vb.state = VIDEOBUF_QUEUED;
> -			dprintk(2, "[%p/%d] buffer_queue - first queued\n",
> -				buf, buf->vb.i);
> -		}
> -	}
> -}
> -
> -static void buffer_release(struct videobuf_queue *q,
> -	struct videobuf_buffer *vb)
> -{
> -	struct cx23885_buffer *buf = container_of(vb,
> -		struct cx23885_buffer, vb);
> -
> -	cx23885_free_buffer(q, buf);
> -}
> -
> -static struct videobuf_queue_ops cx23885_video_qops = {
> -	.buf_setup    = buffer_setup,
> -	.buf_prepare  = buffer_prepare,
> -	.buf_queue    = buffer_queue,
> -	.buf_release  = buffer_release,
> -};
> -
> -static struct videobuf_queue *get_queue(struct file *file)
> -{
> -	struct video_device *vdev = video_devdata(file);
> -	struct cx23885_fh *fh = file->private_data;
> -
> -	switch (vdev->vfl_type) {
> -	case VFL_TYPE_GRABBER:
> -		return &fh->vidq;
> -	case VFL_TYPE_VBI:
> -		return &fh->vbiq;
> -	default:
> -		WARN_ON(1);
> -		return NULL;
> -	}
> -}
> -
> -static int get_resource(u32 type)
> -{
> -	switch (type) {
> -	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
> -		return RESOURCE_VIDEO;
> -	case V4L2_BUF_TYPE_VBI_CAPTURE:
> -		return RESOURCE_VBI;
> -	default:
> -		WARN_ON(1);
> -		return 0;
> +			queue);
> +		list_add_tail(&buf->queue, &q->active);
> +		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
> +		dprintk(2, "[%p/%d] buffer_queue - append to active\n",
> +				buf, buf->vb.v4l2_buf.index);
>  	}
> +	spin_unlock_irqrestore(&dev->slock, flags);
>  }
>  
> -static int video_open(struct file *file)
> +static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
>  {
> -	struct video_device *vdev = video_devdata(file);
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh;
> -
> -	dprintk(1, "open dev=%s\n",
> -		video_device_node_name(vdev));
> -
> -	/* allocate + initialize per filehandle data */
> -	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
> -	if (NULL == fh)
> -		return -ENOMEM;
> -
> -	v4l2_fh_init(&fh->fh, vdev);
> -	file->private_data = &fh->fh;
> -	fh->q_dev      = dev;
> -
> -	videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops,
> -			    &dev->pci->dev, &dev->slock,
> -			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
> -			    V4L2_FIELD_INTERLACED,
> -			    sizeof(struct cx23885_buffer),
> -			    fh, NULL);
> -
> -	videobuf_queue_sg_init(&fh->vbiq, &cx23885_vbi_qops,
> -		&dev->pci->dev, &dev->slock,
> -		V4L2_BUF_TYPE_VBI_CAPTURE,
> -		V4L2_FIELD_SEQ_TB,
> -		sizeof(struct cx23885_buffer),
> -		fh, NULL);
> -
> -	v4l2_fh_add(&fh->fh);
> -
> -	dprintk(1, "post videobuf_queue_init()\n");
> +	struct cx23885_dev *dev = q->drv_priv;
> +	struct cx23885_dmaqueue *dmaq = &dev->vidq;
> +	struct cx23885_buffer *buf = list_entry(dmaq->active.next,
> +			struct cx23885_buffer, queue);
>  
> +	cx23885_start_video_dma(dev, dmaq, buf);
>  	return 0;
>  }
>  
> -static ssize_t video_read(struct file *file, char __user *data,
> -	size_t count, loff_t *ppos)
> +static void cx23885_stop_streaming(struct vb2_queue *q)
>  {
> -	struct video_device *vdev = video_devdata(file);
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh = file->private_data;
> -
> -	switch (vdev->vfl_type) {
> -	case VFL_TYPE_GRABBER:
> -		if (res_locked(dev, RESOURCE_VIDEO))
> -			return -EBUSY;
> -		return videobuf_read_one(&fh->vidq, data, count, ppos,
> -					 file->f_flags & O_NONBLOCK);
> -	case VFL_TYPE_VBI:
> -		if (!res_get(dev, fh, RESOURCE_VBI))
> -			return -EBUSY;
> -		return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1,
> -					    file->f_flags & O_NONBLOCK);
> -	default:
> -		return -EINVAL;
> -	}
> -}
> -
> -static unsigned int video_poll(struct file *file,
> -	struct poll_table_struct *wait)
> -{
> -	struct video_device *vdev = video_devdata(file);
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh = file->private_data;
> -	struct cx23885_buffer *buf;
> -	unsigned long req_events = poll_requested_events(wait);
> -	unsigned int rc = 0;
> -
> -	if (v4l2_event_pending(&fh->fh))
> -		rc = POLLPRI;
> -	else
> -		poll_wait(file, &fh->fh.wait, wait);
> -	if (!(req_events & (POLLIN | POLLRDNORM)))
> -		return rc;
> -
> -	if (vdev->vfl_type == VFL_TYPE_VBI) {
> -		if (!res_get(dev, fh, RESOURCE_VBI))
> -			return rc | POLLERR;
> -		return rc | videobuf_poll_stream(file, &fh->vbiq, wait);
> -	}
> -
> -	mutex_lock(&fh->vidq.vb_lock);
> -	if (res_check(fh, RESOURCE_VIDEO)) {
> -		/* streaming capture */
> -		if (list_empty(&fh->vidq.stream))
> -			goto done;
> -		buf = list_entry(fh->vidq.stream.next,
> -			struct cx23885_buffer, vb.stream);
> -	} else {
> -		/* read() capture */
> -		buf = (struct cx23885_buffer *)fh->vidq.read_buf;
> -		if (NULL == buf)
> -			goto done;
> -	}
> -	poll_wait(file, &buf->vb.done, wait);
> -	if (buf->vb.state == VIDEOBUF_DONE ||
> -	    buf->vb.state == VIDEOBUF_ERROR)
> -		rc |= POLLIN | POLLRDNORM;
> -done:
> -	mutex_unlock(&fh->vidq.vb_lock);
> -	return rc;
> -}
> -
> -static int video_release(struct file *file)
> -{
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh = file->private_data;
> -
> -	/* turn off overlay */
> -	if (res_check(fh, RESOURCE_OVERLAY)) {
> -		/* FIXME */
> -		res_free(dev, fh, RESOURCE_OVERLAY);
> -	}
> +	struct cx23885_dev *dev = q->drv_priv;
> +	struct cx23885_dmaqueue *dmaq = &dev->vidq;
> +	unsigned long flags;
>  
> -	/* stop video capture */
> -	if (res_check(fh, RESOURCE_VIDEO)) {
> -		videobuf_queue_cancel(&fh->vidq);
> -		res_free(dev, fh, RESOURCE_VIDEO);
> -	}
> -	if (fh->vidq.read_buf) {
> -		buffer_release(&fh->vidq, fh->vidq.read_buf);
> -		kfree(fh->vidq.read_buf);
> -	}
> +	cx_clear(VID_A_DMA_CTL, 0x11);
> +	spin_lock_irqsave(&dev->slock, flags);
> +	while (!list_empty(&dmaq->active)) {
> +		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
> +			struct cx23885_buffer, queue);
>  
> -	/* stop vbi capture */
> -	if (res_check(fh, RESOURCE_VBI)) {
> -		if (fh->vbiq.streaming)
> -			videobuf_streamoff(&fh->vbiq);
> -		if (fh->vbiq.reading)
> -			videobuf_read_stop(&fh->vbiq);
> -		res_free(dev, fh, RESOURCE_VBI);
> +		list_del(&buf->queue);
> +		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
>  	}
> -
> -	videobuf_mmap_free(&fh->vidq);
> -	videobuf_mmap_free(&fh->vbiq);
> -
> -	v4l2_fh_del(&fh->fh);
> -	v4l2_fh_exit(&fh->fh);
> -	file->private_data = NULL;
> -	kfree(fh);
> -
> -	/* We are not putting the tuner to sleep here on exit, because
> -	 * we want to use the mpeg encoder in another session to capture
> -	 * tuner video. Closing this will result in no video to the encoder.
> -	 */
> -
> -	return 0;
> +	spin_unlock_irqrestore(&dev->slock, flags);
>  }
>  
> -static int video_mmap(struct file *file, struct vm_area_struct *vma)
> -{
> -	return videobuf_mmap_mapper(get_queue(file), vma);
> -}
> +static struct vb2_ops cx23885_video_qops = {
> +	.queue_setup    = queue_setup,
> +	.buf_prepare  = buffer_prepare,
> +	.buf_finish = buffer_finish,
> +	.buf_queue    = buffer_queue,
> +	.wait_prepare = vb2_ops_wait_prepare,
> +	.wait_finish = vb2_ops_wait_finish,
> +	.start_streaming = cx23885_start_streaming,
> +	.stop_streaming = cx23885_stop_streaming,
> +};
>  
>  /* ------------------------------------------------------------------ */
>  /* VIDEO IOCTLS                                                       */
> @@ -819,11 +521,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
>  	struct v4l2_format *f)
>  {
>  	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh   = priv;
>  
>  	f->fmt.pix.width        = dev->width;
>  	f->fmt.pix.height       = dev->height;
> -	f->fmt.pix.field        = fh->vidq.field;
> +	f->fmt.pix.field        = dev->field;
>  	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
>  	f->fmt.pix.bytesperline =
>  		(f->fmt.pix.width * dev->fmt->depth) >> 3;
> @@ -884,7 +585,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
>  	struct v4l2_format *f)
>  {
>  	struct cx23885_dev *dev = video_drvdata(file);
> -	struct cx23885_fh *fh = priv;
>  	struct v4l2_mbus_framefmt mbus_fmt;
>  	int err;
>  
> @@ -896,9 +596,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
>  	dev->fmt        = format_by_fourcc(f->fmt.pix.pixelformat);
>  	dev->width      = f->fmt.pix.width;
>  	dev->height     = f->fmt.pix.height;
> -	fh->vidq.field = f->fmt.pix.field;
> +	dev->field	= f->fmt.pix.field;
>  	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
> -		dev->width, dev->height, fh->vidq.field);
> +		dev->width, dev->height, dev->field);
>  	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
>  	call_all(dev, video, s_mbus_fmt, &mbus_fmt);
>  	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
> @@ -940,82 +640,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
>  	return 0;
>  }
>  
> -static int vidioc_reqbufs(struct file *file, void *priv,
> -	struct v4l2_requestbuffers *p)
> -{
> -	return videobuf_reqbufs(get_queue(file), p);
> -}
> -
> -static int vidioc_querybuf(struct file *file, void *priv,
> -	struct v4l2_buffer *p)
> -{
> -	return videobuf_querybuf(get_queue(file), p);
> -}
> -
> -static int vidioc_qbuf(struct file *file, void *priv,
> -	struct v4l2_buffer *p)
> -{
> -	return videobuf_qbuf(get_queue(file), p);
> -}
> -
> -static int vidioc_dqbuf(struct file *file, void *priv,
> -	struct v4l2_buffer *p)
> -{
> -	return videobuf_dqbuf(get_queue(file), p,
> -				file->f_flags & O_NONBLOCK);
> -}
> -
> -static int vidioc_streamon(struct file *file, void *priv,
> -	enum v4l2_buf_type i)
> -{
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct video_device *vdev = video_devdata(file);
> -	struct cx23885_fh *fh = priv;
> -	dprintk(1, "%s()\n", __func__);
> -
> -	if (vdev->vfl_type == VFL_TYPE_VBI &&
> -	    i != V4L2_BUF_TYPE_VBI_CAPTURE)
> -		return -EINVAL;
> -	if (vdev->vfl_type == VFL_TYPE_GRABBER &&
> -	    i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> -		return -EINVAL;
> -
> -	if (unlikely(!res_get(dev, fh, get_resource(i))))
> -		return -EBUSY;
> -
> -	/* Don't start VBI streaming unless vida streaming
> -	 * has already started.
> -	 */
> -	if ((i == V4L2_BUF_TYPE_VBI_CAPTURE) &&
> -		((cx_read(VID_A_DMA_CTL) & 0x11) == 0))
> -		return -EINVAL;
> -
> -	return videobuf_streamon(get_queue(file));
> -}
> -
> -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
> -{
> -	struct cx23885_dev *dev = video_drvdata(file);
> -	struct video_device *vdev = video_devdata(file);
> -	struct cx23885_fh *fh = priv;
> -	int err, res;
> -	dprintk(1, "%s()\n", __func__);
> -
> -	if (vdev->vfl_type == VFL_TYPE_VBI &&
> -	    i != V4L2_BUF_TYPE_VBI_CAPTURE)
> -		return -EINVAL;
> -	if (vdev->vfl_type == VFL_TYPE_GRABBER &&
> -	    i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> -		return -EINVAL;
> -
> -	res = get_resource(i);
> -	err = videobuf_streamoff(get_queue(file));
> -	if (err < 0)
> -		return err;
> -	res_free(dev, fh, res);
> -	return 0;
> -}
> -
>  static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
>  {
>  	struct cx23885_dev *dev = video_drvdata(file);
> @@ -1292,7 +916,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
>  {
>  	struct v4l2_ctrl *mute;
>  	int old_mute_val = 1;
> -	struct videobuf_dvb_frontend *vfe;
> +	struct vb2_dvb_frontend *vfe;
>  	struct dvb_frontend *fe;
>  
>  	struct analog_parameters params = {
> @@ -1316,7 +940,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
>  	dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__,
>  		params.frequency, f->tuner, params.std);
>  
> -	vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1);
> +	vfe = vb2_dvb_get_frontend(&dev->ts2.frontends, 1);
>  	if (!vfe) {
>  		return -EINVAL;
>  	}
> @@ -1372,28 +996,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
>  
>  /* ----------------------------------------------------------- */
>  
> -static void cx23885_vid_timeout(unsigned long data)
> -{
> -	struct cx23885_dev *dev = (struct cx23885_dev *)data;
> -	struct cx23885_dmaqueue *q = &dev->vidq;
> -	struct cx23885_buffer *buf;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&dev->slock, flags);
> -	while (!list_empty(&q->active)) {
> -		buf = list_entry(q->active.next,
> -			struct cx23885_buffer, vb.queue);
> -		list_del(&buf->vb.queue);
> -		buf->vb.state = VIDEOBUF_ERROR;
> -		wake_up(&buf->vb.done);
> -		printk(KERN_ERR "%s: [%p/%d] timeout - dma=0x%08lx\n",
> -			dev->name, buf, buf->vb.i,
> -			(unsigned long)buf->risc.dma);
> -	}
> -	cx23885_restart_video_queue(dev, q);
> -	spin_unlock_irqrestore(&dev->slock, flags);
> -}
> -
>  int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
>  {
>  	u32 mask, count;
> @@ -1438,13 +1040,6 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
>  		spin_unlock(&dev->slock);
>  		handled++;
>  	}
> -	if (status & VID_BC_MSK_RISCI2) {
> -		dprintk(2, "stopper video\n");
> -		spin_lock(&dev->slock);
> -		cx23885_restart_video_queue(dev, &dev->vidq);
> -		spin_unlock(&dev->slock);
> -		handled++;
> -	}
>  
>  	/* Allow the VBI framework to process it's payload */
>  	handled += cx23885_vbi_irq(dev, status);
> @@ -1457,12 +1052,12 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status)
>  
>  static const struct v4l2_file_operations video_fops = {
>  	.owner	       = THIS_MODULE,
> -	.open	       = video_open,
> -	.release       = video_release,
> -	.read	       = video_read,
> -	.poll          = video_poll,
> -	.mmap	       = video_mmap,
> +	.open           = v4l2_fh_open,
> +	.release        = vb2_fop_release,
> +	.read           = vb2_fop_read,
> +	.poll		= vb2_fop_poll,
>  	.unlocked_ioctl = video_ioctl2,
> +	.mmap           = vb2_fop_mmap,
>  };
>  
>  static const struct v4l2_ioctl_ops video_ioctl_ops = {
> @@ -1474,18 +1069,19 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
>  	.vidioc_g_fmt_vbi_cap     = cx23885_vbi_fmt,
>  	.vidioc_try_fmt_vbi_cap   = cx23885_vbi_fmt,
>  	.vidioc_s_fmt_vbi_cap     = cx23885_vbi_fmt,
> -	.vidioc_reqbufs       = vidioc_reqbufs,
> -	.vidioc_querybuf      = vidioc_querybuf,
> -	.vidioc_qbuf          = vidioc_qbuf,
> -	.vidioc_dqbuf         = vidioc_dqbuf,
> +	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
> +	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
> +	.vidioc_querybuf      = vb2_ioctl_querybuf,
> +	.vidioc_qbuf          = vb2_ioctl_qbuf,
> +	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
> +	.vidioc_streamon      = vb2_ioctl_streamon,
> +	.vidioc_streamoff     = vb2_ioctl_streamoff,
>  	.vidioc_s_std         = vidioc_s_std,
>  	.vidioc_g_std         = vidioc_g_std,
>  	.vidioc_enum_input    = vidioc_enum_input,
>  	.vidioc_g_input       = vidioc_g_input,
>  	.vidioc_s_input       = vidioc_s_input,
>  	.vidioc_log_status    = vidioc_log_status,
> -	.vidioc_streamon      = vidioc_streamon,
> -	.vidioc_streamoff     = vidioc_streamoff,
>  	.vidioc_g_tuner       = vidioc_g_tuner,
>  	.vidioc_s_tuner       = vidioc_s_tuner,
>  	.vidioc_g_frequency   = vidioc_g_frequency,
> @@ -1521,7 +1117,6 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
>  		else
>  			video_device_release(dev->vbi_dev);
>  		dev->vbi_dev = NULL;
> -		btcx_riscmem_free(dev->pci, &dev->vbiq.stopper);
>  	}
>  	if (dev->video_dev) {
>  		if (video_is_registered(dev->video_dev))
> @@ -1529,8 +1124,6 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
>  		else
>  			video_device_release(dev->video_dev);
>  		dev->video_dev = NULL;
> -
> -		btcx_riscmem_free(dev->pci, &dev->vidq.stopper);
>  	}
>  
>  	if (dev->audio_dev)
> @@ -1539,6 +1132,7 @@ void cx23885_video_unregister(struct cx23885_dev *dev)
>  
>  int cx23885_video_register(struct cx23885_dev *dev)
>  {
> +	struct vb2_queue *q;
>  	int err;
>  
>  	dprintk(1, "%s()\n", __func__);
> @@ -1555,21 +1149,9 @@ int cx23885_video_register(struct cx23885_dev *dev)
>  
>  	/* init video dma queues */
>  	INIT_LIST_HEAD(&dev->vidq.active);
> -	INIT_LIST_HEAD(&dev->vidq.queued);
> -	dev->vidq.timeout.function = cx23885_vid_timeout;
> -	dev->vidq.timeout.data = (unsigned long)dev;
> -	init_timer(&dev->vidq.timeout);
> -	cx23885_risc_stopper(dev->pci, &dev->vidq.stopper,
> -		VID_A_DMA_CTL, 0x11, 0x00);
>  
>  	/* init vbi dma queues */
>  	INIT_LIST_HEAD(&dev->vbiq.active);
> -	INIT_LIST_HEAD(&dev->vbiq.queued);
> -	dev->vbiq.timeout.function = cx23885_vbi_timeout;
> -	dev->vbiq.timeout.data = (unsigned long)dev;
> -	init_timer(&dev->vbiq.timeout);
> -	cx23885_risc_stopper(dev->pci, &dev->vbiq.stopper,
> -		VID_A_DMA_CTL, 0x22, 0x00);
>  
>  	cx23885_irq_add_enable(dev, 0x01);
>  
> @@ -1630,9 +1212,42 @@ int cx23885_video_register(struct cx23885_dev *dev)
>  	cx23885_audio_mux(dev, 0);
>  	mutex_unlock(&dev->lock);
>  
> +	q = &dev->vb2_vidq;
> +	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> +	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
> +	q->gfp_flags = GFP_DMA32;
> +	q->min_buffers_needed = 2;
> +	q->drv_priv = dev;
> +	q->buf_struct_size = sizeof(struct cx23885_buffer);
> +	q->ops = &cx23885_video_qops;
> +	q->mem_ops = &vb2_dma_sg_memops;
> +	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> +	q->lock = &dev->lock;
> +
> +	err = vb2_queue_init(q);
> +	if (err < 0)
> +		goto fail_unreg;
> +
> +	q = &dev->vb2_vbiq;
> +	q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
> +	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
> +	q->gfp_flags = GFP_DMA32;
> +	q->min_buffers_needed = 2;
> +	q->drv_priv = dev;
> +	q->buf_struct_size = sizeof(struct cx23885_buffer);
> +	q->ops = &cx23885_vbi_qops;
> +	q->mem_ops = &vb2_dma_sg_memops;
> +	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> +	q->lock = &dev->lock;
> +
> +	err = vb2_queue_init(q);
> +	if (err < 0)
> +		goto fail_unreg;
> +
>  	/* register Video device */
>  	dev->video_dev = cx23885_vdev_init(dev, dev->pci,
>  		&cx23885_video_template, "video");
> +	dev->video_dev->queue = &dev->vb2_vidq;
>  	err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,
>  				    video_nr[dev->nr]);
>  	if (err < 0) {
> @@ -1646,6 +1261,7 @@ int cx23885_video_register(struct cx23885_dev *dev)
>  	/* register VBI device */
>  	dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
>  		&cx23885_vbi_template, "vbi");
> +	dev->vbi_dev->queue = &dev->vb2_vbiq;
>  	err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
>  				    vbi_nr[dev->nr]);
>  	if (err < 0) {
> diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
> index 95f8c42..99a5fe0 100644
> --- a/drivers/media/pci/cx23885/cx23885.h
> +++ b/drivers/media/pci/cx23885/cx23885.h
> @@ -29,8 +29,8 @@
>  #include <media/v4l2-ctrls.h>
>  #include <media/tuner.h>
>  #include <media/tveeprom.h>
> -#include <media/videobuf-dma-sg.h>
> -#include <media/videobuf-dvb.h>
> +#include <media/videobuf2-dma-sg.h>
> +#include <media/videobuf2-dvb.h>
>  #include <media/rc-core.h>
>  
>  #include "btcx-risc.h"
> @@ -39,7 +39,7 @@
>  
>  #include <linux/mutex.h>
>  
> -#define CX23885_VERSION "0.0.3"
> +#define CX23885_VERSION "0.0.4"
>  
>  #define UNSET (-1U)
>  
> @@ -48,9 +48,6 @@
>  /* Max number of inputs by card */
>  #define MAX_CX23885_INPUT 8
>  #define INPUT(nr) (&cx23885_boards[dev->board].input[nr])
> -#define RESOURCE_OVERLAY       1
> -#define RESOURCE_VIDEO         2
> -#define RESOURCE_VBI           4
>  
>  #define BUFFER_TIMEOUT     (HZ)  /* 0.5 seconds */
>  
> @@ -140,20 +137,6 @@ struct cx23885_tvnorm {
>  	u32		cxoformat;
>  };
>  
> -struct cx23885_fh {
> -	struct v4l2_fh		   fh;
> -	u32                        resources;
> -	struct cx23885_dev         *q_dev;
> -
> -	/* vbi capture */
> -	struct videobuf_queue      vidq;
> -	struct videobuf_queue      vbiq;
> -
> -	/* MPEG Encoder specifics ONLY */
> -	struct videobuf_queue      mpegq;
> -	atomic_t                   v4l_reading;
> -};
> -
>  enum cx23885_itype {
>  	CX23885_VMUX_COMPOSITE1 = 1,
>  	CX23885_VMUX_COMPOSITE2,
> @@ -176,7 +159,8 @@ enum cx23885_src_sel_type {
>  /* buffer for one video frame */
>  struct cx23885_buffer {
>  	/* common v4l buffer stuff -- must be first */
> -	struct videobuf_buffer vb;
> +	struct vb2_buffer vb;
> +	struct list_head queue;
>  
>  	/* cx23885 specific */
>  	unsigned int           bpl;
> @@ -252,9 +236,6 @@ struct cx23885_i2c {
>  
>  struct cx23885_dmaqueue {
>  	struct list_head       active;
> -	struct list_head       queued;
> -	struct timer_list      timeout;
> -	struct btcx_riscmem    stopper;
>  	u32                    count;
>  };
>  
> @@ -264,7 +245,7 @@ struct cx23885_tsport {
>  	int                        nr;
>  	int                        sram_chno;
>  
> -	struct videobuf_dvb_frontends frontends;
> +	struct vb2_dvb_frontends   frontends;
>  
>  	/* dma queues */
>  	struct cx23885_dmaqueue    mpegq;
> @@ -393,7 +374,6 @@ struct cx23885_dev {
>  	} bridge;
>  
>  	/* Analog video */
> -	u32                        resources;
>  	unsigned int               input;
>  	unsigned int               audinput; /* Selectable audio input */
>  	u32                        tvaudio;
> @@ -424,16 +404,20 @@ struct cx23885_dev {
>  	/* video capture */
>  	struct cx23885_fmt         *fmt;
>  	unsigned int               width, height;
> +	unsigned		   field;
>  
>  	struct cx23885_dmaqueue    vidq;
> +	struct vb2_queue           vb2_vidq;
>  	struct cx23885_dmaqueue    vbiq;
> +	struct vb2_queue           vb2_vbiq;
> +
>  	spinlock_t                 slock;
>  
>  	/* MPEG Encoder ONLY settings */
>  	u32                        cx23417_mailbox;
>  	struct cx2341x_handler     cxhdl;
>  	struct video_device        *v4l_device;
> -	atomic_t                   v4l_reader_count;
> +	struct vb2_queue           vb2_mpegq;
>  	struct cx23885_tvnorm      encodernorm;
>  
>  	/* Analog raw audio */
> @@ -509,9 +493,6 @@ extern int cx23885_sram_channel_setup(struct cx23885_dev *dev,
>  extern void cx23885_sram_channel_dump(struct cx23885_dev *dev,
>  	struct sram_channel *ch);
>  
> -extern int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
> -	u32 reg, u32 mask, u32 value);
> -
>  extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>  	struct scatterlist *sglist,
>  	unsigned int top_offset, unsigned int bottom_offset,
> @@ -522,13 +503,11 @@ extern int cx23885_risc_vbibuffer(struct pci_dev *pci,
>  	unsigned int top_offset, unsigned int bottom_offset,
>  	unsigned int bpl, unsigned int padding, unsigned int lines);
>  
> +int cx23885_start_dma(struct cx23885_tsport *port,
> +			     struct cx23885_dmaqueue *q,
> +			     struct cx23885_buffer   *buf);
>  void cx23885_cancel_buffers(struct cx23885_tsport *port);
>  
> -extern int cx23885_restart_queue(struct cx23885_tsport *port,
> -				struct cx23885_dmaqueue *q);
> -
> -extern void cx23885_wakeup(struct cx23885_tsport *port,
> -			   struct cx23885_dmaqueue *q, u32 count);
>  
>  extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
>  extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
> @@ -562,13 +541,11 @@ extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
>  extern int cx23885_dvb_register(struct cx23885_tsport *port);
>  extern int cx23885_dvb_unregister(struct cx23885_tsport *port);
>  
> -extern int cx23885_buf_prepare(struct videobuf_queue *q,
> -			       struct cx23885_tsport *port,
> -			       struct cx23885_buffer *buf,
> -			       enum v4l2_field field);
> +extern int cx23885_buf_prepare(struct cx23885_buffer *buf,
> +			       struct cx23885_tsport *port);
>  extern void cx23885_buf_queue(struct cx23885_tsport *port,
>  			      struct cx23885_buffer *buf);
> -extern void cx23885_free_buffer(struct videobuf_queue *q,
> +extern void cx23885_free_buffer(struct cx23885_dev *dev,
>  				struct cx23885_buffer *buf);
>  
>  /* ----------------------------------------------------------- */
> @@ -590,9 +567,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm);
>  extern int cx23885_vbi_fmt(struct file *file, void *priv,
>  	struct v4l2_format *f);
>  extern void cx23885_vbi_timeout(unsigned long data);
> -extern struct videobuf_queue_ops cx23885_vbi_qops;
> -extern int cx23885_restart_vbi_queue(struct cx23885_dev *dev,
> -	struct cx23885_dmaqueue *q);
> +extern struct vb2_ops cx23885_vbi_qops;
>  extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status);
>  
>  /* cx23885-i2c.c                                                */

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCHv2 17/20] cx23885: fix weird sizes.
  2014-08-14  9:54 ` [PATCHv2 17/20] cx23885: fix weird sizes Hans Verkuil
@ 2014-09-03 11:46   ` Mauro Carvalho Chehab
  2014-09-03 12:07     ` Hans Verkuil
  0 siblings, 1 reply; 28+ messages in thread
From: Mauro Carvalho Chehab @ 2014-09-03 11:46 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, stoth, Hans Verkuil

Em Thu, 14 Aug 2014 11:54:02 +0200
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> These values make no sense. All SDTV standards have the same width.
> This seems to be copied from the cx88 driver. Just drop these weird
> values.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/media/pci/cx23885/cx23885.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
> index 99a5fe0..f542ced 100644
> --- a/drivers/media/pci/cx23885/cx23885.h
> +++ b/drivers/media/pci/cx23885/cx23885.h
> @@ -610,15 +610,15 @@ extern int cx23885_risc_databuffer(struct pci_dev *pci,
>  
>  static inline unsigned int norm_maxw(v4l2_std_id norm)
>  {
> -	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
> +	return 720;

Not sure if you checked cx23885 datasheet. I didn't, but I don't doubt
that it uses about the same A/D logic as cx88.

In the case of cx88, the sampling rate for a few standards is different,
as recommended at the datasheet. This is done to provide the highest
image quality, as there are some customized filters for some standards,
but they require some specific sampling rates. That's why PAL-Nc and
NTSC/PAL-M are handled on a different way.

>  }
>  
>  static inline unsigned int norm_maxh(v4l2_std_id norm)
>  {
> -	return (norm & V4L2_STD_625_50) ? 576 : 480;
> +	return (norm & V4L2_STD_525_60) ? 480 : 576;

This is obviously wrong.

>  }
>  
>  static inline unsigned int norm_swidth(v4l2_std_id norm)
>  {
> -	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
> +	return 754;
>  }

Same as above commented.

Regards,
Mauro

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCHv2 15/20] cx23885: convert to vb2
  2014-09-03 11:32   ` Mauro Carvalho Chehab
@ 2014-09-03 11:57     ` Hans Verkuil
  2014-09-03 12:17       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 28+ messages in thread
From: Hans Verkuil @ 2014-09-03 11:57 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Hans Verkuil; +Cc: linux-media, stoth, Hans Verkuil

Hi Mauro,

On 09/03/14 13:32, Mauro Carvalho Chehab wrote:
> Em Thu, 14 Aug 2014 11:54:00 +0200
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> 
>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>
>> As usual, this patch is very large due to the fact that half a vb2 conversion
>> isn't possible. And since this affects 417, alsa, core, dvb, vbi and video the
>> changes are all over.
>>
>> What made this more difficult was the peculiar way the risc program was setup.
>> The driver allowed for running out of buffers in which case the DMA would stop
>> and restart when the next buffer was queued. There was also a complicated
>> timeout system for when buffers weren't filled. This was replaced by a much
>> simpler scheme where there is always one buffer around and the DMA will just
>> cycle that buffer until a new buffer is queued. In that case the previous
>> buffer will be chained to the new buffer. An interrupt is generated at the
>> start of the new buffer telling the driver that the previous buffer can be
>> passed on to userspace.
>>
>> Much simpler and more robust. The old code seems to be copied from the
>> cx88 driver. But it didn't fit the vb2 ops very well and replacing it with
>> the new scheme made the code easier to understand. Not to mention that this
>> patch removes 600 lines of code.
> 
> Great job!

Thank you.

> Still, there are some issue. In special, the RISC changes should go
> to a separate patch, as such changes have the potential of causing
> some regressions. See below.

I tried (I mentioned that in my git pull request), but I was not able
to separate the two. I couldn't make the risc changes to work with vb1,
and the reverse would be equally painful. Not only that, but I would
have to test this twice (once with just the risc changes or vb2 changes,
and again when both are in place).

I can try to do the vb2 conversion first and the risc changes second, but
this too might be too complicated to get to work.

<snip>

>> @@ -1320,7 +1373,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
>>  				struct v4l2_format *f)
>>  {
>>  	struct cx23885_dev *dev = video_drvdata(file);
>> -	struct cx23885_fh  *fh  = file->private_data;
>>  
>>  	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
>>  	f->fmt.pix.bytesperline = 0;
>> @@ -1329,9 +1381,9 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
>>  	f->fmt.pix.colorspace   = 0;
>>  	f->fmt.pix.width        = dev->ts1.width;
>>  	f->fmt.pix.height       = dev->ts1.height;
>> -	f->fmt.pix.field        = fh->mpegq.field;
>> -	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
>> -		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
>> +	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
> 
> Why? There are other supported formats, right?

Not for the compressed video node. Only MPEG is supported there.

> 
>> +	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
>> +		dev->ts1.width, dev->ts1.height);
>>  	return 0;
>>  }
>>  
>> @@ -1339,15 +1391,15 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
>>  				struct v4l2_format *f)
>>  {
>>  	struct cx23885_dev *dev = video_drvdata(file);
>> -	struct cx23885_fh  *fh  = file->private_data;
>>  
>>  	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
>>  	f->fmt.pix.bytesperline = 0;
>>  	f->fmt.pix.sizeimage    =
>>  		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
>>  	f->fmt.pix.colorspace   = 0;
>> -	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
>> -		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
>> +	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
> 
> Why? There are other supported formats, right?

Ditto.

> 
>> +	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
>> +		dev->ts1.width, dev->ts1.height);
>>  	return 0;
>>  }
>>  

<snip>

>>  
>>  int cx23885_sram_channel_setup(struct cx23885_dev *dev,
>> @@ -482,8 +466,8 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
>>  		lines = 6;
>>  	BUG_ON(lines < 2);
>>  
>> -	cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
>> -	cx_write(8 + 4, 8);
>> +	cx_write(8 + 0, RISC_JUMP | RISC_CNT_RESET);
>> +	cx_write(8 + 4, 12);
> 
> The above doesn't sound as being a pure vb2 conversion, and might cause
> regressions, as we're changing the channel setups. I would very much
> prefer to have such changes on a separate changeset, as it makes easier
> to do bisect if ever needed.

See my comment at the top.

> 
>>  	cx_write(8 + 8, 0);
>>  
>>  	/* write CDT */
>> @@ -699,10 +683,6 @@ static int get_resources(struct cx23885_dev *dev)
>>  	return -EBUSY;
>>  }
>>  
>> -static void cx23885_timeout(unsigned long data);
>> -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
>> -				u32 reg, u32 mask, u32 value);
>> -
>>  static int cx23885_init_tsport(struct cx23885_dev *dev,
>>  	struct cx23885_tsport *port, int portno)
>>  {
>> @@ -719,11 +699,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
>>  	port->nr = portno;
>>  
>>  	INIT_LIST_HEAD(&port->mpegq.active);
>> -	INIT_LIST_HEAD(&port->mpegq.queued);
>> -	port->mpegq.timeout.function = cx23885_timeout;
>> -	port->mpegq.timeout.data = (unsigned long)port;
>> -	init_timer(&port->mpegq.timeout);
>> -
>>  	mutex_init(&port->frontends.lock);
>>  	INIT_LIST_HEAD(&port->frontends.felist);
>>  	port->frontends.active_fe_id = 0;
>> @@ -776,9 +751,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
>>  		BUG();
>>  	}
>>  
>> -	cx23885_risc_stopper(dev->pci, &port->mpegq.stopper,
>> -		     port->reg_dma_ctl, port->dma_ctl_val, 0x00);
>> -
>>  	return 0;
>>  }
>>  
>> @@ -1089,11 +1061,18 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
>>  static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
>>  			       unsigned int offset, u32 sync_line,
>>  			       unsigned int bpl, unsigned int padding,
>> -			       unsigned int lines,  unsigned int lpi)
>> +			       unsigned int lines,  unsigned int lpi, bool jump)
>>  {
>>  	struct scatterlist *sg;
>>  	unsigned int line, todo, sol;
>>  
>> +
>> +	if (jump) {
>> +		*(rp++) = cpu_to_le32(RISC_JUMP);
>> +		*(rp++) = cpu_to_le32(0);
>> +		*(rp++) = cpu_to_le32(0); /* bits 63-32 */
>> +	}
>> +
> 
> Here it seem clear: you're now adding a code to support different
> frame interlacing layouts, but the best is to have such changes on
> a separate changeset, as this is one thing that we may have troubles
> in the future.
> 
> The way I see is that we might start having a flood of complains about
> regressions, and all of them will point to this single patch, making
> really hard to identify what part of the change broke it.
> 
> So, let's split those risc changes on a pre (or post) patch, making
> easier if someone needs to report an issue, for us to track what
> patch broke it.
> 
>>  	/* sync instruction */
>>  	if (sync_line != NO_SYNC_LINE)
>>  		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
>> @@ -1168,7 +1147,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>>  	/* write and jump need and extra dword */
>>  	instructions  = fields * (1 + ((bpl + padding) * lines)
>>  		/ PAGE_SIZE + lines);
>> -	instructions += 2;
>> +	instructions += 5;
>>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
>>  	if (rc < 0)
>>  		return rc;
>> @@ -1177,10 +1156,10 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>>  	rp = risc->cpu;
>>  	if (UNSET != top_offset)
>>  		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
>> -					bpl, padding, lines, 0);
>> +					bpl, padding, lines, 0, true);
>>  	if (UNSET != bottom_offset)
>>  		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
>> -					bpl, padding, lines, 0);
>> +					bpl, padding, lines, 0, UNSET == top_offset);
>>  
>>  	/* save pointer to jmp instruction address */
>>  	risc->jmp = rp;
>> @@ -1204,7 +1183,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
>>  	   than PAGE_SIZE */
>>  	/* Jump and write need an extra dword */
>>  	instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
>> -	instructions += 1;
>> +	instructions += 4;
>>  
>>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
>>  	if (rc < 0)
>> @@ -1213,7 +1192,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
>>  	/* write risc instructions */
>>  	rp = risc->cpu;
>>  	rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE,
>> -				bpl, 0, lines, lpi);
>> +				bpl, 0, lines, lpi, lpi == 0);
>>  
>>  	/* save pointer to jmp instruction address */
>>  	risc->jmp = rp;
>> @@ -1243,7 +1222,7 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>>  	/* write and jump need and extra dword */
>>  	instructions  = fields * (1 + ((bpl + padding) * lines)
>>  		/ PAGE_SIZE + lines);
>> -	instructions += 2;
>> +	instructions += 5;
>>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
>>  	if (rc < 0)
>>  		return rc;
>> @@ -1253,12 +1232,12 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>>  	/* Sync to line 6, so US CC line 21 will appear in line '12'
>>  	 * in the userland vbi payload */
>>  	if (UNSET != top_offset)
>> -		rp = cx23885_risc_field(rp, sglist, top_offset, 6,
>> -					bpl, padding, lines, 0);
>> +		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
>> +					bpl, padding, lines, 0, true);
>>  
>>  	if (UNSET != bottom_offset)
>> -		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207,
>> -					bpl, padding, lines, 0);
>> +		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
>> +					bpl, padding, lines, 0, UNSET == top_offset);
> 
> Why to change the 4th argument of cx23885_risc_field() call?

This was a bug. Hmm, perhaps that should be moved to a separate patch.
The VBI offset was wrong without this.

> 
>>  
>>  
>>  
>> @@ -1269,38 +1248,10 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
>>  }
>>  
>>  
>> -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
>> -				u32 reg, u32 mask, u32 value)
> 
> What happened with this function?

No longer needed after the risc changes.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCHv2 17/20] cx23885: fix weird sizes.
  2014-09-03 11:46   ` Mauro Carvalho Chehab
@ 2014-09-03 12:07     ` Hans Verkuil
  2014-09-03 12:16       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 28+ messages in thread
From: Hans Verkuil @ 2014-09-03 12:07 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media, stoth, Hans Verkuil

On 09/03/14 13:46, Mauro Carvalho Chehab wrote:
> Em Thu, 14 Aug 2014 11:54:02 +0200
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> 
>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>
>> These values make no sense. All SDTV standards have the same width.
>> This seems to be copied from the cx88 driver. Just drop these weird
>> values.
>>
>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>> ---
>>  drivers/media/pci/cx23885/cx23885.h | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
>> index 99a5fe0..f542ced 100644
>> --- a/drivers/media/pci/cx23885/cx23885.h
>> +++ b/drivers/media/pci/cx23885/cx23885.h
>> @@ -610,15 +610,15 @@ extern int cx23885_risc_databuffer(struct pci_dev *pci,
>>  
>>  static inline unsigned int norm_maxw(v4l2_std_id norm)
>>  {
>> -	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
>> +	return 720;
> 
> Not sure if you checked cx23885 datasheet. I didn't, but I don't doubt
> that it uses about the same A/D logic as cx88.
> 
> In the case of cx88, the sampling rate for a few standards is different,
> as recommended at the datasheet. This is done to provide the highest
> image quality, as there are some customized filters for some standards,
> but they require some specific sampling rates. That's why PAL-Nc and
> NTSC/PAL-M are handled on a different way.

I will double-check what the datasheet has to say about this. And if there
is a good reason for this then I will add a comment at the very least.

> 
>>  }
>>  
>>  static inline unsigned int norm_maxh(v4l2_std_id norm)
>>  {
>> -	return (norm & V4L2_STD_625_50) ? 576 : 480;
>> +	return (norm & V4L2_STD_525_60) ? 480 : 576;
> 
> This is obviously wrong.

What is wrong? The original code or the new code? They are both right.

I prefer to use the same standard test everywhere in a driver. That way
if the standard is set to STD_ALL the driver will still interpret it
the same everywhere instead of as 50 Hz in one case and 60 Hz in another.

But it's no big deal.

Regards,

	Hans

> 
>>  }
>>  
>>  static inline unsigned int norm_swidth(v4l2_std_id norm)
>>  {
>> -	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
>> +	return 754;
>>  }
> 
> Same as above commented.
> 
> Regards,
> Mauro
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCHv2 17/20] cx23885: fix weird sizes.
  2014-09-03 12:07     ` Hans Verkuil
@ 2014-09-03 12:16       ` Mauro Carvalho Chehab
  2014-09-05  9:29         ` Hans Verkuil
  0 siblings, 1 reply; 28+ messages in thread
From: Mauro Carvalho Chehab @ 2014-09-03 12:16 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, stoth, Hans Verkuil

Em Wed, 03 Sep 2014 14:07:40 +0200
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> On 09/03/14 13:46, Mauro Carvalho Chehab wrote:
> > Em Thu, 14 Aug 2014 11:54:02 +0200
> > Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> > 
> >> From: Hans Verkuil <hans.verkuil@cisco.com>
> >>
> >> These values make no sense. All SDTV standards have the same width.
> >> This seems to be copied from the cx88 driver. Just drop these weird
> >> values.
> >>
> >> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> >> ---
> >>  drivers/media/pci/cx23885/cx23885.h | 6 +++---
> >>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
> >> index 99a5fe0..f542ced 100644
> >> --- a/drivers/media/pci/cx23885/cx23885.h
> >> +++ b/drivers/media/pci/cx23885/cx23885.h
> >> @@ -610,15 +610,15 @@ extern int cx23885_risc_databuffer(struct pci_dev *pci,
> >>  
> >>  static inline unsigned int norm_maxw(v4l2_std_id norm)
> >>  {
> >> -	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
> >> +	return 720;
> > 
> > Not sure if you checked cx23885 datasheet. I didn't, but I don't doubt
> > that it uses about the same A/D logic as cx88.
> > 
> > In the case of cx88, the sampling rate for a few standards is different,
> > as recommended at the datasheet. This is done to provide the highest
> > image quality, as there are some customized filters for some standards,
> > but they require some specific sampling rates. That's why PAL-Nc and
> > NTSC/PAL-M are handled on a different way.
> 
> I will double-check what the datasheet has to say about this. And if there
> is a good reason for this then I will add a comment at the very least.

OK.

> 
> > 
> >>  }
> >>  
> >>  static inline unsigned int norm_maxh(v4l2_std_id norm)
> >>  {
> >> -	return (norm & V4L2_STD_625_50) ? 576 : 480;
> >> +	return (norm & V4L2_STD_525_60) ? 480 : 576;
> > 
> > This is obviously wrong.
> 
> What is wrong? The original code or the new code? They are both right.

I think I expressed myself badly. I meant to say: the original code were
obviously wrong.

Basically, I agreed with you there ;)

Regards,
Mauro

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCHv2 15/20] cx23885: convert to vb2
  2014-09-03 11:57     ` Hans Verkuil
@ 2014-09-03 12:17       ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 28+ messages in thread
From: Mauro Carvalho Chehab @ 2014-09-03 12:17 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: Hans Verkuil, linux-media, stoth, Hans Verkuil

Em Wed, 03 Sep 2014 13:57:28 +0200
Hans Verkuil <hansverk@cisco.com> escreveu:

> Hi Mauro,
> 
> On 09/03/14 13:32, Mauro Carvalho Chehab wrote:
> > Em Thu, 14 Aug 2014 11:54:00 +0200
> > Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> > 
> >> From: Hans Verkuil <hans.verkuil@cisco.com>
> >>
> >> As usual, this patch is very large due to the fact that half a vb2 conversion
> >> isn't possible. And since this affects 417, alsa, core, dvb, vbi and video the
> >> changes are all over.
> >>
> >> What made this more difficult was the peculiar way the risc program was setup.
> >> The driver allowed for running out of buffers in which case the DMA would stop
> >> and restart when the next buffer was queued. There was also a complicated
> >> timeout system for when buffers weren't filled. This was replaced by a much
> >> simpler scheme where there is always one buffer around and the DMA will just
> >> cycle that buffer until a new buffer is queued. In that case the previous
> >> buffer will be chained to the new buffer. An interrupt is generated at the
> >> start of the new buffer telling the driver that the previous buffer can be
> >> passed on to userspace.
> >>
> >> Much simpler and more robust. The old code seems to be copied from the
> >> cx88 driver. But it didn't fit the vb2 ops very well and replacing it with
> >> the new scheme made the code easier to understand. Not to mention that this
> >> patch removes 600 lines of code.
> > 
> > Great job!
> 
> Thank you.
> 
> > Still, there are some issue. In special, the RISC changes should go
> > to a separate patch, as such changes have the potential of causing
> > some regressions. See below.
> 
> I tried (I mentioned that in my git pull request), but I was not able
> to separate the two. I couldn't make the risc changes to work with vb1,
> and the reverse would be equally painful. Not only that, but I would
> have to test this twice (once with just the risc changes or vb2 changes,
> and again when both are in place).
> 
> I can try to do the vb2 conversion first and the risc changes second, but
> this too might be too complicated to get to work.

Ok. Then, just split that VBI fixup on a separate patch.

Regards,
Mauro

> 
> <snip>
> 
> >> @@ -1320,7 +1373,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
> >>  				struct v4l2_format *f)
> >>  {
> >>  	struct cx23885_dev *dev = video_drvdata(file);
> >> -	struct cx23885_fh  *fh  = file->private_data;
> >>  
> >>  	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
> >>  	f->fmt.pix.bytesperline = 0;
> >> @@ -1329,9 +1381,9 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
> >>  	f->fmt.pix.colorspace   = 0;
> >>  	f->fmt.pix.width        = dev->ts1.width;
> >>  	f->fmt.pix.height       = dev->ts1.height;
> >> -	f->fmt.pix.field        = fh->mpegq.field;
> >> -	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
> >> -		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
> >> +	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
> > 
> > Why? There are other supported formats, right?
> 
> Not for the compressed video node. Only MPEG is supported there.
> 
> > 
> >> +	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
> >> +		dev->ts1.width, dev->ts1.height);
> >>  	return 0;
> >>  }
> >>  
> >> @@ -1339,15 +1391,15 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
> >>  				struct v4l2_format *f)
> >>  {
> >>  	struct cx23885_dev *dev = video_drvdata(file);
> >> -	struct cx23885_fh  *fh  = file->private_data;
> >>  
> >>  	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
> >>  	f->fmt.pix.bytesperline = 0;
> >>  	f->fmt.pix.sizeimage    =
> >>  		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
> >>  	f->fmt.pix.colorspace   = 0;
> >> -	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
> >> -		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
> >> +	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
> > 
> > Why? There are other supported formats, right?
> 
> Ditto.
> 
> > 
> >> +	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
> >> +		dev->ts1.width, dev->ts1.height);
> >>  	return 0;
> >>  }
> >>  
> 
> <snip>
> 
> >>  
> >>  int cx23885_sram_channel_setup(struct cx23885_dev *dev,
> >> @@ -482,8 +466,8 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
> >>  		lines = 6;
> >>  	BUG_ON(lines < 2);
> >>  
> >> -	cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
> >> -	cx_write(8 + 4, 8);
> >> +	cx_write(8 + 0, RISC_JUMP | RISC_CNT_RESET);
> >> +	cx_write(8 + 4, 12);
> > 
> > The above doesn't sound as being a pure vb2 conversion, and might cause
> > regressions, as we're changing the channel setups. I would very much
> > prefer to have such changes on a separate changeset, as it makes easier
> > to do bisect if ever needed.
> 
> See my comment at the top.
> 
> > 
> >>  	cx_write(8 + 8, 0);
> >>  
> >>  	/* write CDT */
> >> @@ -699,10 +683,6 @@ static int get_resources(struct cx23885_dev *dev)
> >>  	return -EBUSY;
> >>  }
> >>  
> >> -static void cx23885_timeout(unsigned long data);
> >> -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
> >> -				u32 reg, u32 mask, u32 value);
> >> -
> >>  static int cx23885_init_tsport(struct cx23885_dev *dev,
> >>  	struct cx23885_tsport *port, int portno)
> >>  {
> >> @@ -719,11 +699,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
> >>  	port->nr = portno;
> >>  
> >>  	INIT_LIST_HEAD(&port->mpegq.active);
> >> -	INIT_LIST_HEAD(&port->mpegq.queued);
> >> -	port->mpegq.timeout.function = cx23885_timeout;
> >> -	port->mpegq.timeout.data = (unsigned long)port;
> >> -	init_timer(&port->mpegq.timeout);
> >> -
> >>  	mutex_init(&port->frontends.lock);
> >>  	INIT_LIST_HEAD(&port->frontends.felist);
> >>  	port->frontends.active_fe_id = 0;
> >> @@ -776,9 +751,6 @@ static int cx23885_init_tsport(struct cx23885_dev *dev,
> >>  		BUG();
> >>  	}
> >>  
> >> -	cx23885_risc_stopper(dev->pci, &port->mpegq.stopper,
> >> -		     port->reg_dma_ctl, port->dma_ctl_val, 0x00);
> >> -
> >>  	return 0;
> >>  }
> >>  
> >> @@ -1089,11 +1061,18 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
> >>  static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
> >>  			       unsigned int offset, u32 sync_line,
> >>  			       unsigned int bpl, unsigned int padding,
> >> -			       unsigned int lines,  unsigned int lpi)
> >> +			       unsigned int lines,  unsigned int lpi, bool jump)
> >>  {
> >>  	struct scatterlist *sg;
> >>  	unsigned int line, todo, sol;
> >>  
> >> +
> >> +	if (jump) {
> >> +		*(rp++) = cpu_to_le32(RISC_JUMP);
> >> +		*(rp++) = cpu_to_le32(0);
> >> +		*(rp++) = cpu_to_le32(0); /* bits 63-32 */
> >> +	}
> >> +
> > 
> > Here it seem clear: you're now adding a code to support different
> > frame interlacing layouts, but the best is to have such changes on
> > a separate changeset, as this is one thing that we may have troubles
> > in the future.
> > 
> > The way I see is that we might start having a flood of complains about
> > regressions, and all of them will point to this single patch, making
> > really hard to identify what part of the change broke it.
> > 
> > So, let's split those risc changes on a pre (or post) patch, making
> > easier if someone needs to report an issue, for us to track what
> > patch broke it.
> > 
> >>  	/* sync instruction */
> >>  	if (sync_line != NO_SYNC_LINE)
> >>  		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
> >> @@ -1168,7 +1147,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
> >>  	/* write and jump need and extra dword */
> >>  	instructions  = fields * (1 + ((bpl + padding) * lines)
> >>  		/ PAGE_SIZE + lines);
> >> -	instructions += 2;
> >> +	instructions += 5;
> >>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
> >>  	if (rc < 0)
> >>  		return rc;
> >> @@ -1177,10 +1156,10 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
> >>  	rp = risc->cpu;
> >>  	if (UNSET != top_offset)
> >>  		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
> >> -					bpl, padding, lines, 0);
> >> +					bpl, padding, lines, 0, true);
> >>  	if (UNSET != bottom_offset)
> >>  		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
> >> -					bpl, padding, lines, 0);
> >> +					bpl, padding, lines, 0, UNSET == top_offset);
> >>  
> >>  	/* save pointer to jmp instruction address */
> >>  	risc->jmp = rp;
> >> @@ -1204,7 +1183,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
> >>  	   than PAGE_SIZE */
> >>  	/* Jump and write need an extra dword */
> >>  	instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
> >> -	instructions += 1;
> >> +	instructions += 4;
> >>  
> >>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
> >>  	if (rc < 0)
> >> @@ -1213,7 +1192,7 @@ int cx23885_risc_databuffer(struct pci_dev *pci,
> >>  	/* write risc instructions */
> >>  	rp = risc->cpu;
> >>  	rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE,
> >> -				bpl, 0, lines, lpi);
> >> +				bpl, 0, lines, lpi, lpi == 0);
> >>  
> >>  	/* save pointer to jmp instruction address */
> >>  	risc->jmp = rp;
> >> @@ -1243,7 +1222,7 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
> >>  	/* write and jump need and extra dword */
> >>  	instructions  = fields * (1 + ((bpl + padding) * lines)
> >>  		/ PAGE_SIZE + lines);
> >> -	instructions += 2;
> >> +	instructions += 5;
> >>  	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
> >>  	if (rc < 0)
> >>  		return rc;
> >> @@ -1253,12 +1232,12 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
> >>  	/* Sync to line 6, so US CC line 21 will appear in line '12'
> >>  	 * in the userland vbi payload */
> >>  	if (UNSET != top_offset)
> >> -		rp = cx23885_risc_field(rp, sglist, top_offset, 6,
> >> -					bpl, padding, lines, 0);
> >> +		rp = cx23885_risc_field(rp, sglist, top_offset, 0,
> >> +					bpl, padding, lines, 0, true);
> >>  
> >>  	if (UNSET != bottom_offset)
> >> -		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207,
> >> -					bpl, padding, lines, 0);
> >> +		rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
> >> +					bpl, padding, lines, 0, UNSET == top_offset);
> > 
> > Why to change the 4th argument of cx23885_risc_field() call?
> 
> This was a bug. Hmm, perhaps that should be moved to a separate patch.
> The VBI offset was wrong without this.
> 
> > 
> >>  
> >>  
> >>  
> >> @@ -1269,38 +1248,10 @@ int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
> >>  }
> >>  
> >>  
> >> -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
> >> -				u32 reg, u32 mask, u32 value)
> > 
> > What happened with this function?
> 
> No longer needed after the risc changes.
> 
> Regards,
> 
> 	Hans

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCHv2 17/20] cx23885: fix weird sizes.
  2014-09-03 12:16       ` Mauro Carvalho Chehab
@ 2014-09-05  9:29         ` Hans Verkuil
  0 siblings, 0 replies; 28+ messages in thread
From: Hans Verkuil @ 2014-09-05  9:29 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: linux-media, stoth, Hans Verkuil

On 09/03/2014 02:16 PM, Mauro Carvalho Chehab wrote:
> Em Wed, 03 Sep 2014 14:07:40 +0200
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> 
>> On 09/03/14 13:46, Mauro Carvalho Chehab wrote:
>>> Em Thu, 14 Aug 2014 11:54:02 +0200
>>> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
>>>
>>>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>>>
>>>> These values make no sense. All SDTV standards have the same width.
>>>> This seems to be copied from the cx88 driver. Just drop these weird
>>>> values.
>>>>
>>>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>>>> ---
>>>>  drivers/media/pci/cx23885/cx23885.h | 6 +++---
>>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
>>>> index 99a5fe0..f542ced 100644
>>>> --- a/drivers/media/pci/cx23885/cx23885.h
>>>> +++ b/drivers/media/pci/cx23885/cx23885.h
>>>> @@ -610,15 +610,15 @@ extern int cx23885_risc_databuffer(struct pci_dev *pci,
>>>>  
>>>>  static inline unsigned int norm_maxw(v4l2_std_id norm)
>>>>  {
>>>> -	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
>>>> +	return 720;
>>>
>>> Not sure if you checked cx23885 datasheet. I didn't, but I don't doubt
>>> that it uses about the same A/D logic as cx88.
>>>
>>> In the case of cx88, the sampling rate for a few standards is different,
>>> as recommended at the datasheet. This is done to provide the highest
>>> image quality, as there are some customized filters for some standards,
>>> but they require some specific sampling rates. That's why PAL-Nc and
>>> NTSC/PAL-M are handled on a different way.
>>
>> I will double-check what the datasheet has to say about this. And if there
>> is a good reason for this then I will add a comment at the very least.
> 
> OK.

I checked the cx23883 datasheet that I have and it does not mention anything
about PAL-Nc/NTSC/PAL-M. What it does mention is that for 50 Hz formats the
768x576 format will give you square pixels (just as 640x480 does for NTSC),
so in order to be able to get frames with square pixels it makes sense to
support 768 as the max width for 50 Hz formats. I see nothing about image
quality, as far as I can tell it is just about square vs non-square pixels.

So norm_maxw should read:

	/* 768 x 576 gives square pixels for 50 Hz formats */
	return (norm & V4L2_STD_525_60) ? 720 : 768;

That makes sense.

I don't have a cx88 datasheet, so can you verify if that datasheet says the
same thing?

Thanks,

	Hans

> 
>>
>>>
>>>>  }
>>>>  
>>>>  static inline unsigned int norm_maxh(v4l2_std_id norm)
>>>>  {
>>>> -	return (norm & V4L2_STD_625_50) ? 576 : 480;
>>>> +	return (norm & V4L2_STD_525_60) ? 480 : 576;
>>>
>>> This is obviously wrong.
>>
>> What is wrong? The original code or the new code? They are both right.
> 
> I think I expressed myself badly. I meant to say: the original code were
> obviously wrong.
> 
> Basically, I agreed with you there ;)
> 
> Regards,
> Mauro
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2014-09-05  9:30 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-14  9:53 [PATCHv2 00/20] cx23885: convert to the V4L2 core frameworks Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 01/20] cx23885: fix querycap Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 02/20] cx23885: fix audio input handling Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 03/20] cx23885: support v4l2_fh and g/s_priority Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 04/20] cx23885: use core locking, switch to unlocked_ioctl Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 05/20] cx23885: convert to the control framework Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 06/20] cx23885: convert 417 " Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 07/20] cx23885: fix format colorspace compliance error Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 08/20] cx23885: map invalid fields to a valid field Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 09/20] cx23885: drop radio-related dead code Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 10/20] cx23885: drop type field from struct cx23885_fh Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 11/20] cx23885: drop unused clip fields " Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 12/20] cx23885: fmt, width and height are global, not per-fh Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 13/20] cx23885: drop videobuf abuse in cx23885-alsa Hans Verkuil
2014-08-14  9:53 ` [PATCHv2 14/20] cx23885: use video_drvdata to get cx23885_dev pointer Hans Verkuil
2014-08-14  9:54 ` [PATCHv2 15/20] cx23885: convert to vb2 Hans Verkuil
2014-09-03 11:32   ` Mauro Carvalho Chehab
2014-09-03 11:57     ` Hans Verkuil
2014-09-03 12:17       ` Mauro Carvalho Chehab
2014-08-14  9:54 ` [PATCHv2 16/20] cx23885: fix field handling Hans Verkuil
2014-08-14  9:54 ` [PATCHv2 17/20] cx23885: fix weird sizes Hans Verkuil
2014-09-03 11:46   ` Mauro Carvalho Chehab
2014-09-03 12:07     ` Hans Verkuil
2014-09-03 12:16       ` Mauro Carvalho Chehab
2014-09-05  9:29         ` Hans Verkuil
2014-08-14  9:54 ` [PATCHv2 18/20] cx23885: remove FSF address as per checkpatch Hans Verkuil
2014-08-14  9:54 ` [PATCHv2 19/20] cx23885: remove btcx-risc dependency Hans Verkuil
2014-08-14  9:54 ` [PATCHv2 20/20] cx23885: Add busy checks before changing formats Hans Verkuil

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.