/*
 * Copyright (C) 2008-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
 *
 * Image Sensor Interface (ISIF) driver
 *
 * This driver is for configuring the ISIF IP available on DM365 or any other
 * TI SoCs. This is used for capturing yuv or bayer video or image data
 * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
 * and DM6446, but with enhanced or additional ip blocks. The driver
 * configures the ISIF upon commands from the vpfe bridge driver through
 * ccdc_hw_device interface.
 *
 * TODO: 1) Raw bayer parameter settings and bayer capture
 *	 2) Add support for control ioctl
 */
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/videodev2.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/module.h>

#include <mach/mux.h>

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

#include "isif_regs.h"
#include "ccdc_hw_device.h"

/* Defaults for module configuration parameters */
static struct isif_config_params_raw isif_config_defaults = {
	.linearize = {
		.en = 0,
		.corr_shft = ISIF_NO_SHIFT,
		.scale_fact = {1, 0},
	},
	.df_csc = {
		.df_or_csc = 0,
		.csc = {
			.en = 0,
		},
	},
	.dfc = {
		.en = 0,
	},
	.bclamp = {
		.en = 0,
	},
	.gain_offset = {
		.gain = {
			.r_ye = {1, 0},
			.gr_cy = {1, 0},
			.gb_g = {1, 0},
			.b_mg = {1, 0},
		},
	},
	.culling = {
		.hcpat_odd = 0xff,
		.hcpat_even = 0xff,
		.vcpat = 0xff,
	},
	.compress = {
		.alg = ISIF_ALAW,
	},
};

/* ISIF operation configuration */
static struct isif_oper_config {
	struct device *dev;
	enum vpfe_hw_if_type if_type;
	struct isif_ycbcr_config ycbcr;
	struct isif_params_raw bayer;
	enum isif_data_pack data_pack;
	/* Master clock */
	struct clk *mclk;
	/* ISIF base address */
	void __iomem *base_addr;
	/* ISIF Linear Table 0 */
	void __iomem *linear_tbl0_addr;
	/* ISIF Linear Table 1 */
	void __iomem *linear_tbl1_addr;
} isif_cfg = {
	.ycbcr = {
		.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
		.frm_fmt = CCDC_FRMFMT_INTERLACED,
		.win = ISIF_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 = {
		.pix_fmt = CCDC_PIXFMT_RAW,
		.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
		.win = ISIF_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 = ISIF_CFA_PAT_MOSAIC,
		.data_msb = ISIF_BIT_MSB_11,
		.config_params = {
			.data_shift = ISIF_NO_SHIFT,
			.col_pat_field0 = {
				.olop = ISIF_GREEN_BLUE,
				.olep = ISIF_BLUE,
				.elop = ISIF_RED,
				.elep = ISIF_GREEN_RED,
			},
			.col_pat_field1 = {
				.olop = ISIF_GREEN_BLUE,
				.olep = ISIF_BLUE,
				.elop = ISIF_RED,
				.elep = ISIF_GREEN_RED,
			},
			.test_pat_gen = 0,
		},
	},
	.data_pack = ISIF_DATA_PACK8,
};

/* Raw Bayer formats */
static const u32 isif_raw_bayer_pix_formats[] = {
	V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};

/* Raw YUV formats */
static const u32 isif_raw_yuv_pix_formats[] = {
	V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};

/* register access routines */
static inline u32 regr(u32 offset)
{
	return __raw_readl(isif_cfg.base_addr + offset);
}

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

/* reg_modify() - read, modify and write register */
static inline u32 reg_modify(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)
		__raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
	else
		__raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
}

static void isif_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 isif_enable(int en)
{
	if (!en) {
		/* Before disable isif, disable all ISIF modules */
		isif_disable_all_modules();
		/*
		 * wait for next VD. Assume lowest scan rate is 12 Hz. So
		 * 100 msec delay is good enough
		 */
		msleep(100);
	}
	reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
}

static void isif_enable_output_to_sdram(int en)
{
	reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
}

static void isif_config_culling(struct isif_cul *cul)
{
	u32 val;

	/* Horizontal pattern */
	val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
	regw(val, CULH);

	/* vertical pattern */
	regw(cul->vcpat, CULV);

	/* LPF */
	reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
		  cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
}

