aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/em28xx/em28xx-vbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-vbi.c')
-rw-r--r--drivers/media/usb/em28xx/em28xx-vbi.c123
1 files changed, 45 insertions, 78 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c
index 2b4c9cba2d67..39f39c527c13 100644
--- a/drivers/media/usb/em28xx/em28xx-vbi.c
+++ b/drivers/media/usb/em28xx/em28xx-vbi.c
@@ -41,105 +41,72 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
41 41
42/* ------------------------------------------------------------------ */ 42/* ------------------------------------------------------------------ */
43 43
44static void 44static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
45free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) 45 unsigned int *nbuffers, unsigned int *nplanes,
46 unsigned int sizes[], void *alloc_ctxs[])
46{ 47{
47 struct em28xx_fh *fh = vq->priv_data; 48 struct em28xx *dev = vb2_get_drv_priv(vq);
48 struct em28xx *dev = fh->dev; 49 unsigned long size;
49 unsigned long flags = 0;
50 if (in_interrupt())
51 BUG();
52
53 /* We used to wait for the buffer to finish here, but this didn't work
54 because, as we were keeping the state as VIDEOBUF_QUEUED,
55 videobuf_queue_cancel marked it as finished for us.
56 (Also, it could wedge forever if the hardware was misconfigured.)
57
58 This should be safe; by the time we get here, the buffer isn't
59 queued anymore. If we ever start marking the buffers as
60 VIDEOBUF_ACTIVE, it won't be, though.
61 */
62 spin_lock_irqsave(&dev->slock, flags);
63 if (dev->isoc_ctl.vbi_buf == buf)
64 dev->isoc_ctl.vbi_buf = NULL;
65 spin_unlock_irqrestore(&dev->slock, flags);
66 50
67 videobuf_vmalloc_free(&buf->vb); 51 if (fmt)
68 buf->vb.state = VIDEOBUF_NEEDS_INIT; 52 size = fmt->fmt.pix.sizeimage;
69} 53 else
54 size = dev->vbi_width * dev->vbi_height * 2;
70 55
71static int 56 if (0 == *nbuffers)
72vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 57 *nbuffers = 32;
73{ 58 if (*nbuffers < 2)
74 struct em28xx_fh *fh = q->priv_data; 59 *nbuffers = 2;
75 struct em28xx *dev = fh->dev; 60 if (*nbuffers > 32)
61 *nbuffers = 32;
76 62
77 *size = dev->vbi_width * dev->vbi_height * 2; 63 *nplanes = 1;
64 sizes[0] = size;
78 65
79 if (0 == *count)
80 *count = vbibufs;
81 if (*count < 2)
82 *count = 2;
83 if (*count > 32)
84 *count = 32;
85 return 0; 66 return 0;
86} 67}
87 68
88static int 69static int vbi_buffer_prepare(struct vb2_buffer *vb)
89vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
90 enum v4l2_field field)
91{ 70{
92 struct em28xx_fh *fh = q->priv_data; 71 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
93 struct em28xx *dev = fh->dev;
94 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); 72 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
95 int rc = 0; 73 unsigned long size;
96 74
97 buf->vb.size = dev->vbi_width * dev->vbi_height * 2; 75 size = dev->vbi_width * dev->vbi_height * 2;
98 76
99 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 77 if (vb2_plane_size(vb, 0) < size) {
78 printk(KERN_INFO "%s data will not fit into plane (%lu < %lu)\n",
79 __func__, vb2_plane_size(vb, 0), size);
100 return -EINVAL; 80 return -EINVAL;
101
102 buf->vb.width = dev->vbi_width;
103 buf->vb.height = dev->vbi_height;
104 buf->vb.field = field;
105
106 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
107 rc = videobuf_iolock(q, &buf->vb, NULL);
108 if (rc < 0)
109 goto fail;
110 } 81 }
82 vb2_set_plane_payload(&buf->vb, 0, size);
111 83
112 buf->vb.state = VIDEOBUF_PREPARED;
113 return 0; 84 return 0;
114
115fail:
116 free_buffer(q, buf);
117 return rc;
118} 85}
119 86
120static void 87static void
121vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) 88vbi_buffer_queue(struct vb2_buffer *vb)
122{
123 struct em28xx_buffer *buf = container_of(vb,
124 struct em28xx_buffer,
125 vb);
126 struct em28xx_fh *fh = vq->priv_data;
127 struct em28xx *dev = fh->dev;
128 struct em28xx_dmaqueue *vbiq = &dev->vbiq;
129
130 buf->vb.state = VIDEOBUF_QUEUED;
131 list_add_tail(&buf->vb.queue, &vbiq->active);
132}
133
134static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
135{ 89{
90 struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue);
136 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); 91 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
137 free_buffer(q, buf); 92 struct em28xx_dmaqueue *vbiq = &dev->vbiq;
93 unsigned long flags = 0;
94
95 buf->mem = vb2_plane_vaddr(vb, 0);
96 buf->length = vb2_plane_size(vb, 0);
97
98 spin_lock_irqsave(&dev->slock, flags);
99 list_add_tail(&buf->list, &vbiq->active);
100 spin_unlock_irqrestore(&dev->slock, flags);
138} 101}
139 102
140struct videobuf_queue_ops em28xx_vbi_qops = { 103
141 .buf_setup = vbi_setup, 104struct vb2_ops em28xx_vbi_qops = {
142 .buf_prepare = vbi_prepare, 105 .queue_setup = vbi_queue_setup,
143 .buf_queue = vbi_queue, 106 .buf_prepare = vbi_buffer_prepare,
144 .buf_release = vbi_release, 107 .buf_queue = vbi_buffer_queue,
108 .start_streaming = em28xx_start_analog_streaming,
109 .stop_streaming = em28xx_stop_vbi_streaming,
110 .wait_prepare = vb2_ops_wait_prepare,
111 .wait_finish = vb2_ops_wait_finish,
145}; 112};