diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-common.c | 325 |
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 | } |
631 | EXPORT_SYMBOL_GPL(v4l_match_dv_timings); | 631 | EXPORT_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 | */ | ||
675 | bool 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 | } | ||
785 | EXPORT_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 | */ | ||
832 | bool 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 | } | ||
905 | EXPORT_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 | */ | ||
916 | struct 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 | } | ||
956 | EXPORT_SYMBOL_GPL(v4l2_calc_aspect_ratio); | ||
957 | |||
633 | const struct v4l2_frmsize_discrete *v4l2_find_nearest_format( | 958 | const 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) |