static void isif_config_gain_offset(void)
{
	struct isif_gain_offsets_adj *gain_off_p =
		&isif_cfg.bayer.config_params.gain_offset;
	u32 val;

	val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
	      (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
	      (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
	      (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
	      (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
	      (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);

	reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);

	val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
	       gain_off_p->gain.r_ye.decimal;
	regw(val, CRGAIN);

	val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
	       gain_off_p->gain.gr_cy.decimal;
	regw(val, CGRGAIN);

	val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
	       gain_off_p->gain.gb_g.decimal;
	regw(val, CGBGAIN);

	val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
	       gain_off_p->gain.b_mg.decimal;
	regw(val, CBGAIN);

	regw(gain_off_p->offset, COFSTA);
}

static void isif_restore_defaults(void)
{
	enum vpss_ccdc_source_sel source = VPSS_CCDCIN;

	dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
	isif_cfg.bayer.config_params = isif_config_defaults;
	/* 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 default offset and gain */
	isif_config_gain_offset();
	vpss_select_ccdc_source(source);
	dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
}

static int isif_open(struct device *device)
{
	isif_restore_defaults();
	return 0;
}

/* This function will configure the window size to be capture in ISIF reg */
static void isif_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(isif_cfg.dev, "\nStarting isif_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 & 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);
	}

	regw(0, 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 isif_config_bclamp(struct isif_black_clamp *bc)
{
	u32 val;

	/*
	 * DC Offset is always added to image data irrespective of bc enable
	 * status
	 */
	regw(bc->dc_offset, CLDCOFST);

	if (bc->en) {
		val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;

		/* Enable BC and horizontal clamp caculation paramaters */
		val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);

		regw(val, CLAMPCFG);

		if (bc->horz.mode != ISIF_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 |
			      ((!!bc->horz.base_win_sel_calc) <<
				ISIF_HORZ_BC_WIN_SEL_SHIFT) |
			      ((!!bc->horz.clamp_pix_limit) <<
				ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
			      (bc->horz.win_h_sz_calc <<
				ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
			      (bc->horz.win_v_sz_calc <<
				ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
			regw(val, CLHWIN0);

			regw(bc->horz.win_start_h_calc, CLHWIN1);
			regw(bc->horz.win_start_v_calc, CLHWIN2);
		}

		/* vertical clamp caculation paramaters */

		/* Reset clamp value sel for previous line */
		val |=
		(bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
		(bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
		regw(val, CLVWIN0);

		/* Optical Black horizontal start position */
		regw(bc->vert.ob_start_h, CLVWIN1);
		/* Optical Black vertical start position */
		regw(bc->vert.ob_start_v, CLVWIN2);
		/* Optical Black vertical size for calculation */
		regw(bc->vert.ob_v_sz_calc, CLVWIN3);
		/* Vertical start position for BC subtraction */
		regw(bc->vert_start_sub, CLSV);
	}
}

static void isif_config_linearization(struct isif_linearize *linearize)
{
	u32 val, i;

	if (!linearize->en) {
		regw(0, LINCFG0);
		return;
	}

	/* shift value for correction & enable linearization (set lsb) */
	val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
	regw(val, LINCFG0);

	/* Scale factor */
	val = ((!!linearize->scale_fact.integer) <<
	       ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
	       linearize->scale_fact.decimal;
	regw(val, LINCFG1);

	for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
		if (i % 2)
			regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
		else
			regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
	}
}

static int isif_config_dfc(struct isif_dfc *vdfc)
{
	/* initialize retries to loop for max ~ 250 usec */
	u32 val, count, retries = loops_per_jiffy / (4000/HZ);
	int i;

	if (!vdfc->en)
		return 0;

	/* Correction mode */
	val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);

	/* Correct whole line or partial */
	if (vdfc->corr_whole_line)
		val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;

	/* level shift value */
	val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;

	regw(val, DFCCTL);

	/* Defect saturation level */
	regw(vdfc->def_sat_level, VDFSATLV);

	regw(vdfc->table[0].pos_vert, DFCMEM0);
	regw(vdfc->table[0].pos_horz, DFCMEM1);
	if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
	    vdfc->corr_mode == ISIF_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);
	}

	/* set DFCMARST and set DFCMWR */
	val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
	regw(val, DFCMEMCTL);

	count = retries;
	while (count && (regr(DFCMEMCTL) & 0x1))
		count--;

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

	for (i = 1; i < vdfc->num_vdefects; i++) {
		regw(vdfc->table[i].pos_vert, DFCMEM0);
		regw(vdfc->table[i].pos_horz, DFCMEM1);
		if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
		    vdfc->corr_mode == ISIF_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 &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
		val |= 1;
		regw(val, DFCMEMCTL);

		count = retries;
		while (count && (regr(DFCMEMCTL) & 0x1))
			count--;

		if (!count) {
			dev_err(isif_cfg.dev,
				"defect table write timeout !!!\n");
			return -1;
		}
	}
	if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
		/* Extra cycle needed */
		regw(0, DFCMEM0);
		regw(0x1FFF, DFCMEM1);
		regw(1, DFCMEMCTL);
	}

	/* enable VDFC */
	reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
		   DFCCTL);
	return 0;
}

static void isif_config_csc(struct isif_df_csc *df_csc)
{
	u32 val1 = 0, val2 = 0, i;

	if (!df_csc->csc.en) {
		regw(0, CSCCTL);
		return;
	}
	for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
		if ((i % 2) == 0) {
			/* CSCM - LSB */
			val1 = (df_csc->csc.coeff[i].integer <<
				ISIF_CSC_COEF_INTEG_SHIFT) |
				df_csc->csc.coeff[i].decimal;
		} else {

			/* CSCM - MSB */
			val2 = (df_csc->csc.coeff[i].integer <<
				ISIF_CSC_COEF_INTEG_SHIFT) |
				df_csc->csc.coeff[i].decimal;
			val2 <<= ISIF_CSCM_MSB_SHIFT;
			val2 |= val1;
			regw(val2, (CSCM0 + ((i - 1) << 1)));
		}
	}

	/* program the active area */
	regw(df_csc->start_pix, 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, FMTLNH);
	regw(df_csc->start_line, FMTSLV);
	/*
	 * one extra line as required for CSC. See reason documented for
	 * num_pixels
	 */
	regw(df_csc->num_lines, FMTLNV);

	/* Enable CSC */
	regw(1, CSCCTL);
}

static int isif_config_raw(void)
{
	struct isif_params_raw *params = &isif_cfg.bayer;
	struct isif_config_params_raw *module_params =
		&isif_cfg.bayer.config_params;
	struct vpss_pg_frame_size frame_size;
	struct vpss_sync_pol sync;
	u32 val;

	dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");

	/*
	 * 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 - isif valid area
	 * Set TRGSEL
	 * Set EXTRG
	 * Packed to 8 or 16 bits
	 */

	val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
		ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
		ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;

	dev_dbg(isif_cfg.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 = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
		(params->hd_pol << ISIF_HD_POL_SHIFT) |
		(params->fid_pol << ISIF_FID_POL_SHIFT) |
		(ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
		(ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
		(params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
		(params->pix_fmt << ISIF_INPUT_SHIFT) |
		(params->config_params.data_shift << ISIF_DATASFT_SHIFT);

	regw(val, MODESET);
	dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);

	/*
	 * Configure GAMMAWD register
	 * CFA pattern setting
	 */
	val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;

	/* Gamma msb */
	if (module_params->compress.alg == ISIF_ALAW)
		val |= ISIF_ALAW_ENABLE;

	val |= (params->data_msb << ISIF_ALAW_GAMA_WD_SHIFT);
	regw(val, CGAMMAWD);

	/* Configure DPCM compression settings */
	if (module_params->compress.alg == ISIF_DPCM) {
		val =  BIT(ISIF_DPCM_EN_SHIFT) |
		       (module_params->compress.pred <<
		       ISIF_DPCM_PREDICTOR_SHIFT);
	}

	regw(val, MISC);

	/* Configure Gain & Offset */
	isif_config_gain_offset();

	/* Configure Color pattern */
	val = (params->config_params.col_pat_field0.olop) |
	      (params->config_params.col_pat_field0.olep << 2) |
	      (params->config_params.col_pat_field0.elop << 4) |
	      (params->config_params.col_pat_field0.elep << 6) |
	      (params->config_params.col_pat_field1.olop << 8) |
	      (params->config_params.col_pat_field1.olep << 10) |
	      (params->config_params.col_pat_field1.elop << 12) |
	      (params->config_params.col_pat_field1.elep << 14);
	regw(val, CCOLP);
	dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);

	/* Configure HSIZE register  */
	val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;

	/* calculate line offset in 32 bytes based on pack value */
	if (isif_cfg.data_pack == ISIF_PACK_8BIT)
		val |= ((params->win.width + 31) >> 5);
	else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
		val |= (((params->win.width +
		       (params->win.width >> 2)) + 31) >> 5);
	else
		val |= (((params->win.width * 2) + 31) >> 5);
	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(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
		} else {
			/* For interlace non inverse mode */
			regw(0x0B6D, SDOFST);
			dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
		}
	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
		if (params->image_invert_en) {
			/* For progressive inverse mode */
			regw(0x4000, SDOFST);
			dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
		} else {
			/* For progressive non inverse mode */
			regw(0x0000, SDOFST);
			dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
		}
	}

	/* Configure video window */
	isif_setwin(&params->win, params->frm_fmt, 1);

	/* Configure Black Clamp */
	isif_config_bclamp(&module_params->bclamp);

	/* Configure Vertical Defection Pixel Correction */
	if (isif_config_dfc(&module_params->dfc) < 0)
		return -EFAULT;

	if (!module_params->df_csc.df_or_csc)
		/* Configure Color Space Conversion */
		isif_config_csc(&module_params->df_csc);

	isif_config_linearization(&module_params->linearize);

	/* Configure Culling */
	isif_config_culling(&module_params->culling);

	/* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
	regw(module_params->horz_offset, DATAHOFST);
	regw(module_params->vert_offset, DATAVOFST);

	/* Setup test pattern if enabled */
	if (params->config_params.test_pat_gen) {
		/* Use the HD/VD pol settings from user */
		sync.ccdpg_hdpol = params->hd_pol;
		sync.ccdpg_vdpol = params->vd_pol;
		dm365_vpss_set_sync_pol(sync);
		frame_size.hlpfr = isif_cfg.bayer.win.width;
		frame_size.pplen = isif_cfg.bayer.win.height;
		dm365_vpss_set_pg_frame_size(frame_size);
		vpss_select_ccdc_source(VPSS_PGLPBK);
	}

	dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
	return 0;
}

static int isif_set_buftype(enum ccdc_buftype buf_type)
{
	if (isif_cfg.if_type == VPFE_RAW_BAYER)
		isif_cfg.bayer.buf_type = buf_type;
	else
		isif_cfg.ycbcr.buf_type = buf_type;

	return 0;

}
static enum ccdc_buftype isif_get_buftype(void)
{
	if (isif_cfg.if_type == VPFE_RAW_BAYER)
		return isif_cfg.bayer.buf_type;

	return isif_cfg.ycbcr.buf_type;
}

static int isif_enum_pix(u32 *pix, int i)
{
	int ret = -EINVAL;

	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
		if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
			*pix = isif_raw_bayer_pix_formats[i];
			ret = 0;
		}
	} else {
		if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
			*pix = isif_raw_yuv_pix_formats[i];
			ret = 0;
		}
	}

	return ret;
}

