summaryrefslogtreecommitdiffstats
path: root/Documentation/video4linux/v4l2-pci-skeleton.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-08 11:31:16 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-08 11:31:16 -0700
commit3f17ea6dea8ba5668873afa54628a91aaa3fb1c0 (patch)
treeafbeb2accd4c2199ddd705ae943995b143a0af02 /Documentation/video4linux/v4l2-pci-skeleton.c
parent1860e379875dfe7271c649058aeddffe5afd9d0d (diff)
parent1a5700bc2d10cd379a795fd2bb377a190af5acd4 (diff)
Merge branch 'next' (accumulated 3.16 merge window patches) into master
Now that 3.15 is released, this merges the 'next' branch into 'master', bringing us to the normal situation where my 'master' branch is the merge window. * accumulated work in next: (6809 commits) ufs: sb mutex merge + mutex_destroy powerpc: update comments for generic idle conversion cris: update comments for generic idle conversion idle: remove cpu_idle() forward declarations nbd: zero from and len fields in NBD_CMD_DISCONNECT. mm: convert some level-less printks to pr_* MAINTAINERS: adi-buildroot-devel is moderated MAINTAINERS: add linux-api for review of API/ABI changes mm/kmemleak-test.c: use pr_fmt for logging fs/dlm/debug_fs.c: replace seq_printf by seq_puts fs/dlm/lockspace.c: convert simple_str to kstr fs/dlm/config.c: convert simple_str to kstr mm: mark remap_file_pages() syscall as deprecated mm: memcontrol: remove unnecessary memcg argument from soft limit functions mm: memcontrol: clean up memcg zoneinfo lookup mm/memblock.c: call kmemleak directly from memblock_(alloc|free) mm/mempool.c: update the kmemleak stack trace for mempool allocations lib/radix-tree.c: update the kmemleak stack trace for radix tree allocations mm: introduce kmemleak_update_trace() mm/kmemleak.c: use %u to print ->checksum ...
Diffstat (limited to 'Documentation/video4linux/v4l2-pci-skeleton.c')
-rw-r--r--Documentation/video4linux/v4l2-pci-skeleton.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/Documentation/video4linux/v4l2-pci-skeleton.c b/Documentation/video4linux/v4l2-pci-skeleton.c
index 3a1c0d2dafc..46904fe4960 100644
--- a/Documentation/video4linux/v4l2-pci-skeleton.c
+++ b/Documentation/video4linux/v4l2-pci-skeleton.c
@@ -77,7 +77,8 @@ struct skeleton {
spinlock_t qlock;
struct list_head buf_list;
- unsigned int sequence;
+ unsigned field;
+ unsigned sequence;
};
struct skel_buffer {
@@ -124,7 +125,7 @@ static const struct v4l2_dv_timings_cap skel_timings_cap = {
* Interrupt handler: typically interrupts happen after a new frame has been
* captured. It is the job of the handler to remove the new frame from the
* internal list and give it back to the vb2 framework, updating the sequence
- * counter and timestamp at the same time.
+ * counter, field and timestamp at the same time.
*/
static irqreturn_t skeleton_irq(int irq, void *dev_id)
{
@@ -139,8 +140,15 @@ static irqreturn_t skeleton_irq(int irq, void *dev_id)
spin_lock(&skel->qlock);
list_del(&new_buf->list);
spin_unlock(&skel->qlock);
- new_buf->vb.v4l2_buf.sequence = skel->sequence++;
v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp);
+ new_buf->vb.v4l2_buf.sequence = skel->sequence++;
+ new_buf->vb.v4l2_buf.field = skel->field;
+ if (skel->format.field == V4L2_FIELD_ALTERNATE) {
+ if (skel->field == V4L2_FIELD_BOTTOM)
+ skel->field = V4L2_FIELD_TOP;
+ else if (skel->field == V4L2_FIELD_TOP)
+ skel->field = V4L2_FIELD_BOTTOM;
+ }
vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE);
}
#endif
@@ -160,6 +168,17 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
{
struct skeleton *skel = vb2_get_drv_priv(vq);
+ skel->field = skel->format.field;
+ if (skel->field == V4L2_FIELD_ALTERNATE) {
+ /*
+ * You cannot use read() with FIELD_ALTERNATE since the field
+ * information (TOP/BOTTOM) cannot be passed back to the user.
+ */
+ if (vb2_fileio_is_active(vq))
+ return -EINVAL;
+ skel->field = V4L2_FIELD_TOP;
+ }
+
if (vq->num_buffers + *nbuffers < 3)
*nbuffers = 3 - vq->num_buffers;
@@ -173,10 +192,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
/*
* Prepare the buffer for queueing to the DMA engine: check and set the
- * payload size and fill in the field. Note: if the format's field is
- * V4L2_FIELD_ALTERNATE, then vb->v4l2_buf.field should be set in the
- * interrupt handler since that's usually where you know if the TOP or
- * BOTTOM field has been captured.
+ * payload size.
*/
static int buffer_prepare(struct vb2_buffer *vb)
{
@@ -190,7 +206,6 @@ static int buffer_prepare(struct vb2_buffer *vb)
}
vb2_set_plane_payload(vb, 0, size);
- vb->v4l2_buf.field = skel->format.field;
return 0;
}
@@ -254,7 +269,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
* Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
* and passed on to the vb2 framework marked as STATE_ERROR.
*/
-static int stop_streaming(struct vb2_queue *vq)
+static void stop_streaming(struct vb2_queue *vq)
{
struct skeleton *skel = vb2_get_drv_priv(vq);
@@ -262,7 +277,6 @@ static int stop_streaming(struct vb2_queue *vq)
/* Release all active buffers */
return_all_buffers(skel, VB2_BUF_STATE_ERROR);
- return 0;
}
/*
@@ -319,10 +333,12 @@ static void skeleton_fill_pix_format(struct skeleton *skel,
/* HDMI input */
pix->width = skel->timings.bt.width;
pix->height = skel->timings.bt.height;
- if (skel->timings.bt.interlaced)
- pix->field = V4L2_FIELD_INTERLACED;
- else
+ if (skel->timings.bt.interlaced) {
+ pix->field = V4L2_FIELD_ALTERNATE;
+ pix->height /= 2;
+ } else {
pix->field = V4L2_FIELD_NONE;
+ }
pix->colorspace = V4L2_COLORSPACE_REC709;
}