[media] v4l2-dv-timings: add interlace support in detect cvt/gtf
authorPrashant Laddha <prladdha@cisco.com>
Fri, 22 May 2015 05:27:34 +0000 (02:27 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 9 Jun 2015 20:44:42 +0000 (17:44 -0300)
Extend detect_cvt/gtf API to indicate the format type (interlaced
or progressive). In case of interlaced, the vertical front and back
porch and vsync values for both (odd,even) fields are considered to
derive image height. Populated vsync, vertical front, back porch
values in bt timing structure for even and odd fields and updated
the flags appropriately.

Also modified the functions calling the detect_cvt/gtf(). As of now
these functions are calling detect_cvt/gtf() with interlaced flag
set to false.

Cc: Martin Bugge <marbugge@cisco.com>
Cc: Mats Randgaard <matrandg@cisco.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Prashant Laddha <prladdha@cisco.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/i2c/adv7604.c
drivers/media/i2c/adv7842.c
drivers/media/platform/vivid/vivid-vid-cap.c
drivers/media/v4l2-core/v4l2-dv-timings.c
include/media/v4l2-dv-timings.h

index daf9386a5031cbe39d91ad46c3c5bffac06f4be6..808360fd6539a3b153c5e328b964032630485e2c 100644 (file)
@@ -1331,12 +1331,12 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
        if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs,
                        (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
                        (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
-                       timings))
+                       false, timings))
                return 0;
        if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
                        (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
                        (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
-                       state->aspect_ratio, timings))
+                       false, state->aspect_ratio, timings))
                return 0;
 
        v4l2_dbg(2, debug, sd,
index f14ea78a7c9cbebd48b31a90dd2c43c02cec30e7..4cf79b2422d4a431daff462aed35809980f06bd0 100644 (file)
@@ -1445,12 +1445,12 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
        if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs,
                        (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
                        (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
-                           timings))
+                       false, timings))
                return 0;
        if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
                        (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
                        (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
-                           state->aspect_ratio, timings))
+                       false, state->aspect_ratio, timings))
                return 0;
 
        v4l2_dbg(2, debug, sd,
index 7b80bda4c34c1267872b61b0f6113cc0331ae352..d83bdf7df1949bfba8a0751dafa29a8e94cbf71d 100644 (file)
@@ -1628,7 +1628,7 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
 
        if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) {
                if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync,
-                                   bt->polarities, timings))
+                                   bt->polarities, false, timings))
                        return true;
        }
 
@@ -1639,7 +1639,8 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
                                  &aspect_ratio.numerator,
                                  &aspect_ratio.denominator);
                if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync,
-                                   bt->polarities, aspect_ratio, timings))
+                                   bt->polarities, false,
+                                   aspect_ratio, timings))
                        return true;
        }
        return false;
index 9031405912693537b36c1752ab5d63e02d0daaa0..04dc71e3ebf0eb3c6eca01cf8f43cc2afc6d8b1e 100644 (file)
@@ -346,6 +346,7 @@ EXPORT_SYMBOL_GPL(v4l2_print_dv_timings);
  * @vsync - the height of the vertical sync in lines.
  * @polarities - the horizontal and vertical polarities (same as struct
  *             v4l2_bt_timings polarities).
+ * @interlaced - if this flag is true, it indicates interlaced format
  * @fmt - the resulting timings.
  *
  * This function will attempt to detect if the given values correspond to a
@@ -357,7 +358,7 @@ EXPORT_SYMBOL_GPL(v4l2_print_dv_timings);
  * detection function.
  */
 bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
-               u32 polarities, struct v4l2_dv_timings *fmt)
+               u32 polarities, bool interlaced, struct v4l2_dv_timings *fmt)
 {
        int  v_fp, v_bp, h_fp, h_bp, hsync;
        int  frame_width, image_height, image_width;
@@ -392,7 +393,11 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
                if (v_bp < CVT_MIN_V_BPORCH)
                        v_bp = CVT_MIN_V_BPORCH;
        }
-       image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
+
+       if (interlaced)
+               image_height = (frame_height - 2 * v_fp - 2 * vsync - 2 * v_bp) & ~0x1;
+       else
+               image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
 
        if (image_height < 0)
                return false;
@@ -465,11 +470,27 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
        fmt->bt.hsync = hsync;
        fmt->bt.vsync = vsync;
        fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
