diff options
-rw-r--r-- | drivers/media/video/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/video/soc_camera.c | 90 | ||||
-rw-r--r-- | include/media/soc_camera.h | 11 |
3 files changed, 84 insertions, 18 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index d40a8fc01bf..07c5baaa2d0 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -750,6 +750,7 @@ config SOC_CAMERA | |||
750 | tristate "SoC camera support" | 750 | tristate "SoC camera support" |
751 | depends on VIDEO_V4L2 && HAS_DMA && I2C | 751 | depends on VIDEO_V4L2 && HAS_DMA && I2C |
752 | select VIDEOBUF_GEN | 752 | select VIDEOBUF_GEN |
753 | select VIDEOBUF2_CORE | ||
753 | help | 754 | help |
754 | SoC Camera is a common API to several cameras, not connecting | 755 | SoC Camera is a common API to several cameras, not connecting |
755 | over a bus like PCI or USB. For example some i2c camera connected | 756 | over a bus like PCI or USB. For example some i2c camera connected |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 67611ad6af9..fa80a4a914d 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 | ||
236 | static int soc_camera_qbuf(struct file *file, void *priv, | 246 | static 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 | ||
249 | static int soc_camera_dqbuf(struct file *file, void *priv, | 263 | static 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 | */ |
493 | einitvb: | ||
468 | esfmt: | 494 | esfmt: |
469 | pm_runtime_disable(&icd->vdev->dev); | 495 | pm_runtime_disable(&icd->vdev->dev); |
470 | eresume: | 496 | eresume: |
@@ -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, | |||
519 | static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) | 547 | static 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 | ||
587 | void 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 | } | ||
592 | EXPORT_SYMBOL(soc_camera_lock); | ||
593 | |||
594 | void 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 | } | ||
599 | EXPORT_SYMBOL(soc_camera_unlock); | ||
600 | |||
555 | static struct v4l2_file_operations soc_camera_fops = { | 601 | static 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 || |
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 09b827192ae..e29ff74fbe3 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/videodev2.h> | 18 | #include <linux/videodev2.h> |
19 | #include <media/videobuf-core.h> | 19 | #include <media/videobuf-core.h> |
20 | #include <media/videobuf2-core.h> | ||
20 | #include <media/v4l2-device.h> | 21 | #include <media/v4l2-device.h> |
21 | 22 | ||
22 | extern struct bus_type soc_camera_bus_type; | 23 | extern struct bus_type soc_camera_bus_type; |
@@ -44,7 +45,10 @@ struct soc_camera_device { | |||
44 | int use_count; | 45 | int use_count; |
45 | struct mutex video_lock; /* Protects device data */ | 46 | struct mutex video_lock; /* Protects device data */ |
46 | struct file *streamer; /* stream owner */ | 47 | struct file *streamer; /* stream owner */ |
47 | struct videobuf_queue vb_vidq; | 48 | union { |
49 | struct videobuf_queue vb_vidq; | ||
50 | struct vb2_queue vb2_vidq; | ||
51 | }; | ||
48 | }; | 52 | }; |
49 | 53 | ||
50 | struct soc_camera_host { | 54 | struct soc_camera_host { |
@@ -78,6 +82,8 @@ struct soc_camera_host_ops { | |||
78 | int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); | 82 | int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); |
79 | void (*init_videobuf)(struct videobuf_queue *, | 83 | void (*init_videobuf)(struct videobuf_queue *, |
80 | struct soc_camera_device *); | 84 | struct soc_camera_device *); |
85 | int (*init_videobuf2)(struct vb2_queue *, | ||
86 | struct soc_camera_device *); | ||
81 | int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *); | 87 | int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *); |
82 | int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); | 88 | int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); |
83 | int (*set_bus_param)(struct soc_camera_device *, __u32); | 89 | int (*set_bus_param)(struct soc_camera_device *, __u32); |
@@ -300,4 +306,7 @@ static inline struct video_device *soc_camera_i2c_to_vdev(struct i2c_client *cli | |||
300 | return icd->vdev; | 306 | return icd->vdev; |
301 | } | 307 | } |
302 | 308 | ||
309 | void soc_camera_lock(struct vb2_queue *vq); | ||
310 | void soc_camera_unlock(struct vb2_queue *vq); | ||
311 | |||
303 | #endif | 312 | #endif |