static int isif_set_pixel_format(unsigned int pixfmt)
{
	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
		if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
			if ((isif_cfg.bayer.config_params.compress.alg !=
			     ISIF_ALAW) &&
			    (isif_cfg.bayer.config_params.compress.alg !=
			     ISIF_DPCM)) {
				dev_dbg(isif_cfg.dev,
					"Either configure A-Law or DPCM\n");
				return -EINVAL;
			}
			isif_cfg.data_pack = ISIF_PACK_8BIT;
		} else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
			isif_cfg.bayer.config_params.compress.alg =
					ISIF_NO_COMPRESSION;
			isif_cfg.data_pack = ISIF_PACK_16BIT;
		} else
			return -EINVAL;
		isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
	} else {
		if (pixfmt == V4L2_PIX_FMT_YUYV)
			isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
		else if (pixfmt == V4L2_PIX_FMT_UYVY)
			isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
		else
			return -EINVAL;
		isif_cfg.data_pack = ISIF_PACK_8BIT;
	}
	return 0;
}

static u32 isif_get_pixel_format(void)
{
	u32 pixfmt;

	if (isif_cfg.if_type == VPFE_RAW_BAYER)
		if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
		    isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
			pixfmt = V4L2_PIX_FMT_SBGGR8;
		else
			pixfmt = V4L2_PIX_FMT_SBGGR16;
	else {
		if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
			pixfmt = V4L2_PIX_FMT_YUYV;
		else
			pixfmt = V4L2_PIX_FMT_UYVY;
	}
	return pixfmt;
}

static int isif_set_image_window(struct v4l2_rect *win)
{
	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
		isif_cfg.bayer.win.top = win->top;
		isif_cfg.bayer.win.left = win->left;
		isif_cfg.bayer.win.width = win->width;
		isif_cfg.bayer.win.height = win->height;
	} else {
		isif_cfg.ycbcr.win.top = win->top;
		isif_cfg.ycbcr.win.left = win->left;
		isif_cfg.ycbcr.win.width = win->width;
		isif_cfg.ycbcr.win.height = win->height;
	}
	return 0;
}

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

static unsigned int isif_get_line_length(void)
{
	unsigned int len;

	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
		if (isif_cfg.data_pack == ISIF_PACK_8BIT)
			len = ((isif_cfg.bayer.win.width));
		else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
			len = (((isif_cfg.bayer.win.width * 2) +
				 (isif_cfg.bayer.win.width >> 2)));
		else
			len = (((isif_cfg.bayer.win.width * 2)));
	} else
		len = (((isif_cfg.ycbcr.win.width * 2)));
	return ALIGN(len, 32);
}

static int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
{
	if (isif_cfg.if_type == VPFE_RAW_BAYER)
		isif_cfg.bayer.frm_fmt = frm_fmt;
	else
		isif_cfg.ycbcr.frm_fmt = frm_fmt;
	return 0;
}
static enum ccdc_frmfmt isif_get_frame_format(void)
{
	if (isif_cfg.if_type == VPFE_RAW_BAYER)
		return isif_cfg.bayer.frm_fmt;
	return isif_cfg.ycbcr.frm_fmt;
}

static int isif_getfid(void)
{
	return (regr(MODESET) >> 15) & 0x1;
}

/* misc operations */
static void isif_setfbaddr(unsigned long addr)
{
	regw((addr >> 21) & 0x07ff, CADU);
	regw((addr >> 5) & 0x0ffff, CADL);
}

static int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
{
	isif_cfg.if_type = params->if_type;

	switch (params->if_type) {
	case VPFE_BT656:
	case VPFE_BT656_10BIT:
	case VPFE_YCBCR_SYNC_8:
		isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
		isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
		break;
	case VPFE_BT1120:
	case VPFE_YCBCR_SYNC_16:
		isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
		isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
		break;
	case VPFE_RAW_BAYER:
		isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
		break;
	default:
		dev_dbg(isif_cfg.dev, "Invalid interface type\n");
		return -EINVAL;
	}

	return 0;
}

/* This function will configure ISIF for YCbCr parameters. */
static int isif_config_ycbcr(void)
{
	struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
	struct vpss_pg_frame_size frame_size;
	u32 modeset = 0, ccdcfg = 0;
	struct vpss_sync_pol sync;

	dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");

	/* configure pixel format or input mode */
	modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
		  (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
		  (params->fid_pol << ISIF_FID_POL_SHIFT) |
		  (params->hd_pol << ISIF_HD_POL_SHIFT) |
		  (params->vd_pol << ISIF_VD_POL_SHIFT);

	/* pack the data to 8-bit ISIFCFG */
	switch (isif_cfg.if_type) {
	case VPFE_BT656:
		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
			return -EINVAL;
		}
		modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
		regw(3, REC656IF);
		ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
		break;
	case VPFE_BT656_10BIT:
		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
			dev_dbg(isif_cfg.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 | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
			ISIF_BW656_ENABLE;
		break;
	case VPFE_BT1120:
		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
			return -EINVAL;
		}
		regw(3, REC656IF);
		break;

	case VPFE_YCBCR_SYNC_8:
		ccdcfg |= ISIF_DATA_PACK8;
		ccdcfg |= ISIF_YCINSWP_YCBCR;
		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
			return -EINVAL;
		}
		break;
	case VPFE_YCBCR_SYNC_16:
		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
			return -EINVAL;
		}
		break;
	default:
		/* should never come here */
		dev_dbg(isif_cfg.dev, "Invalid interface type\n");
		return -EINVAL;
	}

	regw(modeset, MODESET);

	/* Set up pix order */
	ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;

	regw(ccdcfg, CCDCFG);

	/* configure video window */
	if ((isif_cfg.if_type == VPFE_BT1120) ||
	    (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
		isif_setwin(&params->win, params->frm_fmt, 1);
	else
		isif_setwin(&params->win, params->frm_fmt, 2);

	/*
	 * 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 (isif_cfg.bayer.config_params.test_pat_gen) {
		sync.ccdpg_hdpol = params->hd_pol;
		sync.ccdpg_vdpol = params->vd_pol;
		dm365_vpss_set_sync_pol(sync);
		dm365_vpss_set_pg_frame_size(frame_size);
	}
	return 0;
}

static int isif_configure(void)
{
	if (isif_cfg.if_type == VPFE_RAW_BAYER)
		return isif_config_raw();
	return isif_config_ycbcr();
}

static int isif_close(struct device *device)
{
	/* copy defaults to module params */
	isif_cfg.bayer.config_params = isif_config_defaults;
	return 0;
}

static struct ccdc_hw_device isif_hw_dev = {
	.name = "ISIF",
	.owner = THIS_MODULE,
	.hw_ops = {
		.open = isif_open,
		.close = isif_close,
		.enable = isif_enable,
		.enable_out_to_sdram = isif_enable_output_to_sdram,
		.set_hw_if_params = isif_set_hw_if_params,
		.configure = isif_configure,
		.set_buftype = isif_set_buftype,
		.get_buftype = isif_get_buftype,
		.enum_pix = isif_enum_pix,
		.set_pixel_format = isif_set_pixel_format,
		.get_pixel_format = isif_get_pixel_format,
		.set_frame_format = isif_set_frame_format,
		.get_frame_format = isif_get_frame_format,
		.set_image_window = isif_set_image_window,
		.get_image_window = isif_get_image_window,
		.get_line_length = isif_get_line_length,
		.setfbaddr = isif_setfbaddr,
		.getfid = isif_getfid,
	},
};

static int __init isif_probe(struct platform_device *pdev)
{
	void (*setup_pinmux)(void);
	struct resource	*res;
	void *__iomem addr;
	int status = 0, i;

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

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

	/* Platform data holds setup_pinmux function ptr */
	if (NULL == pdev->dev.platform_data) {
		status = -ENODEV;
		goto fail_mclk;
	}
	setup_pinmux = pdev->dev.platform_data;
	/*
	 * setup Mux configuration for ccdc which may be different for
	 * different SoCs using this CCDC
	 */
	setup_pinmux();

	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 = -ENODEV;
			goto fail_nobase_res;
		}
		res = request_mem_region(res->start, resource_size(res),
					 res->name);
		if (!res) {
			status = -EBUSY;
			goto fail_nobase_res;
		}
		addr = ioremap_nocache(res->start, resource_size(res));
		if (!addr) {
			status = -ENOMEM;
			goto fail_base_iomap;
		}
		switch (i) {
		case 0:
			/* ISIF base address */
			isif_cfg.base_addr = addr;
			break;
		case 1:
			/* ISIF linear tbl0 address */
			isif_cfg.linear_tbl0_addr = addr;
			break;
		default:
			/* ISIF linear tbl0 address */
			isif_cfg.linear_tbl1_addr = addr;
			break;
		}
		i++;
	}
	isif_cfg.dev = &pdev->dev;

	printk(KERN_NOTICE "%s is registered with vpfe.\n",
		isif_hw_dev.name);
	return 0;
