omap3isp: Add support for interlaced input data
Commit Message
If the remote video sensor reports an interlaced video mode, the CCDC block
should configure itself appropriately.
This patch reintroduces code with was removed in commit
cf7a3d91ade6c56bfd860b377f84bd58132f7a81, but in a way that is compatible
with the new media pipeline work.
Signed-off-by: William Swanson <william.swanson@fuel7.com>
---
drivers/media/platform/omap3isp/ispccdc.c | 16 ++++++++++++++--
include/media/omap3isp.h | 3 +++
2 files changed, 17 insertions(+), 2 deletions(-)
@@ -970,10 +970,11 @@ void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
* @ccdc: Pointer to ISP CCDC device.
* @pdata: Parallel interface platform data (may be NULL)
* @data_size: Data size
+ * @interlaced: Use interlaced mode instead of progressive mode
*/
static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
struct isp_parallel_platform_data *pdata,
- unsigned int data_size)
+ unsigned int data_size, bool interlaced)
{
struct isp_device *isp = to_isp_device(ccdc);
const struct v4l2_mbus_framefmt *format;
@@ -1004,9 +1005,15 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
break;
}
+ if (interlaced)
+ syn_mode |= ISPCCDC_SYN_MODE_FLDMODE;
+
if (pdata && pdata->data_pol)
syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
+ if (pdata && pdata->fld_pol)
+ syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
+
if (pdata && pdata->hs_pol)
syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
@@ -1111,6 +1118,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
const struct v4l2_rect *crop;
const struct isp_format_info *fmt_info;
struct v4l2_subdev_format fmt_src;
+ bool src_interlaced = false;
unsigned int depth_out;
unsigned int depth_in = 0;
struct media_pad *pad;
@@ -1132,6 +1140,10 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
fmt_src.pad = pad->index;
fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) {
+ if (fmt_src.format.field == V4L2_FIELD_INTERLACED ||
+ fmt_src.format.field == V4L2_FIELD_INTERLACED_TB ||
+ fmt_src.format.field == V4L2_FIELD_INTERLACED_BT)
+ src_interlaced = true;
fmt_info = omap3isp_video_format_info(fmt_src.format.code);
depth_in = fmt_info->width;
}
@@ -1150,7 +1162,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge);
- ccdc_config_sync_if(ccdc, pdata, depth_out);
+ ccdc_config_sync_if(ccdc, pdata, depth_out, src_interlaced);
syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
@@ -57,6 +57,8 @@ enum {
* ISP_LANE_SHIFT_6 - CAMEXT[13:6] -> CAM[7:0]
* @clk_pol: Pixel clock polarity
* 0 - Sample on rising edge, 1 - Sample on falling edge
+ * @fld_pol: Field identification signal polarity
+ * 0 - Active high, 1 - Active low
* @hs_pol: Horizontal synchronization polarity
* 0 - Active high, 1 - Active low
* @vs_pol: Vertical synchronization polarity
@@ -67,6 +69,7 @@ enum {
struct isp_parallel_platform_data {
unsigned int data_lane_shift:2;
unsigned int clk_pol:1;
+ unsigned int fld_pol:1;
unsigned int hs_pol:1;
unsigned int vs_pol:1;
unsigned int data_pol:1;