aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Martin <javier.martin@vista-silicon.com>2012-01-30 07:14:11 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-08 07:40:45 -0500
commitfb51cbdd3ec868b903bd706aa7db065c8c36bcd4 (patch)
treebf747879b2c7bf6a0b4926f3f89b432c9f3deb0d
parentc6a41e3271c61f6f5aec1a91b4458330d4266e5f (diff)
[media] media i.MX27 camera: add start_stream and stop_stream callbacks
Add "start_stream" and "stop_stream" callback in order to enable and disable the eMMa-PrP properly and save CPU usage avoiding IRQs when the device is not streaming. This also makes the driver return 0 as the sequence number of the first frame. Signed-off-by: Javier Martin <javier.martin@vista-silicon.com> [g.liakhovetski@gmx.de: remove the mx27_camera_emma() macro] Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/mx2_camera.c100
1 files changed, 75 insertions, 25 deletions
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 22f5dbcf6db8..2e232092fc10 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -373,7 +373,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
373 writel(pcdev->csicr1, pcdev->base_csi + CSICR1); 373 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
374 374
375 pcdev->icd = icd; 375 pcdev->icd = icd;
376 pcdev->frame_count = 0; 376 pcdev->frame_count = -1;
377 377
378 dev_info(icd->parent, "Camera driver attached to camera %d\n", 378 dev_info(icd->parent, "Camera driver attached to camera %d\n",
379 icd->devnum); 379 icd->devnum);
@@ -644,11 +644,79 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)
644 spin_unlock_irqrestore(&pcdev->lock, flags); 644 spin_unlock_irqrestore(&pcdev->lock, flags);
645} 645}
646 646
647static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
648{
649 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
650 struct soc_camera_host *ici =
651 to_soc_camera_host(icd->parent);
652 struct mx2_camera_dev *pcdev = ici->priv;
653 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
654
655 if (cpu_is_mx27()) {
656 unsigned long flags;
657 if (count < 2)
658 return -EINVAL;
659
660 spin_lock_irqsave(&pcdev->lock, flags);
661 if (prp->cfg.channel == 1) {
662 writel(PRP_CNTL_CH1EN |
663 PRP_CNTL_CSIEN |
664 prp->cfg.in_fmt |
665 prp->cfg.out_fmt |
666 PRP_CNTL_CH1_LEN |
667 PRP_CNTL_CH1BYP |
668 PRP_CNTL_CH1_TSKIP(0) |
669 PRP_CNTL_IN_TSKIP(0),
670 pcdev->base_emma + PRP_CNTL);
671 } else {
672 writel(PRP_CNTL_CH2EN |
673 PRP_CNTL_CSIEN |
674 prp->cfg.in_fmt |
675 prp->cfg.out_fmt |
676 PRP_CNTL_CH2_LEN |
677 PRP_CNTL_CH2_TSKIP(0) |
678 PRP_CNTL_IN_TSKIP(0),
679 pcdev->base_emma + PRP_CNTL);
680 }
681 spin_unlock_irqrestore(&pcdev->lock, flags);
682 }
683
684 return 0;
685}
686
687static int mx2_stop_streaming(struct vb2_queue *q)
688{
689 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
690 struct soc_camera_host *ici =
691 to_soc_camera_host(icd->parent);
692 struct mx2_camera_dev *pcdev = ici->priv;
693 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
694 unsigned long flags;
695 u32 cntl;
696
697 spin_lock_irqsave(&pcdev->lock, flags);
698 if (cpu_is_mx27()) {
699 cntl = readl(pcdev->base_emma + PRP_CNTL);
700 if (prp->cfg.channel == 1) {
701 writel(cntl & ~PRP_CNTL_CH1EN,
702 pcdev->base_emma + PRP_CNTL);
703 } else {
704 writel(cntl & ~PRP_CNTL_CH2EN,
705 pcdev->base_emma + PRP_CNTL);
706 }
707 }
708 spin_unlock_irqrestore(&pcdev->lock, flags);
709
710 return 0;
711}
712
647static struct vb2_ops mx2_videobuf_ops = { 713static struct vb2_ops mx2_videobuf_ops = {
648 .queue_setup = mx2_videobuf_setup, 714 .queue_setup = mx2_videobuf_setup,
649 .buf_prepare = mx2_videobuf_prepare, 715 .buf_prepare = mx2_videobuf_prepare,
650 .buf_queue = mx2_videobuf_queue, 716 .buf_queue = mx2_videobuf_queue,
651 .buf_cleanup = mx2_videobuf_release, 717 .buf_cleanup = mx2_videobuf_release,
718 .start_streaming = mx2_start_streaming,
719 .stop_streaming = mx2_stop_streaming,
652}; 720};
653 721
654static int mx2_camera_init_videobuf(struct vb2_queue *q, 722static int mx2_camera_init_videobuf(struct vb2_queue *q,
@@ -706,16 +774,6 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
706 writel(pcdev->discard_buffer_dma, 774 writel(pcdev->discard_buffer_dma,
707 pcdev->base_emma + PRP_DEST_RGB2_PTR); 775 pcdev->base_emma + PRP_DEST_RGB2_PTR);
708 776
709 writel(PRP_CNTL_CH1EN |
710 PRP_CNTL_CSIEN |
711 prp->cfg.in_fmt |
712 prp->cfg.out_fmt |
713 PRP_CNTL_CH1_LEN |
714 PRP_CNTL_CH1BYP |
715 PRP_CNTL_CH1_TSKIP(0) |
716 PRP_CNTL_IN_TSKIP(0),
717 pcdev->base_emma + PRP_CNTL);
718
719 writel((icd->user_width << 16) | icd->user_height, 777 writel((icd->user_width << 16) | icd->user_height,
720 pcdev->base_emma + PRP_SRC_FRAME_SIZE); 778 pcdev->base_emma + PRP_SRC_FRAME_SIZE);
721 writel((icd->user_width << 16) | icd->user_height, 779 writel((icd->user_width << 16) | icd->user_height,
@@ -743,15 +801,6 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
743 pcdev->base_emma + PRP_SOURCE_CR_PTR); 801 pcdev->base_emma + PRP_SOURCE_CR_PTR);
744 } 802 }
745 803
746 writel(PRP_CNTL_CH2EN |
747 PRP_CNTL_CSIEN |
748 prp->cfg.in_fmt |
749 prp->cfg.out_fmt |
750 PRP_CNTL_CH2_LEN |
751 PRP_CNTL_CH2_TSKIP(0) |
752 PRP_CNTL_IN_TSKIP(0),
753 pcdev->base_emma + PRP_CNTL);
754
755 writel((icd->user_width << 16) | icd->user_height, 804 writel((icd->user_width << 16) | icd->user_height,
756 pcdev->base_emma + PRP_SRC_FRAME_SIZE); 805 pcdev->base_emma + PRP_SRC_FRAME_SIZE);
757 806
@@ -1156,11 +1205,12 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
1156 1205
1157 list_del_init(&buf->queue); 1206 list_del_init(&buf->queue);
1158 do_gettimeofday(&vb->v4l2_buf.timestamp); 1207 do_gettimeofday(&vb->v4l2_buf.timestamp);
1159 pcdev->frame_count++;
1160 vb->v4l2_buf.sequence = pcdev->frame_count; 1208 vb->v4l2_buf.sequence = pcdev->frame_count;
1161 vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 1209 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
1162 } 1210 }
1163 1211
1212 pcdev->frame_count++;
1213
1164 if (list_empty(&pcdev->capture)) { 1214 if (list_empty(&pcdev->capture)) {
1165 if (prp->cfg.channel == 1) { 1215 if (prp->cfg.channel == 1) {
1166 writel(pcdev->discard_buffer_dma, pcdev->base_emma + 1216 writel(pcdev->discard_buffer_dma, pcdev->base_emma +