fail_base_iomap:
	release_mem_region(res->start, resource_size(res));
	i--;
fail_nobase_res:
	if (isif_cfg.base_addr)
		iounmap(isif_cfg.base_addr);
	if (isif_cfg.linear_tbl0_addr)
		iounmap(isif_cfg.linear_tbl0_addr);

	while (i >= 0) {
		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
		release_mem_region(res->start, resource_size(res));
		i--;
	}
fail_mclk:
	clk_put(isif_cfg.mclk);
	vpfe_unregister_ccdc_device(&isif_hw_dev);
	return status;
}

static int isif_remove(struct platform_device *pdev)
{
	struct resource	*res;
	int i = 0;

	iounmap(isif_cfg.base_addr);
	iounmap(isif_cfg.linear_tbl0_addr);
	iounmap(isif_cfg.linear_tbl1_addr);
	while (i < 3) {
		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
		if (res)
			release_mem_region(res->start, resource_size(res));
		i++;
	}
	vpfe_unregister_ccdc_device(&isif_hw_dev);
	return 0;
}

static struct platform_driver isif_driver = {
	.driver = {
		.name	= "isif",
		.owner = THIS_MODULE,
	},
	.remove = __devexit_p(isif_remove),
	.probe = isif_probe,
};

module_platform_driver(isif_driver);

MODULE_LICENSE("GPL");
