aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-08-10 05:11:12 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-09-13 15:09:59 -0400
commitc61bd6a0e2a92009f3879457eeec75b5ad102303 (patch)
tree267c448b50c3a0ee0515a838dfbcd109f98c0578 /drivers/media/v4l2-core
parentc2a667fa2b40ccb7d21a99ffae53610699a3102c (diff)
[media] v4l2-common: add CVT and GTF detection functions
These two helper functions detect whether the analog video timings detected by the video receiver match the VESA CVT or GTF standards. They basically do the inverse of the CVT and GTF modeline calculations. This patch also adds a helper function that will determine the aspect ratio based on the provided EDID values. This aspect ratio can be given to the GTF helper function. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c325
1 files changed, 325 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 028133ba4c6b..b6ee929f7ba5 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -630,6 +630,331 @@ bool v4l_match_dv_timings(const struct v4l2_dv_timings *t1,
630} 630}
631EXPORT_SYMBOL_GPL(v4l_match_dv_timings); 631EXPORT_SYMBOL_GPL(v4l_match_dv_timings);
632 632
633/*
634 * CVT defines
635 * Based on Coordinated Video Timings Standard
636 * version 1.1 September 10, 2003
637 */
638
639#define CVT_PXL_CLK_GRAN 250000 /* pixel clock granularity */
640
641/* Normal blanking */
642#define CVT_MIN_V_BPORCH 7 /* lines */
643#define CVT_MIN_V_PORCH_RND 3 /* lines */
644#define CVT_MIN_VSYNC_BP 550 /* min time of vsync + back porch (us) */
645
646/* Normal blanking for CVT uses GTF to calculate horizontal blanking */
647#define CVT_CELL_GRAN 8 /* character cell granularity */
648#define CVT_M 600 /* blanking formula gradient */
649#define CVT_C 40 /* blanking formula offset */
650#define CVT_K 128 /* blanking formula scaling factor */
651#define CVT_J 20 /* blanking formula scaling factor */
652#define CVT_C_PRIME (((CVT_C - CVT_J) * CVT_K / 256) + CVT_J)
653#define CVT_M_PRIME (CVT_K * CVT_M / 256)
654
655/* Reduced Blanking */
656#define CVT_RB_MIN_V_BPORCH 7 /* lines */
657#define CVT_RB_V_FPORCH 3 /* lines */
658#define CVT_RB_MIN_V_BLANK 460 /* us */
659#define CVT_RB_H_SYNC 32 /* pixels */
660#define CVT_RB_H_BPORCH 80 /* pixels */
661#define CVT_RB_H_BLANK 160 /* pixels */
662
663/** v4l2_detect_cvt - detect if the given timings follow the CVT standard
664 * @frame_height - the total height of the frame (including blanking) in lines.
665 * @hfreq - the horizontal frequency in Hz.
666 * @vsync - the height of the vertical sync in lines.
667 * @polarities - the horizontal and vertical polarities (same as struct
668 * v4l2_bt_timings polarities).
669 * @fmt - the resulting timings.
670 *
671 * This function will attempt to detect if the given values correspond to a
672 * valid CVT format. If so, then it will return true, and fmt will be filled
673 * in with the found CVT timings.
674 */
675bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
676 u32 polarities, struct v4l2_dv_timings *fmt)
677{
678 int v_fp, v_bp, h_fp, h_bp, hsync;
679 int frame_width, image_height, image_width;
680 bool reduced_blanking;
681 unsigned pix_clk;
682
683 if (vsync < 4 || vsync > 7)
684 return false;
685
686 if (polarities == V4L2_DV_VSYNC_POS_POL)
687 reduced_blanking = false;
688 else if (polarities == V4L2_DV_HSYNC_POS_POL)
689 reduced_blanking = true;
690 else
691 return false;
692
693 /* Vertical */
694 if (reduced_blanking) {
695 v_fp = CVT_RB_V_FPORCH;
696 v_bp = (CVT_RB_MIN_V_BLANK * hfreq + 999999) / 1000000;
697 v_bp -= vsync + v_fp;
698
699 if (v_bp < CVT_RB_MIN_V_BPORCH)
700 v_bp = CVT_RB_MIN_V_BPORCH;
701 } else {
702 v_fp = CVT_MIN_V_PORCH_RND;
703 v_bp = (CVT_MIN_VSYNC_BP * hfreq + 999999) / 1000000 - vsync;
704
705 if (v_bp < CVT_MIN_V_BPORCH)
706 v_bp = CVT_MIN_V_BPORCH;
707 }
708 image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
709
710 /* Aspect ratio based on vsync */
711 switch (vsync) {
712 case 4:
713 image_width = (image_height * 4) / 3;
714 break;
715 case 5:
716 image_width = (image_height * 16) / 9;
717 break;
718 case 6:
719 image_width = (image_height * 16) / 10;
720 break;
721 case 7:
722 /* special case */
723 if (image_height == 1024)
724 image_width = (image_height * 5) / 4;
725 else if (image_height == 768)
726 image_width = (image_height * 15) / 9;
727 else
728 return false;
729 break;
730 default:
731 return false;
732 }
733
734 image_width = image_width & ~7;
735
736 /* Horizontal */
737 if (reduced_blanking) {
738 pix_clk = (image_width + CVT_RB_H_BLANK) * hfreq;
739 pix_clk = (pix_clk / CVT_PXL_CLK_GRAN) * CVT_PXL_CLK_GRAN;
740
741 h_bp = CVT_RB_H_BPORCH;
742 hsync = CVT_RB_H_SYNC;
743 h_fp = CVT_RB_H_BLANK - h_bp - hsync;
744
745 frame_width = image_width + CVT_RB_H_BLANK;
746 } else {
747 int h_blank;
748 unsigned ideal_duty_cycle = CVT_C_PRIME - (CVT_M_PRIME * 1000) / hfreq;
749
750 h_blank = (image_width * ideal_duty_cycle + (100 - ideal_duty_cycle) / 2) /
751 (100 - ideal_duty_cycle);
752 h_blank = h_blank - h_blank % (2 * CVT_CELL_GRAN);
753
754 if (h_blank * 100 / image_width < 20) {
755 h_blank = image_width / 5;
756 h_blank = (h_blank + 0x7) & ~0x7;
757 }
758
759 pix_clk = (image_width + h_blank) * hfreq;
760 pix_clk = (pix_clk / CVT_PXL_CLK_GRAN) * CVT_PXL_CLK_GRAN;
761
762 h_bp = h_blank / 2;
763 frame_width = image_width + h_blank;
764
765 hsync = (frame_width * 8 + 50) / 100;
766 hsync = hsync - hsync % CVT_CELL_GRAN;
767 h_fp = h_blank - hsync - h_bp;
768 }
769
770 fmt->bt.polarities = polarities;
771 fmt->bt.width = image_width;
772 fmt->bt.height = image_height;
773 fmt->bt.hfrontporch = h_fp;
774 fmt->bt.vfrontporch = v_fp;
775 fmt->bt.hsync = hsync;
776 fmt->bt.vsync = vsync;
777 fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
778 fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
779 fmt->bt.pixelclock = pix_clk;
780 fmt->bt.standards = V4L2_DV_BT_STD_CVT;
781 if (reduced_blanking)
782 fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
783 return true;
784}
785EXPORT_SYMBOL_GPL(v4l2_detect_cvt);
786
787/*
788 * GTF defines
789 * Based on Generalized Timing Formula Standard
790 * Version 1.1 September 2, 1999
791 */
792
793#define GTF_PXL_CLK_GRAN 250000 /* pixel clock granularity */
794
795#define GTF_MIN_VSYNC_BP 550 /* min time of vsync + back porch (us) */
796#define GTF_V_FP 1 /* vertical front porch (lines) */
797#define GTF_CELL_GRAN 8 /* character cell granularity */
798
799/* Default */
800#define GTF_D_M 600 /* blanking formula gradient */
801#define GTF_D_C 40 /* blanking formula offset */
802#define GTF_D_K 128 /* blanking formula scaling factor */
803#define GTF_D_J 20 /* blanking formula scaling factor */
804#define GTF_D_C_PRIME ((((GTF_D_C - GTF_D_J) * GTF_D_K) / 256) + GTF_D_J)
805#define GTF_D_M_PRIME ((GTF_D_K * GTF_D_M) / 256)
806
807/* Secondary */
808#define GTF_S_M 3600 /* blanking formula gradient */
809#define GTF_S_C 40 /* blanking formula offset */
810#define GTF_S_K 128 /* blanking formula scaling factor */
811#define GTF_S_J 35 /* blanking formula scaling factor */
812#define GTF_S_C_PRIME ((((GTF_S_C - GTF_S_J) * GTF_S_K) / 256) + GTF_S_J)
813#define GTF_S_M_PRIME ((GTF_S_K * GTF_S_M) / 256)
814
815/** v4l2_detect_gtf - detect if the given timings follow the GTF standard
816 * @frame_height - the total height of the frame (including blanking) in lines.
817 * @hfreq - the horizontal frequency in Hz.
818 * @vsync - the height of the vertical sync in lines.
819 * @polarities - the horizontal and vertical polarities (same as struct
820 * v4l2_bt_timings polarities).
821 * @aspect - preferred aspect ratio. GTF has no method of determining the
822 * aspect ratio in order to derive the image width from the
823 * image height, so it has to be passed explicitly. Usually
824 * the native screen aspect ratio is used for this. If it
825 * is not filled in correctly, then 16:9 will be assumed.
826 * @fmt - the resulting timings.
827 *
828 * This function will attempt to detect if the given values correspond to a
829 * valid GTF format. If so, then it will return true, and fmt will be filled
830 * in with the found GTF timings.
831 */
832bool v4l2_detect_gtf(unsigned frame_height,
833 unsigned hfreq,
834 unsigned vsync,
835 u32 polarities,
836 struct v4l2_fract aspect,
837 struct v4l2_dv_timings *fmt)
838{
839 int pix_clk;
840 int v_fp, v_bp, h_fp, h_bp, hsync;
841 int frame_width, image_height, image_width;
842 bool default_gtf;
843 int h_blank;
844
845 if (vsync != 3)
846 return false;
847
848 if (polarities == V4L2_DV_VSYNC_POS_POL)
849 default_gtf = true;
850 else if (polarities == V4L2_DV_HSYNC_POS_POL)
851 default_gtf = false;
852 else
853 return false;
854
855 /* Vertical */
856 v_fp = GTF_V_FP;
857 v_bp = (GTF_MIN_VSYNC_BP * hfreq + 999999) / 1000000 - vsync;
858 image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
859
860 if (aspect.numerator == 0 || aspect.denominator == 0) {
861 aspect.numerator = 16;
862 aspect.denominator = 9;
863 }
864 image_width = ((image_height * aspect.numerator) / aspect.denominator);
865
866 /* Horizontal */
867 if (default_gtf)
868 h_blank = ((image_width * GTF_D_C_PRIME * hfreq) -
869 (image_width * GTF_D_M_PRIME * 1000) +
870 (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) / 2) /
871 (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000);
872 else
873 h_blank = ((image_width * GTF_S_C_PRIME * hfreq) -
874 (image_width * GTF_S_M_PRIME * 1000) +
875 (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) / 2) /
876 (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000);
877
878 h_blank = h_blank - h_blank % (2 * GTF_CELL_GRAN);
879 frame_width = image_width + h_blank;
880
881 pix_clk = (image_width + h_blank) * hfreq;
882 pix_clk = pix_clk / GTF_PXL_CLK_GRAN * GTF_PXL_CLK_GRAN;
883
884 hsync = (frame_width * 8 + 50) / 100;
885 hsync = hsync - hsync % GTF_CELL_GRAN;
886
887 h_fp = h_blank / 2 - hsync;
888 h_bp = h_blank / 2;
889
890 fmt->bt.polarities = polarities;
891 fmt->bt.width = image_width;
892 fmt->bt.height = image_height;
893 fmt->bt.hfrontporch = h_fp;
894 fmt->bt.vfrontporch = v_fp;
895 fmt->bt.hsync = hsync;
896 fmt->bt.vsync = vsync;
897 fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
898 fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
899 fmt->bt.pixelclock = pix_clk;
900 fmt->bt.standards = V4L2_DV_BT_STD_GTF;
901 if (!default_gtf)
902 fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
903 return true;
904}
905EXPORT_SYMBOL_GPL(v4l2_detect_gtf);
906
907/** v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes
908 * 0x15 and 0x16 from the EDID.
909 * @hor_landscape - byte 0x15 from the EDID.
910 * @vert_portrait - byte 0x16 from the EDID.
911 *
912 * Determines the aspect ratio from the EDID.
913 * See VESA Enhanced EDID standard, release A, rev 2, section 3.6.2:
914 * "Horizontal and Vertical Screen Size or Aspect Ratio"
915 */
916struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait)
917{
918 struct v4l2_fract aspect = { 16, 9 };
919 u32 tmp;
920 u8 ratio;
921
922 /* Nothing filled in, fallback to 16:9 */
923 if (!hor_landscape && !vert_portrait)
924 return aspect;
925 /* Both filled in, so they are interpreted as the screen size in cm */
926 if (hor_landscape && vert_portrait) {
927 aspect.numerator = hor_landscape;
928 aspect.denominator = vert_portrait;
929 return aspect;
930 }
931 /* Only one is filled in, so interpret them as a ratio:
932 (val + 99) / 100 */
933 ratio = hor_landscape | vert_portrait;
934 /* Change some rounded values into the exact aspect ratio */
935 if (ratio == 79) {
936 aspect.numerator = 16;
937 aspect.denominator = 9;
938 } else if (ratio == 34) {
939 aspect.numerator = 4;
940 aspect.numerator = 3;
941 } else if (ratio == 68) {
942 aspect.numerator = 15;
943 aspect.numerator = 9;
944 } else {
945 aspect.numerator = hor_landscape + 99;
946 aspect.denominator = 100;
947 }
948 if (hor_landscape)
949 return aspect;
950 /* The aspect ratio is for portrait, so swap numerator and denominator */
951 tmp = aspect.denominator;
952 aspect.denominator = aspect.numerator;
953 aspect.numerator = tmp;
954 return aspect;
955}
956EXPORT_SYMBOL_GPL(v4l2_calc_aspect_ratio);
957
633const struct v4l2_frmsize_discrete *v4l2_find_nearest_format( 958const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
634 const struct v4l2_discrete_probe *probe, 959 const struct v4l2_discrete_probe *probe,
635 s32 width, s32 height) 960 s32 width, s32 height)