-       fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
+
+       if (!interlaced) {
+               fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
+               fmt->bt.interlaced = V4L2_DV_PROGRESSIVE;
+       } else {
+               fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp -
+                                     2 * vsync) / 2;
+               fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
+                                       2 * vsync - fmt->bt.vbackporch;
+               fmt->bt.il_vfrontporch = v_fp;
+               fmt->bt.il_vsync = vsync;
+               fmt->bt.flags |= V4L2_DV_FL_HALF_LINE;
+               fmt->bt.interlaced = V4L2_DV_INTERLACED;
+       }
+
        fmt->bt.pixelclock = pix_clk;
        fmt->bt.standards = V4L2_DV_BT_STD_CVT;
+
        if (reduced_blanking)
                fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
+
        return true;
 }
 EXPORT_SYMBOL_GPL(v4l2_detect_cvt);
@@ -508,6 +529,7 @@ EXPORT_SYMBOL_GPL(v4l2_detect_cvt);
  * @vsync - the height of the vertical sync in lines.
  * @polarities - the horizontal and vertical polarities (same as struct
  *             v4l2_bt_timings polarities).
+ * @interlaced - if this flag is true, it indicates interlaced format
  * @aspect - preferred aspect ratio. GTF has no method of determining the
  *             aspect ratio in order to derive the image width from the
  *             image height, so it has to be passed explicitly. Usually
@@ -523,6 +545,7 @@ bool v4l2_detect_gtf(unsigned frame_height,
                unsigned hfreq,
                unsigned vsync,
                u32 polarities,
+               bool interlaced,
                struct v4l2_fract aspect,
                struct v4l2_dv_timings *fmt)
 {
@@ -547,9 +570,11 @@ bool v4l2_detect_gtf(unsigned frame_height,
 
        /* Vertical */
        v_fp = GTF_V_FP;
-
        v_bp = (GTF_MIN_VSYNC_BP * hfreq + 500000) / 1000000 - vsync;
-       image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
+       if (interlaced)
+               image_height = (frame_height - 2 * v_fp - 2 * vsync - 2 * v_bp) & ~0x1;
+       else
+               image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
 
        if (image_height < 0)
                return false;
@@ -603,11 +628,27 @@ bool v4l2_detect_gtf(unsigned frame_height,
        fmt->bt.hsync = hsync;
        fmt->bt.vsync = vsync;
        fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
-       fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
+
+       if (!interlaced) {
+               fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
+               fmt->bt.interlaced = V4L2_DV_PROGRESSIVE;
+       } else {
+               fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp -
+                                     2 * vsync) / 2;
+               fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
+                                       2 * vsync - fmt->bt.vbackporch;
+               fmt->bt.il_vfrontporch = v_fp;
+               fmt->bt.il_vsync = vsync;
+               fmt->bt.flags |= V4L2_DV_FL_HALF_LINE;
+               fmt->bt.interlaced = V4L2_DV_INTERLACED;
+       }
+
        fmt->bt.pixelclock = pix_clk;
        fmt->bt.standards = V4L2_DV_BT_STD_GTF;
+
        if (!default_gtf)
                fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
+
        return true;
 }
 EXPORT_SYMBOL_GPL(v4l2_detect_gtf);
index 4becc6716393172802b50636137ba09bc95371bd..eecd3102a618cbdc441ec4925774209f5f0ed6da 100644 (file)
@@ -117,6 +117,7 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix,
  * @vsync - the height of the vertical sync in lines.
  * @polarities - the horizontal and vertical polarities (same as struct
  *             v4l2_bt_timings polarities).
+ * @interlaced - if this flag is true, it indicates interlaced format
  * @fmt - the resulting timings.
  *
  * This function will attempt to detect if the given values correspond to a
@@ -124,7 +125,7 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix,
  * in with the found CVT timings.
  */
 bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
-               u32 polarities, struct v4l2_dv_timings *fmt);
+               u32 polarities, bool interlaced, struct v4l2_dv_timings *fmt);
 
 /** v4l2_detect_gtf - detect if the given timings follow the GTF standard
  * @frame_height - the total height of the frame (including blanking) in lines.
@@ -132,6 +133,7 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
  * @vsync - the height of the vertical sync in lines.
  * @polarities - the horizontal and vertical polarities (same as struct
  *             v4l2_bt_timings polarities).
+ * @interlaced - if this flag is true, it indicates interlaced format
  * @aspect - preferred aspect ratio. GTF has no method of determining the
  *             aspect ratio in order to derive the image width from the
  *             image height, so it has to be passed explicitly. Usually
@@ -144,7 +146,7 @@ bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
  * in with the found GTF timings.
  */
 bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync,
-               u32 polarities, struct v4l2_fract aspect,
+               u32 polarities, bool interlaced, struct v4l2_fract aspect,
                struct v4l2_dv_timings *fmt);
 
 /** v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes