diff options
author | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-21 05:12:35 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-21 05:12:35 -0400 |
commit | 676ee36be04985062522804c2de04f0764212be6 (patch) | |
tree | 781df135c5a91a04decad1b7d53b5a925dc11522 /drivers/media/platform/blackfin/bfin_capture.c | |
parent | b18042a673e88c9457a6d1716219c2367ca447b0 (diff) | |
parent | e183201b9e917daf2530b637b2f34f1d5afb934d (diff) |
Merge branch 'patchwork' into v4l_for_linus
* patchwork: (404 commits)
[media] uvcvideo: add support for VIDIOC_QUERY_EXT_CTRL
[media] uvcvideo: fix cropcap v4l2-compliance failure
[media] media: omap3isp: remove unused clkdev
[media] coda: Add tracing support
[media] coda: drop dma_sync_single_for_device in coda_bitstream_queue
[media] coda: fix fill bitstream errors in nonstreaming case
[media] coda: call SEQ_END when the first queue is stopped
[media] coda: fail to start streaming if userspace set invalid formats
[media] coda: remove duplicate error messages for buffer allocations
[media] coda: move parameter buffer in together with context buffer allocation
[media] coda: allocate bitstream buffer from REQBUFS, size depends on the format
[media] coda: allocate per-context buffers from REQBUFS
[media] coda: use strlcpy instead of snprintf
[media] coda: bitstream payload is unsigned
[media] coda: fix double call to debugfs_remove
[media] coda: check kasprintf return value in coda_open
[media] coda: bitrate can only be set in kbps steps
[media] v4l2-mem2mem: no need to initialize b in v4l2_m2m_next_buf and v4l2_m2m_buf_remove
[media] s5p-mfc: set allow_zero_bytesused flag for vb2_queue_init
[media] coda: set allow_zero_bytesused flag for vb2_queue_init
...
Diffstat (limited to 'drivers/media/platform/blackfin/bfin_capture.c')
-rw-r--r-- | drivers/media/platform/blackfin/bfin_capture.c | 348 |
1 files changed, 103 insertions, 245 deletions
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 8f6698668ecf..6a437f86dcdc 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <media/blackfin/ppi.h> | 44 | #include <media/blackfin/ppi.h> |
45 | 45 | ||
46 | #define CAPTURE_DRV_NAME "bfin_capture" | 46 | #define CAPTURE_DRV_NAME "bfin_capture" |
47 | #define BCAP_MIN_NUM_BUF 2 | ||
48 | 47 | ||
49 | struct bcap_format { | 48 | struct bcap_format { |
50 | char *desc; | 49 | char *desc; |
@@ -65,7 +64,7 @@ struct bcap_device { | |||
65 | /* v4l2 control handler */ | 64 | /* v4l2 control handler */ |
66 | struct v4l2_ctrl_handler ctrl_handler; | 65 | struct v4l2_ctrl_handler ctrl_handler; |
67 | /* device node data */ | 66 | /* device node data */ |
68 | struct video_device *video_dev; | 67 | struct video_device video_dev; |
69 | /* sub device instance */ | 68 | /* sub device instance */ |
70 | struct v4l2_subdev *sd; | 69 | struct v4l2_subdev *sd; |
71 | /* capture config */ | 70 | /* capture config */ |
@@ -104,12 +103,8 @@ struct bcap_device { | |||
104 | struct completion comp; | 103 | struct completion comp; |
105 | /* prepare to stop */ | 104 | /* prepare to stop */ |
106 | bool stop; | 105 | bool stop; |
107 | }; | 106 | /* vb2 buffer sequence counter */ |
108 | 107 | unsigned sequence; | |
109 | struct bcap_fh { | ||
110 | struct v4l2_fh fh; | ||
111 | /* indicates whether this file handle is doing IO */ | ||
112 | bool io_allowed; | ||
113 | }; | 108 | }; |
114 | 109 | ||
115 | static const struct bcap_format bcap_formats[] = { | 110 | static const struct bcap_format bcap_formats[] = { |
@@ -201,90 +196,6 @@ static void bcap_free_sensor_formats(struct bcap_device *bcap_dev) | |||
201 | bcap_dev->sensor_formats = NULL; | 196 | bcap_dev->sensor_formats = NULL; |
202 | } | 197 | } |
203 | 198 | ||
204 | static int bcap_open(struct file *file) | ||
205 | { | ||
206 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
207 | struct video_device *vfd = bcap_dev->video_dev; | ||
208 | struct bcap_fh *bcap_fh; | ||
209 | |||
210 | if (!bcap_dev->sd) { | ||
211 | v4l2_err(&bcap_dev->v4l2_dev, "No sub device registered\n"); | ||
212 | return -ENODEV; | ||
213 | } | ||
214 | |||
215 | bcap_fh = kzalloc(sizeof(*bcap_fh), GFP_KERNEL); | ||
216 | if (!bcap_fh) { | ||
217 | v4l2_err(&bcap_dev->v4l2_dev, | ||
218 | "unable to allocate memory for file handle object\n"); | ||
219 | return -ENOMEM; | ||
220 | } | ||
221 | |||
222 | v4l2_fh_init(&bcap_fh->fh, vfd); | ||
223 | |||
224 | /* store pointer to v4l2_fh in private_data member of file */ | ||
225 | file->private_data = &bcap_fh->fh; | ||
226 | v4l2_fh_add(&bcap_fh->fh); | ||
227 | bcap_fh->io_allowed = false; | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int bcap_release(struct file *file) | ||
232 | { | ||
233 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
234 | struct v4l2_fh *fh = file->private_data; | ||
235 | struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); | ||
236 | |||
237 | /* if this instance is doing IO */ | ||
238 | if (bcap_fh->io_allowed) | ||
239 | vb2_queue_release(&bcap_dev->buffer_queue); | ||
240 | |||
241 | file->private_data = NULL; | ||
242 | v4l2_fh_del(&bcap_fh->fh); | ||
243 | v4l2_fh_exit(&bcap_fh->fh); | ||
244 | kfree(bcap_fh); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int bcap_mmap(struct file *file, struct vm_area_struct *vma) | ||
249 | { | ||
250 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
251 | int ret; | ||
252 | |||
253 | if (mutex_lock_interruptible(&bcap_dev->mutex)) | ||
254 | return -ERESTARTSYS; | ||
255 | ret = vb2_mmap(&bcap_dev->buffer_queue, vma); | ||
256 | mutex_unlock(&bcap_dev->mutex); | ||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | #ifndef CONFIG_MMU | ||
261 | static unsigned long bcap_get_unmapped_area(struct file *file, | ||
262 | unsigned long addr, | ||
263 | unsigned long len, | ||
264 | unsigned long pgoff, | ||
265 | unsigned long flags) | ||
266 | { | ||
267 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
268 | |||
269 | return vb2_get_unmapped_area(&bcap_dev->buffer_queue, | ||
270 | addr, | ||
271 | len, | ||
272 | pgoff, | ||
273 | flags); | ||
274 | } | ||
275 | #endif | ||
276 | |||
277 | static unsigned int bcap_poll(struct file *file, poll_table *wait) | ||
278 | { | ||
279 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
280 | unsigned int res; | ||
281 | |||
282 | mutex_lock(&bcap_dev->mutex); | ||
283 | res = vb2_poll(&bcap_dev->buffer_queue, file, wait); | ||
284 | mutex_unlock(&bcap_dev->mutex); | ||
285 | return res; | ||
286 | } | ||
287 | |||
288 | static int bcap_queue_setup(struct vb2_queue *vq, | 199 | static int bcap_queue_setup(struct vb2_queue *vq, |
289 | const struct v4l2_format *fmt, | 200 | const struct v4l2_format *fmt, |
290 | unsigned int *nbuffers, unsigned int *nplanes, | 201 | unsigned int *nbuffers, unsigned int *nplanes, |
@@ -292,37 +203,32 @@ static int bcap_queue_setup(struct vb2_queue *vq, | |||
292 | { | 203 | { |
293 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); | 204 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); |
294 | 205 | ||
295 | if (*nbuffers < BCAP_MIN_NUM_BUF) | 206 | if (fmt && fmt->fmt.pix.sizeimage < bcap_dev->fmt.sizeimage) |
296 | *nbuffers = BCAP_MIN_NUM_BUF; | 207 | return -EINVAL; |
208 | |||
209 | if (vq->num_buffers + *nbuffers < 2) | ||
210 | *nbuffers = 2; | ||
297 | 211 | ||
298 | *nplanes = 1; | 212 | *nplanes = 1; |
299 | sizes[0] = bcap_dev->fmt.sizeimage; | 213 | sizes[0] = fmt ? fmt->fmt.pix.sizeimage : bcap_dev->fmt.sizeimage; |
300 | alloc_ctxs[0] = bcap_dev->alloc_ctx; | 214 | alloc_ctxs[0] = bcap_dev->alloc_ctx; |
301 | 215 | ||
302 | return 0; | 216 | return 0; |
303 | } | 217 | } |
304 | 218 | ||
305 | static int bcap_buffer_init(struct vb2_buffer *vb) | ||
306 | { | ||
307 | struct bcap_buffer *buf = to_bcap_vb(vb); | ||
308 | |||
309 | INIT_LIST_HEAD(&buf->list); | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static int bcap_buffer_prepare(struct vb2_buffer *vb) | 219 | static int bcap_buffer_prepare(struct vb2_buffer *vb) |
314 | { | 220 | { |
315 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); | 221 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); |
316 | struct bcap_buffer *buf = to_bcap_vb(vb); | 222 | unsigned long size = bcap_dev->fmt.sizeimage; |
317 | unsigned long size; | ||
318 | 223 | ||
319 | size = bcap_dev->fmt.sizeimage; | ||
320 | if (vb2_plane_size(vb, 0) < size) { | 224 | if (vb2_plane_size(vb, 0) < size) { |
321 | v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n", | 225 | v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n", |
322 | vb2_plane_size(vb, 0), size); | 226 | vb2_plane_size(vb, 0), size); |
323 | return -EINVAL; | 227 | return -EINVAL; |
324 | } | 228 | } |
325 | vb2_set_plane_payload(&buf->vb, 0, size); | 229 | vb2_set_plane_payload(vb, 0, size); |
230 | |||
231 | vb->v4l2_buf.field = bcap_dev->fmt.field; | ||
326 | 232 | ||
327 | return 0; | 233 | return 0; |
328 | } | 234 | } |
@@ -353,14 +259,16 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
353 | { | 259 | { |
354 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); | 260 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); |
355 | struct ppi_if *ppi = bcap_dev->ppi; | 261 | struct ppi_if *ppi = bcap_dev->ppi; |
262 | struct bcap_buffer *buf, *tmp; | ||
356 | struct ppi_params params; | 263 | struct ppi_params params; |
264 | dma_addr_t addr; | ||
357 | int ret; | 265 | int ret; |
358 | 266 | ||
359 | /* enable streamon on the sub device */ | 267 | /* enable streamon on the sub device */ |
360 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1); | 268 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1); |
361 | if (ret && (ret != -ENOIOCTLCMD)) { | 269 | if (ret && (ret != -ENOIOCTLCMD)) { |
362 | v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n"); | 270 | v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n"); |
363 | return ret; | 271 | goto err; |
364 | } | 272 | } |
365 | 273 | ||
366 | /* set ppi params */ | 274 | /* set ppi params */ |
@@ -399,7 +307,7 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
399 | if (ret < 0) { | 307 | if (ret < 0) { |
400 | v4l2_err(&bcap_dev->v4l2_dev, | 308 | v4l2_err(&bcap_dev->v4l2_dev, |
401 | "Error in setting ppi params\n"); | 309 | "Error in setting ppi params\n"); |
402 | return ret; | 310 | goto err; |
403 | } | 311 | } |
404 | 312 | ||
405 | /* attach ppi DMA irq handler */ | 313 | /* attach ppi DMA irq handler */ |
@@ -407,12 +315,34 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
407 | if (ret < 0) { | 315 | if (ret < 0) { |
408 | v4l2_err(&bcap_dev->v4l2_dev, | 316 | v4l2_err(&bcap_dev->v4l2_dev, |
409 | "Error in attaching interrupt handler\n"); | 317 | "Error in attaching interrupt handler\n"); |
410 | return ret; | 318 | goto err; |
411 | } | 319 | } |
412 | 320 | ||
321 | bcap_dev->sequence = 0; | ||
322 | |||
413 | reinit_completion(&bcap_dev->comp); | 323 | reinit_completion(&bcap_dev->comp); |
414 | bcap_dev->stop = false; | 324 | bcap_dev->stop = false; |
325 | |||
326 | /* get the next frame from the dma queue */ | ||
327 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | ||
328 | struct bcap_buffer, list); | ||
329 | /* remove buffer from the dma queue */ | ||
330 | list_del_init(&bcap_dev->cur_frm->list); | ||
331 | addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); | ||
332 | /* update DMA address */ | ||
333 | ppi->ops->update_addr(ppi, (unsigned long)addr); | ||
334 | /* enable ppi */ | ||
335 | ppi->ops->start(ppi); | ||
336 | |||
415 | return 0; | 337 | return 0; |
338 | |||
339 | err: | ||
340 | list_for_each_entry_safe(buf, tmp, &bcap_dev->dma_queue, list) { | ||
341 | list_del(&buf->list); | ||
342 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); | ||
343 | } | ||
344 | |||
345 | return ret; | ||
416 | } | 346 | } |
417 | 347 | ||
418 | static void bcap_stop_streaming(struct vb2_queue *vq) | 348 | static void bcap_stop_streaming(struct vb2_queue *vq) |
@@ -431,6 +361,9 @@ static void bcap_stop_streaming(struct vb2_queue *vq) | |||
431 | "stream off failed in subdev\n"); | 361 | "stream off failed in subdev\n"); |
432 | 362 | ||
433 | /* release all active buffers */ | 363 | /* release all active buffers */ |
364 | if (bcap_dev->cur_frm) | ||
365 | vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR); | ||
366 | |||
434 | while (!list_empty(&bcap_dev->dma_queue)) { | 367 | while (!list_empty(&bcap_dev->dma_queue)) { |
435 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | 368 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, |
436 | struct bcap_buffer, list); | 369 | struct bcap_buffer, list); |
@@ -441,7 +374,6 @@ static void bcap_stop_streaming(struct vb2_queue *vq) | |||
441 | 374 | ||
442 | static struct vb2_ops bcap_video_qops = { | 375 | static struct vb2_ops bcap_video_qops = { |
443 | .queue_setup = bcap_queue_setup, | 376 | .queue_setup = bcap_queue_setup, |
444 | .buf_init = bcap_buffer_init, | ||
445 | .buf_prepare = bcap_buffer_prepare, | 377 | .buf_prepare = bcap_buffer_prepare, |
446 | .buf_cleanup = bcap_buffer_cleanup, | 378 | .buf_cleanup = bcap_buffer_cleanup, |
447 | .buf_queue = bcap_buffer_queue, | 379 | .buf_queue = bcap_buffer_queue, |
@@ -451,57 +383,6 @@ static struct vb2_ops bcap_video_qops = { | |||
451 | .stop_streaming = bcap_stop_streaming, | 383 | .stop_streaming = bcap_stop_streaming, |
452 | }; | 384 | }; |
453 | 385 | ||
454 | static int bcap_reqbufs(struct file *file, void *priv, | ||
455 | struct v4l2_requestbuffers *req_buf) | ||
456 | { | ||
457 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
458 | struct vb2_queue *vq = &bcap_dev->buffer_queue; | ||
459 | struct v4l2_fh *fh = file->private_data; | ||
460 | struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); | ||
461 | |||
462 | if (vb2_is_busy(vq)) | ||
463 | return -EBUSY; | ||
464 | |||
465 | bcap_fh->io_allowed = true; | ||
466 | |||
467 | return vb2_reqbufs(vq, req_buf); | ||
468 | } | ||
469 | |||
470 | static int bcap_querybuf(struct file *file, void *priv, | ||
471 | struct v4l2_buffer *buf) | ||
472 | { | ||
473 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
474 | |||
475 | return vb2_querybuf(&bcap_dev->buffer_queue, buf); | ||
476 | } | ||
477 | |||
478 | static int bcap_qbuf(struct file *file, void *priv, | ||
479 | struct v4l2_buffer *buf) | ||
480 | { | ||
481 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
482 | struct v4l2_fh *fh = file->private_data; | ||
483 | struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); | ||
484 | |||
485 | if (!bcap_fh->io_allowed) | ||
486 | return -EBUSY; | ||
487 | |||
488 | return vb2_qbuf(&bcap_dev->buffer_queue, buf); | ||
489 | } | ||
490 | |||
491 | static int bcap_dqbuf(struct file *file, void *priv, | ||
492 | struct v4l2_buffer *buf) | ||
493 | { | ||
494 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
495 | struct v4l2_fh *fh = file->private_data; | ||
496 | struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); | ||
497 | |||
498 | if (!bcap_fh->io_allowed) | ||
499 | return -EBUSY; | ||
500 | |||
501 | return vb2_dqbuf(&bcap_dev->buffer_queue, | ||
502 | buf, file->f_flags & O_NONBLOCK); | ||
503 | } | ||
504 | |||
505 | static irqreturn_t bcap_isr(int irq, void *dev_id) | 386 | static irqreturn_t bcap_isr(int irq, void *dev_id) |
506 | { | 387 | { |
507 | struct ppi_if *ppi = dev_id; | 388 | struct ppi_if *ppi = dev_id; |
@@ -517,6 +398,7 @@ static irqreturn_t bcap_isr(int irq, void *dev_id) | |||
517 | vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); | 398 | vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); |
518 | ppi->err = false; | 399 | ppi->err = false; |
519 | } else { | 400 | } else { |
401 | vb->v4l2_buf.sequence = bcap_dev->sequence++; | ||
520 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); | 402 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); |
521 | } | 403 | } |
522 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | 404 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, |
@@ -543,62 +425,14 @@ static irqreturn_t bcap_isr(int irq, void *dev_id) | |||
543 | return IRQ_HANDLED; | 425 | return IRQ_HANDLED; |
544 | } | 426 | } |
545 | 427 | ||
546 | static int bcap_streamon(struct file *file, void *priv, | ||
547 | enum v4l2_buf_type buf_type) | ||
548 | { | ||
549 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
550 | struct bcap_fh *fh = file->private_data; | ||
551 | struct ppi_if *ppi = bcap_dev->ppi; | ||
552 | dma_addr_t addr; | ||
553 | int ret; | ||
554 | |||
555 | if (!fh->io_allowed) | ||
556 | return -EBUSY; | ||
557 | |||
558 | /* call streamon to start streaming in videobuf */ | ||
559 | ret = vb2_streamon(&bcap_dev->buffer_queue, buf_type); | ||
560 | if (ret) | ||
561 | return ret; | ||
562 | |||
563 | /* if dma queue is empty, return error */ | ||
564 | if (list_empty(&bcap_dev->dma_queue)) { | ||
565 | v4l2_err(&bcap_dev->v4l2_dev, "dma queue is empty\n"); | ||
566 | ret = -EINVAL; | ||
567 | goto err; | ||
568 | } | ||
569 | |||
570 | /* get the next frame from the dma queue */ | ||
571 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | ||
572 | struct bcap_buffer, list); | ||
573 | /* remove buffer from the dma queue */ | ||
574 | list_del_init(&bcap_dev->cur_frm->list); | ||
575 | addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); | ||
576 | /* update DMA address */ | ||
577 | ppi->ops->update_addr(ppi, (unsigned long)addr); | ||
578 | /* enable ppi */ | ||
579 | ppi->ops->start(ppi); | ||
580 | |||
581 | return 0; | ||
582 | err: | ||
583 | vb2_streamoff(&bcap_dev->buffer_queue, buf_type); | ||
584 | return ret; | ||
585 | } | ||
586 | |||
587 | static int bcap_streamoff(struct file *file, void *priv, | ||
588 | enum v4l2_buf_type buf_type) | ||
589 | { | ||
590 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
591 | struct bcap_fh *fh = file->private_data; | ||
592 | |||
593 | if (!fh->io_allowed) | ||
594 | return -EBUSY; | ||
595 | |||
596 | return vb2_streamoff(&bcap_dev->buffer_queue, buf_type); | ||
597 | } | ||
598 | |||
599 | static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) | 428 | static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) |
600 | { | 429 | { |
601 | struct bcap_device *bcap_dev = video_drvdata(file); | 430 | struct bcap_device *bcap_dev = video_drvdata(file); |
431 | struct v4l2_input input; | ||
432 | |||
433 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
434 | if (!(input.capabilities & V4L2_IN_CAP_STD)) | ||
435 | return -ENODATA; | ||
602 | 436 | ||
603 | return v4l2_subdev_call(bcap_dev->sd, video, querystd, std); | 437 | return v4l2_subdev_call(bcap_dev->sd, video, querystd, std); |
604 | } | 438 | } |
@@ -606,6 +440,11 @@ static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) | |||
606 | static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) | 440 | static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) |
607 | { | 441 | { |
608 | struct bcap_device *bcap_dev = video_drvdata(file); | 442 | struct bcap_device *bcap_dev = video_drvdata(file); |
443 | struct v4l2_input input; | ||
444 | |||
445 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
446 | if (!(input.capabilities & V4L2_IN_CAP_STD)) | ||
447 | return -ENODATA; | ||
609 | 448 | ||
610 | *std = bcap_dev->std; | 449 | *std = bcap_dev->std; |
611 | return 0; | 450 | return 0; |
@@ -614,8 +453,13 @@ static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) | |||
614 | static int bcap_s_std(struct file *file, void *priv, v4l2_std_id std) | 453 | static int bcap_s_std(struct file *file, void *priv, v4l2_std_id std) |
615 | { | 454 | { |
616 | struct bcap_device *bcap_dev = video_drvdata(file); | 455 | struct bcap_device *bcap_dev = video_drvdata(file); |
456 | struct v4l2_input input; | ||
617 | int ret; | 457 | int ret; |
618 | 458 | ||
459 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
460 | if (!(input.capabilities & V4L2_IN_CAP_STD)) | ||
461 | return -ENODATA; | ||
462 | |||
619 | if (vb2_is_busy(&bcap_dev->buffer_queue)) | 463 | if (vb2_is_busy(&bcap_dev->buffer_queue)) |
620 | return -EBUSY; | 464 | return -EBUSY; |
621 | 465 | ||
@@ -631,6 +475,11 @@ static int bcap_enum_dv_timings(struct file *file, void *priv, | |||
631 | struct v4l2_enum_dv_timings *timings) | 475 | struct v4l2_enum_dv_timings *timings) |
632 | { | 476 | { |
633 | struct bcap_device *bcap_dev = video_drvdata(file); | 477 | struct bcap_device *bcap_dev = video_drvdata(file); |
478 | struct v4l2_input input; | ||
479 | |||
480 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
481 | if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS)) | ||
482 | return -ENODATA; | ||
634 | 483 | ||
635 | timings->pad = 0; | 484 | timings->pad = 0; |
636 | 485 | ||
@@ -642,6 +491,11 @@ static int bcap_query_dv_timings(struct file *file, void *priv, | |||
642 | struct v4l2_dv_timings *timings) | 491 | struct v4l2_dv_timings *timings) |
643 | { | 492 | { |
644 | struct bcap_device *bcap_dev = video_drvdata(file); | 493 | struct bcap_device *bcap_dev = video_drvdata(file); |
494 | struct v4l2_input input; | ||
495 | |||
496 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
497 | if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS)) | ||
498 | return -ENODATA; | ||
645 | 499 | ||
646 | return v4l2_subdev_call(bcap_dev->sd, video, | 500 | return v4l2_subdev_call(bcap_dev->sd, video, |
647 | query_dv_timings, timings); | 501 | query_dv_timings, timings); |
@@ -651,6 +505,11 @@ static int bcap_g_dv_timings(struct file *file, void *priv, | |||
651 | struct v4l2_dv_timings *timings) | 505 | struct v4l2_dv_timings *timings) |
652 | { | 506 | { |
653 | struct bcap_device *bcap_dev = video_drvdata(file); | 507 | struct bcap_device *bcap_dev = video_drvdata(file); |
508 | struct v4l2_input input; | ||
509 | |||
510 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
511 | if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS)) | ||
512 | return -ENODATA; | ||
654 | 513 | ||
655 | *timings = bcap_dev->dv_timings; | 514 | *timings = bcap_dev->dv_timings; |
656 | return 0; | 515 | return 0; |
@@ -660,7 +519,13 @@ static int bcap_s_dv_timings(struct file *file, void *priv, | |||
660 | struct v4l2_dv_timings *timings) | 519 | struct v4l2_dv_timings *timings) |
661 | { | 520 | { |
662 | struct bcap_device *bcap_dev = video_drvdata(file); | 521 | struct bcap_device *bcap_dev = video_drvdata(file); |
522 | struct v4l2_input input; | ||
663 | int ret; | 523 | int ret; |
524 | |||
525 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
526 | if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS)) | ||
527 | return -ENODATA; | ||
528 | |||
664 | if (vb2_is_busy(&bcap_dev->buffer_queue)) | 529 | if (vb2_is_busy(&bcap_dev->buffer_queue)) |
665 | return -EBUSY; | 530 | return -EBUSY; |
666 | 531 | ||
@@ -881,12 +746,14 @@ static const struct v4l2_ioctl_ops bcap_ioctl_ops = { | |||
881 | .vidioc_g_dv_timings = bcap_g_dv_timings, | 746 | .vidioc_g_dv_timings = bcap_g_dv_timings, |
882 | .vidioc_query_dv_timings = bcap_query_dv_timings, | 747 | .vidioc_query_dv_timings = bcap_query_dv_timings, |
883 | .vidioc_enum_dv_timings = bcap_enum_dv_timings, | 748 | .vidioc_enum_dv_timings = bcap_enum_dv_timings, |
884 | .vidioc_reqbufs = bcap_reqbufs, | 749 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
885 | .vidioc_querybuf = bcap_querybuf, | 750 | .vidioc_create_bufs = vb2_ioctl_create_bufs, |
886 | .vidioc_qbuf = bcap_qbuf, | 751 | .vidioc_querybuf = vb2_ioctl_querybuf, |
887 | .vidioc_dqbuf = bcap_dqbuf, | 752 | .vidioc_qbuf = vb2_ioctl_qbuf, |
888 | .vidioc_streamon = bcap_streamon, | 753 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
889 | .vidioc_streamoff = bcap_streamoff, | 754 | .vidioc_expbuf = vb2_ioctl_expbuf, |
755 | .vidioc_streamon = vb2_ioctl_streamon, | ||
756 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
890 | .vidioc_g_parm = bcap_g_parm, | 757 | .vidioc_g_parm = bcap_g_parm, |
891 | .vidioc_s_parm = bcap_s_parm, | 758 | .vidioc_s_parm = bcap_s_parm, |
892 | .vidioc_log_status = bcap_log_status, | 759 | .vidioc_log_status = bcap_log_status, |
@@ -894,14 +761,14 @@ static const struct v4l2_ioctl_ops bcap_ioctl_ops = { | |||
894 | 761 | ||
895 | static struct v4l2_file_operations bcap_fops = { | 762 | static struct v4l2_file_operations bcap_fops = { |
896 | .owner = THIS_MODULE, | 763 | .owner = THIS_MODULE, |
897 | .open = bcap_open, | 764 | .open = v4l2_fh_open, |
898 | .release = bcap_release, | 765 | .release = vb2_fop_release, |
899 | .unlocked_ioctl = video_ioctl2, | 766 | .unlocked_ioctl = video_ioctl2, |
900 | .mmap = bcap_mmap, | 767 | .mmap = vb2_fop_mmap, |
901 | #ifndef CONFIG_MMU | 768 | #ifndef CONFIG_MMU |
902 | .get_unmapped_area = bcap_get_unmapped_area, | 769 | .get_unmapped_area = vb2_fop_get_unmapped_area, |
903 | #endif | 770 | #endif |
904 | .poll = bcap_poll | 771 | .poll = vb2_fop_poll |
905 | }; | 772 | }; |
906 | 773 | ||
907 | static int bcap_probe(struct platform_device *pdev) | 774 | static int bcap_probe(struct platform_device *pdev) |
@@ -942,27 +809,20 @@ static int bcap_probe(struct platform_device *pdev) | |||
942 | goto err_free_ppi; | 809 | goto err_free_ppi; |
943 | } | 810 | } |
944 | 811 | ||
945 | vfd = video_device_alloc(); | 812 | vfd = &bcap_dev->video_dev; |
946 | if (!vfd) { | ||
947 | ret = -ENOMEM; | ||
948 | v4l2_err(pdev->dev.driver, "Unable to alloc video device\n"); | ||
949 | goto err_cleanup_ctx; | ||
950 | } | ||
951 | |||
952 | /* initialize field of video device */ | 813 | /* initialize field of video device */ |
953 | vfd->release = video_device_release; | 814 | vfd->release = video_device_release_empty; |
954 | vfd->fops = &bcap_fops; | 815 | vfd->fops = &bcap_fops; |
955 | vfd->ioctl_ops = &bcap_ioctl_ops; | 816 | vfd->ioctl_ops = &bcap_ioctl_ops; |
956 | vfd->tvnorms = 0; | 817 | vfd->tvnorms = 0; |
957 | vfd->v4l2_dev = &bcap_dev->v4l2_dev; | 818 | vfd->v4l2_dev = &bcap_dev->v4l2_dev; |
958 | strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name)); | 819 | strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name)); |
959 | bcap_dev->video_dev = vfd; | ||
960 | 820 | ||
961 | ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev); | 821 | ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev); |
962 | if (ret) { | 822 | if (ret) { |
963 | v4l2_err(pdev->dev.driver, | 823 | v4l2_err(pdev->dev.driver, |
964 | "Unable to register v4l2 device\n"); | 824 | "Unable to register v4l2 device\n"); |
965 | goto err_release_vdev; | 825 | goto err_cleanup_ctx; |
966 | } | 826 | } |
967 | v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n"); | 827 | v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n"); |
968 | 828 | ||
@@ -978,13 +838,14 @@ static int bcap_probe(struct platform_device *pdev) | |||
978 | /* initialize queue */ | 838 | /* initialize queue */ |
979 | q = &bcap_dev->buffer_queue; | 839 | q = &bcap_dev->buffer_queue; |
980 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 840 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
981 | q->io_modes = VB2_MMAP; | 841 | q->io_modes = VB2_MMAP | VB2_DMABUF; |
982 | q->drv_priv = bcap_dev; | 842 | q->drv_priv = bcap_dev; |
983 | q->buf_struct_size = sizeof(struct bcap_buffer); | 843 | q->buf_struct_size = sizeof(struct bcap_buffer); |
984 | q->ops = &bcap_video_qops; | 844 | q->ops = &bcap_video_qops; |
985 | q->mem_ops = &vb2_dma_contig_memops; | 845 | q->mem_ops = &vb2_dma_contig_memops; |
986 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 846 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
987 | q->lock = &bcap_dev->mutex; | 847 | q->lock = &bcap_dev->mutex; |
848 | q->min_buffers_needed = 1; | ||
988 | 849 | ||
989 | ret = vb2_queue_init(q); | 850 | ret = vb2_queue_init(q); |
990 | if (ret) | 851 | if (ret) |
@@ -997,15 +858,16 @@ static int bcap_probe(struct platform_device *pdev) | |||
997 | INIT_LIST_HEAD(&bcap_dev->dma_queue); | 858 | INIT_LIST_HEAD(&bcap_dev->dma_queue); |
998 | 859 | ||
999 | vfd->lock = &bcap_dev->mutex; | 860 | vfd->lock = &bcap_dev->mutex; |
861 | vfd->queue = q; | ||
1000 | 862 | ||
1001 | /* register video device */ | 863 | /* register video device */ |
1002 | ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1); | 864 | ret = video_register_device(&bcap_dev->video_dev, VFL_TYPE_GRABBER, -1); |
1003 | if (ret) { | 865 | if (ret) { |
1004 | v4l2_err(&bcap_dev->v4l2_dev, | 866 | v4l2_err(&bcap_dev->v4l2_dev, |
1005 | "Unable to register video device\n"); | 867 | "Unable to register video device\n"); |
1006 | goto err_free_handler; | 868 | goto err_free_handler; |
1007 | } | 869 | } |
1008 | video_set_drvdata(bcap_dev->video_dev, bcap_dev); | 870 | video_set_drvdata(&bcap_dev->video_dev, bcap_dev); |
1009 | v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n", | 871 | v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n", |
1010 | video_device_node_name(vfd)); | 872 | video_device_node_name(vfd)); |
1011 | 873 | ||
@@ -1083,15 +945,11 @@ static int bcap_probe(struct platform_device *pdev) | |||
1083 | } | 945 | } |
1084 | return 0; | 946 | return 0; |
1085 | err_unreg_vdev: | 947 | err_unreg_vdev: |
1086 | video_unregister_device(bcap_dev->video_dev); | 948 | video_unregister_device(&bcap_dev->video_dev); |
1087 | bcap_dev->video_dev = NULL; | ||
1088 | err_free_handler: | 949 | err_free_handler: |
1089 | v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); | 950 | v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); |
1090 | err_unreg_v4l2: | 951 | err_unreg_v4l2: |
1091 | v4l2_device_unregister(&bcap_dev->v4l2_dev); | 952 | v4l2_device_unregister(&bcap_dev->v4l2_dev); |
1092 | err_release_vdev: | ||
1093 | if (bcap_dev->video_dev) | ||
1094 | video_device_release(bcap_dev->video_dev); | ||
1095 | err_cleanup_ctx: | 953 | err_cleanup_ctx: |
1096 | vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); | 954 | vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); |
1097 | err_free_ppi: | 955 | err_free_ppi: |
@@ -1108,7 +966,7 @@ static int bcap_remove(struct platform_device *pdev) | |||
1108 | struct bcap_device, v4l2_dev); | 966 | struct bcap_device, v4l2_dev); |
1109 | 967 | ||
1110 | bcap_free_sensor_formats(bcap_dev); | 968 | bcap_free_sensor_formats(bcap_dev); |
1111 | video_unregister_device(bcap_dev->video_dev); | 969 | video_unregister_device(&bcap_dev->video_dev); |
1112 | v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); | 970 | v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); |
1113 | v4l2_device_unregister(v4l2_dev); | 971 | v4l2_device_unregister(v4l2_dev); |
1114 | vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); | 972 | vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); |