diff mbox

[04/14] davinci: vpfe: add support for CCDC hardware for dm365

Message ID 1347626804-5703-5-git-send-email-prabhakar.lad@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Prabhakar Sept. 14, 2012, 12:46 p.m. UTC
From: Manjunath Hadli <manjunath.hadli@ti.com>

add support for ccdc on dm365 SoC. ccdc is responsible for
capturing video data- both raw bayer through sync seperate
signals and through BT656/1120 interfaces. This driver implements
the hardware functionality. Mainly- setting of hardware, validation
of parameters, and isr configuration.

Signed-off-by: Manjunath Hadli <manjunath.hadli@ti.com>
Signed-off-by: Lad, Prabhakar <prabhakar.lad@ti.com>
---
 drivers/media/platform/davinci/dm365_ccdc.c      | 1424 ++++++++++++++++++++++
 drivers/media/platform/davinci/dm365_ccdc.h      |  137 +++
 drivers/media/platform/davinci/dm365_ccdc_regs.h |  314 +++++
 include/linux/dm365_ccdc.h                       |  592 +++++++++
 4 files changed, 2467 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/platform/davinci/dm365_ccdc.c
 create mode 100644 drivers/media/platform/davinci/dm365_ccdc.h
 create mode 100644 drivers/media/platform/davinci/dm365_ccdc_regs.h
 create mode 100644 include/linux/dm365_ccdc.h
diff mbox

Patch

