/*
 * Copyright (C) 2005-2009 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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
 *
 * CCDC hardware module for DM355
 * ------------------------------
 *
 * This module is for configuring DM355 CCD controller of VPFE to capture
 * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
 * such as Defect Pixel Correction, Color Space Conversion etc to
 * pre-process the Bayer RGB data, before writing it to SDRAM. This
 * module also allows application to configure individual
 * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
 * To do so, application include dm355_ccdc.h and vpfe_capture.h header
 * files. The setparams() API is called by vpfe_capture driver
 * to configure module parameters
 *
 * TODO: 1) Raw bayer parameter settings and bayer capture
 * 	 2) Split module parameter structure to module specific ioctl structs
 *	 3) add support for lense shading correction
 *	 4) investigate if enum used for user space type definition
 * 	    to be replaced by #defines or integer
 */
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/videodev2.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/module.h>

#include <media/davinci/dm355_ccdc.h>
#include <media/davinci/vpss.h>

#include "dm355_ccdc_regs.h"
#include "ccdc_hw_device.h"

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CCDC Driver for DM355");
MODULE_AUTHOR("Texas Instruments");

static struct ccdc_oper_config {
	struct device *dev;
	/* CCDC interface type */
	enum vpfe_hw_if_type if_type;
	/* Raw Bayer configuration */
	struct ccdc_params_raw bayer;
	/* YCbCr configuration */
	struct ccdc_params_ycbcr ycbcr;
	/* Master clock */
	struct clk *mclk;
	/* slave clock */
	struct clk *sclk;
	/* ccdc base address */
	void __iomem *base_addr;
} ccdc_cfg = {
	/* Raw configurations */
	.bayer = {
		.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 = 256,
			.gb_g = 256,
			.gr_cy = 256,
			.b_mg = 256
		},
		.config_params = {
			.datasft = 2,
			.mfilt1 = CCDC_NO_MEDIAN_FILTER1,
			.mfilt2 = CCDC_NO_MEDIAN_FILTER2,
			.alaw = {
				.gama_wd = 2,
			},
			.blk_clamp = {
				.sample_pixel = 1,
				.dc_sub = 25
			},
			.col_pat_field0 = {
				.olop = CCDC_GREEN_BLUE,
				.olep = CCDC_BLUE,
				.elop = CCDC_RED,
				.elep = CCDC_GREEN_RED
			},
			.col_pat_field1 = {
				.olop = CCDC_GREEN_BLUE,
				.olep = CCDC_BLUE,
				.elop = CCDC_RED,
				.elep = CCDC_GREEN_RED
			},
		},
	},
	/* YCbCr configuration */
	.ycbcr = {
		.win = CCDC_WIN_PAL,
		.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
		.frm_fmt = CCDC_FRMFMT_INTERLACED,
		.fid_pol = VPFE_PINPOL_POSITIVE,
		.vd_pol = VPFE_PINPOL_POSITIVE,
		.hd_pol = VPFE_PINPOL_POSITIVE,
		.bt656_enable = 1,
		.pix_order = CCDC_PIXORDER_CBYCRY,
		.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
	},
};


/* Raw Bayer formats */
static u32 ccdc_raw_bayer_pix_formats[] =
		{V4L2_PIX_FMT_SBGGR8, 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 __raw_readl(ccdc_cfg.base_addr + offset);
}

static inline void regw(u32 val, u32 offset)
{
	__raw_writel(val, ccdc_cfg.base_addr + offset);
}

static void ccdc_enable(int en)
{
	unsigned int temp;
	temp = regr(SYNCEN);
	temp &= (~CCDC_SYNCEN_VDHDEN_MASK);
	temp |= (en & CCDC_SYNCEN_VDHDEN_MASK);
	regw(temp, SYNCEN);
}

static void ccdc_enable_output_to_sdram(int en)
{
	unsigned int temp;
	temp = regr(SYNCEN);
	temp &= (~(CCDC_SYNCEN_WEN_MASK));
	temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK);
	regw(temp, SYNCEN);
}

static void ccdc_config_gain_offset(void)
{
	/* configure gain */
	regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
	regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
	regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
	regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
	/* configure offset */
	regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
}

/*
 * ccdc_restore_defaults()
 * This function restore power on defaults in the ccdc registers
 */
static int ccdc_restore_defaults(void)
{
	int i;

	dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
	/* set all registers to zero */
	for (i = 0; i <= CCDC_REG_LAST; i += 4)
		regw(0, i);

	/* now override the values with power on defaults in registers */
	regw(MODESET_DEFAULT, MODESET);
	/* no culling support */
	regw(CULH_DEFAULT, CULH);
	regw(CULV_DEFAULT, CULV);
	/* Set default Gain and Offset */
	ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
	ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
	ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
	ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
	ccdc_config_gain_offset();
	regw(OUTCLIP_DEFAULT, OUTCLIP);
	regw(LSCCFG2_DEFAULT, LSCCFG2);
	/* select ccdc input */
	if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
		dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
		return -EFAULT;
	}
	/* select ccdc clock */
	if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
		dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
		return -EFAULT;
	}
	dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
	return 0;
}

static int ccdc_open(struct device *device)
{
	return ccdc_restore_defaults();
}

static int ccdc_close(struct device *device)
{
	/* disable clock */
	vpss_enable_clock(VPSS_CCDC_CLOCK, 0);
	/* do nothing for now */
	return 0;
}
/*
 * ccdc_setwin()
 * 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 horz_start, horz_nr_pixels;
	int vert_start, vert_nr_lines;
	int mid_img = 0;

	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");

	/*
	 * 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, SPH);
	regw(horz_nr_pixels, NPH);
	vert_start = image_win->top;

	if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
		vert_nr_lines = (image_win->height >> 1) - 1;
		vert_start >>= 1;
		/* Since first line doesn't have any data */
		vert_start += 1;
		/* configure VDINT0 and VDINT1 */
		regw(vert_start, VDINT0);
	} else {
		/* Since first line 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(vert_start, VDINT0);
		regw(mid_img, VDINT1);
	}
	regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
	regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
	regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
	dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
}

static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
{
	if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
	    ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
		dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n");
		return -EINVAL;
	}

	if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
	    ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
		dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n");
		return -EINVAL;
	}

	if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
	    ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
		dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n");
		return -EINVAL;
	}

	if ((ccdcparam->med_filt_thres < 0) ||
	   (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
		dev_dbg(ccdc_cfg.dev,
			"Invalid value of median filter thresold\n");
		return -EINVAL;
	}

	if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
	    ccdcparam->data_sz > CCDC_DATA_8BITS) {
		dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n");
		return -EINVAL;
	}

	if (ccdcparam->alaw.enable) {
		if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
		    ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
			dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n");
			return -EINVAL;
		}
	}

	if (ccdcparam->blk_clamp.b_clamp_enable) {
		if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
		    ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
			dev_dbg(ccdc_cfg.dev,
				"Invalid value of sample pixel\n");
			return -EINVAL;
		}
		if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
		    ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
			dev_dbg(ccdc_cfg.dev,
				"Invalid value of sample lines\n");
			return -EINVAL;
		}
	}
	return 0;
}

/* Parameter operations */
static int ccdc_set_params(void __user *params)
{
	struct ccdc_config_params_raw ccdc_raw_params;
	int x;

	/* only raw module parameters can be set through the IOCTL */
	if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
		return -EINVAL;

	x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
	if (x) {
		dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdc"
			"params, %d\n", x);
		return -EFAULT;
	}

	if (!validate_ccdc_param(&ccdc_raw_params)) {
		memcpy(&ccdc_cfg.bayer.config_params,
			&ccdc_raw_params,
			sizeof(ccdc_raw_params));
		return 0;
	}
	return -EINVAL;
}

/* This function will configure CCDC for YCbCr video capture */
static void ccdc_config_ycbcr(void)
{
	struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
	u32 temp;

	/* first set the CCDC power on defaults values in all registers */
	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
	ccdc_restore_defaults();

	/* configure pixel format & video frame format */
	temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) <<
		CCDC_INPUT_MODE_SHIFT) |
		((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
		CCDC_FRM_FMT_SHIFT));

	/* setup BT.656 sync mode */
	if (params->bt656_enable) {
		regw(CCDC_REC656IF_BT656_EN, REC656IF);
		/*
		 * configure the FID, VD, HD pin polarity fld,hd pol positive,
		 * vd negative, 8-bit pack mode
		 */
		temp |= CCDC_VD_POL_NEGATIVE;
	} else {		/* y/c external sync mode */
		temp |= (((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 */
	temp |= CCDC_DATA_PACK_ENABLE;

	regw(temp, MODESET);

	/* configure video window */
	ccdc_setwin(&params->win, params->frm_fmt, 2);

	/* configure the order of y cb cr in SD-RAM */
	temp = (params->pix_order << CCDC_Y8POS_SHIFT);
	temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC;
	regw(temp, CCDCFG);

	/*
	 * 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) >> 5), HSIZE);

	/* configure the memory line offset */
	if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
		/* two fields are interleaved in memory */
		regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
	}

	dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
}

/*
 * ccdc_config_black_clamp()
 * configure parameters for Optical Black Clamp
 */
static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
{
	u32 val;

	if (!bclamp->b_clamp_enable) {
		/* configure DCSub */
		regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB);
		regw(0x0000, CLAMP);
		return;
	}
	/* Enable the Black clamping, set sample lines and pixels */
	val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) |
	      ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
		CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE;
	regw(val, CLAMP);

	/* If Black clamping is enable then make dcsub 0 */
	val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK)
			<< CCDC_NUM_LINE_CALC_SHIFT;
	regw(val, DCSUB);
}

/*
 * ccdc_config_black_compense()
 * configure parameters for Black Compensation
 */
static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
{
	u32 val;

	val = (bcomp->b & CCDC_BLK_COMP_MASK) |
		((bcomp->gb & CCDC_BLK_COMP_MASK) <<
		CCDC_BLK_COMP_GB_COMP_SHIFT);
	regw(val, BLKCMP1);

	val = ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
		CCDC_BLK_COMP_GR_COMP_SHIFT) |
		((bcomp->r & CCDC_BLK_COMP_MASK) <<
		CCDC_BLK_COMP_R_COMP_SHIFT);
	regw(val, BLKCMP0);
}

/*
 * ccdc_write_dfc_entry()
 * write an entry in the dfc table.
 */
int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
{
/* TODO This is to be re-visited and adjusted */
#define DFC_WRITE_WAIT_COUNT	1000
	u32 val, count = DFC_WRITE_WAIT_COUNT;

	regw(dfc->dft_corr_vert[index], DFCMEM0);
	regw(dfc->dft_corr_horz[index], DFCMEM1);
	regw(dfc->dft_corr_sub1[index], DFCMEM2);
	regw(dfc->dft_corr_sub2[index], DFCMEM3);
	regw(dfc->dft_corr_sub3[index], DFCMEM4);
	/* set WR bit to write */
	val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK;
	regw(val, DFCMEMCTL);

	/*
	 * Assume, it is very short. If we get an error, we need to
	 * adjust this value
	 */
	while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK)
		count--;
	/*
	 * TODO We expect the count to be non-zero to be successful. Adjust
	 * the count if write requires more time
	 */

	if (count) {
		dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
		return -1;
	}
	return 0;
}

/*
 * ccdc_config_vdfc()
 * configure parameters for Vertical Defect Correction
 */
static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc)
{
	u32 val;
	int i;

	/* Configure General Defect Correction. The table used is from IPIPE */
	val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;

	/* Configure Vertical Defect Correction if needed */
	if (!dfc->ver_dft_en) {
		/* Enable only General Defect Correction */
		regw(val, DFCCTL);
		return 0;
	}

	if (dfc->table_size > CCDC_DFT_TABLE_SIZE)
		return -EINVAL;

	val |= CCDC_DFCCTL_VDFC_DISABLE;
	val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
		CCDC_DFCCTL_VDFCSL_SHIFT;
	val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
		CCDC_DFCCTL_VDFCUDA_SHIFT;
	val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
		CCDC_DFCCTL_VDFLSFT_SHIFT;
	regw(val , DFCCTL);

	/* clear address ptr to offset 0 */
	val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT;

	/* write defect table entries */
	for (i = 0; i < dfc->table_size; i++) {
		/* increment address for non zero index */
		if (i != 0)
			val = CCDC_DFCMEMCTL_INC_ADDR;
		regw(val, DFCMEMCTL);
		if (ccdc_write_dfc_entry(i, dfc) < 0)
			return -EFAULT;
	}

	/* update saturation level and enable dfc */
	regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
	val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK <<
			CCDC_DFCCTL_VDFCEN_SHIFT);
	regw(val, DFCCTL);
	return 0;
}

/*
 * ccdc_config_csc()
 * configure parameters for color space conversion
 * Each register CSCM0-7 has two values in S8Q5 format.
 */
static void ccdc_config_csc(struct ccdc_csc *csc)
{
	u32 val1, val2;
	int i;

	if (!csc->enable)
		return;

	/* Enable the CSC sub-module */
	regw(CCDC_CSC_ENABLE, CSCCTL);

	/* Converting the co-eff as per the format of the register */
	for (i = 0; i < CCDC_CSC_COEFF_TABLE_SIZE; i++) {
		if ((i % 2) == 0) {
			/* CSCM - LSB */
			val1 = (csc->coeff[i].integer &
				CCDC_CSC_COEF_INTEG_MASK)
				<< CCDC_CSC_COEF_INTEG_SHIFT;
			/*
			 * convert decimal part to binary. Use 2 decimal
			 * precision, user values range from .00 - 0.99
			 */
			val1 |= (((csc->coeff[i].decimal &
				CCDC_CSC_COEF_DECIMAL_MASK) *
				CCDC_CSC_DEC_MAX) / 100);
		} else {

			/* CSCM - MSB */
			val2 = (csc->coeff[i].integer &
				CCDC_CSC_COEF_INTEG_MASK)
				<< CCDC_CSC_COEF_INTEG_SHIFT;
			val2 |= (((csc->coeff[i].decimal &
				 CCDC_CSC_COEF_DECIMAL_MASK) *
				 CCDC_CSC_DEC_MAX) / 100);
			val2 <<= CCDC_CSCM_MSB_SHIFT;
			val2 |= val1;
			regw(val2, (CSCM0 + ((i - 1) << 1)));
		}
	}
}

/*
 * ccdc_config_color_patterns()
 * configure parameters for color patterns
 */
static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
				       struct ccdc_col_pat *pat1)
{
	u32 val;

	val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) |
		(pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) |
		(pat1->elop << 12) | (pat1->elep << 14));
	regw(val, COLPTN);
}

/* This function will configure CCDC for Raw mode image capture */
static int ccdc_config_raw(void)
{
	struct ccdc_params_raw *params = &ccdc_cfg.bayer;
	struct ccdc_config_params_raw *config_params =
					&ccdc_cfg.bayer.config_params;
	unsigned int val;

	dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");

	/* restore power on defaults to register */
	ccdc_restore_defaults();

	/* 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 to AND
	 * set TRGSEL to WENBIT
	 * set EXTRG to DISABLE
	 * disable latching function on VSYNC - shadowed registers
	 */
	regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
	     CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
	     CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);

	/*
	 * Set VDHD direction to input,  input type to raw input
	 * normal data polarity, do not use external WEN
	 */
	val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL |
		CCDC_EXWEN_DISABLE);

	/*
	 * Configure the vertical sync polarity (MODESET.VDPOL), horizontal
	 * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL),
	 * frame format(progressive or interlace), & pixel format (Input mode)
	 */
	val |= (((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) |
		((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
		((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT));

	/* set pack for alaw compression */
	if ((config_params->data_sz == CCDC_DATA_8BITS) ||
	     config_params->alaw.enable)
		val |= CCDC_DATA_PACK_ENABLE;

	/* Configure for LPF */
	if (config_params->lpf_enable)
		val |= (config_params->lpf_enable & CCDC_LPF_MASK) <<
			CCDC_LPF_SHIFT;

	/* Configure the data shift */
	val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
		CCDC_DATASFT_SHIFT;
	regw(val , MODESET);
	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);

	/* Configure the Median Filter threshold */
	regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);

	/* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */
	val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT |
		CCDC_CFA_MOSAIC;

	/* Enable and configure aLaw register if needed */
	if (config_params->alaw.enable) {
		val |= (CCDC_ALAW_ENABLE |
			((config_params->alaw.gama_wd &
			CCDC_ALAW_GAMA_WD_MASK) <<
			CCDC_GAMMAWD_INPUT_SHIFT));
	}

	/* Configure Median filter1 & filter2 */
	val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) |
		(config_params->mfilt2 << CCDC_MFILT2_SHIFT));

	regw(val, GAMMAWD);
	dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);

	/* configure video window */
	ccdc_setwin(&params->win, params->frm_fmt, 1);

	/* Optical Clamp Averaging */
	ccdc_config_black_clamp(&config_params->blk_clamp);

	/* Black level compensation */
	ccdc_config_black_compense(&config_params->blk_comp);

	/* Vertical Defect Correction if needed */
	if (ccdc_config_vdfc(&config_params->vertical_dft) < 0)
		return -EFAULT;

	/* color space conversion */
	ccdc_config_csc(&config_params->csc);

	/* color pattern */
	ccdc_config_color_patterns(&config_params->col_pat_field0,
				   &config_params->col_pat_field1);

	/* Configure the Gain  & offset control */
	ccdc_config_gain_offset();

	dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);

	/* Configure DATAOFST  register */
	val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
		CCDC_DATAOFST_H_SHIFT;
	val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) <<
		CCDC_DATAOFST_V_SHIFT;
	regw(val, DATAOFST);

	/* configuring HSIZE register */
	val = (params->horz_flip_enable & CCDC_HSIZE_FLIP_MASK) <<
		CCDC_HSIZE_FLIP_SHIFT;

	/* If pack 8 is enable then 1 pixel will take 1 byte */
	if ((config_params->data_sz == CCDC_DATA_8BITS) ||
	     config_params->alaw.enable) {
		val |= (((params->win.width) + 31) >> 5) &
			CCDC_HSIZE_VAL_MASK;

		/* adjust to multiple of 32 */
		dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
		       (((params->win.width) + 31) >> 5) &
			CCDC_HSIZE_VAL_MASK);
	} else {
		/* else one pixel will take 2 byte */
		val |= (((params->win.width * 2) + 31) >> 5) &
			CCDC_HSIZE_VAL_MASK;

		dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
		       (((params->win.width * 2) + 31) >> 5) &
			CCDC_HSIZE_VAL_MASK);
	}
	regw(val, HSIZE);

	/* Configure SDOFST register */
	if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
		if (params->image_invert_enable) {
			/* For interlace inverse mode */
			regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
			dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
				CCDC_SDOFST_INTERLACE_INVERSE);
		} else {
			/* For interlace non inverse mode */
			regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
			dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
				CCDC_SDOFST_INTERLACE_NORMAL);
		}
	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
		if (params->image_invert_enable) {
			/* For progessive inverse mode */
			regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
			dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
				CCDC_SDOFST_PROGRESSIVE_INVERSE);
		} else {
			/* For progessive non inverse mode */
			regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
			dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
				CCDC_SDOFST_PROGRESSIVE_NORMAL);
		}
	}
	dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
	return 0;
}

static int ccdc_configure(void)
{
	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
		return ccdc_config_raw();
	else
		ccdc_config_ycbcr();
	return 0;
}

static int ccdc_set_buftype(enum ccdc_buftype buf_type)
{
	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
		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 == VPFE_RAW_BAYER)
		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 == VPFE_RAW_BAYER) {
		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(u32 pixfmt)
{
	struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;

	if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
		ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
		if (pixfmt == V4L2_PIX_FMT_SBGGR8)
			alaw->enable = 1;
		else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
			return -EINVAL;
	} 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;
	}
	return 0;
}
static u32 ccdc_get_pixel_format(void)
{
	struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
	u32 pixfmt;

	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
		if (alaw->enable)
			pixfmt = V4L2_PIX_FMT_SBGGR8;
		else
			pixfmt = V4L2_PIX_FMT_SBGGR16;
	else {
		if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
			pixfmt = V4L2_PIX_FMT_YUYV;
		else
			pixfmt = V4L2_PIX_FMT_UYVY;
	}
	return pixfmt;
}
static int ccdc_set_image_window(struct v4l2_rect *win)
{
	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
		ccdc_cfg.bayer.win = *win;
	else
		ccdc_cfg.ycbcr.win = *win;
	return 0;
}

static void ccdc_get_image_window(struct v4l2_rect *win)
{
	if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
		*win = ccdc_cfg.bayer.win;
	else
		*win = ccdc_cfg.ycbcr.win;
}

static unsigned int ccdc_get_line_length(void)
{
	struct ccdc_config_params_raw *config_params =
				&ccdc_cfg.bayer.config_params;
	unsigned int len;

	if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
		if ((config_params->alaw.enable) ||
		    (config_params->data_sz == CCDC_DATA_8BITS))
			len = ccdc_cfg.bayer.win.width;
		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 == VPFE_RAW_BAYER)
		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 == VPFE_RAW_BAYER)
		return ccdc_cfg.bayer.frm_fmt;
	else
		return ccdc_cfg.ycbcr.frm_fmt;
}

static int ccdc_getfid(void)
{
	return  (regr(MODESET) >> 15) & 1;
}

/* misc operations */
static inline void ccdc_setfbaddr(unsigned long addr)
{
	regw((addr >> 21) & 0x007f, STADRH);
	regw((addr >> 5) & 0x0ffff, STADRL);
}

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 VPFE_BT656:
	case VPFE_YCBCR_SYNC_16:
	case VPFE_YCBCR_SYNC_8:
		ccdc_cfg.ycbcr.vd_pol = params->vdpol;
		ccdc_cfg.ycbcr.hd_pol = params->hdpol;
		break;
	default:
		/* TODO add support for raw bayer here */
		return -EINVAL;
	}
	return 0;
}

static struct ccdc_hw_device ccdc_hw_dev = {
	.name = "DM355 CCDC",
	.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,
		.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,
	},
};

static int __init dm355_ccdc_probe(struct platform_device *pdev)
{
	void (*setup_pinmux)(void);
	struct resource	*res;
	int status = 0;

	/*
	 * first try to register with vpfe. If not correct platform, then we
	 * don't have to iomap
	 */
	status = vpfe_register_ccdc_device(&ccdc_hw_dev);
	if (status < 0)
		return status;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		status = -ENODEV;
		goto fail_nores;
	}

	res = request_mem_region(res->start, resource_size(res), res->name);
	if (!res) {
		status = -EBUSY;
		goto fail_nores;
	}

	ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
	if (!ccdc_cfg.base_addr) {
		status = -ENOMEM;
		goto fail_nomem;
	}

	/* Get and enable Master clock */
	ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
	if (IS_ERR(ccdc_cfg.mclk)) {
		status = PTR_ERR(ccdc_cfg.mclk);
		goto fail_nomap;
	}
	if (clk_enable(ccdc_cfg.mclk)) {
		status = -ENODEV;
		goto fail_mclk;
	}

	/* Get and enable Slave clock */
	ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
	if (IS_ERR(ccdc_cfg.sclk)) {
		status = PTR_ERR(ccdc_cfg.sclk);
		goto fail_mclk;
	}
	if (clk_enable(ccdc_cfg.sclk)) {
		status = -ENODEV;
		goto fail_sclk;
	}

	/* Platform data holds setup_pinmux function ptr */
	if (NULL == pdev->dev.platform_data) {
		status = -ENODEV;
		goto fail_sclk;
	}
	setup_pinmux = pdev->dev.platform_data;
	/*
	 * setup Mux configuration for ccdc which may be different for
	 * different SoCs using this CCDC
	 */
	setup_pinmux();
	ccdc_cfg.dev = &pdev->dev;
	printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
	return 0;
fail_sclk:
	clk_put(ccdc_cfg.sclk);
fail_mclk:
	clk_put(ccdc_cfg.mclk);
fail_nomap:
	iounmap(ccdc_cfg.base_addr);
fail_nomem:
	release_mem_region(res->start, resource_size(res));
fail_nores:
	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
	return status;
}

static int dm355_ccdc_remove(struct platform_device *pdev)
{
	struct resource	*res;

	clk_put(ccdc_cfg.mclk);
	clk_put(ccdc_cfg.sclk);
	iounmap(ccdc_cfg.base_addr);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res)
		release_mem_region(res->start, resource_size(res));
	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
	return 0;
}

static struct platform_driver dm355_ccdc_driver = {
	.driver = {
		.name	= "dm355_ccdc",
		.owner = THIS_MODULE,
	},
	.remove = __devexit_p(dm355_ccdc_remove),
	.probe = dm355_ccdc_probe,
};

static int __init dm355_ccdc_init(void)
{
	return platform_driver_register(&dm355_ccdc_driver);
}

static void __exit dm355_ccdc_exit(void)
{
	platform_driver_unregister(&dm355_ccdc_driver);
}

module_init(dm355_ccdc_init);
module_exit(dm355_ccdc_exit);
