diff options
Diffstat (limited to 'drivers/media/platform/blackfin/bfin_capture.c')
-rw-r--r-- | drivers/media/platform/blackfin/bfin_capture.c | 189 |
1 files changed, 155 insertions, 34 deletions
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 1aad2a65d2f3..5f209d5810dc 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c | |||
@@ -52,6 +52,7 @@ struct bcap_format { | |||
52 | u32 pixelformat; | 52 | u32 pixelformat; |
53 | enum v4l2_mbus_pixelcode mbus_code; | 53 | enum v4l2_mbus_pixelcode mbus_code; |
54 | int bpp; /* bits per pixel */ | 54 | int bpp; /* bits per pixel */ |
55 | int dlen; /* data length for ppi in bits */ | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | struct bcap_buffer { | 58 | struct bcap_buffer { |
@@ -76,18 +77,20 @@ struct bcap_device { | |||
76 | unsigned int cur_input; | 77 | unsigned int cur_input; |
77 | /* current selected standard */ | 78 | /* current selected standard */ |
78 | v4l2_std_id std; | 79 | v4l2_std_id std; |
80 | /* current selected dv_timings */ | ||
81 | struct v4l2_dv_timings dv_timings; | ||
79 | /* used to store pixel format */ | 82 | /* used to store pixel format */ |
80 | struct v4l2_pix_format fmt; | 83 | struct v4l2_pix_format fmt; |
81 | /* bits per pixel*/ | 84 | /* bits per pixel*/ |
82 | int bpp; | 85 | int bpp; |
86 | /* data length for ppi in bits */ | ||
87 | int dlen; | ||
83 | /* used to store sensor supported format */ | 88 | /* used to store sensor supported format */ |
84 | struct bcap_format *sensor_formats; | 89 | struct bcap_format *sensor_formats; |
85 | /* number of sensor formats array */ | 90 | /* number of sensor formats array */ |
86 | int num_sensor_formats; | 91 | int num_sensor_formats; |
87 | /* pointing to current video buffer */ | 92 | /* pointing to current video buffer */ |
88 | struct bcap_buffer *cur_frm; | 93 | struct bcap_buffer *cur_frm; |
89 | /* pointing to next video buffer */ | ||
90 | struct bcap_buffer *next_frm; | ||
91 | /* buffer queue used in videobuf2 */ | 94 | /* buffer queue used in videobuf2 */ |
92 | struct vb2_queue buffer_queue; | 95 | struct vb2_queue buffer_queue; |
93 | /* allocator-specific contexts for each plane */ | 96 | /* allocator-specific contexts for each plane */ |
@@ -116,24 +119,35 @@ static const struct bcap_format bcap_formats[] = { | |||
116 | .pixelformat = V4L2_PIX_FMT_UYVY, | 119 | .pixelformat = V4L2_PIX_FMT_UYVY, |
117 | .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, | 120 | .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, |
118 | .bpp = 16, | 121 | .bpp = 16, |
122 | .dlen = 8, | ||
119 | }, | 123 | }, |
120 | { | 124 | { |
121 | .desc = "YCbCr 4:2:2 Interleaved YUYV", | 125 | .desc = "YCbCr 4:2:2 Interleaved YUYV", |
122 | .pixelformat = V4L2_PIX_FMT_YUYV, | 126 | .pixelformat = V4L2_PIX_FMT_YUYV, |
123 | .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, | 127 | .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, |
124 | .bpp = 16, | 128 | .bpp = 16, |
129 | .dlen = 8, | ||
130 | }, | ||
131 | { | ||
132 | .desc = "YCbCr 4:2:2 Interleaved UYVY", | ||
133 | .pixelformat = V4L2_PIX_FMT_UYVY, | ||
134 | .mbus_code = V4L2_MBUS_FMT_UYVY8_1X16, | ||
135 | .bpp = 16, | ||
136 | .dlen = 16, | ||
125 | }, | 137 | }, |
126 | { | 138 | { |
127 | .desc = "RGB 565", | 139 | .desc = "RGB 565", |
128 | .pixelformat = V4L2_PIX_FMT_RGB565, | 140 | .pixelformat = V4L2_PIX_FMT_RGB565, |
129 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, | 141 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, |
130 | .bpp = 16, | 142 | .bpp = 16, |
143 | .dlen = 8, | ||
131 | }, | 144 | }, |
132 | { | 145 | { |
133 | .desc = "RGB 444", | 146 | .desc = "RGB 444", |
134 | .pixelformat = V4L2_PIX_FMT_RGB444, | 147 | .pixelformat = V4L2_PIX_FMT_RGB444, |
135 | .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, | 148 | .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, |
136 | .bpp = 16, | 149 | .bpp = 16, |
150 | .dlen = 8, | ||
137 | }, | 151 | }, |
138 | 152 | ||
139 | }; | 153 | }; |
@@ -366,9 +380,39 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
366 | params.width = bcap_dev->fmt.width; | 380 | params.width = bcap_dev->fmt.width; |
367 | params.height = bcap_dev->fmt.height; | 381 | params.height = bcap_dev->fmt.height; |
368 | params.bpp = bcap_dev->bpp; | 382 | params.bpp = bcap_dev->bpp; |
383 | params.dlen = bcap_dev->dlen; | ||
369 | params.ppi_control = bcap_dev->cfg->ppi_control; | 384 | params.ppi_control = bcap_dev->cfg->ppi_control; |
370 | params.int_mask = bcap_dev->cfg->int_mask; | 385 | params.int_mask = bcap_dev->cfg->int_mask; |
371 | params.blank_clocks = bcap_dev->cfg->blank_clocks; | 386 | if (bcap_dev->cfg->inputs[bcap_dev->cur_input].capabilities |
387 | & V4L2_IN_CAP_CUSTOM_TIMINGS) { | ||
388 | struct v4l2_bt_timings *bt = &bcap_dev->dv_timings.bt; | ||
389 | |||
390 | params.hdelay = bt->hsync + bt->hbackporch; | ||
391 | params.vdelay = bt->vsync + bt->vbackporch; | ||
392 | params.line = bt->hfrontporch + bt->hsync | ||
393 | + bt->hbackporch + bt->width; | ||
394 | params.frame = bt->vfrontporch + bt->vsync | ||
395 | + bt->vbackporch + bt->height; | ||
396 | if (bt->interlaced) | ||
397 | params.frame += bt->il_vfrontporch + bt->il_vsync | ||
398 | + bt->il_vbackporch; | ||
399 | } else if (bcap_dev->cfg->inputs[bcap_dev->cur_input].capabilities | ||
400 | & V4L2_IN_CAP_STD) { | ||
401 | params.hdelay = 0; | ||
402 | params.vdelay = 0; | ||
403 | if (bcap_dev->std & V4L2_STD_525_60) { | ||
404 | params.line = 858; | ||
405 | params.frame = 525; | ||
406 | } else { | ||
407 | params.line = 864; | ||
408 | params.frame = 625; | ||
409 | } | ||
410 | } else { | ||
411 | params.hdelay = 0; | ||
412 | params.vdelay = 0; | ||
413 | params.line = params.width + bcap_dev->cfg->blank_pixels; | ||
414 | params.frame = params.height; | ||
415 | } | ||
372 | ret = ppi->ops->set_params(ppi, ¶ms); | 416 | ret = ppi->ops->set_params(ppi, ¶ms); |
373 | if (ret < 0) { | 417 | if (ret < 0) { |
374 | v4l2_err(&bcap_dev->v4l2_dev, | 418 | v4l2_err(&bcap_dev->v4l2_dev, |
@@ -409,10 +453,10 @@ static int bcap_stop_streaming(struct vb2_queue *vq) | |||
409 | 453 | ||
410 | /* release all active buffers */ | 454 | /* release all active buffers */ |
411 | while (!list_empty(&bcap_dev->dma_queue)) { | 455 | while (!list_empty(&bcap_dev->dma_queue)) { |
412 | bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, | 456 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, |
413 | struct bcap_buffer, list); | 457 | struct bcap_buffer, list); |
414 | list_del(&bcap_dev->next_frm->list); | 458 | list_del(&bcap_dev->cur_frm->list); |
415 | vb2_buffer_done(&bcap_dev->next_frm->vb, VB2_BUF_STATE_ERROR); | 459 | vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR); |
416 | } | 460 | } |
417 | return 0; | 461 | return 0; |
418 | } | 462 | } |
@@ -484,17 +528,26 @@ static irqreturn_t bcap_isr(int irq, void *dev_id) | |||
484 | { | 528 | { |
485 | struct ppi_if *ppi = dev_id; | 529 | struct ppi_if *ppi = dev_id; |
486 | struct bcap_device *bcap_dev = ppi->priv; | 530 | struct bcap_device *bcap_dev = ppi->priv; |
487 | struct timeval timevalue; | ||
488 | struct vb2_buffer *vb = &bcap_dev->cur_frm->vb; | 531 | struct vb2_buffer *vb = &bcap_dev->cur_frm->vb; |
489 | dma_addr_t addr; | 532 | dma_addr_t addr; |
490 | 533 | ||
491 | spin_lock(&bcap_dev->lock); | 534 | spin_lock(&bcap_dev->lock); |
492 | 535 | ||
493 | if (bcap_dev->cur_frm != bcap_dev->next_frm) { | 536 | if (!list_empty(&bcap_dev->dma_queue)) { |
494 | do_gettimeofday(&timevalue); | 537 | v4l2_get_timestamp(&vb->v4l2_buf.timestamp); |
495 | vb->v4l2_buf.timestamp = timevalue; | 538 | if (ppi->err) { |
496 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); | 539 | vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); |
497 | bcap_dev->cur_frm = bcap_dev->next_frm; | 540 | ppi->err = false; |
541 | } else { | ||
542 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); | ||
543 | } | ||
544 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | ||
545 | struct bcap_buffer, list); | ||
546 | list_del(&bcap_dev->cur_frm->list); | ||
547 | } else { | ||
548 | /* clear error flag, we will get a new frame */ | ||
549 | if (ppi->err) | ||
550 | ppi->err = false; | ||
498 | } | 551 | } |
499 | 552 | ||
500 | ppi->ops->stop(ppi); | 553 | ppi->ops->stop(ppi); |
@@ -502,13 +555,8 @@ static irqreturn_t bcap_isr(int irq, void *dev_id) | |||
502 | if (bcap_dev->stop) { | 555 | if (bcap_dev->stop) { |
503 | complete(&bcap_dev->comp); | 556 | complete(&bcap_dev->comp); |
504 | } else { | 557 | } else { |
505 | if (!list_empty(&bcap_dev->dma_queue)) { | 558 | addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); |
506 | bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, | 559 | ppi->ops->update_addr(ppi, (unsigned long)addr); |
507 | struct bcap_buffer, list); | ||
508 | list_del(&bcap_dev->next_frm->list); | ||
509 | addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->next_frm->vb, 0); | ||
510 | ppi->ops->update_addr(ppi, (unsigned long)addr); | ||
511 | } | ||
512 | ppi->ops->start(ppi); | 560 | ppi->ops->start(ppi); |
513 | } | 561 | } |
514 | 562 | ||
@@ -542,9 +590,8 @@ static int bcap_streamon(struct file *file, void *priv, | |||
542 | } | 590 | } |
543 | 591 | ||
544 | /* get the next frame from the dma queue */ | 592 | /* get the next frame from the dma queue */ |
545 | bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, | 593 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, |
546 | struct bcap_buffer, list); | 594 | struct bcap_buffer, list); |
547 | bcap_dev->cur_frm = bcap_dev->next_frm; | ||
548 | /* remove buffer from the dma queue */ | 595 | /* remove buffer from the dma queue */ |
549 | list_del(&bcap_dev->cur_frm->list); | 596 | list_del(&bcap_dev->cur_frm->list); |
550 | addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); | 597 | addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); |
@@ -602,6 +649,37 @@ static int bcap_s_std(struct file *file, void *priv, v4l2_std_id *std) | |||
602 | return 0; | 649 | return 0; |
603 | } | 650 | } |
604 | 651 | ||
652 | static int bcap_g_dv_timings(struct file *file, void *priv, | ||
653 | struct v4l2_dv_timings *timings) | ||
654 | { | ||
655 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
656 | int ret; | ||
657 | |||
658 | ret = v4l2_subdev_call(bcap_dev->sd, video, | ||
659 | g_dv_timings, timings); | ||
660 | if (ret < 0) | ||
661 | return ret; | ||
662 | |||
663 | bcap_dev->dv_timings = *timings; | ||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static int bcap_s_dv_timings(struct file *file, void *priv, | ||
668 | struct v4l2_dv_timings *timings) | ||
669 | { | ||
670 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
671 | int ret; | ||
672 | if (vb2_is_busy(&bcap_dev->buffer_queue)) | ||
673 | return -EBUSY; | ||
674 | |||
675 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_dv_timings, timings); | ||
676 | if (ret < 0) | ||
677 | return ret; | ||
678 | |||
679 | bcap_dev->dv_timings = *timings; | ||
680 | return 0; | ||
681 | } | ||
682 | |||
605 | static int bcap_enum_input(struct file *file, void *priv, | 683 | static int bcap_enum_input(struct file *file, void *priv, |
606 | struct v4l2_input *input) | 684 | struct v4l2_input *input) |
607 | { | 685 | { |
@@ -650,13 +728,15 @@ static int bcap_s_input(struct file *file, void *priv, unsigned int index) | |||
650 | return ret; | 728 | return ret; |
651 | } | 729 | } |
652 | bcap_dev->cur_input = index; | 730 | bcap_dev->cur_input = index; |
731 | /* if this route has specific config, update ppi control */ | ||
732 | if (route->ppi_control) | ||
733 | config->ppi_control = route->ppi_control; | ||
653 | return 0; | 734 | return 0; |
654 | } | 735 | } |
655 | 736 | ||
656 | static int bcap_try_format(struct bcap_device *bcap, | 737 | static int bcap_try_format(struct bcap_device *bcap, |
657 | struct v4l2_pix_format *pixfmt, | 738 | struct v4l2_pix_format *pixfmt, |
658 | enum v4l2_mbus_pixelcode *mbus_code, | 739 | struct bcap_format *bcap_fmt) |
659 | int *bpp) | ||
660 | { | 740 | { |
661 | struct bcap_format *sf = bcap->sensor_formats; | 741 | struct bcap_format *sf = bcap->sensor_formats; |
662 | struct bcap_format *fmt = NULL; | 742 | struct bcap_format *fmt = NULL; |
@@ -671,16 +751,20 @@ static int bcap_try_format(struct bcap_device *bcap, | |||
671 | if (i == bcap->num_sensor_formats) | 751 | if (i == bcap->num_sensor_formats) |
672 | fmt = &sf[0]; | 752 | fmt = &sf[0]; |
673 | 753 | ||
674 | if (mbus_code) | ||
675 | *mbus_code = fmt->mbus_code; | ||
676 | if (bpp) | ||
677 | *bpp = fmt->bpp; | ||
678 | v4l2_fill_mbus_format(&mbus_fmt, pixfmt, fmt->mbus_code); | 754 | v4l2_fill_mbus_format(&mbus_fmt, pixfmt, fmt->mbus_code); |
679 | ret = v4l2_subdev_call(bcap->sd, video, | 755 | ret = v4l2_subdev_call(bcap->sd, video, |
680 | try_mbus_fmt, &mbus_fmt); | 756 | try_mbus_fmt, &mbus_fmt); |
681 | if (ret < 0) | 757 | if (ret < 0) |
682 | return ret; | 758 | return ret; |
683 | v4l2_fill_pix_format(pixfmt, &mbus_fmt); | 759 | v4l2_fill_pix_format(pixfmt, &mbus_fmt); |
760 | if (bcap_fmt) { | ||
761 | for (i = 0; i < bcap->num_sensor_formats; i++) { | ||
762 | fmt = &sf[i]; | ||
763 | if (mbus_fmt.code == fmt->mbus_code) | ||
764 | break; | ||
765 | } | ||
766 | *bcap_fmt = *fmt; | ||
767 | } | ||
684 | pixfmt->bytesperline = pixfmt->width * fmt->bpp / 8; | 768 | pixfmt->bytesperline = pixfmt->width * fmt->bpp / 8; |
685 | pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; | 769 | pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; |
686 | return 0; | 770 | return 0; |
@@ -709,7 +793,7 @@ static int bcap_try_fmt_vid_cap(struct file *file, void *priv, | |||
709 | struct bcap_device *bcap_dev = video_drvdata(file); | 793 | struct bcap_device *bcap_dev = video_drvdata(file); |
710 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; | 794 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; |
711 | 795 | ||
712 | return bcap_try_format(bcap_dev, pixfmt, NULL, NULL); | 796 | return bcap_try_format(bcap_dev, pixfmt, NULL); |
713 | } | 797 | } |
714 | 798 | ||
715 | static int bcap_g_fmt_vid_cap(struct file *file, void *priv, | 799 | static int bcap_g_fmt_vid_cap(struct file *file, void *priv, |
@@ -726,24 +810,25 @@ static int bcap_s_fmt_vid_cap(struct file *file, void *priv, | |||
726 | { | 810 | { |
727 | struct bcap_device *bcap_dev = video_drvdata(file); | 811 | struct bcap_device *bcap_dev = video_drvdata(file); |
728 | struct v4l2_mbus_framefmt mbus_fmt; | 812 | struct v4l2_mbus_framefmt mbus_fmt; |
729 | enum v4l2_mbus_pixelcode mbus_code; | 813 | struct bcap_format bcap_fmt; |
730 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; | 814 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; |
731 | int ret, bpp; | 815 | int ret; |
732 | 816 | ||
733 | if (vb2_is_busy(&bcap_dev->buffer_queue)) | 817 | if (vb2_is_busy(&bcap_dev->buffer_queue)) |
734 | return -EBUSY; | 818 | return -EBUSY; |
735 | 819 | ||
736 | /* see if format works */ | 820 | /* see if format works */ |
737 | ret = bcap_try_format(bcap_dev, pixfmt, &mbus_code, &bpp); | 821 | ret = bcap_try_format(bcap_dev, pixfmt, &bcap_fmt); |
738 | if (ret < 0) | 822 | if (ret < 0) |
739 | return ret; | 823 | return ret; |
740 | 824 | ||
741 | v4l2_fill_mbus_format(&mbus_fmt, pixfmt, mbus_code); | 825 | v4l2_fill_mbus_format(&mbus_fmt, pixfmt, bcap_fmt.mbus_code); |
742 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_mbus_fmt, &mbus_fmt); | 826 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_mbus_fmt, &mbus_fmt); |
743 | if (ret < 0) | 827 | if (ret < 0) |
744 | return ret; | 828 | return ret; |
745 | bcap_dev->fmt = *pixfmt; | 829 | bcap_dev->fmt = *pixfmt; |
746 | bcap_dev->bpp = bpp; | 830 | bcap_dev->bpp = bcap_fmt.bpp; |
831 | bcap_dev->dlen = bcap_fmt.dlen; | ||
747 | return 0; | 832 | return 0; |
748 | } | 833 | } |
749 | 834 | ||
@@ -834,6 +919,8 @@ static const struct v4l2_ioctl_ops bcap_ioctl_ops = { | |||
834 | .vidioc_querystd = bcap_querystd, | 919 | .vidioc_querystd = bcap_querystd, |
835 | .vidioc_s_std = bcap_s_std, | 920 | .vidioc_s_std = bcap_s_std, |
836 | .vidioc_g_std = bcap_g_std, | 921 | .vidioc_g_std = bcap_g_std, |
922 | .vidioc_s_dv_timings = bcap_s_dv_timings, | ||
923 | .vidioc_g_dv_timings = bcap_g_dv_timings, | ||
837 | .vidioc_reqbufs = bcap_reqbufs, | 924 | .vidioc_reqbufs = bcap_reqbufs, |
838 | .vidioc_querybuf = bcap_querybuf, | 925 | .vidioc_querybuf = bcap_querybuf, |
839 | .vidioc_qbuf = bcap_qbuf, | 926 | .vidioc_qbuf = bcap_qbuf, |
@@ -869,6 +956,7 @@ static int bcap_probe(struct platform_device *pdev) | |||
869 | struct i2c_adapter *i2c_adap; | 956 | struct i2c_adapter *i2c_adap; |
870 | struct bfin_capture_config *config; | 957 | struct bfin_capture_config *config; |
871 | struct vb2_queue *q; | 958 | struct vb2_queue *q; |
959 | struct bcap_route *route; | ||
872 | int ret; | 960 | int ret; |
873 | 961 | ||
874 | config = pdev->dev.platform_data; | 962 | config = pdev->dev.platform_data; |
@@ -978,6 +1066,12 @@ static int bcap_probe(struct platform_device *pdev) | |||
978 | NULL); | 1066 | NULL); |
979 | if (bcap_dev->sd) { | 1067 | if (bcap_dev->sd) { |
980 | int i; | 1068 | int i; |
1069 | if (!config->num_inputs) { | ||
1070 | v4l2_err(&bcap_dev->v4l2_dev, | ||
1071 | "Unable to work without input\n"); | ||
1072 | goto err_unreg_vdev; | ||
1073 | } | ||
1074 | |||
981 | /* update tvnorms from the sub devices */ | 1075 | /* update tvnorms from the sub devices */ |
982 | for (i = 0; i < config->num_inputs; i++) | 1076 | for (i = 0; i < config->num_inputs; i++) |
983 | vfd->tvnorms |= config->inputs[i].std; | 1077 | vfd->tvnorms |= config->inputs[i].std; |
@@ -989,8 +1083,24 @@ static int bcap_probe(struct platform_device *pdev) | |||
989 | 1083 | ||
990 | v4l2_info(&bcap_dev->v4l2_dev, "v4l2 sub device registered\n"); | 1084 | v4l2_info(&bcap_dev->v4l2_dev, "v4l2 sub device registered\n"); |
991 | 1085 | ||
1086 | /* | ||
1087 | * explicitly set input, otherwise some boards | ||
1088 | * may not work at the state as we expected | ||
1089 | */ | ||
1090 | route = &config->routes[0]; | ||
1091 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_routing, | ||
1092 | route->input, route->output, 0); | ||
1093 | if ((ret < 0) && (ret != -ENOIOCTLCMD)) { | ||
1094 | v4l2_err(&bcap_dev->v4l2_dev, "Failed to set input\n"); | ||
1095 | goto err_unreg_vdev; | ||
1096 | } | ||
1097 | bcap_dev->cur_input = 0; | ||
1098 | /* if this route has specific config, update ppi control */ | ||
1099 | if (route->ppi_control) | ||
1100 | config->ppi_control = route->ppi_control; | ||
1101 | |||
992 | /* now we can probe the default state */ | 1102 | /* now we can probe the default state */ |
993 | if (vfd->tvnorms) { | 1103 | if (config->inputs[0].capabilities & V4L2_IN_CAP_STD) { |
994 | v4l2_std_id std; | 1104 | v4l2_std_id std; |
995 | ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std); | 1105 | ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std); |
996 | if (ret) { | 1106 | if (ret) { |
@@ -1000,6 +1110,17 @@ static int bcap_probe(struct platform_device *pdev) | |||
1000 | } | 1110 | } |
1001 | bcap_dev->std = std; | 1111 | bcap_dev->std = std; |
1002 | } | 1112 | } |
1113 | if (config->inputs[0].capabilities & V4L2_IN_CAP_CUSTOM_TIMINGS) { | ||
1114 | struct v4l2_dv_timings dv_timings; | ||
1115 | ret = v4l2_subdev_call(bcap_dev->sd, video, | ||
1116 | g_dv_timings, &dv_timings); | ||
1117 | if (ret) { | ||
1118 | v4l2_err(&bcap_dev->v4l2_dev, | ||
1119 | "Unable to get dv timings\n"); | ||
1120 | goto err_unreg_vdev; | ||
1121 | } | ||
1122 | bcap_dev->dv_timings = dv_timings; | ||
1123 | } | ||
1003 | ret = bcap_init_sensor_formats(bcap_dev); | 1124 | ret = bcap_init_sensor_formats(bcap_dev); |
1004 | if (ret) { | 1125 | if (ret) { |
1005 | v4l2_err(&bcap_dev->v4l2_dev, | 1126 | v4l2_err(&bcap_dev->v4l2_dev, |