diff options
author | Lad, Prabhakar <prabhakar.csengg@gmail.com> | 2014-05-16 09:33:54 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-06-17 11:04:44 -0400 |
commit | a4965c592e3323967170daa8fdde798b6f84e8ee (patch) | |
tree | 7847d7353367fae90ba51e0e4bd5956a88383073 /drivers/media/platform/davinci | |
parent | 4015bef6495f5153fccbb8d4476f71511af82f4d (diff) |
[media] media: davinci: vpif_capture: fix v4l-compliance issues
This patch does the following:
1: sets initial default format during probe.
2: removes spurious messages.
3: optimize vpif_s/try_fmt_vid_out code.
Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/platform/davinci')
-rw-r--r-- | drivers/media/platform/davinci/vpif_capture.c | 191 |
1 files changed, 54 insertions, 137 deletions
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index cb746e9a73f6..ee0a5fcecbe4 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c | |||
@@ -498,10 +498,28 @@ static int vpif_update_std_info(struct channel_obj *ch) | |||
498 | common->width = std_info->width; | 498 | common->width = std_info->width; |
499 | common->fmt.fmt.pix.height = std_info->height; | 499 | common->fmt.fmt.pix.height = std_info->height; |
500 | common->height = std_info->height; | 500 | common->height = std_info->height; |
501 | common->fmt.fmt.pix.sizeimage = common->height * common->width * 2; | ||
501 | common->fmt.fmt.pix.bytesperline = std_info->width; | 502 | common->fmt.fmt.pix.bytesperline = std_info->width; |
502 | vpifparams->video_params.hpitch = std_info->width; | 503 | vpifparams->video_params.hpitch = std_info->width; |
503 | vpifparams->video_params.storage_mode = std_info->frm_fmt; | 504 | vpifparams->video_params.storage_mode = std_info->frm_fmt; |
504 | 505 | ||
506 | if (vid_ch->stdid) | ||
507 | common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
508 | else | ||
509 | common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709; | ||
510 | |||
511 | if (ch->vpifparams.std_info.frm_fmt) | ||
512 | common->fmt.fmt.pix.field = V4L2_FIELD_NONE; | ||
513 | else | ||
514 | common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
515 | |||
516 | if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) | ||
517 | common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8; | ||
518 | else | ||
519 | common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; | ||
520 | |||
521 | common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
522 | |||
505 | return 0; | 523 | return 0; |
506 | } | 524 | } |
507 | 525 | ||
@@ -578,24 +596,6 @@ static void vpif_calculate_offsets(struct channel_obj *ch) | |||
578 | } | 596 | } |
579 | 597 | ||
580 | /** | 598 | /** |
581 | * vpif_config_format: configure default frame format in the device | ||
582 | * ch : ptr to channel object | ||
583 | */ | ||
584 | static void vpif_config_format(struct channel_obj *ch) | ||
585 | { | ||
586 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
587 | |||
588 | vpif_dbg(2, debug, "vpif_config_format\n"); | ||
589 | |||
590 | common->fmt.fmt.pix.field = V4L2_FIELD_ANY; | ||
591 | if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) | ||
592 | common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8; | ||
593 | else | ||
594 | common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; | ||
595 | common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
596 | } | ||
597 | |||
598 | /** | ||
599 | * vpif_get_default_field() - Get default field type based on interface | 599 | * vpif_get_default_field() - Get default field type based on interface |
600 | * @vpif_params - ptr to vpif params | 600 | * @vpif_params - ptr to vpif params |
601 | */ | 601 | */ |
@@ -607,112 +607,6 @@ static inline enum v4l2_field vpif_get_default_field( | |||
607 | } | 607 | } |
608 | 608 | ||
609 | /** | 609 | /** |
610 | * vpif_check_format() - check given pixel format for compatibility | ||
611 | * @ch - channel ptr | ||
612 | * @pixfmt - Given pixel format | ||
613 | * @update - update the values as per hardware requirement | ||
614 | * | ||
615 | * Check the application pixel format for S_FMT and update the input | ||
616 | * values as per hardware limits for TRY_FMT. The default pixel and | ||
617 | * field format is selected based on interface type. | ||
618 | */ | ||
619 | static int vpif_check_format(struct channel_obj *ch, | ||
620 | struct v4l2_pix_format *pixfmt, | ||
621 | int update) | ||
622 | { | ||
623 | struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); | ||
624 | struct vpif_params *vpif_params = &ch->vpifparams; | ||
625 | enum v4l2_field field = pixfmt->field; | ||
626 | u32 sizeimage, hpitch, vpitch; | ||
627 | int ret = -EINVAL; | ||
628 | |||
629 | vpif_dbg(2, debug, "vpif_check_format\n"); | ||
630 | /** | ||
631 | * first check for the pixel format. If if_type is Raw bayer, | ||
632 | * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only | ||
633 | * V4L2_PIX_FMT_YUV422P is supported | ||
634 | */ | ||
635 | if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) { | ||
636 | if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) { | ||
637 | if (!update) { | ||
638 | vpif_dbg(2, debug, "invalid pix format\n"); | ||
639 | goto exit; | ||
640 | } | ||
641 | pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8; | ||
642 | } | ||
643 | } else { | ||
644 | if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) { | ||
645 | if (!update) { | ||
646 | vpif_dbg(2, debug, "invalid pixel format\n"); | ||
647 | goto exit; | ||
648 | } | ||
649 | pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P; | ||
650 | } | ||
651 | } | ||
652 | |||
653 | if (!(VPIF_VALID_FIELD(field))) { | ||
654 | if (!update) { | ||
655 | vpif_dbg(2, debug, "invalid field format\n"); | ||
656 | goto exit; | ||
657 | } | ||
658 | /** | ||
659 | * By default use FIELD_NONE for RAW Bayer capture | ||
660 | * and FIELD_INTERLACED for other interfaces | ||
661 | */ | ||
662 | field = vpif_get_default_field(&vpif_params->iface); | ||
663 | } else if (field == V4L2_FIELD_ANY) | ||
664 | /* unsupported field. Use default */ | ||
665 | field = vpif_get_default_field(&vpif_params->iface); | ||
666 | |||
667 | /* validate the hpitch */ | ||
668 | hpitch = pixfmt->bytesperline; | ||
669 | if (hpitch < vpif_params->std_info.width) { | ||
670 | if (!update) { | ||
671 | vpif_dbg(2, debug, "invalid hpitch\n"); | ||
672 | goto exit; | ||
673 | } | ||
674 | hpitch = vpif_params->std_info.width; | ||
675 | } | ||
676 | |||
677 | sizeimage = pixfmt->sizeimage; | ||
678 | |||
679 | vpitch = sizeimage / (hpitch * 2); | ||
680 | |||
681 | /* validate the vpitch */ | ||
682 | if (vpitch < vpif_params->std_info.height) { | ||
683 | if (!update) { | ||
684 | vpif_dbg(2, debug, "Invalid vpitch\n"); | ||
685 | goto exit; | ||
686 | } | ||
687 | vpitch = vpif_params->std_info.height; | ||
688 | } | ||
689 | |||
690 | /* Check for 8 byte alignment */ | ||
691 | if (!ALIGN(hpitch, 8)) { | ||
692 | if (!update) { | ||
693 | vpif_dbg(2, debug, "invalid pitch alignment\n"); | ||
694 | goto exit; | ||
695 | } | ||
696 | /* adjust to next 8 byte boundary */ | ||
697 | hpitch = (((hpitch + 7) / 8) * 8); | ||
698 | } | ||
699 | /* if update is set, modify the bytesperline and sizeimage */ | ||
700 | if (update) { | ||
701 | pixfmt->bytesperline = hpitch; | ||
702 | pixfmt->sizeimage = hpitch * vpitch * 2; | ||
703 | } | ||
704 | /** | ||
705 | * Image width and height is always based on current standard width and | ||
706 | * height | ||
707 | */ | ||
708 | pixfmt->width = common->fmt.fmt.pix.width; | ||
709 | pixfmt->height = common->fmt.fmt.pix.height; | ||
710 | return 0; | ||
711 | exit: | ||
712 | return ret; | ||
713 | } | ||
714 | |||
715 | /** | ||
716 | * vpif_config_addr() - function to configure buffer address in vpif | 610 | * vpif_config_addr() - function to configure buffer address in vpif |
717 | * @ch - channel ptr | 611 | * @ch - channel ptr |
718 | * @muxmode - channel mux mode | 612 | * @muxmode - channel mux mode |
@@ -922,9 +816,6 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) | |||
922 | return -EINVAL; | 816 | return -EINVAL; |
923 | } | 817 | } |
924 | 818 | ||
925 | /* Configure the default format information */ | ||
926 | vpif_config_format(ch); | ||
927 | |||
928 | /* set standard in the sub device */ | 819 | /* set standard in the sub device */ |
929 | ret = v4l2_subdev_call(ch->sd, video, s_std, std_id); | 820 | ret = v4l2_subdev_call(ch->sd, video, s_std, std_id); |
930 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) { | 821 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) { |
@@ -951,10 +842,8 @@ static int vpif_enum_input(struct file *file, void *priv, | |||
951 | 842 | ||
952 | chan_cfg = &config->chan_config[ch->channel_id]; | 843 | chan_cfg = &config->chan_config[ch->channel_id]; |
953 | 844 | ||
954 | if (input->index >= chan_cfg->input_count) { | 845 | if (input->index >= chan_cfg->input_count) |
955 | vpif_dbg(1, debug, "Invalid input index\n"); | ||
956 | return -EINVAL; | 846 | return -EINVAL; |
957 | } | ||
958 | 847 | ||
959 | memcpy(input, &chan_cfg->inputs[input->index].input, | 848 | memcpy(input, &chan_cfg->inputs[input->index].input, |
960 | sizeof(*input)); | 849 | sizeof(*input)); |
@@ -1043,8 +932,34 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv, | |||
1043 | struct video_device *vdev = video_devdata(file); | 932 | struct video_device *vdev = video_devdata(file); |
1044 | struct channel_obj *ch = video_get_drvdata(vdev); | 933 | struct channel_obj *ch = video_get_drvdata(vdev); |
1045 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; | 934 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; |
935 | struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); | ||
936 | struct vpif_params *vpif_params = &ch->vpifparams; | ||
937 | |||
938 | /* | ||
939 | * to supress v4l-compliance warnings silently correct | ||
940 | * the pixelformat | ||
941 | */ | ||
942 | if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) { | ||
943 | if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) | ||
944 | pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8; | ||
945 | } else { | ||
946 | if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) | ||
947 | pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P; | ||
948 | } | ||
949 | |||
950 | common->fmt.fmt.pix.pixelformat = pixfmt->pixelformat; | ||
1046 | 951 | ||
1047 | return vpif_check_format(ch, pixfmt, 1); | 952 | vpif_update_std_info(ch); |
953 | |||
954 | pixfmt->field = common->fmt.fmt.pix.field; | ||
955 | pixfmt->colorspace = common->fmt.fmt.pix.colorspace; | ||
956 | pixfmt->bytesperline = common->fmt.fmt.pix.width; | ||
957 | pixfmt->width = common->fmt.fmt.pix.width; | ||
958 | pixfmt->height = common->fmt.fmt.pix.height; | ||
959 | pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2; | ||
960 | pixfmt->priv = 0; | ||
961 | |||
962 | return 0; | ||
1048 | } | 963 | } |
1049 | 964 | ||
1050 | 965 | ||
@@ -1082,20 +997,17 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv, | |||
1082 | struct video_device *vdev = video_devdata(file); | 997 | struct video_device *vdev = video_devdata(file); |
1083 | struct channel_obj *ch = video_get_drvdata(vdev); | 998 | struct channel_obj *ch = video_get_drvdata(vdev); |
1084 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 999 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
1085 | struct v4l2_pix_format *pixfmt; | 1000 | int ret; |
1086 | int ret = 0; | ||
1087 | 1001 | ||
1088 | vpif_dbg(2, debug, "%s\n", __func__); | 1002 | vpif_dbg(2, debug, "%s\n", __func__); |
1089 | 1003 | ||
1090 | if (vb2_is_busy(&common->buffer_queue)) | 1004 | if (vb2_is_busy(&common->buffer_queue)) |
1091 | return -EBUSY; | 1005 | return -EBUSY; |
1092 | 1006 | ||
1093 | pixfmt = &fmt->fmt.pix; | 1007 | ret = vpif_try_fmt_vid_cap(file, priv, fmt); |
1094 | /* Check for valid field format */ | ||
1095 | ret = vpif_check_format(ch, pixfmt, 0); | ||
1096 | |||
1097 | if (ret) | 1008 | if (ret) |
1098 | return ret; | 1009 | return ret; |
1010 | |||
1099 | /* store the format in the channel object */ | 1011 | /* store the format in the channel object */ |
1100 | common->fmt = *fmt; | 1012 | common->fmt = *fmt; |
1101 | return 0; | 1013 | return 0; |
@@ -1443,6 +1355,11 @@ static int vpif_probe_complete(void) | |||
1443 | if (err) | 1355 | if (err) |
1444 | goto probe_out; | 1356 | goto probe_out; |
1445 | 1357 | ||
1358 | /* set initial format */ | ||
1359 | ch->video.stdid = V4L2_STD_525_60; | ||
1360 | memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings)); | ||
1361 | vpif_update_std_info(ch); | ||
1362 | |||
1446 | /* Initialize vb2 queue */ | 1363 | /* Initialize vb2 queue */ |
1447 | q = &common->buffer_queue; | 1364 | q = &common->buffer_queue; |
1448 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1365 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |