aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2011-01-29 10:44:51 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:15 -0400
commit592c2aba266ca5be0dce300d0400817d943d49af (patch)
tree91f36e6afca6a010ee5ac5ac2fe46a2559104e13 /drivers/media/video/soc_camera.c
parentbd94f588283b167f7fa8c2dc2164dcd2f4a4a7a5 (diff)
[media] V4L: soc-camera: extend to also support videobuf2
Extend soc-camera core to also support the videobuf2 API. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/soc_camera.c')
-rw-r--r--drivers/media/video/soc_camera.c90
1 files changed, 73 insertions, 17 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 67611ad6af96..fa80a4a914d4 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -34,6 +34,7 @@
34#include <media/v4l2-ioctl.h> 34#include <media/v4l2-ioctl.h>
35#include <media/v4l2-dev.h> 35#include <media/v4l2-dev.h>
36#include <media/videobuf-core.h> 36#include <media/videobuf-core.h>
37#include <media/videobuf2-core.h>
37#include <media/soc_mediabus.h> 38#include <media/soc_mediabus.h>
38 39
39/* Default to VGA resolution */ 40/* Default to VGA resolution */
@@ -212,11 +213,16 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
212 if (icd->streamer && icd->streamer != file) 213 if (icd->streamer && icd->streamer != file)
213 return -EBUSY; 214 return -EBUSY;
214 215
215 ret = videobuf_reqbufs(&icd->vb_vidq, p); 216 if (ici->ops->init_videobuf) {
216 if (ret < 0) 217 ret = videobuf_reqbufs(&icd->vb_vidq, p);
217 return ret; 218 if (ret < 0)
219 return ret;
220
221 ret = ici->ops->reqbufs(icd, p);
222 } else {
223 ret = vb2_reqbufs(&icd->vb2_vidq, p);
224 }
218 225
219 ret = ici->ops->reqbufs(icd, p);
220 if (!ret && !icd->streamer) 226 if (!ret && !icd->streamer)
221 icd->streamer = file; 227 icd->streamer = file;
222 228
@@ -227,36 +233,48 @@ static int soc_camera_querybuf(struct file *file, void *priv,
227 struct v4l2_buffer *p) 233 struct v4l2_buffer *p)
228{ 234{
229 struct soc_camera_device *icd = file->private_data; 235 struct soc_camera_device *icd = file->private_data;
236 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
230 237
231 WARN_ON(priv != file->private_data); 238 WARN_ON(priv != file->private_data);
232 239
233 return videobuf_querybuf(&icd->vb_vidq, p); 240 if (ici->ops->init_videobuf)
241 return videobuf_querybuf(&icd->vb_vidq, p);
242 else
243 return vb2_querybuf(&icd->vb2_vidq, p);
234} 244}
235 245
236static int soc_camera_qbuf(struct file *file, void *priv, 246static int soc_camera_qbuf(struct file *file, void *priv,
237 struct v4l2_buffer *p) 247 struct v4l2_buffer *p)
238{ 248{
239 struct soc_camera_device *icd = file->private_data; 249 struct soc_camera_device *icd = file->private_data;
250 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
240 251
241 WARN_ON(priv != file->private_data); 252 WARN_ON(priv != file->private_data);
242 253
243 if (icd->streamer != file) 254 if (icd->streamer != file)
244 return -EBUSY; 255 return -EBUSY;
245 256
246 return videobuf_qbuf(&icd->vb_vidq, p); 257 if (ici->ops->init_videobuf)
258 return videobuf_qbuf(&icd->vb_vidq, p);
259 else
260 return vb2_qbuf(&icd->vb2_vidq, p);
247} 261}
248 262
249static int soc_camera_dqbuf(struct file *file, void *priv, 263static int soc_camera_dqbuf(struct file *file, void *priv,
250 struct v4l2_buffer *p) 264 struct v4l2_buffer *p)
251{ 265{
252 struct soc_camera_device *icd = file->private_data; 266 struct soc_camera_device *icd = file->private_data;
267 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
253 268
254 WARN_ON(priv != file->private_data); 269 WARN_ON(priv != file->private_data);
255 270
256 if (icd->streamer != file) 271 if (icd->streamer != file)
257 return -EBUSY; 272 return -EBUSY;
258 273
259 return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK); 274 if (ici->ops->init_videobuf)
275 return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK);
276 else
277 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
260} 278}
261 279
262/* Always entered with .video_lock held */ 280/* Always entered with .video_lock held */
@@ -372,8 +390,9 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
372 icd->user_width = pix->width; 390 icd->user_width = pix->width;
373 icd->user_height = pix->height; 391 icd->user_height = pix->height;
374 icd->colorspace = pix->colorspace; 392 icd->colorspace = pix->colorspace;
375 icd->vb_vidq.field = 393 icd->field = pix->field;
376 icd->field = pix->field; 394 if (ici->ops->init_videobuf)
395 icd->vb_vidq.field = pix->field;
377 396
378 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 397 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
379 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", 398 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
@@ -453,7 +472,13 @@ static int soc_camera_open(struct file *file)
453 if (ret < 0) 472 if (ret < 0)
454 goto esfmt; 473 goto esfmt;
455 474
456 ici->ops->init_videobuf(&icd->vb_vidq, icd); 475 if (ici->ops->init_videobuf) {
476 ici->ops->init_videobuf(&icd->vb_vidq, icd);
477 } else {
478 ret = ici->ops->init_videobuf2(&icd->vb2_vidq, icd);
479 if (ret < 0)
480 goto einitvb;
481 }
457 } 482 }
458 483
459 file->private_data = icd; 484 file->private_data = icd;
@@ -465,6 +490,7 @@ static int soc_camera_open(struct file *file)
465 * First four errors are entered with the .video_lock held 490 * First four errors are entered with the .video_lock held
466 * and use_count == 1 491 * and use_count == 1
467 */ 492 */
493einitvb:
468esfmt: 494esfmt:
469 pm_runtime_disable(&icd->vdev->dev); 495 pm_runtime_disable(&icd->vdev->dev);
470eresume: 496eresume:
@@ -491,6 +517,8 @@ static int soc_camera_close(struct file *file)
491 pm_runtime_disable(&icd->vdev->dev); 517 pm_runtime_disable(&icd->vdev->dev);
492 518
493 ici->ops->remove(icd); 519 ici->ops->remove(icd);
520 if (ici->ops->init_videobuf2)
521 vb2_queue_release(&icd->vb2_vidq);
494 522
495 soc_camera_power_set(icd, icl, 0); 523 soc_camera_power_set(icd, icl, 0);
496 } 524 }
@@ -519,6 +547,7 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
519static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) 547static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
520{ 548{
521 struct soc_camera_device *icd = file->private_data; 549 struct soc_camera_device *icd = file->private_data;
550 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
522 int err; 551 int err;
523 552
524 dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); 553 dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
@@ -526,7 +555,10 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
526 if (icd->streamer != file) 555 if (icd->streamer != file)
527 return -EBUSY; 556 return -EBUSY;
528 557
529 err = videobuf_mmap_mapper(&icd->vb_vidq, vma); 558 if (ici->ops->init_videobuf)
559 err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
560 else
561 err = vb2_mmap(&icd->vb2_vidq, vma);
530 562
531 dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n", 563 dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n",
532 (unsigned long)vma->vm_start, 564 (unsigned long)vma->vm_start,
@@ -544,7 +576,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
544 if (icd->streamer != file) 576 if (icd->streamer != file)
545 return -EBUSY; 577 return -EBUSY;
546 578
547 if (list_empty(&icd->vb_vidq.stream)) { 579 if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) {
548 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); 580 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n");
549 return POLLERR; 581 return POLLERR;
550 } 582 }
@@ -552,6 +584,20 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
552 return ici->ops->poll(file, pt); 584 return ici->ops->poll(file, pt);
553} 585}
554 586
587void soc_camera_lock(struct vb2_queue *vq)
588{
589 struct soc_camera_device *icd = vb2_get_drv_priv(vq);
590 mutex_lock(&icd->video_lock);
591}
592EXPORT_SYMBOL(soc_camera_lock);
593
594void soc_camera_unlock(struct vb2_queue *vq)
595{
596 struct soc_camera_device *icd = vb2_get_drv_priv(vq);
597 mutex_unlock(&icd->video_lock);
598}
599EXPORT_SYMBOL(soc_camera_unlock);
600
555static struct v4l2_file_operations soc_camera_fops = { 601static struct v4l2_file_operations soc_camera_fops = {
556 .owner = THIS_MODULE, 602 .owner = THIS_MODULE,
557 .open = soc_camera_open, 603 .open = soc_camera_open,
@@ -615,7 +661,7 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
615 661
616 pix->width = icd->user_width; 662 pix->width = icd->user_width;
617 pix->height = icd->user_height; 663 pix->height = icd->user_height;
618 pix->field = icd->vb_vidq.field; 664 pix->field = icd->field;
619 pix->pixelformat = icd->current_fmt->host_fmt->fourcc; 665 pix->pixelformat = icd->current_fmt->host_fmt->fourcc;
620 pix->bytesperline = soc_mbus_bytes_per_line(pix->width, 666 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
621 icd->current_fmt->host_fmt); 667 icd->current_fmt->host_fmt);
@@ -644,6 +690,7 @@ static int soc_camera_streamon(struct file *file, void *priv,
644 enum v4l2_buf_type i) 690 enum v4l2_buf_type i)
645{ 691{
646 struct soc_camera_device *icd = file->private_data; 692 struct soc_camera_device *icd = file->private_data;
693 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
647 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 694 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
648 int ret; 695 int ret;
649 696
@@ -656,7 +703,11 @@ static int soc_camera_streamon(struct file *file, void *priv,
656 return -EBUSY; 703 return -EBUSY;
657 704
658 /* This calls buf_queue from host driver's videobuf_queue_ops */ 705 /* This calls buf_queue from host driver's videobuf_queue_ops */
659 ret = videobuf_streamon(&icd->vb_vidq); 706 if (ici->ops->init_videobuf)
707 ret = videobuf_streamon(&icd->vb_vidq);
708 else
709 ret = vb2_streamon(&icd->vb2_vidq, i);
710
660 if (!ret) 711 if (!ret)
661 v4l2_subdev_call(sd, video, s_stream, 1); 712 v4l2_subdev_call(sd, video, s_stream, 1);
662 713
@@ -668,6 +719,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
668{ 719{
669 struct soc_camera_device *icd = file->private_data; 720 struct soc_camera_device *icd = file->private_data;
670 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 721 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
722 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
671 723
672 WARN_ON(priv != file->private_data); 724 WARN_ON(priv != file->private_data);
673 725
@@ -681,7 +733,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
681 * This calls buf_release from host driver's videobuf_queue_ops for all 733 * This calls buf_release from host driver's videobuf_queue_ops for all
682 * remaining buffers. When the last buffer is freed, stop capture 734 * remaining buffers. When the last buffer is freed, stop capture
683 */ 735 */
684 videobuf_streamoff(&icd->vb_vidq); 736 if (ici->ops->init_videobuf)
737 videobuf_streamoff(&icd->vb_vidq);
738 else
739 vb2_streamoff(&icd->vb2_vidq, i);
685 740
686 v4l2_subdev_call(sd, video, s_stream, 0); 741 v4l2_subdev_call(sd, video, s_stream, 0);
687 742
@@ -1226,8 +1281,9 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1226 !ici->ops->set_fmt || 1281 !ici->ops->set_fmt ||
1227 !ici->ops->set_bus_param || 1282 !ici->ops->set_bus_param ||
1228 !ici->ops->querycap || 1283 !ici->ops->querycap ||
1229 !ici->ops->init_videobuf || 1284 ((!ici->ops->init_videobuf ||
1230 !ici->ops->reqbufs || 1285 !ici->ops->reqbufs) &&
1286 !ici->ops->init_videobuf2) ||
1231 !ici->ops->add || 1287 !ici->ops->add ||
1232 !ici->ops->remove || 1288 !ici->ops->remove ||
1233 !ici->ops->poll || 1289 !ici->ops->poll ||