diff --git a/drivers/media/platform/davinci/dm365_ccdc.c b/drivers/media/platform/davinci/dm365_ccdc.c
new file mode 100644
index 0000000..eee2d58
--- /dev/null
+++ b/drivers/media/platform/davinci/dm365_ccdc.c
@@ -0,0 +1,1424 @@ 
+/*
+ * Copyright (C) 2012 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Contributors:
+ *      Manjunath Hadli <manjunath.hadli@ti.com>
+ *      Prabhakar Lad <prabhakar.lad@ti.com>
+ */
+
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+
+#include <mach/mux.h>
+
+#include <media/davinci/vpfe_types.h>
+#include <media/davinci/vpss.h>
+
+#include "dm365_ccdc.h"
+#include "ccdc_hw_device.h"
+#include "dm365_ccdc_regs.h"
+
+static struct device *dev;
+
+/* Defauts for module configuation paramaters */
+static struct ccdc_config_params_raw ccdc_config_defaults = {
+	.linearize = {
+		.corr_shft = CCDC_NO_SHIFT,
+		.scale_fact = {1, 0},
+	},
+	.culling = {
+		.hcpat_odd = 0xff,
+		.hcpat_even = 0xff,
+		.vcpat = 0xff
+	},
+};
+
+static struct ccdc_gain_values ccdc_gain_params;
+static unsigned char ccdc_test_pat_gen;
+
+/* ISIF operation configuration */
+struct ccdc_oper_config {
+	enum v4l2_mbus_pixelcode if_type;
+	struct ccdc_ycbcr_config ycbcr;
+	struct ccdc_params_raw bayer;
+	enum ccdc_data_pack data_pack;
+	void *__iomem base_addr;
+	void *__iomem linear_tbl0_addr;
+	void *__iomem linear_tbl1_addr;
+};
+
+static struct ccdc_oper_config ccdc_cfg = {
+	.ycbcr = {
+		.v4l2_pix_fmt = V4L2_PIX_FMT_UYVY,
+		.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+		.frm_fmt = CCDC_FRMFMT_INTERLACED,
+		.win = CCDC_WIN_NTSC,
+		.fid_pol = VPFE_PINPOL_POSITIVE,
+		.vd_pol = VPFE_PINPOL_POSITIVE,
+		.hd_pol = VPFE_PINPOL_POSITIVE,
+		.pix_order = CCDC_PIXORDER_CBYCRY,
+		.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
+	},
+	.bayer = {
+		.v4l2_pix_fmt = V4L2_PIX_FMT_SGRBG10ALAW8,
+		.pix_fmt = CCDC_PIXFMT_RAW,
+		.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+		.win = CCDC_WIN_VGA,
+		.fid_pol = VPFE_PINPOL_POSITIVE,
+		.vd_pol = VPFE_PINPOL_POSITIVE,
+		.hd_pol = VPFE_PINPOL_POSITIVE,
+		.gain = {
+			.r_ye = {1, 0},
+			.gr_cy = {1, 0},
+			.gb_g = {1, 0},
+			.b_mg = {1, 0},
+		},
+		.cfa_pat = CCDC_CFA_PAT_MOSAIC,
+		.data_msb = CCDC_BIT_MSB_11,
+	},
+	.data_pack = CCDC_DATA_PACK8,
+};
+
+/* Raw Bayer formats */
+static u32 ccdc_raw_bayer_pix_formats[] = { V4L2_PIX_FMT_SGRBG10ALAW8,
+						V4L2_PIX_FMT_SGRBG10DPCM8,
+						V4L2_PIX_FMT_SBGGR16 };
+
+/* Raw YUV formats */
+static u32 ccdc_raw_yuv_pix_formats[] = { V4L2_PIX_FMT_UYVY,
+					      V4L2_PIX_FMT_YUYV };
+
+/* register access routines */
+static inline u32 regr(u32 offset)
+{
+	return readl(ccdc_cfg.base_addr + offset);
+}
+
+static inline void regw(u32 val, u32 offset)
+{
+	writel(val, ccdc_cfg.base_addr + offset);
+}
+
+static inline u32 ccdc_merge(u32 mask, u32 val, u32 offset)
+{
+	u32 new_val = (regr(offset) & ~mask) | (val & mask);
+
+	regw(new_val, offset);
+
+	return new_val;
+}
+
+static inline void regw_lin_tbl(u32 val, u32 offset, int i)
+{
+	if (!i)
+		writel(val, ccdc_cfg.linear_tbl0_addr + offset);
+	else
+		writel(val, ccdc_cfg.linear_tbl1_addr + offset);
+}
+
+static void ccdc_disable_all_modules(void)
+{
+	/* disable BC */
+	regw(0, CLAMPCFG);
+	/* disable vdfc */
+	regw(0, DFCCTL);
+	/* disable CSC */
+	regw(0, CSCCTL);
+	/* disable linearization */
+	regw(0, LINCFG0);
+	/* disable other modules here as they are supported */
+}
+
+static void ccdc_enable(int en)
+{
+	if (!en) {
+		/* Before disable isif, disable all ISIF modules */
+		ccdc_disable_all_modules();
+		/**
+		 * wait for next VD. Assume lowest scan rate is 12 Hz. So
+		 * 100 msec delay is good enough
+		 */
+	}
+	msleep(100);
+	ccdc_merge(CCDC_SYNCEN_VDHDEN_MASK, en, SYNCEN);
+}
+
+static void ccdc_enable_output_to_sdram(int en)
+{
+	ccdc_merge(CCDC_SYNCEN_WEN_MASK, en << CCDC_SYNCEN_WEN_SHIFT, SYNCEN);
+}
+
+static void ccdc_config_culling(struct ccdc_cul *cul)
+{
+	u32 val;
+
+	/* Horizontal pattern */
+	val = cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT;
+	val |= cul->hcpat_odd;
+	regw(val, CULH);
+
+	/* vertical pattern */
+	regw(cul->vcpat, CULV);
+
+	/* LPF */
+	ccdc_merge((CCDC_LPF_MASK << CCDC_LPF_SHIFT),
+		   (cul->en_lpf << CCDC_LPF_SHIFT), MODESET);
+}
+
+static void ccdc_config_gain_offset(void)
+{
+	struct ccdc_gain_offsets_adj *gain_off_ptr =
+		&ccdc_cfg.bayer.config_params.gain_offset;
+	u32 val;
+
+	val = ((gain_off_ptr->gain_sdram_en & 1) << GAIN_SDRAM_EN_SHIFT) |
+	((gain_off_ptr->gain_ipipe_en & 1) << GAIN_IPIPE_EN_SHIFT) |
+	((gain_off_ptr->gain_h3a_en & 1) << GAIN_H3A_EN_SHIFT) |
+	((gain_off_ptr->offset_sdram_en & 1) << OFST_SDRAM_EN_SHIFT) |
+	((gain_off_ptr->offset_ipipe_en & 1) << OFST_IPIPE_EN_SHIFT) |
+	((gain_off_ptr->offset_h3a_en & 1) << OFST_H3A_EN_SHIFT);
+
+	ccdc_merge(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
+
+	regw(ccdc_gain_params.cr_gain, CRGAIN);
+	regw(ccdc_gain_params.cgr_gain, CGRGAIN);
+	regw(ccdc_gain_params.cgb_gain, CGBGAIN);
+	regw(ccdc_gain_params.cb_gain, CBGAIN);
+	regw((ccdc_gain_params.offset & OFFSET_MASK), COFSTA);
+
+}
+
+static void ccdc_restore_defaults(void)
+{
+	enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
+	int i;
+
+	memcpy(&ccdc_cfg.bayer.config_params, &ccdc_config_defaults,
+			sizeof(struct ccdc_config_params_raw));
+
+	dev_dbg(dev, "ccdc_restore_defaults...\n");
+	/* Enable clock to ISIF, IPIPEIF and BL */
+	vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
+	vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
+	vpss_enable_clock(VPSS_BL_CLOCK, 1);
+
+	/* set all registers to default value */
+	for (i = 0; i <= 0x1f8; i += 4)
+		regw(0, i);
+	/* no culling support */
+	regw(0xffff, CULH);
+	regw(0xff, CULV);
+
+	/* Set default offset and gain */
+	ccdc_config_gain_offset();
+	vpss_select_ccdc_source(source);
+}
+
+static int ccdc_open(struct device *device)
+{
+	dev = device;
+	ccdc_restore_defaults();
+	return 0;
+}
+
+/* This function will configure the window size to be capture in CCDC reg */
+static void ccdc_setwin(struct v4l2_rect *image_win,
+			enum ccdc_frmfmt frm_fmt, int ppc, int mode)
+{
+	int horz_nr_pixels;
+	int vert_nr_lines;
+	int horz_start;
+	int vert_start;
+	int mid_img;
+
+	dev_dbg(dev, "ccdc_setwin...\n");
+	/**
+	 * ppc - per pixel count. indicates how many pixels per cell
+	 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
+	 * raw capture this is 1
+	 */
+	horz_start = image_win->left << (ppc - 1);
+	horz_nr_pixels = (image_win->width << (ppc - 1)) - 1;
+
+	/* Writing the horizontal info into the registers */
+	regw(horz_start & START_PX_HOR_MASK, SPH);
+	regw(horz_nr_pixels & NUM_PX_HOR_MASK, LNH);
+	vert_start = image_win->top;
+
+	if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		vert_nr_lines = (image_win->height >> 1) - 1;
+		vert_start >>= 1;
+		/* To account for VD since line 0 doesn't have any data */
+		vert_start += 1;
+	} else {
+		/* To account for VD since line 0 doesn't have any data */
+		vert_start += 1;
+		vert_nr_lines = image_win->height - 1;
+		/* configure VDINT0 and VDINT1 */
+		mid_img = vert_start + (image_win->height / 2);
+		regw(mid_img, VDINT1);
+	}
+
+	if (!mode)
+		regw(0, VDINT0);
+	else
+		regw(vert_nr_lines, VDINT0);
+	regw(vert_start & START_VER_ONE_MASK, SLV0);
+	regw(vert_start & START_VER_TWO_MASK, SLV1);
+	regw(vert_nr_lines & NUM_LINES_VER, LNV);
+}
+
+static void ccdc_config_bclamp(struct ccdc_black_clamp *bc)
+{
+	u32 val;
+
+	/**
+	 * DC Offset is always added to image data irrespective of bc enable
+	 * status
+	 */
+	val = bc->dc_offset & CCDC_BC_DCOFFSET_MASK;
+	regw(val, CLDCOFST);
+
+	if (!bc->en)
+		return;
+
+	val = (bc->bc_mode_color & CCDC_BC_MODE_COLOR_MASK) <<
+		CCDC_BC_MODE_COLOR_SHIFT;
+
+	/* Enable BC and horizontal clamp caculation paramaters */
+	val = val | 1 | ((bc->horz.mode & CCDC_HORZ_BC_MODE_MASK) <<
+	CCDC_HORZ_BC_MODE_SHIFT);
+
+	regw(val, CLAMPCFG);
+
+	if (bc->horz.mode != CCDC_HORZ_BC_DISABLE) {
+		/**
+		  * Window count for calculation
+		  * Base window selection
+		  * pixel limit
+		  * Horizontal size of window
+		  * vertical size of the window
+		  * Horizontal start position of the window
+		  * Vertical start position of the window
+		  */
+		val = (bc->horz.win_count_calc & CCDC_HORZ_BC_WIN_COUNT_MASK) |
+			((bc->horz.base_win_sel_calc & 1) <<
+			CCDC_HORZ_BC_WIN_SEL_SHIFT) |
+			((bc->horz.clamp_pix_limit & 1) <<
+			CCDC_HORZ_BC_PIX_LIMIT_SHIFT) |
+			((bc->horz.win_h_sz_calc &
+			CCDC_HORZ_BC_WIN_H_SIZE_MASK) <<
+			CCDC_HORZ_BC_WIN_H_SIZE_SHIFT) |
+			((bc->horz.win_v_sz_calc &
+			CCDC_HORZ_BC_WIN_V_SIZE_MASK) <<
+			CCDC_HORZ_BC_WIN_V_SIZE_SHIFT);
+
+		regw(val, CLHWIN0);
+
+		val = bc->horz.win_start_h_calc & CCDC_HORZ_BC_WIN_START_H_MASK;
+		regw(val, CLHWIN1);
+
+		val = bc->horz.win_start_v_calc & CCDC_HORZ_BC_WIN_START_V_MASK;
+		regw(val, CLHWIN2);
+	}
+
+	/* vertical clamp caculation paramaters */
+
+	/* OB H Valid */
+	val = bc->vert.ob_h_sz_calc & CCDC_VERT_BC_OB_H_SZ_MASK;
+
+	/* Reset clamp value sel for previous line */
+	val |= (bc->vert.reset_val_sel & CCDC_VERT_BC_RST_VAL_SEL_MASK) <<
+				CCDC_VERT_BC_RST_VAL_SEL_SHIFT;
+
+	/* Line average coefficient */
+	val |= bc->vert.line_ave_coef << CCDC_VERT_BC_LINE_AVE_COEF_SHIFT;
+	regw(val, CLVWIN0);
+
+	/* Configured reset value */
+	if (bc->vert.reset_val_sel == CCDC_VERT_BC_USE_CONFIG_CLAMP_VAL) {
+		val = bc->vert.reset_clamp_val & CCDC_VERT_BC_RST_VAL_MASK;
+		regw(val, CLVRV);
+	}
+
+	/* Optical Black horizontal start position */
+	val = bc->vert.ob_start_h & CCDC_VERT_BC_OB_START_HORZ_MASK;
+	regw(val, CLVWIN1);
+
+	/* Optical Black vertical start position */
+	val = bc->vert.ob_start_v & CCDC_VERT_BC_OB_START_VERT_MASK;
+	regw(val, CLVWIN2);
+
+	val = bc->vert.ob_v_sz_calc & CCDC_VERT_BC_OB_VERT_SZ_MASK;
+	regw(val, CLVWIN3);
+
+	/* Vertical start position for BC subtraction */
+	val = bc->vert_start_sub & CCDC_BC_VERT_START_SUB_V_MASK;
+	regw(val, CLSV);
+}
+
+static void ccdc_config_linearization(struct ccdc_linearize *linearize)
+{
+	u32 val;
+	u32 i;
+
+	if (!linearize->en) {
+		regw(0, LINCFG0);
+		return;
+	}
+
+	/* shift value for correction */
+	val = (linearize->corr_shft & CCDC_LIN_CORRSFT_MASK) <<
+					CCDC_LIN_CORRSFT_SHIFT;
+	/* enable */
+	val |= 1;
+	regw(val, LINCFG0);
+
+	/* Scale factor */
+	val = (linearize->scale_fact.integer & 1) <<
+				    CCDC_LIN_SCALE_FACT_INTEG_SHIFT;
+	val |= linearize->scale_fact.decimal & CCDC_LIN_SCALE_FACT_DECIMAL_MASK;
+	regw(val, LINCFG1);
+
+	for (i = 0; i < CCDC_LINEAR_TAB_SIZE; i++) {
+		val = linearize->table[i] & CCDC_LIN_ENTRY_MASK;
+		if (i%2)
+			regw_lin_tbl(val, ((i >> 1) << 2), 1);
+		else
+			regw_lin_tbl(val, ((i >> 1) << 2), 0);
+	}
+}
+
+static void ccdc_config_dfc(struct ccdc_dfc *vdfc)
+{
+#define DFC_WRITE_WAIT_COUNT	1000
+	u32 count = DFC_WRITE_WAIT_COUNT;
+	u32 val;
+	int i;
+
+	if (!vdfc->en)
+		return;
+
+	/* Correction mode */
+	val = (vdfc->corr_mode & CCDC_VDFC_CORR_MOD_MASK) <<
+					CCDC_VDFC_CORR_MOD_SHIFT;
+
+	/* Correct whole line or partial */
+	if (vdfc->corr_whole_line)
+		val |= 1 << CCDC_VDFC_CORR_WHOLE_LN_SHIFT;
+
+	/* level shift value */
+	val |= (vdfc->def_level_shift & CCDC_VDFC_LEVEL_SHFT_MASK) <<
+		CCDC_VDFC_LEVEL_SHFT_SHIFT;
+
+	regw(val, DFCCTL);
+
+	/* Defect saturation level */
+	val = vdfc->def_sat_level & CCDC_VDFC_SAT_LEVEL_MASK;
+	regw(val, VDFSATLV);
+
+	regw(vdfc->table[0].pos_vert & CCDC_VDFC_POS_MASK, DFCMEM0);
+	regw(vdfc->table[0].pos_horz & CCDC_VDFC_POS_MASK, DFCMEM1);
+	if (vdfc->corr_mode == CCDC_VDFC_NORMAL ||
+	    vdfc->corr_mode == CCDC_VDFC_HORZ_INTERPOL_IF_SAT) {
+		regw(vdfc->table[0].level_at_pos, DFCMEM2);
+		regw(vdfc->table[0].level_up_pixels, DFCMEM3);
+		regw(vdfc->table[0].level_low_pixels, DFCMEM4);
+	}
+
+	val = regr(DFCMEMCTL);
+	/* set DFCMARST and set DFCMWR */
+	val |= 1 << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
+	val |= 1;
+	regw(val, DFCMEMCTL);
+
+	while (count && (regr(DFCMEMCTL) & 0x01))
+		count--;
+
+	val = regr(DFCMEMCTL);
+	if (!count) {
+		dev_dbg(dev, "defect table write timeout !!\n");
+		return;
+	}
+
+	for (i = 1; i < vdfc->num_vdefects; i++) {
+		regw(vdfc->table[i].pos_vert & CCDC_VDFC_POS_MASK, DFCMEM0);
+		regw(vdfc->table[i].pos_horz & CCDC_VDFC_POS_MASK, DFCMEM1);
+		if (vdfc->corr_mode == CCDC_VDFC_NORMAL ||
+		    vdfc->corr_mode == CCDC_VDFC_HORZ_INTERPOL_IF_SAT) {
+			regw(vdfc->table[i].level_at_pos, DFCMEM2);
+			regw(vdfc->table[i].level_up_pixels, DFCMEM3);
+			regw(vdfc->table[i].level_low_pixels, DFCMEM4);
+		}
+		val = regr(DFCMEMCTL);
+		/* clear DFCMARST and set DFCMWR */
+		val &= ~(1 << CCDC_DFCMEMCTL_DFCMARST_SHIFT);
+		val |= 1;
+		regw(val, DFCMEMCTL);
+
+		count = DFC_WRITE_WAIT_COUNT;
+		while (count && (regr(DFCMEMCTL) & 0x01))
+			count--;
+
+		val = regr(DFCMEMCTL);
+		if (!count) {
+			dev_err(dev, "defect table write timeout !!\n");
+			return;
+		}
+	}
+	if (vdfc->num_vdefects < CCDC_VDFC_TABLE_SIZE) {
+		/* Extra cycle needed */
+		regw(0, DFCMEM0);
+		regw(0x1FFF, DFCMEM1);
+		val = 1;
+		regw(val, DFCMEMCTL);
+	}
+
+	/* enable VDFC */
+	ccdc_merge((1 << CCDC_VDFC_EN_SHIFT), (1 << CCDC_VDFC_EN_SHIFT),
+		   DFCCTL);
+
+	ccdc_merge((1 << CCDC_VDFC_EN_SHIFT), (0 << CCDC_VDFC_EN_SHIFT),
+		   DFCCTL);
+
+	regw(0x6, DFCMEMCTL);
+	for (i = 0 ; i < vdfc->num_vdefects; i++) {
+		count = DFC_WRITE_WAIT_COUNT;
+		while (count && (regr(DFCMEMCTL) & 0x2))
+			count--;
+
+		val = regr(DFCMEMCTL);
+		if (!count) {
+			dev_err(dev, "defect table write timeout !!\n");
+			return;
+		}
+
+		val = regr(DFCMEM0) | regr(DFCMEM1) | regr(DFCMEM2) |
+			regr(DFCMEM3) | regr(DFCMEM4);
+		regw(0x2, DFCMEMCTL);
+	}
+}
+
+static void ccdc_config_csc(struct ccdc_df_csc *df_csc)
+{
+	u32 val1;
+	u32 val2;
+	u32 i;
+
+	if (!df_csc->csc.en) {
+		regw(0, CSCCTL);
+		return;
+	}
+
+	/* initialize all bits to 0 */
+	val1 = 0;
+
+	for (i = 0; i < CCDC_CSC_NUM_COEFF; i++) {
+		if ((i % 2) == 0) {
+			/* CSCM - LSB */
+			val1 = ((df_csc->csc.coeff[i].integer &
+				CCDC_CSC_COEF_INTEG_MASK) <<
+				CCDC_CSC_COEF_INTEG_SHIFT) |
+				((df_csc->csc.coeff[i].decimal &
+				CCDC_CSC_COEF_DECIMAL_MASK));
+		} else {
+
+			/* CSCM - MSB */
+			val2 = ((df_csc->csc.coeff[i].integer &
+				CCDC_CSC_COEF_INTEG_MASK) <<
+				CCDC_CSC_COEF_INTEG_SHIFT) |
+				((df_csc->csc.coeff[i].decimal &
+				CCDC_CSC_COEF_DECIMAL_MASK));
+			val2 <<= CCDC_CSCM_MSB_SHIFT;
+			val2 |= val1;
+			regw(val2, (CSCM0 + ((i-1) << 1)));
+		}
+	}
+
+	/* program the active area */
+	regw(df_csc->start_pix & CCDC_DF_CSC_SPH_MASK, FMTSPH);
+	/**
+	 * one extra pixel as required for CSC. Actually number of
+	 * pixel - 1 should be configured in this register. So we
+	 * need to subtract 1 before writing to FMTSPH, but we will
+	 * not do this since csc requires one extra pixel
+	 */
+	regw((df_csc->num_pixels) & CCDC_DF_CSC_SPH_MASK, FMTLNH);
+	regw(df_csc->start_line & CCDC_DF_CSC_SPH_MASK, FMTSLV);
+	/**
+	 * one extra line as required for CSC. See reason documented for
+	 * num_pixels
+	 */
+	regw((df_csc->num_lines) & CCDC_DF_CSC_SPH_MASK, FMTLNV);
+
+	/* Enable CSC */
+	regw(1, CSCCTL);
+}
+
+static int ccdc_config_raw(int mode)
+{
+	struct ccdc_params_raw *params = &ccdc_cfg.bayer;
+	struct ccdc_config_params_raw *module_params =
+		&ccdc_cfg.bayer.config_params;
+	struct vpss_pg_frame_size frame_size;
+	struct vpss_sync_pol sync;
+	u32 val;
+
+	dev_dbg(dev, "ccdc_config_raw..\n");
+
+	/* In case of user has set BT656IF earlier, it should be reset
+	   when configuring for raw input.
+	 */
+	regw(0, REC656IF);
+
+	/* Configure CCDCFG register */
+
+	/**
+	 * Set CCD Not to swap input since input is RAW data
+	 * Set FID detection function to Latch at V-Sync
+	 * Set WENLOG - ccdc valid area
+	 * Set TRGSEL
+	 * Set EXTRG
+	 * Packed to 8 or 16 bits
+	 */
+
+	val = CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
+		CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
+		CCDC_CCDCFG_EXTRG_DISABLE | (ccdc_cfg.data_pack &
+		CCDC_DATA_PACK_MASK);
+
+	dev_dbg(dev, "Writing 0x%x to ...CCDCFG\n", val);
+	regw(val, CCDCFG);
+
+	/**
+	 * Configure the vertical sync polarity(MODESET.VDPOL)
+	 * Configure the horizontal sync polarity (MODESET.HDPOL)
+	 * Configure frame id polarity (MODESET.FLDPOL)
+	 * Configure data polarity
+	 * Configure External WEN Selection
+	 * Configure frame format(progressive or interlace)
+	 * Configure pixel format (Input mode)
+	 * Configure the data shift
+	 */
+
+	val = CCDC_VDHDOUT_INPUT | ((params->vd_pol & CCDC_VD_POL_MASK) <<
+	      CCDC_VD_POL_SHIFT) | ((params->hd_pol & CCDC_HD_POL_MASK) <<
+	      CCDC_HD_POL_SHIFT) | ((params->fid_pol & CCDC_FID_POL_MASK) <<
+	      CCDC_FID_POL_SHIFT) | ((CCDC_DATAPOL_NORMAL &
+	      CCDC_DATAPOL_MASK) << CCDC_DATAPOL_SHIFT) | ((CCDC_EXWEN_DISABLE &
+	      CCDC_EXWEN_MASK) << CCDC_EXWEN_SHIFT) | ((params->frm_fmt &
+	      CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) | ((params->pix_fmt &
+	      CCDC_INPUT_MASK) << CCDC_INPUT_SHIFT);
+
+	/* currently only V4L2_MBUS_FMT_SGRBG12_1X12 is
+	 * supported. shift appropriately depending on
+	 * different MBUS fmt's added
+	 */
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		val |= ((CCDC_NO_SHIFT &
+			CCDC_DATASFT_MASK) << CCDC_DATASFT_SHIFT);
+
+	regw(val, MODESET);
+	dev_dbg(dev, "Writing 0x%x to MODESET...\n", val);
+
+	/**
+	 * Configure GAMMAWD register
+	 * CFA pattern setting
+	 */
+	val = (params->cfa_pat & CCDC_GAMMAWD_CFA_MASK) <<
+		CCDC_GAMMAWD_CFA_SHIFT;
+
+	/* Gamma msb */
+	if (params->v4l2_pix_fmt == V4L2_PIX_FMT_SGRBG10ALAW8)
+		val = val | CCDC_ALAW_ENABLE;
+
+	val = val | ((params->data_msb & CCDC_ALAW_GAMA_WD_MASK) <<
+			CCDC_ALAW_GAMA_WD_SHIFT);
+
+	regw(val, CGAMMAWD);
+
+	/* Configure DPCM compression settings */
+	if (params->v4l2_pix_fmt == V4L2_PIX_FMT_SGRBG10DPCM8) {
+		val =  1 << CCDC_DPCM_EN_SHIFT;
+		val |= (module_params->pred &
+			CCDC_DPCM_PREDICTOR_MASK) << CCDC_DPCM_PREDICTOR_SHIFT;
+	}
+	regw(val, MISC);
+	/* Configure Gain & Offset */
+	ccdc_config_gain_offset();
+	/* Configure Color pattern */
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		val = ccdc_sgrbg_pattern;
+	else
+		/* default set to rggb */
+		val = ccdc_srggb_pattern;
+
+	regw(val, CCOLP);
+	dev_dbg(dev, "Writing %x to CCOLP ...\n", val);
+
+	/* Configure HSIZE register  */
+	val = (params->horz_flip_en & CCDC_HSIZE_FLIP_MASK) <<
+			  CCDC_HSIZE_FLIP_SHIFT;
+
+	/* calculate line offset in 32 bytes based on pack value */
+	if (ccdc_cfg.data_pack == CCDC_PACK_8BIT)
+		val |= ((params->win.width + 31) >> 5) & CCDC_LINEOFST_MASK;
+	else if (ccdc_cfg.data_pack == CCDC_PACK_12BIT)
+		val |= ((((params->win.width + (params->win.width >> 2)) +
+			31) >> 5) & CCDC_LINEOFST_MASK);
+	else
+		val |= (((params->win.width * 2) + 31) >> 5) &
+			CCDC_LINEOFST_MASK;
+	regw(val, HSIZE);
+
+	/* Configure SDOFST register  */
+	if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		if (params->image_invert_en) {
+			/* For interlace inverse mode */
+			regw(0x4B6D, SDOFST);
+			dev_dbg(dev, "Writing 0x4B6D to SDOFST...\n");
+		} else {
+			/* For interlace non inverse mode */
+			regw(0x0B6D, SDOFST);
+			dev_dbg(dev, "Writing 0x0B6D to SDOFST...\n");
+		}
+	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
+		if (params->image_invert_en) {
+			/* For progessive inverse mode */
+			regw(0x4000, SDOFST);
+			dev_dbg(dev, "Writing 0x4000 to SDOFST...\n");
+		} else {
+			/* For progessive non inverse mode */
+			regw(0x0000, SDOFST);
+			dev_dbg(dev, "Writing 0x0000 to SDOFST...\n");
+		}
+	}
+
+	/* Configure video window */
+	ccdc_setwin(&params->win, params->frm_fmt, 1, mode);
+
+	/* Configure Black Clamp */
+	ccdc_config_bclamp(&module_params->bclamp);
+
+	/* Configure Vertical Defection Pixel Correction */
+	ccdc_config_dfc(&module_params->dfc);
+
+	if (!module_params->df_csc.df_or_csc)
+		/* Configure Color Space Conversion */
+		ccdc_config_csc(&module_params->df_csc);
+
+	ccdc_config_linearization(&module_params->linearize);
+
+	/* Configure Culling */
+	ccdc_config_culling(&module_params->culling);
+
+	/* Configure Horizontal and vertical offsets(DFC,LSC,Gain) */
+	val = module_params->horz_offset & CCDC_DATA_H_OFFSET_MASK;
+	regw(val, DATAHOFST);
+
+	val = module_params->vert_offset & CCDC_DATA_V_OFFSET_MASK;
+	regw(val, DATAVOFST);
+
+	/* Setup test pattern if enabled */
+	if (ccdc_test_pat_gen) {
+		/* Use the HD/VD pol settings from user */
+		sync.ccdpg_hdpol = params->hd_pol & CCDC_HD_POL_MASK;
+		sync.ccdpg_vdpol = params->vd_pol & CCDC_VD_POL_MASK;
+
+		vpss_set_sync_pol(sync);
+
+		frame_size.hlpfr = ccdc_cfg.bayer.win.width;
+		frame_size.pplen = ccdc_cfg.bayer.win.height;
+		vpss_set_pg_frame_size(frame_size);
+		vpss_select_ccdc_source(VPSS_PGLPBK);
+	}
+
+	return 0;
+}
+
+static int ccdc_validate_df_csc_params(struct ccdc_df_csc *df_csc)
+{
+	struct ccdc_color_space_conv *csc;
+	int err = -EINVAL;
+	int csc_df_en;
+	int i;
+
+	if (!df_csc->df_or_csc) {
+		/* csc configuration */
+		csc = &df_csc->csc;
+		if (csc->en) {
+			csc_df_en = 1;
+			for (i = 0; i < CCDC_CSC_NUM_COEFF; i++) {
+				if (csc->coeff[i].integer >
+					CCDC_CSC_COEF_INTEG_MASK ||
+				    csc->coeff[i].decimal >
+					CCDC_CSC_COEF_DECIMAL_MASK) {
+					dev_dbg(dev,
+						"invalid CSC coefficients\n");
+					return err;
+				}
+			}
+		}
+	}
+
+	if (df_csc->start_pix > CCDC_DF_CSC_SPH_MASK) {
+		dev_dbg(dev, "invalid df_csc start pix value\n");
+		return err;
+	}
+	if (df_csc->num_pixels > CCDC_DF_NUMPIX) {
+		dev_dbg(dev, "invalid df_csc num pixels value\n");
+		return err;
+	}
+	if (df_csc->start_line > CCDC_DF_CSC_LNH_MASK) {
+		dev_dbg(dev, "invalid df_csc start_line value\n");
+		return err;
+	}
+	if (df_csc->num_lines > CCDC_DF_NUMLINES) {
+		dev_dbg(dev, "invalid df_csc num_lines value\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static int ccdc_validate_dfc_params(struct ccdc_dfc *dfc)
+{
+	int err = -EINVAL;
+	int i;
+
+	if (!dfc->en)
+		return 0;
+
+	if (dfc->corr_whole_line > 1) {
+		dev_dbg(dev, "invalid corr_whole_line value\n");
+		return err;
+	}
+
+	if (dfc->def_level_shift > 4) {
+		dev_dbg(dev, "invalid def_level_shift value\n");
+		return err;
+	}
+
+	if (dfc->def_sat_level > 4095) {
+		dev_dbg(dev, "invalid def_sat_level value\n");
+		return err;
+	}
+
+	if (!dfc->num_vdefects || dfc->num_vdefects > 8) {
+		dev_dbg(dev, "invalid num_vdefects value\n");
+		return err;
+	}
+
+	for (i = 0; i < CCDC_VDFC_TABLE_SIZE; i++) {
+		if (dfc->table[i].pos_vert > 0x1fff) {
+			dev_dbg(dev, "invalid pos_vert value\n");
+			return err;
+		}
+
+		if (dfc->table[i].pos_horz > 0x1fff) {
+			dev_dbg(dev, "invalid pos_horz value\n");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int ccdc_validate_bclamp_params(struct ccdc_black_clamp *bclamp)
+{
+	int err = -EINVAL;
+
+	if (bclamp->dc_offset > 0x1fff) {
+		dev_dbg(dev, "invalid bclamp dc_offset value\n");
+		return err;
+	}
+
+	if (!bclamp->en)
+		return 0;
+
+	if (bclamp->horz.clamp_pix_limit > 1) {
+		dev_dbg(dev,
+			"invalid bclamp horz clamp_pix_limit value\n");
+		return err;
+	}
+
+	if (bclamp->horz.win_count_calc < 1 ||
+			bclamp->horz.win_count_calc > 32) {
+		dev_dbg(dev, "invalid bclamp horz win_count_calc value\n");
+		return err;
+	}
+
+	if (bclamp->horz.win_start_h_calc > 0x1fff) {
+		dev_dbg(dev, "invalid bclamp win_start_v_calc value\n");
+		return err;
+	}
+
+	if (bclamp->horz.win_start_v_calc > 0x1fff) {
+		dev_dbg(dev, "invalid bclamp win_start_v_calc value\n");
+		return err;
+	}
+
+	if (bclamp->vert.reset_clamp_val > 0xfff) {
+		dev_dbg(dev, "invalid bclamp reset_clamp_val value\n");
+		return err;
+	}
+
+	if (bclamp->vert.ob_v_sz_calc > 0x1fff) {
+		dev_dbg(dev, "invalid bclamp ob_v_sz_calc value\n");
+		return err;
+	}
+
+	if (bclamp->vert.ob_start_h > 0x1fff) {
+		dev_dbg(dev, "invalid bclamp ob_start_h value\n");
+		return err;
+	}
+
+	if (bclamp->vert.ob_start_v > 0x1fff) {
+		dev_dbg(dev, "invalid bclamp ob_start_h value\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static int ccdc_validate_gain_ofst_params(struct ccdc_gain_offsets_adj
+					  *gain_offset)
+{
+	int err = -EINVAL;
+
+	if ((gain_offset->offset_sdram_en || gain_offset->offset_ipipe_en ||
+		gain_offset->offset_h3a_en) &&
+		ccdc_gain_params.offset > 0xfff) {
+		dev_dbg(dev, "Invalid  gain b_mg\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static int
+validate_ccdc_config_params_raw(struct ccdc_config_params_raw *params)
+{
+	int err;
+
+	err = ccdc_validate_df_csc_params(&params->df_csc);
+	if (err)
+		goto exit;
+	err = ccdc_validate_dfc_params(&params->dfc);
+	if (err)
+		goto exit;
+	err = ccdc_validate_bclamp_params(&params->bclamp);
+	if (err)
+		goto exit;
+	err = ccdc_validate_gain_ofst_params(&params->gain_offset);
+exit:
+	return err;
+}
+
+static int ccdc_set_buftype(enum ccdc_buftype buf_type)
+{
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		ccdc_cfg.bayer.buf_type = buf_type;
+	else
+		ccdc_cfg.ycbcr.buf_type = buf_type;
+
+	return 0;
+}
+
+static enum ccdc_buftype ccdc_get_buftype(void)
+{
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		return ccdc_cfg.bayer.buf_type;
+
+	return ccdc_cfg.ycbcr.buf_type;
+}
+
+static int ccdc_enum_pix(u32 *pix, int i)
+{
+	int ret = -EINVAL;
+
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12) {
+		if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
+			*pix = ccdc_raw_bayer_pix_formats[i];
+			ret = 0;
+		}
+	} else {
+		if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
+			*pix = ccdc_raw_yuv_pix_formats[i];
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+
+static int ccdc_set_pixel_format(unsigned int pixfmt)
+{
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12) {
+		if (pixfmt == V4L2_PIX_FMT_SBGGR16)
+			ccdc_cfg.data_pack = CCDC_PACK_16BIT;
+		else if ((pixfmt == V4L2_PIX_FMT_SGRBG10DPCM8) ||
+				(pixfmt == V4L2_PIX_FMT_SGRBG10ALAW8))
+			ccdc_cfg.data_pack = CCDC_PACK_8BIT;
+		else
+			return -EINVAL;
+
+		ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
+		ccdc_cfg.bayer.v4l2_pix_fmt = pixfmt;
+	} else {
+		if (pixfmt == V4L2_PIX_FMT_YUYV)
+			ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+		else if (pixfmt == V4L2_PIX_FMT_UYVY)
+			ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+		else
+		  return -EINVAL;
+
+		ccdc_cfg.data_pack = CCDC_PACK_8BIT;
+		ccdc_cfg.ycbcr.v4l2_pix_fmt = pixfmt;
+	}
+
+	return 0;
+}
+
+static u32 ccdc_get_pixel_format(void)
+{
+	u32 pixfmt;
+
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		pixfmt = ccdc_cfg.bayer.v4l2_pix_fmt;
+	else
+		pixfmt = ccdc_cfg.ycbcr.v4l2_pix_fmt;
+
+	return pixfmt;
+}
+
+static int ccdc_set_image_window(struct v4l2_rect *win)
+{
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12) {
+		ccdc_cfg.bayer.win.top = win->top;
+		ccdc_cfg.bayer.win.left = win->left;
+		ccdc_cfg.bayer.win.width = win->width;
+		ccdc_cfg.bayer.win.height = win->height;
+	} else {
+		ccdc_cfg.ycbcr.win.top = win->top;
+		ccdc_cfg.ycbcr.win.left = win->left;
+		ccdc_cfg.ycbcr.win.width = win->width;
+		ccdc_cfg.ycbcr.win.height = win->height;
+	}
+
+	return 0;
+}
+
+static void ccdc_get_image_window(struct v4l2_rect *win)
+{
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		*win = ccdc_cfg.bayer.win;
+	else
+		*win = ccdc_cfg.ycbcr.win;
+}
+
+static unsigned int ccdc_get_line_length(void)
+{
+	unsigned int len;
+
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12) {
+		if (ccdc_cfg.data_pack == CCDC_PACK_8BIT)
+			len = ((ccdc_cfg.bayer.win.width));
+		else if (ccdc_cfg.data_pack == CCDC_PACK_12BIT)
+			len = (ccdc_cfg.bayer.win.width * 2) +
+				 (ccdc_cfg.bayer.win.width >> 2);
+		else
+			len = ccdc_cfg.bayer.win.width * 2;
+	} else {
+		len = ccdc_cfg.ycbcr.win.width * 2;
+	}
+
+	return ALIGN(len, 32);
+}
+
+static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
+{
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		ccdc_cfg.bayer.frm_fmt = frm_fmt;
+	else
+		ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
+
+	return 0;
+}
+
+static enum ccdc_frmfmt ccdc_get_frame_format(void)
+{
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		return ccdc_cfg.bayer.frm_fmt;
+	else
+		return ccdc_cfg.ycbcr.frm_fmt;
+}
+
+static int ccdc_getfid(void)
+{
+	return (regr(MODESET) >> 15) & 0x1;
+}
+
+static int ccdc_set_ctrl(u32 ctrl_id, s32 val)
+{
+	switch (ctrl_id) {
+	case VPFE_CCDC_CID_CRGAIN:
+		ccdc_gain_params.cr_gain = val;
+		break;
+	case VPFE_CCDC_CID_CGRGAIN:
+		ccdc_gain_params.cgr_gain = val;
+		break;
+	case VPFE_CCDC_CID_CGBGAIN:
+		ccdc_gain_params.cgb_gain = val;
+		break;
+	case VPFE_CCDC_CID_CBGAIN:
+		ccdc_gain_params.cb_gain = val;
+		break;
+	case VPFE_CCDC_CID_GAIN_OFFSET:
+		ccdc_gain_params.offset = val;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* misc operations */
+static void ccdc_setfbaddr(unsigned long addr)
+{
+	regw((addr >> 21) & 0x07ff, CADU);
+	regw((addr >> 5) & 0x0ffff, CADL);
+}
+
+static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
+{
+	ccdc_cfg.if_type = params->if_type;
+
+	switch (params->if_type) {
+	case V4L2_MBUS_FMT_YUYV8_2X8:
+	case V4L2_MBUS_FMT_YUYV10_2X10:
+	case V4L2_MBUS_FMT_Y8_1X8:
+		ccdc_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
+		break;
+	case V4L2_MBUS_FMT_YUYV10_1X20:
+	case V4L2_MBUS_FMT_YUYV8_1X16:
+		ccdc_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
+		break;
+	case V4L2_MBUS_FMT_SGRBG12_1X12:
+		ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
+		break;
+	default:
+		dev_dbg(dev, "Invalid interface type\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Parameter operations */
+static int ccdc_get_params(void *params)
+{
+	/* only raw module parameters can be set through the IOCTL */
+	if (ccdc_cfg.if_type != V4L2_MBUS_FMT_SGRBG12_1X12)
+		return -EINVAL;
+
+	memcpy(params, &ccdc_cfg.bayer.config_params,
+			sizeof(ccdc_cfg.bayer.config_params));
+
+	return 0;
+}
+
+/* Parameter operations */
+static int ccdc_set_params(void *params)
+{
+	struct ccdc_config_params_raw ccdc_raw_params;
+	int ret = -EINVAL;
+
+	/* only raw module parameters can be set through the IOCTL */
+	if (ccdc_cfg.if_type != V4L2_MBUS_FMT_SGRBG12_1X12)
+		return ret;
+
+	memcpy(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
+
+	if (!validate_ccdc_config_params_raw(&ccdc_raw_params)) {
+		memcpy(&ccdc_cfg.bayer.config_params, &ccdc_raw_params,
+			sizeof(ccdc_raw_params));
+		ret = 0;
+	}
+
+	return ret;
+}
+
+/* This function will configure CCDC for YCbCr parameters. */
+static int ccdc_config_ycbcr(int mode)
+{
+	struct ccdc_ycbcr_config *params = &ccdc_cfg.ycbcr;
+	struct vpss_pg_frame_size frame_size;
+	struct vpss_sync_pol sync;
+	u32 modeset;
+	u32 ccdcfg;
+
+	/**
+	 * first reset the CCDC
+	 * all registers have default values after reset
+	 * This is important since we assume default values to be set in
+	 * a lot of registers that we didn't touch
+	 */
+	dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
+
+	/* start with all bits zero */
+	modeset = 0;
+	ccdcfg = 0;
+
+	/* configure pixel format or input mode */
+	modeset = modeset | ((params->pix_fmt & CCDC_INPUT_MASK) <<
+		  CCDC_INPUT_SHIFT) | ((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
+		  CCDC_FRM_FMT_SHIFT) | (((params->fid_pol &
+		  CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT)) |
+		  (((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT)) |
+		  (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT));
+
+	/* pack the data to 8-bit CCDCCFG */
+	switch (ccdc_cfg.if_type) {
+	case V4L2_MBUS_FMT_YUYV8_2X8:
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+			dev_dbg(dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		modeset |= ((VPFE_PINPOL_NEGATIVE & CCDC_VD_POL_MASK) <<
+				CCDC_VD_POL_SHIFT);
+		regw(3, REC656IF);
+		ccdcfg = ccdcfg | CCDC_DATA_PACK8 | CCDC_YCINSWP_YCBCR;
+		break;
+	case V4L2_MBUS_FMT_YUYV10_2X10:
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+			dev_dbg(dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		/* setup BT.656, embedded sync  */
+		regw(3, REC656IF);
+		/* enable 10 bit mode in ccdcfg */
+		ccdcfg = ccdcfg | CCDC_DATA_PACK8 | CCDC_YCINSWP_YCBCR |
+			CCDC_BW656_ENABLE;
+		break;
+	case V4L2_MBUS_FMT_YUYV10_1X20:
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
+			dev_dbg(dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		regw(3, REC656IF);
+		break;
+
+	case V4L2_MBUS_FMT_Y8_1X8:
+		ccdcfg |= CCDC_DATA_PACK8;
+		ccdcfg |= CCDC_YCINSWP_YCBCR;
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+			dev_dbg(dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		break;
+	case V4L2_MBUS_FMT_YUYV8_1X16:
+		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
+			dev_dbg(dev, "Invalid pix_fmt(input mode)\n");
+			return -EINVAL;
+		}
+		break;
+	default:
+		/* should never come here */
+		dev_dbg(dev, "Invalid interface type\n");
+		return -EINVAL;
+	}
+
+	regw(modeset, MODESET);
+
+	/* Set up pix order */
+	ccdcfg |= (params->pix_order & CCDC_PIX_ORDER_MASK) <<
+		CCDC_PIX_ORDER_SHIFT;
+
+	regw(ccdcfg, CCDCFG);
+
+	/* configure video window */
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_YUYV10_1X20 ||
+			ccdc_cfg.if_type == V4L2_MBUS_FMT_YUYV8_1X16)
+		ccdc_setwin(&params->win, params->frm_fmt, 1, mode);
+	else
+		ccdc_setwin(&params->win, params->frm_fmt, 2, mode);
+
+	/**
+	 * configure the horizontal line offset
+	 * this is done by rounding up width to a multiple of 16 pixels
+	 * and multiply by two to account for y:cb:cr 4:2:2 data
+	 */
+	regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5), HSIZE);
+
+	/* configure the memory line offset */
+	if (params->frm_fmt == CCDC_FRMFMT_INTERLACED &&
+	    params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
+		/* two fields are interleaved in memory */
+		regw(0x00000249, SDOFST);
+	}
+
+	/* Setup test pattern if enabled */
+	if (ccdc_test_pat_gen) {
+		sync.ccdpg_hdpol = (params->hd_pol & CCDC_HD_POL_MASK);
+		sync.ccdpg_vdpol = (params->vd_pol & CCDC_VD_POL_MASK);
+		vpss_set_sync_pol(sync);
+		vpss_set_pg_frame_size(frame_size);
+	}
+
+	return 0;
+}
+
+static int ccdc_configure(int mode)
+{
+	if (ccdc_cfg.if_type == V4L2_MBUS_FMT_SGRBG12_1X12)
+		return ccdc_config_raw(mode);
+
+	return ccdc_config_ycbcr(mode);
+}
+
+static int ccdc_close(struct device *device)
+{
+	/* copy defaults to module params */
+	memcpy(&ccdc_cfg.bayer.config_params, &ccdc_config_defaults,
+		sizeof(struct ccdc_config_params_raw));
+
+	return 0;
+}
+
+static struct ccdc_hw_device ccdc_hw_dev = {
+	.name = "dm365_isif",
+	.owner = THIS_MODULE,
+	.hw_ops = {
+		.open = ccdc_open,
+		.close = ccdc_close,
+		.enable = ccdc_enable,
+		.enable_out_to_sdram = ccdc_enable_output_to_sdram,
+		.set_hw_if_params = ccdc_set_hw_if_params,
+		.set_params = ccdc_set_params,
+		.get_params = ccdc_get_params,
+		.configure = ccdc_configure,
+		.set_buftype = ccdc_set_buftype,
+		.get_buftype = ccdc_get_buftype,
+		.enum_pix = ccdc_enum_pix,
+		.set_pixel_format = ccdc_set_pixel_format,
+		.get_pixel_format = ccdc_get_pixel_format,
+		.set_frame_format = ccdc_set_frame_format,
+		.get_frame_format = ccdc_get_frame_format,
+		.set_image_window = ccdc_set_image_window,
+		.get_image_window = ccdc_get_image_window,
+		.get_line_length = ccdc_get_line_length,
+		.setfbaddr = ccdc_setfbaddr,
+		.getfid = ccdc_getfid,
+		.set_ctrl = ccdc_set_ctrl,
+	},
+};
+
+struct ccdc_hw_device *get_ccdc_dev(void)
+{
+	return &ccdc_hw_dev;
+}
+
+int ccdc_init(struct platform_device *pdev)
+{
+	static resource_size_t res_len;
+	struct resource *res;
+	void *__iomem addr;
+	int status;
+	int i;
+
+	i = 0;
+	/* Get the ISIF base address, linearization table0 and table1 addr. */
+	while (i < 3) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!res) {
+			status = -ENOENT;
+			goto fail_nobase_res;
+		}
+		res_len = res->end - res->start + 1;
+		res = request_mem_region(res->start, res_len, res->name);
+		if (!res) {
+			status = -EBUSY;
+			goto fail_nobase_res;
+		}
+		addr = ioremap_nocache(res->start, res_len);
+		if (!addr) {
+			status = -EBUSY;
+			goto fail_base_iomap;
+		}
+		switch (i) {
+		case 0:
+			/* ISIF base address */
+			ccdc_cfg.base_addr = addr;
+			break;
+		case 1:
+			/* ISIF linear tbl0 address */
+			ccdc_cfg.linear_tbl0_addr = addr;
+			break;
+		default:
+			/* ISIF linear tbl0 address */
+			ccdc_cfg.linear_tbl1_addr = addr;
+			break;
+		}
+		i++;
+	}
+
+	davinci_cfg_reg(DM365_VIN_CAM_WEN);
+	davinci_cfg_reg(DM365_VIN_CAM_VD);
+	davinci_cfg_reg(DM365_VIN_CAM_HD);
+	davinci_cfg_reg(DM365_VIN_YIN4_7_EN);
+	davinci_cfg_reg(DM365_VIN_YIN0_3_EN);
+
+	return 0;
+fail_base_iomap:
+	release_mem_region(res->start, res_len);
+	i--;
+fail_nobase_res:
+	if (ccdc_cfg.base_addr)
+		iounmap(ccdc_cfg.base_addr);
+	if (ccdc_cfg.linear_tbl0_addr)
+		iounmap(ccdc_cfg.linear_tbl0_addr);
+
+	while (i >= 0) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		release_mem_region(res->start, res_len);
+		i--;
+	}
+
+	return status;
+}
+
+void ccdc_remove(struct platform_device *pdev)
+{
+	struct resource *res;
+	int i;
+
+	iounmap(ccdc_cfg.base_addr);
+	iounmap(ccdc_cfg.linear_tbl0_addr);
+	iounmap(ccdc_cfg.linear_tbl1_addr);
+
+	i = 0;
+	while (i < 3) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (res)
+			release_mem_region(res->start,
+					   res->end - res->start + 1);
+		i++;
+	}
+}
diff --git a/drivers/media/platform/davinci/dm365_ccdc.h b/drivers/media/platform/davinci/dm365_ccdc.h
new file mode 100644
index 0000000..ce9358f
--- /dev/null
+++ b/drivers/media/platform/davinci/dm365_ccdc.h
@@ -0,0 +1,137 @@ 
+/*
+ * Copyright (C) 2012 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Contributors:
+ *      Manjunath Hadli <manjunath.hadli@ti.com>
+ *      Prabhakar Lad <prabhakar.lad@ti.com>
+ */
+
+#ifndef _DM365_CCDC_H
+#define _DM365_CCDC_H
+
+#include <linux/dm365_ccdc.h>
+
+#include <media/davinci/vpfe.h>
+#include <media/davinci/ccdc_types.h>
+
+#define CCDC_COLPTN_R_Ye	0x0
+#define CCDC_COLPTN_Gr_Cy	0x1
+#define CCDC_COLPTN_Gb_G	0x2
+#define CCDC_COLPTN_B_Mg	0x3
+
+#define CCDC_CCOLP_CP01_0	0
+#define CCDC_CCOLP_CP03_2	2
+#define CCDC_CCOLP_CP05_4	4
+#define CCDC_CCOLP_CP07_6	6
+#define CCDC_CCOLP_CP11_0	8
+#define CCDC_CCOLP_CP13_2	10
+#define CCDC_CCOLP_CP15_4	12
+#define CCDC_CCOLP_CP17_6	14
+
+static const u32 ccdc_sgrbg_pattern =
+	CCDC_COLPTN_Gr_Cy <<  CCDC_CCOLP_CP01_0 |
+	CCDC_COLPTN_R_Ye  << CCDC_CCOLP_CP03_2 |
+	CCDC_COLPTN_B_Mg  << CCDC_CCOLP_CP05_4 |
+	CCDC_COLPTN_Gb_G  << CCDC_CCOLP_CP07_6 |
+	CCDC_COLPTN_Gr_Cy << CCDC_CCOLP_CP11_0 |
+	CCDC_COLPTN_R_Ye  << CCDC_CCOLP_CP13_2 |
+	CCDC_COLPTN_B_Mg  << CCDC_CCOLP_CP15_4 |
+	CCDC_COLPTN_Gb_G  << CCDC_CCOLP_CP17_6;
+
+static const u32 ccdc_srggb_pattern =
+	CCDC_COLPTN_R_Ye  << CCDC_CCOLP_CP01_0 |
+	CCDC_COLPTN_Gr_Cy << CCDC_CCOLP_CP03_2 |
+	CCDC_COLPTN_Gb_G  << CCDC_CCOLP_CP05_4 |
+	CCDC_COLPTN_B_Mg  << CCDC_CCOLP_CP07_6 |
+	CCDC_COLPTN_R_Ye  << CCDC_CCOLP_CP11_0 |
+	CCDC_COLPTN_Gr_Cy << CCDC_CCOLP_CP13_2 |
+	CCDC_COLPTN_Gb_G  << CCDC_CCOLP_CP15_4 |
+	CCDC_COLPTN_B_Mg  << CCDC_CCOLP_CP17_6;
+
+struct ccdc_ycbcr_config {
+	/* v4l2 pixel format */
+	unsigned long v4l2_pix_fmt;
+	/* ccdc pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* ccdc frame format */
+	enum ccdc_frmfmt frm_fmt;
+	/* CCDC crop window */
+	struct v4l2_rect win;
+	/* field polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* interface VD polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* interface HD polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* ccdc pix order. Only used for ycbcr capture */
+	enum ccdc_pixorder pix_order;
+	/* ccdc buffer type. Only used for ycbcr capture */
+	enum ccdc_buftype buf_type;
+};
+
+struct ccdc_params_raw {
+	/* v4l2 pixel format */
+	unsigned long v4l2_pix_fmt;
+	/* ccdc pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* ccdc frame format */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* interface VD polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* interface HD polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* buffer type. Applicable for interlaced mode */
+	enum ccdc_buftype buf_type;
+	/* Gain values */
+	struct ccdc_gain gain;
+	/* cfa pattern */
+	enum ccdc_cfa_pattern cfa_pat;
+	/* Data MSB position */
+	enum ccdc_data_msb data_msb;
+	/* Enable horizontal flip */
+	unsigned char horz_flip_en;
+	/* Enable image invert vertically */
+	unsigned char image_invert_en;
+
+	/*all the userland defined stuff*/
+	struct ccdc_config_params_raw config_params;
+};
+
+enum ccdc_data_pack {
+	CCDC_PACK_16BIT,
+	CCDC_PACK_12BIT,
+	CCDC_PACK_8BIT
+};
+
+struct ccdc_gain_values {
+	unsigned int cr_gain;
+	unsigned int cgr_gain;
+	unsigned int cgb_gain;
+	unsigned int cb_gain;
+	unsigned int offset;
+};
+
+struct ccdc_hw_device *get_ccdc_dev(void);
+
+#define CCDC_WIN_NTSC		{0, 0, 720, 480}
+#define CCDC_WIN_VGA		{0, 0, 640, 480}
+#define ISP5_CCDCMUX		0x20
+
+#endif
diff --git a/drivers/media/platform/davinci/dm365_ccdc_regs.h b/drivers/media/platform/davinci/dm365_ccdc_regs.h
new file mode 100644
index 0000000..fcc82ea
--- /dev/null
+++ b/drivers/media/platform/davinci/dm365_ccdc_regs.h
@@ -0,0 +1,314 @@ 
+/*
+ * Copyright (C) 2012 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Contributors:
+ *      Manjunath Hadli <manjunath.hadli@ti.com>
+ *      Prabhakar Lad <prabhakar.lad@ti.com>
+ */
+
+#ifndef _DM365_CCDC_REGS_H
+#define _DM365_CCDC_REGS_H
+
+/* ISIF registers relative offsets */
+#define SYNCEN					0x00
+#define MODESET					0x04
+#define HDW					0x08
+#define VDW					0x0c
+#define PPLN					0x10
+#define LPFR					0x14
+#define SPH					0x18
+#define LNH					0x1c
+#define SLV0					0x20
+#define SLV1					0x24
+#define LNV					0x28
+#define CULH					0x2c
+#define CULV					0x30
+#define HSIZE					0x34
+#define SDOFST					0x38
+#define CADU					0x3c
+#define CADL					0x40
+#define LINCFG0					0x44
+#define LINCFG1					0x48
+#define CCOLP					0x4c
+#define CRGAIN					0x50
+#define CGRGAIN					0x54
+#define CGBGAIN					0x58
+#define CBGAIN					0x5c
+#define COFSTA					0x60
+#define FLSHCFG0				0x64
+#define FLSHCFG1				0x68
+#define FLSHCFG2				0x6c
+#define VDINT0					0x70
+#define VDINT1					0x74
+#define VDINT2					0x78
+#define MISC					0x7c
+#define CGAMMAWD				0x80
+#define REC656IF				0x84
+#define CCDCFG					0x88
+/*****************************************************
+* Defect Correction registers
+*****************************************************/
+#define DFCCTL					0x8c
+#define VDFSATLV				0x90
+#define DFCMEMCTL				0x94
+#define DFCMEM0					0x98
+#define DFCMEM1					0x9c
+#define DFCMEM2					0xa0
+#define DFCMEM3					0xa4
+#define DFCMEM4					0xa8
+/****************************************************
+* Black Clamp registers
+****************************************************/
+#define CLAMPCFG				0xac
+#define CLDCOFST				0xb0
+#define CLSV					0xb4
+#define CLHWIN0					0xb8
+#define CLHWIN1					0xbc
+#define CLHWIN2					0xc0
+#define CLVRV					0xc4
+#define CLVWIN0					0xc8
+#define CLVWIN1					0xcc
+#define CLVWIN2					0xd0
+#define CLVWIN3					0xd4
+/****************************************************
+* Lense Shading Correction
+****************************************************/
+#define DATAHOFST				0xd8
+#define DATAVOFST				0xdc
+#define LSCHVAL					0xe0
+#define LSCVVAL					0xe4
+#define TWODLSCCFG				0xe8
+#define TWODLSCOFST				0xec
+#define TWODLSCINI				0xf0
+#define TWODLSCGRBU				0xf4
+#define TWODLSCGRBL				0xf8
+#define TWODLSCGROF				0xfc
+#define TWODLSCORBU				0x100
+#define TWODLSCORBL				0x104
+#define TWODLSCOROF				0x108
+#define TWODLSCIRQEN				0x10c
+#define TWODLSCIRQST				0x110
+/****************************************************
+* Data formatter
+****************************************************/
+#define FMTCFG					0x114
+#define FMTPLEN					0x118
+#define FMTSPH					0x11c
+#define FMTLNH					0x120
+#define FMTSLV					0x124
+#define FMTLNV					0x128
+#define FMTRLEN					0x12c
+#define FMTHCNT					0x130
+#define FMTAPTR_BASE				0x134
+/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
+#define FMTAPTR(i)			(FMTAPTR_BASE + (i * 4))
+#define FMTPGMVF0				0x174
+#define FMTPGMVF1				0x178
+#define FMTPGMAPU0				0x17c
+#define FMTPGMAPU1				0x180
+#define FMTPGMAPS0				0x184
+#define FMTPGMAPS1				0x188
+#define FMTPGMAPS2				0x18c
+#define FMTPGMAPS3				0x190
+#define FMTPGMAPS4				0x194
+#define FMTPGMAPS5				0x198
+#define FMTPGMAPS6				0x19c
+#define FMTPGMAPS7				0x1a0
+/************************************************
+* Color Space Converter
+************************************************/
+#define CSCCTL					0x1a4
+#define CSCM0					0x1a8
+#define CSCM1					0x1ac
+#define CSCM2					0x1b0
+#define CSCM3					0x1b4
+#define CSCM4					0x1b8
+#define CSCM5					0x1bc
+#define CSCM6					0x1c0
+#define CSCM7					0x1c4
+#define OBWIN0					0x1c8
+#define OBWIN1					0x1cc
+#define OBWIN2					0x1d0
+#define OBWIN3					0x1d4
+#define OBVAL0					0x1d8
+#define OBVAL1					0x1dc
+#define OBVAL2					0x1e0
+#define OBVAL3					0x1e4
+#define OBVAL4					0x1e8
+#define OBVAL5					0x1ec
+#define OBVAL6					0x1f0
+#define OBVAL7					0x1f4
+#define CLKCTL					0x1f8
+
+#define CCDC_LINEAR_LUT0_ADDR			0x1c7c000
+#define CCDC_LINEAR_LUT1_ADDR			0x1c7c400
+
+/* Masks & Shifts below */
+#define START_PX_HOR_MASK			0x7fff
+#define NUM_PX_HOR_MASK				0x7fff
+#define START_VER_ONE_MASK			0x7fff
+#define START_VER_TWO_MASK			0x7fff
+#define NUM_LINES_VER				0x7fff
+
+/* gain - offset masks */
+#define GAIN_INTEGER_MASK			0x7
+#define GAIN_INTEGER_SHIFT			0x9
+#define GAIN_DECIMAL_MASK			0x1ff
+#define OFFSET_MASK				0xfff
+#define GAIN_SDRAM_EN_SHIFT			12
+#define GAIN_IPIPE_EN_SHIFT			13
+#define GAIN_H3A_EN_SHIFT			14
+#define OFST_SDRAM_EN_SHIFT			8
+#define OFST_IPIPE_EN_SHIFT			9
+#define OFST_H3A_EN_SHIFT			10
+#define GAIN_OFFSET_EN_MASK			0x7700
+
+/* Culling */
+#define CULL_PAT_EVEN_LINE_SHIFT		8
+
+/* CCDCFG register */
+#define CCDC_YCINSWP_RAW			(0x00 << 4)
+#define CCDC_YCINSWP_YCBCR			(0x01 << 4)
+#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC		(0x00 << 6)
+#define CCDC_CCDCFG_WENLOG_AND			(0x00 << 8)
+#define CCDC_CCDCFG_TRGSEL_WEN			(0x00 << 9)
+#define CCDC_CCDCFG_EXTRG_DISABLE		(0x00 << 10)
+#define CCDC_LATCH_ON_VSYNC_DISABLE		(0x01 << 15)
+#define CCDC_LATCH_ON_VSYNC_ENABLE		(0x00 << 15)
+#define CCDC_DATA_PACK_MASK			0x03
+#define CCDC_DATA_PACK16			0x0
+#define CCDC_DATA_PACK12			0x1
+#define CCDC_DATA_PACK8				0x2
+#define CCDC_PIX_ORDER_SHIFT			11
+#define CCDC_PIX_ORDER_MASK			0x01
+#define CCDC_BW656_ENABLE			(0x01 << 5)
+
+/* MODESET registers */
+#define CCDC_VDHDOUT_INPUT			(0x00 << 0)
+#define CCDC_INPUT_MASK				0x03
+#define CCDC_INPUT_SHIFT			12
+#define CCDC_RAW_INPUT_MODE			0x00
+#define CCDC_FID_POL_MASK			0x01
+#define CCDC_FID_POL_SHIFT			4
+#define CCDC_HD_POL_MASK			0x01
+#define CCDC_HD_POL_SHIFT			3
+#define CCDC_VD_POL_MASK			0x01
+#define CCDC_VD_POL_SHIFT			2
+#define CCDC_DATAPOL_NORMAL			0x00
+#define CCDC_DATAPOL_MASK			0x01
+#define CCDC_DATAPOL_SHIFT			6
+#define CCDC_EXWEN_DISABLE			0x00
+#define CCDC_EXWEN_MASK				0x01
+#define CCDC_EXWEN_SHIFT			5
+#define CCDC_FRM_FMT_MASK			0x01
+#define CCDC_FRM_FMT_SHIFT			7
+#define CCDC_DATASFT_MASK			0x07
+#define CCDC_DATASFT_SHIFT			8
+#define CCDC_LPF_SHIFT				14
+#define CCDC_LPF_MASK				0x1
+
+/* GAMMAWD registers */
+#define CCDC_ALAW_GAMA_WD_MASK			0xf
+#define CCDC_ALAW_GAMA_WD_SHIFT			1
+#define CCDC_ALAW_ENABLE			0x01
+#define CCDC_GAMMAWD_CFA_MASK			0x01
+#define CCDC_GAMMAWD_CFA_SHIFT			5
+
+/* HSIZE registers */
+#define CCDC_HSIZE_FLIP_MASK			0x01
+#define CCDC_HSIZE_FLIP_SHIFT			12
+#define CCDC_LINEOFST_MASK			0xfff
+
+/* MISC registers */
+#define CCDC_DPCM_EN_SHIFT			12
+#define CCDC_DPCM_EN_MASK			1
+#define CCDC_DPCM_PREDICTOR_SHIFT		13
+#define CCDC_DPCM_PREDICTOR_MASK		1
+
+/* Black clamp related */
+#define CCDC_BC_DCOFFSET_MASK			0x1fff
+#define CCDC_BC_MODE_COLOR_MASK			1
+#define CCDC_BC_MODE_COLOR_SHIFT		4
+#define CCDC_HORZ_BC_MODE_MASK			3
+#define CCDC_HORZ_BC_MODE_SHIFT			1
+#define CCDC_HORZ_BC_WIN_COUNT_MASK		0x1f
+#define CCDC_HORZ_BC_WIN_SEL_SHIFT		5
+#define CCDC_HORZ_BC_PIX_LIMIT_SHIFT		6
+#define CCDC_HORZ_BC_WIN_H_SIZE_MASK		3
+#define CCDC_HORZ_BC_WIN_H_SIZE_SHIFT		8
+#define CCDC_HORZ_BC_WIN_V_SIZE_MASK		3
+#define CCDC_HORZ_BC_WIN_V_SIZE_SHIFT		12
+#define CCDC_HORZ_BC_WIN_START_H_MASK		0x1fff
+#define CCDC_HORZ_BC_WIN_START_V_MASK		0x1fff
+#define CCDC_VERT_BC_OB_H_SZ_MASK		7
+#define CCDC_VERT_BC_RST_VAL_SEL_MASK		3
+#define CCDC_VERT_BC_RST_VAL_SEL_SHIFT		4
+#define CCDC_VERT_BC_LINE_AVE_COEF_SHIFT	8
+#define CCDC_VERT_BC_OB_START_HORZ_MASK		0x1fff
+#define CCDC_VERT_BC_OB_START_VERT_MASK		0x1fff
+#define CCDC_VERT_BC_OB_VERT_SZ_MASK		0x1fff
+#define CCDC_VERT_BC_RST_VAL_MASK		0xfff
+#define CCDC_BC_VERT_START_SUB_V_MASK		0x1fff
+
+/* VDFC registers */
+#define CCDC_VDFC_EN_SHIFT			4
+#define CCDC_VDFC_CORR_MOD_MASK			3
+#define CCDC_VDFC_CORR_MOD_SHIFT		5
+#define CCDC_VDFC_CORR_WHOLE_LN_SHIFT		7
+#define CCDC_VDFC_LEVEL_SHFT_MASK		7
+#define CCDC_VDFC_LEVEL_SHFT_SHIFT		8
+#define CCDC_VDFC_SAT_LEVEL_MASK		0xfff
+#define CCDC_VDFC_POS_MASK			0x1fff
+#define CCDC_DFCMEMCTL_DFCMARST_SHIFT		2
+
+/* CSC registers */
+#define CCDC_CSC_COEF_INTEG_MASK		7
+#define CCDC_CSC_COEF_DECIMAL_MASK		0x1f
+#define CCDC_CSC_COEF_INTEG_SHIFT		5
+#define CCDC_CSCM_MSB_SHIFT			8
+#define CCDC_DF_CSC_SPH_MASK			0x1fff
+#define CCDC_DF_CSC_LNH_MASK			0x1fff
+#define CCDC_DF_CSC_SLV_MASK			0x1fff
+#define CCDC_DF_CSC_LNV_MASK			0x1fff
+#define CCDC_DF_NUMLINES			0x7fff
+#define CCDC_DF_NUMPIX				0x1fff
+
+/* Offsets for LSC/DFC/Gain */
+#define CCDC_DATA_H_OFFSET_MASK			0x1fff
+#define CCDC_DATA_V_OFFSET_MASK			0x1fff
+
+/* Linearization */
+#define CCDC_LIN_CORRSFT_MASK			7
+#define CCDC_LIN_CORRSFT_SHIFT			4
+#define CCDC_LIN_SCALE_FACT_INTEG_SHIFT		10
+#define CCDC_LIN_SCALE_FACT_DECIMAL_MASK	0x3ff
+#define CCDC_LIN_ENTRY_MASK			0x3ff
+
+#define CCDC_DF_FMTRLEN_MASK			0x1fff
+#define CCDC_DF_FMTHCNT_MASK			0x1fff
+
+/* Pattern registers */
+#define CCDC_PG_EN				(1 << 3)
+#define CCDC_SEL_PG_SRC				(3 << 4)
+#define CCDC_PG_VD_POL_SHIFT			0
+#define CCDC_PG_HD_POL_SHIFT			1
+
+/*masks and shifts*/
+#define CCDC_SYNCEN_VDHDEN_MASK			(1 << 0)
+#define CCDC_SYNCEN_WEN_MASK			(1 << 1)
+#define CCDC_SYNCEN_WEN_SHIFT			1
+
+#endif
diff --git a/include/linux/dm365_ccdc.h b/include/linux/dm365_ccdc.h
new file mode 100644
index 0000000..da37b9b
--- /dev/null
+++ b/include/linux/dm365_ccdc.h
@@ -0,0 +1,592 @@ 
+/*
+ * Copyright (C) 2012 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Contributors:
+ *      Manjunath Hadli <manjunath.hadli@ti.com>
+ *      Prabhakar Lad <prabhakar.lad@ti.com>
+ */
+
+#ifndef _DM365_CCDC_INCLUDE_H
+#define _DM365_CCDC_INCLUDE_H
+
+/**
+ * ccdc float type S8Q8/U8Q8
+ */
+struct ccdc_float_8 {
+	/* 8 bit integer part */
+	__u8 integer;
+	/* 8 bit decimal part */
+	__u8 decimal;
+};
+
+/**
+ * brief ccdc float type U16Q16/S16Q16
+ */
+struct ccdc_float_16 {
+	/* 16 bit integer part */
+	__u16 integer;
+	/* 16 bit decimal part */
+	__u16 decimal;
+};
+
+/************************************************************************
+ *   Vertical Defect Correction parameters
+ ***********************************************************************/
+
+/**
+ * vertical defect correction methods
+ */
+enum ccdc_vdfc_corr_mode {
+	/* Defect level subtraction. Just fed through if saturating */
+	CCDC_VDFC_NORMAL,
+	/**
+	 * Defect level subtraction. Horizontal interpolation ((i-2)+(i+2))/2
+	 * if data saturating
+	 */
+	CCDC_VDFC_HORZ_INTERPOL_IF_SAT,
+	/* Horizontal interpolation (((i-2)+(i+2))/2) */
+	CCDC_VDFC_HORZ_INTERPOL
+};
+
+/**
+ * Max Size of the Vertical Defect Correction table
+ */
+#define CCDC_VDFC_TABLE_SIZE 8
+
+/**
+ * Values used for shifting up the vdfc defect level
+ */
+enum ccdc_vdfc_shift {
+	/* No Shift */
+	CCDC_VDFC_NO_SHIFT,
+	/* Shift by 1 bit */
+	CCDC_VDFC_SHIFT_1,
+	/* Shift by 2 bit */
+	CCDC_VDFC_SHIFT_2,
+	/* Shift by 3 bit */
+	CCDC_VDFC_SHIFT_3,
+	/* Shift by 4 bit */
+	CCDC_VDFC_SHIFT_4
+};
+
+/**
+ * Defect Correction (DFC) table entry
+ */
+struct ccdc_vdfc_entry {
+	/* vertical position of defect */
+	unsigned short pos_vert;
+	/* horizontal position of defect */
+	unsigned short pos_horz;
+	/**
+	 * Defect level of Vertical line defect position. This is subtracted
+	 * from the data at the defect position
+	 */
+	unsigned char level_at_pos;
+	/**
+	 * Defect level of the pixels upper than the vertical line defect.
+	 * This is subtracted from the data
+	 */
+	unsigned char level_up_pixels;
+	/**
+	 * Defect level of the pixels lower than the vertical line defect.
+	 * This is subtracted from the data
+	 */
+	unsigned char level_low_pixels;
+};
+
+/**
+ * Structure for Defect Correction (DFC) parameter
+ */
+struct ccdc_dfc {
+	/* enable vertical defect correction */
+	unsigned char en;
+	/* Correction methods */
+	enum ccdc_vdfc_corr_mode corr_mode;
+	/**
+	 * 0 - whole line corrected, 1 - not
+	 * pixels upper than the defect
+	 */
+	unsigned char corr_whole_line;
+	/**
+	 * defect level shift value. level_at_pos, level_upper_pos,
+	 * and level_lower_pos can be shifted up by this value
+	 */
+	enum ccdc_vdfc_shift def_level_shift;
+	/* defect saturation level */
+	unsigned short def_sat_level;
+	/* number of vertical defects. Max is CCDC_VDFC_TABLE_SIZE */
+	short num_vdefects;
+	/* VDFC table ptr */
+	struct ccdc_vdfc_entry table[CCDC_VDFC_TABLE_SIZE];
+};
+
+/************************************************************************
+*   Digital/Black clamp or DC Subtract parameters
+************************************************************************/
+/**
+ * Horizontal Black Clamp modes
+ */
+enum ccdc_horz_bc_mode {
+	/**
+	 * Horizontal clamp disabled. Only vertical clamp
+	 * value is subtracted
+	 */
+	CCDC_HORZ_BC_DISABLE,
+	/**
+	 * Horizontal clamp value is calculated and subtracted
+	 * from image data along with vertical clamp value
+	 */
+	CCDC_HORZ_BC_CLAMP_CALC_ENABLED,
+	/**
+	 * Horizontal clamp value calculated from previous image
+	 * is subtracted from image data along with vertical clamp
+	 * value. How the horizontal clamp value for the first image
+	 * is calculated in this case ???
+	 */
+	CCDC_HORZ_BC_CLAMP_NOT_UPDATED
+};
+
+/**
+ * Base window selection for Horizontal Black Clamp calculations
+ */
+enum ccdc_horz_bc_base_win_sel {
+	/* Select Most left window for bc calculation */
+	CCDC_SEL_MOST_LEFT_WIN,
+
+	/* Select Most right window for bc calculation */
+	CCDC_SEL_MOST_RIGHT_WIN,
+};
+
+/* Size of window in horizontal direction for horizontal bc */
+enum ccdc_horz_bc_sz_h {
+	CCDC_HORZ_BC_SZ_H_2PIXELS,
+	CCDC_HORZ_BC_SZ_H_4PIXELS,
+	CCDC_HORZ_BC_SZ_H_8PIXELS,
+	CCDC_HORZ_BC_SZ_H_16PIXELS
+};
+
+/* Size of window in vertcal direction for vertical bc */
+enum ccdc_horz_bc_sz_v {
+	CCDC_HORZ_BC_SZ_H_32PIXELS,
+	CCDC_HORZ_BC_SZ_H_64PIXELS,
+	CCDC_HORZ_BC_SZ_H_128PIXELS,
+	CCDC_HORZ_BC_SZ_H_256PIXELS
+};
+
+/**
+ * Structure for Horizontal Black Clamp config params
+ */
+struct ccdc_horz_bclamp {
+	/* horizontal clamp mode */
+	enum ccdc_horz_bc_mode mode;
+	/**
+	 * pixel value limit enable.
+	 *  0 - limit disabled
+	 *  1 - pixel value limited to 1023
+	 */
+	unsigned char clamp_pix_limit;
+	/**
+	 * Select most left or right window for clamp val
+	 * calculation
+	 */
+	enum ccdc_horz_bc_base_win_sel base_win_sel_calc;
+	/* Window count per color for calculation. range 1-32 */
+	unsigned char win_count_calc;
+	/* Window start position - horizontal for calculation. 0 - 8191 */
+	unsigned short win_start_h_calc;
+	/* Window start position - vertical for calculation 0 - 8191 */
+	unsigned short win_start_v_calc;
+	/* Width of the sample window in pixels for calculation */
+	enum ccdc_horz_bc_sz_h win_h_sz_calc;
+	/* Height of the sample window in pixels for calculation */
+	enum ccdc_horz_bc_sz_v win_v_sz_calc;
+};
+
+/**
+ * Black Clamp vertical reset values
+ */
+enum ccdc_vert_bc_reset_val_sel {
+	/* Reset value used is the clamp value calculated */
+	CCDC_VERT_BC_USE_HORZ_CLAMP_VAL,
+	/* Reset value used is reset_clamp_val configured */
+	CCDC_VERT_BC_USE_CONFIG_CLAMP_VAL,
+	/* No update, previous image value is used */
+	CCDC_VERT_BC_NO_UPDATE
+};
+
+enum ccdc_vert_bc_sz_h {
+	CCDC_VERT_BC_SZ_H_2PIXELS,
+	CCDC_VERT_BC_SZ_H_4PIXELS,
+	CCDC_VERT_BC_SZ_H_8PIXELS,
+	CCDC_VERT_BC_SZ_H_16PIXELS,
+	CCDC_VERT_BC_SZ_H_32PIXELS,
+	CCDC_VERT_BC_SZ_H_64PIXELS
+};
+
+/**
+ * Structure for Vetical Black Clamp configuration params
+ */
+struct ccdc_vert_bclamp {
+	/* Reset value selection for vertical clamp calculation */
+	enum ccdc_vert_bc_reset_val_sel reset_val_sel;
+	/* U12 value if reset_sel = CCDC_BC_VERT_USE_CONFIG_CLAMP_VAL */
+	unsigned short reset_clamp_val;
+	/**
+	 * U8Q8. Line average coefficient used in vertical clamp
+	 * calculation
+	 */
+	unsigned char line_ave_coef;
+	/* Width in pixels of the optical black region used for calculation. */
+	enum ccdc_vert_bc_sz_h ob_h_sz_calc;
+	/* Height of the optical black region for calculation */
+	unsigned short ob_v_sz_calc;
+	/* Optical black region start position - horizontal. 0 - 8191 */
+	unsigned short ob_start_h;
+	/* Optical black region start position - vertical 0 - 8191 */
+	unsigned short ob_start_v;
+};
+
+/**
+ * Structure for Black Clamp configuration params
+ */
+struct ccdc_black_clamp {
+	/**
+	 * this offset value is added irrespective of the clamp
+	 * enable status. S13
+	 */
+	unsigned short dc_offset;
+	/**
+	 * Enable black/digital clamp value to be subtracted
+	 * from the image data
+	 */
+	unsigned char en;
+	/**
+	 * black clamp mode. same/separate clamp for 4 colors
+	 * 0 - disable - same clamp value for all colors
+	 * 1 - clamp value calculated separately for all colors
+	 */
+	unsigned char bc_mode_color;
+	/* Vrtical start position for bc subtraction */
+	unsigned short vert_start_sub;
+	/* Black clamp for horizontal direction */
+	struct ccdc_horz_bclamp horz;
+	/* Black clamp for vertical direction */
+	struct ccdc_vert_bclamp vert;
+};
+
+/*************************************************************************
+** Color Space Convertion (CSC)
+*************************************************************************/
+/**
+ * Number of Coefficient values used for CSC
+ */
+#define CCDC_CSC_NUM_COEFF 16
+
+/*************************************************************************
+**  Color Space Conversion parameters
+*************************************************************************/
+/**
+ * Structure used for CSC config params
+ */
+struct ccdc_color_space_conv {
+	/* Enable color space conversion */
+	unsigned char en;
+	/**
+	 * csc coeffient table. S8Q5, M00 at index 0, M01 at index 1, and
+	 * so forth
+	 */
+	struct ccdc_float_8 coeff[CCDC_CSC_NUM_COEFF];
+};
+
+enum ccdc_datasft {
+	/* No Shift */
+	CCDC_NO_SHIFT,
+	/* 1 bit Shift */
+	CCDC_1BIT_SHIFT,
+	/* 2 bit Shift */
+	CCDC_2BIT_SHIFT,
+	/* 3 bit Shift */
+	CCDC_3BIT_SHIFT,
+	/* 4 bit Shift */
+	CCDC_4BIT_SHIFT,
+	/* 5 bit Shift */
+	CCDC_5BIT_SHIFT,
+	/* 6 bit Shift */
+	CCDC_6BIT_SHIFT
+};
+
+enum ccdc_data_msb {
+	/* MSB b15 */
+	CCDC_BIT_MSB_15,
+	/* MSB b14 */
+	CCDC_BIT_MSB_14,
+	/* MSB b13 */
+	CCDC_BIT_MSB_13,
+	/* MSB b12 */
+	CCDC_BIT_MSB_12,
+	/* MSB b11 */
+	CCDC_BIT_MSB_11,
+	/* MSB b10 */
+	CCDC_BIT_MSB_10,
+	/* MSB b9 */
+	CCDC_BIT_MSB_9,
+	/* MSB b8 */
+	CCDC_BIT_MSB_8,
+	/* MSB b7 */
+	CCDC_BIT_MSB_7
+};
+
+/*************************************************************************
+**  Gain parameters
+*************************************************************************/
+/**
+ * Structure for Gain parameters
+ */
+struct ccdc_gain {
+	/* Gain for Red or ye */
+	struct ccdc_float_16 r_ye;
+	/* Gain for Gr or cy */
+	struct ccdc_float_16 gr_cy;
+	/* Gain for Gb or g */
+	struct ccdc_float_16 gb_g;
+	/* Gain for Blue or mg */
+	struct ccdc_float_16 b_mg;
+};
+
+/**
+ * Predicator types for DPCM compression
+ */
+enum ccdc_dpcm_predictor {
+	/* Choose Predictor1 for DPCM compression */
+	CCDC_DPCM_PRED1,
+	/* Choose Predictor2 for DPCM compression */
+	CCDC_DPCM_PRED2
+};
+
+#define CCDC_LINEAR_TAB_SIZE 192
+/*************************************************************************
+**  Linearization parameters
+*************************************************************************/
+/**
+ * Structure for Sensor data linearization
+ */
+struct ccdc_linearize {
+	/* Enable or Disable linearization of data */
+	unsigned char en;
+	/* Shift value applied */
+	enum ccdc_datasft corr_shft;
+	/* scale factor applied U11Q10 */
+	struct ccdc_float_16 scale_fact;
+	/* Size of the linear table */
+	unsigned short table[CCDC_LINEAR_TAB_SIZE];
+};
+
+enum ccdc_cfa_pattern {
+	CCDC_CFA_PAT_MOSAIC,
+	CCDC_CFA_PAT_STRIPE
+};
+
+enum ccdc_colpats {
+	CCDC_RED,
+	CCDC_GREEN_RED,
+	CCDC_GREEN_BLUE,
+	CCDC_BLUE
+};
+
+struct ccdc_col_pat {
+	enum ccdc_colpats olop;
+	enum ccdc_colpats olep;
+	enum ccdc_colpats elop;
+	enum ccdc_colpats elep;
+};
+
+/*************************************************************************
+**  CCDC Raw configuration parameters
+*************************************************************************/
+enum ccdc_fmt_mode {
+	CCDC_SPLIT,
+	CCDC_COMBINE
+};
+
+enum ccdc_lnum {
+	CCDC_1LINE,
+	CCDC_2LINES,
+	CCDC_3LINES,
+	CCDC_4LINES
+};
+
+enum ccdc_line {
+	CCDC_1STLINE,
+	CCDC_2NDLINE,
+	CCDC_3RDLINE,
+	CCDC_4THLINE
+};
+
+struct ccdc_fmtplen {
+	/**
+	 * number of program entries for SET0, range 1 - 16
+	 * when fmtmode is CCDC_SPLIT, 1 - 8 when fmtmode is
+	 * CCDC_COMBINE
+	 */
+	unsigned short plen0;
+	/**
+	 * number of program entries for SET1, range 1 - 16
+	 * when fmtmode is CCDC_SPLIT, 1 - 8 when fmtmode is
+	 * CCDC_COMBINE
+	 */
+	unsigned short plen1;
+	/**
+	 * number of program entries for SET2, range 1 - 16
+	 * when fmtmode is CCDC_SPLIT, 1 - 8 when fmtmode is
+	 * CCDC_COMBINE
+	 */
+	unsigned short plen2;
+	/**
+	 * number of program entries for SET3, range 1 - 16
+	 * when fmtmode is CCDC_SPLIT, 1 - 8 when fmtmode is
+	 * CCDC_COMBINE
+	 */
+	unsigned short plen3;
+};
+
+struct ccdc_fmt_cfg {
+	/* Split or combine or line alternate */
+	enum ccdc_fmt_mode fmtmode;
+	/* enable or disable line alternating mode */
+	unsigned char ln_alter_en;
+	/* Split/combine line number */
+	enum ccdc_lnum lnum;
+	/* Address increment Range 1 - 16 */
+	unsigned int addrinc;
+};
+
+struct ccdc_fmt_addr_ptr {
+	/* Initial address */
+	unsigned int init_addr;
+	/* output line number */
+	enum ccdc_line out_line;
+};
+
+struct ccdc_fmtpgm_ap {
+	/* program address pointer */
+	unsigned char pgm_aptr;
+	/* program address increment or decrement */
+	unsigned char pgmupdt;
+};
+
+struct ccdc_data_formatter {
+	/* Enable/Disable data formatter */
+	unsigned char en;
+	/* data formatter configuration */
+	struct ccdc_fmt_cfg cfg;
+	/* Formatter program entries length */
+	struct ccdc_fmtplen plen;
+	/* first pixel in a line fed to formatter */
+	unsigned short fmtrlen;
+	/* HD interval for output line. Only valid when split line */
+	unsigned short fmthcnt;
+	/* formatter address pointers */
+	struct ccdc_fmt_addr_ptr fmtaddr_ptr[16];
+	/* program enable/disable */
+	unsigned char pgm_en[32];
+	/* program address pointers */
+	struct ccdc_fmtpgm_ap fmtpgm_ap[32];
+};
+
+struct ccdc_df_csc {
+	/* Color Space Conversion confguration, 0 - csc, 1 - df */
+	unsigned int df_or_csc;
+	/* csc configuration valid if df_or_csc is 0 */
+	struct ccdc_color_space_conv csc;
+	/* data formatter configuration valid if df_or_csc is 1 */
+	struct ccdc_data_formatter df;
+	/* start pixel in a line at the input */
+	unsigned int start_pix;
+	/* number of pixels in input line */
+	unsigned int num_pixels;
+	/* start line at the input */
+	unsigned int start_line;
+	/* number of lines at the input */
+	unsigned int num_lines;
+};
+
+struct ccdc_gain_offsets_adj {
+	/* Enable or Disable Gain adjustment for SDRAM data */
+	unsigned char gain_sdram_en;
+	/* Enable or Disable Gain adjustment for IPIPE data */
+	unsigned char gain_ipipe_en;
+	/* Enable or Disable Gain adjustment for H3A data */
+	unsigned char gain_h3a_en;
+	/* Enable or Disable Gain adjustment for SDRAM data */
+	unsigned char offset_sdram_en;
+	/* Enable or Disable Gain adjustment for IPIPE data */
+	unsigned char offset_ipipe_en;
+	/* Enable or Disable Gain adjustment for H3A data */
+	unsigned char offset_h3a_en;
+};
+
+struct ccdc_cul {
+	/* Horizontal Cull pattern for odd lines */
+	unsigned char hcpat_odd;
+	/* Horizontal Cull pattern for even lines */
+	unsigned char hcpat_even;
+	/* Vertical Cull pattern */
+	unsigned char vcpat;
+	/* Enable or disable lpf. Apply when cull is enabled */
+	unsigned char en_lpf;
+};
+
+/* all the stuff in this struct will be provided by userland */
+struct ccdc_config_params_raw {
+	/* Linearization parameters for image sensor data input */
+	struct ccdc_linearize linearize;
+	/* Data formatter or CSC */
+	struct ccdc_df_csc df_csc;
+	/* Defect Pixel Correction (DFC) confguration */
+	struct ccdc_dfc dfc;
+	/* Black/Digital Clamp configuration */
+	struct ccdc_black_clamp bclamp;
+	/* Gain, offset adjustments */
+	struct ccdc_gain_offsets_adj gain_offset;
+	/* Culling */
+	struct ccdc_cul culling;
+	/* Predictor for DPCM compression */
+	enum ccdc_dpcm_predictor pred;
+	/* horizontal offset for Gain/LSC/DFC */
+	unsigned short horz_offset;
+	/* vertical offset for Gain/LSC/DFC */
+	unsigned short vert_offset;
+};
+
+#define VPFE_CCDC_CID_CRGAIN           (V4L2_CID_USER_BASE | 0xa001)
+#define VPFE_CCDC_CID_CGRGAIN          (V4L2_CID_USER_BASE | 0xa002)
+#define VPFE_CCDC_CID_CGBGAIN          (V4L2_CID_USER_BASE | 0xa003)
+#define VPFE_CCDC_CID_CBGAIN           (V4L2_CID_USER_BASE | 0xa004)
+#define VPFE_CCDC_CID_GAIN_OFFSET      (V4L2_CID_USER_BASE | 0xa005)
+
+/*
+ * Private IOCTL
+ *
+ * VIDIOC_VPFE_CCDC_S_RAW_PARAMS: Set raw params in CCDC
+ * VIDIOC_VPFE_CCDC_G_RAW_PARAMS: Get raw params from CCDC
+ */
+
+#define VIDIOC_VPFE_CCDC_S_RAW_PARAMS \
+	_IOW('V', BASE_VIDIOC_PRIVATE + 6,  struct ccdc_config_params_raw)
+#define VIDIOC_VPFE_CCDC_G_RAW_PARAMS \
+	_IOR('V', BASE_VIDIOC_PRIVATE + 7, struct ccdc_config_params_raw)
+
+#endif