163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/*
263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * Copyright (C) 2008-2009 Texas Instruments Inc
363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri *
463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * This program is free software; you can redistribute it and/or modify
563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * it under the terms of the GNU General Public License as published by
663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * the Free Software Foundation; either version 2 of the License, or
763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * (at your option) any later version.
863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri *
963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * This program is distributed in the hope that it will be useful,
1063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * but WITHOUT ANY WARRANTY; without even the implied warranty of
1163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * GNU General Public License for more details.
1363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri *
1463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * You should have received a copy of the GNU General Public License
1563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * along with this program; if not, write to the Free Software
1663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri *
1863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * Image Sensor Interface (ISIF) driver
1963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri *
2063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * This driver is for configuring the ISIF IP available on DM365 or any other
2163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * TI SoCs. This is used for capturing yuv or bayer video or image data
2263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
2363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * and DM6446, but with enhanced or additional ip blocks. The driver
2463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * configures the ISIF upon commands from the vpfe bridge driver through
2563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * ccdc_hw_device interface.
2663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri *
2763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri * TODO: 1) Raw bayer parameter settings and bayer capture
2863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri *	 2) Add support for control ioctl
2963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri */
3063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <linux/delay.h>
3163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <linux/platform_device.h>
3263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <linux/uaccess.h>
3363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <linux/io.h>
3463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <linux/videodev2.h>
3563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <linux/clk.h>
3663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <linux/err.h>
374a98b212768a3ba98c6508e0d5ca7470d3bccec3Henrique Camargo#include <linux/module.h>
3863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
3963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <mach/mux.h>
4063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
4163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <media/davinci/isif.h>
4263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include <media/davinci/vpss.h>
4363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
4463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include "isif_regs.h"
4563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri#include "ccdc_hw_device.h"
4663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
4763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* Defaults for module configuration parameters */
4863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic struct isif_config_params_raw isif_config_defaults = {
4963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.linearize = {
5063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.en = 0,
5163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.corr_shft = ISIF_NO_SHIFT,
5263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.scale_fact = {1, 0},
5363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
5463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.df_csc = {
5563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.df_or_csc = 0,
5663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.csc = {
5763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.en = 0,
5863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		},
5963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
6063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.dfc = {
6163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.en = 0,
6263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
6363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.bclamp = {
6463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.en = 0,
6563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
6663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.gain_offset = {
6763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.gain = {
6863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.r_ye = {1, 0},
6963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.gr_cy = {1, 0},
7063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.gb_g = {1, 0},
7163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.b_mg = {1, 0},
7263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		},
7363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
7463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.culling = {
7563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.hcpat_odd = 0xff,
7663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.hcpat_even = 0xff,
7763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.vcpat = 0xff,
7863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
7963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.compress = {
8063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.alg = ISIF_ALAW,
8163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
8263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri};
8363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
8463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* ISIF operation configuration */
8563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic struct isif_oper_config {
8663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct device *dev;
8763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	enum vpfe_hw_if_type if_type;
8863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct isif_ycbcr_config ycbcr;
8963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct isif_params_raw bayer;
9063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	enum isif_data_pack data_pack;
9163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Master clock */
9263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct clk *mclk;
9363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* ISIF base address */
9463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	void __iomem *base_addr;
9563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* ISIF Linear Table 0 */
9663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	void __iomem *linear_tbl0_addr;
9763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* ISIF Linear Table 1 */
9863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	void __iomem *linear_tbl1_addr;
9963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri} isif_cfg = {
10063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.ycbcr = {
10163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
10263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.frm_fmt = CCDC_FRMFMT_INTERLACED,
10363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.win = ISIF_WIN_NTSC,
10463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.fid_pol = VPFE_PINPOL_POSITIVE,
10563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.vd_pol = VPFE_PINPOL_POSITIVE,
10663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.hd_pol = VPFE_PINPOL_POSITIVE,
10763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.pix_order = CCDC_PIXORDER_CBYCRY,
10863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
10963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
11063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.bayer = {
11163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.pix_fmt = CCDC_PIXFMT_RAW,
11263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
11363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.win = ISIF_WIN_VGA,
11463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.fid_pol = VPFE_PINPOL_POSITIVE,
11563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.vd_pol = VPFE_PINPOL_POSITIVE,
11663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.hd_pol = VPFE_PINPOL_POSITIVE,
11763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.gain = {
11863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.r_ye = {1, 0},
11963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.gr_cy = {1, 0},
12063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.gb_g = {1, 0},
12163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.b_mg = {1, 0},
12263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		},
12363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.cfa_pat = ISIF_CFA_PAT_MOSAIC,
12463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.data_msb = ISIF_BIT_MSB_11,
12563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.config_params = {
12663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.data_shift = ISIF_NO_SHIFT,
12763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.col_pat_field0 = {
12863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				.olop = ISIF_GREEN_BLUE,
12963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				.olep = ISIF_BLUE,
13063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				.elop = ISIF_RED,
13163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				.elep = ISIF_GREEN_RED,
13263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			},
13363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.col_pat_field1 = {
13463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				.olop = ISIF_GREEN_BLUE,
13563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				.olep = ISIF_BLUE,
13663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				.elop = ISIF_RED,
13763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				.elep = ISIF_GREEN_RED,
13863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			},
13963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			.test_pat_gen = 0,
14063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		},
14163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
14263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.data_pack = ISIF_DATA_PACK8,
14363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri};
14463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
14563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* Raw Bayer formats */
14663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic const u32 isif_raw_bayer_pix_formats[] = {
14763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
14863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
14963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* Raw YUV formats */
15063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic const u32 isif_raw_yuv_pix_formats[] = {
15163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
15263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
15363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* register access routines */
15463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic inline u32 regr(u32 offset)
15563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
15663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return __raw_readl(isif_cfg.base_addr + offset);
15763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
15863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
15963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic inline void regw(u32 val, u32 offset)
16063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
16163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	__raw_writel(val, isif_cfg.base_addr + offset);
16263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
16363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
16463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* reg_modify() - read, modify and write register */
16563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic inline u32 reg_modify(u32 mask, u32 val, u32 offset)
16663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
16763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 new_val = (regr(offset) & ~mask) | (val & mask);
16863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
16963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(new_val, offset);
17063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return new_val;
17163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
17263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
17363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic inline void regw_lin_tbl(u32 val, u32 offset, int i)
17463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
17563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (!i)
17663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		__raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
17763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	else
17863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		__raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
17963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
18063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
18163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_disable_all_modules(void)
18263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
18363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* disable BC */
18463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(0, CLAMPCFG);
18563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* disable vdfc */
18663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(0, DFCCTL);
18763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* disable CSC */
18863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(0, CSCCTL);
18963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* disable linearization */
19063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(0, LINCFG0);
19163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* disable other modules here as they are supported */
19263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
19363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
19463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_enable(int en)
19563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
19663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (!en) {
19763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Before disable isif, disable all ISIF modules */
19863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_disable_all_modules();
19963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/*
20063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		 * wait for next VD. Assume lowest scan rate is 12 Hz. So
20163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		 * 100 msec delay is good enough
20263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		 */
20363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		msleep(100);
20463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
20563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
20663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
20763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
20863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_enable_output_to_sdram(int en)
20963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
21063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
21163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
21263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
21363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_config_culling(struct isif_cul *cul)
21463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
21563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 val;
21663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
21763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Horizontal pattern */
21863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
21963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, CULH);
22063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
22163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* vertical pattern */
22263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(cul->vcpat, CULV);
22363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
22463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* LPF */
22563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
22663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		  cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
22763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
22863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
22963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_config_gain_offset(void)
23063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
23163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct isif_gain_offsets_adj *gain_off_p =
23263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		&isif_cfg.bayer.config_params.gain_offset;
23363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 val;
23463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
23563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
23663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
23763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
23863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
23963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
24063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);
24163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
24263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
24363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
24463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
24563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	       gain_off_p->gain.r_ye.decimal;
24663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, CRGAIN);
24763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
24863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
24963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	       gain_off_p->gain.gr_cy.decimal;
25063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, CGRGAIN);
25163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
25263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
25363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	       gain_off_p->gain.gb_g.decimal;
25463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, CGBGAIN);
25563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
25663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
25763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	       gain_off_p->gain.b_mg.decimal;
25863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, CBGAIN);
25963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
26063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(gain_off_p->offset, COFSTA);
26163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
26263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
26363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_restore_defaults(void)
26463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
26563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
26663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
26763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
26863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_cfg.bayer.config_params = isif_config_defaults;
26963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Enable clock to ISIF, IPIPEIF and BL */
27063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
27163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
27263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	vpss_enable_clock(VPSS_BL_CLOCK, 1);
27363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Set default offset and gain */
27463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_config_gain_offset();
27563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	vpss_select_ccdc_source(source);
27663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
27763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
27863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
27963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_open(struct device *device)
28063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
28163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_restore_defaults();
28263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
28363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
28463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
28563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* This function will configure the window size to be capture in ISIF reg */
28663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_setwin(struct v4l2_rect *image_win,
28763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			enum ccdc_frmfmt frm_fmt, int ppc)
28863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
28963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	int horz_start, horz_nr_pixels;
29063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	int vert_start, vert_nr_lines;
29163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	int mid_img = 0;
29263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
29363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "\nStarting isif_setwin...");
29463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
29563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * ppc - per pixel count. indicates how many pixels per cell
29663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
29763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * raw capture this is 1
29863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
29963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	horz_start = image_win->left << (ppc - 1);
30063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
30163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
30263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Writing the horizontal info into the registers */
30363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(horz_start & START_PX_HOR_MASK, SPH);
30463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(horz_nr_pixels & NUM_PX_HOR_MASK, LNH);
30563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	vert_start = image_win->top;
30663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
30763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
30863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		vert_nr_lines = (image_win->height >> 1) - 1;
30963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		vert_start >>= 1;
31063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* To account for VD since line 0 doesn't have any data */
31163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		vert_start += 1;
31263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	} else {
31363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* To account for VD since line 0 doesn't have any data */
31463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		vert_start += 1;
31563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		vert_nr_lines = image_win->height - 1;
31663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* configure VDINT0 and VDINT1 */
31763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		mid_img = vert_start + (image_win->height / 2);
31863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(mid_img, VDINT1);
31963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
32063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
32163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(0, VDINT0);
32263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(vert_start & START_VER_ONE_MASK, SLV0);
32363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(vert_start & START_VER_TWO_MASK, SLV1);
32463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(vert_nr_lines & NUM_LINES_VER, LNV);
32563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
32663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
32763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_config_bclamp(struct isif_black_clamp *bc)
32863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
32963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 val;
33063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
33163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
33263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * DC Offset is always added to image data irrespective of bc enable
33363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * status
33463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
33563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(bc->dc_offset, CLDCOFST);
33663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
33763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (bc->en) {
33863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;
33963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
34063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Enable BC and horizontal clamp caculation paramaters */
34163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);
34263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
34363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(val, CLAMPCFG);
34463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
34563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (bc->horz.mode != ISIF_HORZ_BC_DISABLE) {
34663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/*
34763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			 * Window count for calculation
34863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			 * Base window selection
34963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			 * pixel limit
35063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			 * Horizontal size of window
35163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			 * vertical size of the window
35263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			 * Horizontal start position of the window
35363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			 * Vertical start position of the window
35463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			 */
35563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			val = bc->horz.win_count_calc |
35663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			      ((!!bc->horz.base_win_sel_calc) <<
35763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				ISIF_HORZ_BC_WIN_SEL_SHIFT) |
35863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			      ((!!bc->horz.clamp_pix_limit) <<
35963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
36063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			      (bc->horz.win_h_sz_calc <<
36163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
36263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			      (bc->horz.win_v_sz_calc <<
36363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
36463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(val, CLHWIN0);
36563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
36663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(bc->horz.win_start_h_calc, CLHWIN1);
36763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(bc->horz.win_start_v_calc, CLHWIN2);
36863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
36963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
37063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* vertical clamp caculation paramaters */
37163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
37263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Reset clamp value sel for previous line */
37363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val |=
37463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
37563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
37663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(val, CLVWIN0);
37763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
37863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Optical Black horizontal start position */
37963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(bc->vert.ob_start_h, CLVWIN1);
38063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Optical Black vertical start position */
38163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(bc->vert.ob_start_v, CLVWIN2);
38263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Optical Black vertical size for calculation */
38363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(bc->vert.ob_v_sz_calc, CLVWIN3);
38463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Vertical start position for BC subtraction */
38563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(bc->vert_start_sub, CLSV);
38663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
38763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
38863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
38963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_config_linearization(struct isif_linearize *linearize)
39063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
39163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 val, i;
39263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
39363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (!linearize->en) {
39463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(0, LINCFG0);
39563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return;
39663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
39763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
39863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* shift value for correction & enable linearization (set lsb) */
39963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
40063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, LINCFG0);
40163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
40263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Scale factor */
40363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = ((!!linearize->scale_fact.integer) <<
40463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	       ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
40563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	       linearize->scale_fact.decimal;
40663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, LINCFG1);
40763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
40863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
40963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (i % 2)
41063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
41163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		else
41263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
41363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
41463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
41563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
41663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_config_dfc(struct isif_dfc *vdfc)
41763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
41863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* initialize retries to loop for max ~ 250 usec */
41963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 val, count, retries = loops_per_jiffy / (4000/HZ);
42063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	int i;
42163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
42263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (!vdfc->en)
42363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return 0;
42463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
42563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Correction mode */
42663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);
42763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
42863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Correct whole line or partial */
42963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (vdfc->corr_whole_line)
43063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;
43163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
43263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* level shift value */
43363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;
43463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
43563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, DFCCTL);
43663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
43763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Defect saturation level */
43863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(vdfc->def_sat_level, VDFSATLV);
43963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
44063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(vdfc->table[0].pos_vert, DFCMEM0);
44163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(vdfc->table[0].pos_horz, DFCMEM1);
44263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
44363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	    vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
44463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(vdfc->table[0].level_at_pos, DFCMEM2);
44563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(vdfc->table[0].level_up_pixels, DFCMEM3);
44663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(vdfc->table[0].level_low_pixels, DFCMEM4);
44763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
44863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
44963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* set DFCMARST and set DFCMWR */
45063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
45163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, DFCMEMCTL);
45263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
45363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	count = retries;
45463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	while (count && (regr(DFCMEMCTL) & 0x1))
45563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		count--;
45663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
45763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (!count) {
45863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		dev_dbg(isif_cfg.dev, "defect table write timeout !!!\n");
45963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return -1;
46063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
46163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
46263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	for (i = 1; i < vdfc->num_vdefects; i++) {
46363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(vdfc->table[i].pos_vert, DFCMEM0);
46463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(vdfc->table[i].pos_horz, DFCMEM1);
46563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
46663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		    vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
46763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(vdfc->table[i].level_at_pos, DFCMEM2);
46863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(vdfc->table[i].level_up_pixels, DFCMEM3);
46963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(vdfc->table[i].level_low_pixels, DFCMEM4);
47063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
47163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val = regr(DFCMEMCTL);
47263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* clear DFCMARST and set DFCMWR */
47363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
47463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val |= 1;
47563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(val, DFCMEMCTL);
47663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
47763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		count = retries;
47863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		while (count && (regr(DFCMEMCTL) & 0x1))
47963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			count--;
48063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
48163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (!count) {
48263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_err(isif_cfg.dev,
48363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				"defect table write timeout !!!\n");
48463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			return -1;
48563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
48663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
48763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
48863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Extra cycle needed */
48963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(0, DFCMEM0);
49063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(0x1FFF, DFCMEM1);
49163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(1, DFCMEMCTL);
49263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
49363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
49463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* enable VDFC */
49563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
49663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		   DFCCTL);
49763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
49863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
49963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
50063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_config_csc(struct isif_df_csc *df_csc)
50163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
50263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 val1 = 0, val2 = 0, i;
50363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
50463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (!df_csc->csc.en) {
50563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(0, CSCCTL);
50663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return;
50763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
50863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
50963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if ((i % 2) == 0) {
51063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* CSCM - LSB */
51163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			val1 = (df_csc->csc.coeff[i].integer <<
51263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				ISIF_CSC_COEF_INTEG_SHIFT) |
51363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				df_csc->csc.coeff[i].decimal;
51463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		} else {
51563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
51663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* CSCM - MSB */
51763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			val2 = (df_csc->csc.coeff[i].integer <<
51863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				ISIF_CSC_COEF_INTEG_SHIFT) |
51963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				df_csc->csc.coeff[i].decimal;
52063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			val2 <<= ISIF_CSCM_MSB_SHIFT;
52163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			val2 |= val1;
52263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(val2, (CSCM0 + ((i - 1) << 1)));
52363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
52463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
52563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
52663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* program the active area */
52763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(df_csc->start_pix, FMTSPH);
52863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
52963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * one extra pixel as required for CSC. Actually number of
53063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * pixel - 1 should be configured in this register. So we
53163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * need to subtract 1 before writing to FMTSPH, but we will
53263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * not do this since csc requires one extra pixel
53363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
53463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(df_csc->num_pixels, FMTLNH);
53563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(df_csc->start_line, FMTSLV);
53663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
53763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * one extra line as required for CSC. See reason documented for
53863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * num_pixels
53963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
54063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(df_csc->num_lines, FMTLNV);
54163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
54263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Enable CSC */
54363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(1, CSCCTL);
54463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
54563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
54663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_config_raw(void)
54763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
54863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct isif_params_raw *params = &isif_cfg.bayer;
54963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct isif_config_params_raw *module_params =
55063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		&isif_cfg.bayer.config_params;
55163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct vpss_pg_frame_size frame_size;
55263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct vpss_sync_pol sync;
55363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 val;
55463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
55563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");
55663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
55763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
55863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure CCDCFG register:-
55963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Set CCD Not to swap input since input is RAW data
56063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Set FID detection function to Latch at V-Sync
56163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Set WENLOG - isif valid area
56263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Set TRGSEL
56363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Set EXTRG
56463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Packed to 8 or 16 bits
56563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
56663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
56763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
56863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
56963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;
57063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
57163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "Writing 0x%x to ...CCDCFG \n", val);
57263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, CCDCFG);
57363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
57463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
57563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure the vertical sync polarity(MODESET.VDPOL)
57663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure the horizontal sync polarity (MODESET.HDPOL)
57763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure frame id polarity (MODESET.FLDPOL)
57863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure data polarity
57963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure External WEN Selection
58063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure frame format(progressive or interlace)
58163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure pixel format (Input mode)
58263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure the data shift
58363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
58463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
58563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
58663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(params->hd_pol << ISIF_HD_POL_SHIFT) |
58763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(params->fid_pol << ISIF_FID_POL_SHIFT) |
58863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
58963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
59063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
59163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(params->pix_fmt << ISIF_INPUT_SHIFT) |
59263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		(params->config_params.data_shift << ISIF_DATASFT_SHIFT);
59363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
59463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, MODESET);
59563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);
59663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
59763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
59863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * Configure GAMMAWD register
59963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * CFA pattern setting
60063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
60163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;
60263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
60363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Gamma msb */
60463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (module_params->compress.alg == ISIF_ALAW)
60563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val |= ISIF_ALAW_ENABLE;
60663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
60763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val |= (params->data_msb << ISIF_ALAW_GAMA_WD_SHIFT);
60863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, CGAMMAWD);
60963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
61063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure DPCM compression settings */
61163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (module_params->compress.alg == ISIF_DPCM) {
61263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val =  BIT(ISIF_DPCM_EN_SHIFT) |
61363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		       (module_params->compress.pred <<
61463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		       ISIF_DPCM_PREDICTOR_SHIFT);
61563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
61663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
61763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, MISC);
61863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
61963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure Gain & Offset */
62063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_config_gain_offset();
62163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
62263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure Color pattern */
62363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (params->config_params.col_pat_field0.olop) |
62463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (params->config_params.col_pat_field0.olep << 2) |
62563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (params->config_params.col_pat_field0.elop << 4) |
62663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (params->config_params.col_pat_field0.elep << 6) |
62763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (params->config_params.col_pat_field1.olop << 8) |
62863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (params->config_params.col_pat_field1.olep << 10) |
62963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (params->config_params.col_pat_field1.elop << 12) |
63063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	      (params->config_params.col_pat_field1.elep << 14);
63163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, CCOLP);
63263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);
63363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
63463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure HSIZE register  */
63563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;
63663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
63763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* calculate line offset in 32 bytes based on pack value */
63863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.data_pack == ISIF_PACK_8BIT)
63963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val |= ((params->win.width + 31) >> 5);
64063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
64163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val |= (((params->win.width +
64263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		       (params->win.width >> 2)) + 31) >> 5);
64363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	else
64463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		val |= (((params->win.width * 2) + 31) >> 5);
64563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(val, HSIZE);
64663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
64763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure SDOFST register  */
64863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
64963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (params->image_invert_en) {
65063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* For interlace inverse mode */
65163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(0x4B6D, SDOFST);
65263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
65363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		} else {
65463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* For interlace non inverse mode */
65563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(0x0B6D, SDOFST);
65663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
65763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
65863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
65963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (params->image_invert_en) {
66063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* For progressive inverse mode */
66163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(0x4000, SDOFST);
66263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
66363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		} else {
66463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* For progressive non inverse mode */
66563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			regw(0x0000, SDOFST);
66663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
66763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
66863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
66963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
67063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure video window */
67163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_setwin(&params->win, params->frm_fmt, 1);
67263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
67363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure Black Clamp */
67463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_config_bclamp(&module_params->bclamp);
67563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
67663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure Vertical Defection Pixel Correction */
67763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_config_dfc(&module_params->dfc) < 0)
67863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return -EFAULT;
67963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
68063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (!module_params->df_csc.df_or_csc)
68163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Configure Color Space Conversion */
68263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_config_csc(&module_params->df_csc);
68363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
68463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_config_linearization(&module_params->linearize);
68563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
68663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure Culling */
68763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_config_culling(&module_params->culling);
68863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
68963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
69063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(module_params->horz_offset, DATAHOFST);
69163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(module_params->vert_offset, DATAVOFST);
69263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
69363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Setup test pattern if enabled */
69463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (params->config_params.test_pat_gen) {
69563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* Use the HD/VD pol settings from user */
69663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		sync.ccdpg_hdpol = params->hd_pol;
69763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		sync.ccdpg_vdpol = params->vd_pol;
69863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		dm365_vpss_set_sync_pol(sync);
69963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		frame_size.hlpfr = isif_cfg.bayer.win.width;
70063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		frame_size.pplen = isif_cfg.bayer.win.height;
70163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		dm365_vpss_set_pg_frame_size(frame_size);
70263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		vpss_select_ccdc_source(VPSS_PGLPBK);
70363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
70463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
70563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
70663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
70763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
70863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
70963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_set_buftype(enum ccdc_buftype buf_type)
71063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
71163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER)
71263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.bayer.buf_type = buf_type;
71363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	else
71463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.buf_type = buf_type;
71563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
71663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
71763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
71863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
71963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic enum ccdc_buftype isif_get_buftype(void)
72063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
72163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER)
72263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return isif_cfg.bayer.buf_type;
72363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
72463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return isif_cfg.ycbcr.buf_type;
72563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
72663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
72763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_enum_pix(u32 *pix, int i)
72863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
72963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	int ret = -EINVAL;
73063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
73163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
73263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
73363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			*pix = isif_raw_bayer_pix_formats[i];
73463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			ret = 0;
73563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
73663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	} else {
73763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
73863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			*pix = isif_raw_yuv_pix_formats[i];
73963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			ret = 0;
74063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
74163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
74263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
74363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return ret;
74463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
74563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
74663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_set_pixel_format(unsigned int pixfmt)
74763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
74863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
74963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
75063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			if ((isif_cfg.bayer.config_params.compress.alg !=
75163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			     ISIF_ALAW) &&
75263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			    (isif_cfg.bayer.config_params.compress.alg !=
75363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			     ISIF_DPCM)) {
75463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				dev_dbg(isif_cfg.dev,
75563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri					"Either configure A-Law or DPCM\n");
75663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				return -EINVAL;
75763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			}
75863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			isif_cfg.data_pack = ISIF_PACK_8BIT;
75963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		} else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
76063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			isif_cfg.bayer.config_params.compress.alg =
76163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri					ISIF_NO_COMPRESSION;
76263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			isif_cfg.data_pack = ISIF_PACK_16BIT;
76363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		} else
76463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			return -EINVAL;
76563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
76663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	} else {
76763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (pixfmt == V4L2_PIX_FMT_YUYV)
76863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
76963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		else if (pixfmt == V4L2_PIX_FMT_UYVY)
77063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
77163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		else
77263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			return -EINVAL;
77363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.data_pack = ISIF_PACK_8BIT;
77463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
77563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
77663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
77763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
77863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic u32 isif_get_pixel_format(void)
77963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
78063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 pixfmt;
78163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
78263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER)
78363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
78463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		    isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
78563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			pixfmt = V4L2_PIX_FMT_SBGGR8;
78663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		else
78763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			pixfmt = V4L2_PIX_FMT_SBGGR16;
78863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	else {
78963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
79063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			pixfmt = V4L2_PIX_FMT_YUYV;
79163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		else
79263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			pixfmt = V4L2_PIX_FMT_UYVY;
79363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
79463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return pixfmt;
79563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
79663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
79763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_set_image_window(struct v4l2_rect *win)
79863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
79963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
80063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.bayer.win.top = win->top;
80163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.bayer.win.left = win->left;
80263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.bayer.win.width = win->width;
80363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.bayer.win.height = win->height;
80463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	} else {
80563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.win.top = win->top;
80663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.win.left = win->left;
80763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.win.width = win->width;
80863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.win.height = win->height;
80963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
81063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
81163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
81263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
81363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_get_image_window(struct v4l2_rect *win)
81463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
81563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER)
81663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		*win = isif_cfg.bayer.win;
81763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	else
81863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		*win = isif_cfg.ycbcr.win;
81963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
82063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
82163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic unsigned int isif_get_line_length(void)
82263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
82363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	unsigned int len;
82463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
82563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER) {
82663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (isif_cfg.data_pack == ISIF_PACK_8BIT)
82763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			len = ((isif_cfg.bayer.win.width));
82863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
82963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			len = (((isif_cfg.bayer.win.width * 2) +
83063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri				 (isif_cfg.bayer.win.width >> 2)));
83163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		else
83263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			len = (((isif_cfg.bayer.win.width * 2)));
83363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	} else
83463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		len = (((isif_cfg.ycbcr.win.width * 2)));
83563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return ALIGN(len, 32);
83663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
83763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
83863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
83963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
84063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER)
84163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.bayer.frm_fmt = frm_fmt;
84263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	else
84363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.frm_fmt = frm_fmt;
84463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
84563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
84663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic enum ccdc_frmfmt isif_get_frame_format(void)
84763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
84863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER)
84963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return isif_cfg.bayer.frm_fmt;
85063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return isif_cfg.ycbcr.frm_fmt;
85163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
85263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
85363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_getfid(void)
85463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
85563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return (regr(MODESET) >> 15) & 0x1;
85663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
85763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
85863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* misc operations */
85963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic void isif_setfbaddr(unsigned long addr)
86063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
86163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw((addr >> 21) & 0x07ff, CADU);
86263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw((addr >> 5) & 0x0ffff, CADL);
86363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
86463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
86563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
86663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
86763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_cfg.if_type = params->if_type;
86863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
86963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	switch (params->if_type) {
87063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_BT656:
87163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_BT656_10BIT:
87263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_YCBCR_SYNC_8:
87363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
87463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
87563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		break;
87663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_BT1120:
87763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_YCBCR_SYNC_16:
87863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
87963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
88063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		break;
88163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_RAW_BAYER:
88263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
88363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		break;
88463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	default:
88563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		dev_dbg(isif_cfg.dev, "Invalid interface type\n");
88663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return -EINVAL;
88763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
88863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
88963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
89063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
89163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
89263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri/* This function will configure ISIF for YCbCr parameters. */
89363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_config_ycbcr(void)
89463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
89563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
89663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct vpss_pg_frame_size frame_size;
89763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	u32 modeset = 0, ccdcfg = 0;
89863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct vpss_sync_pol sync;
89963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
90063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");
90163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
90263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* configure pixel format or input mode */
90363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
90463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		  (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
90563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		  (params->fid_pol << ISIF_FID_POL_SHIFT) |
90663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		  (params->hd_pol << ISIF_HD_POL_SHIFT) |
90763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		  (params->vd_pol << ISIF_VD_POL_SHIFT);
90863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
90963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* pack the data to 8-bit ISIFCFG */
91063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	switch (isif_cfg.if_type) {
91163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_BT656:
91263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
91363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
91463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			return -EINVAL;
91563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
91663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
91763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(3, REC656IF);
91863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
91963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		break;
92063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_BT656_10BIT:
92163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
92263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
92363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			return -EINVAL;
92463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
92563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* setup BT.656, embedded sync  */
92663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(3, REC656IF);
92763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* enable 10 bit mode in ccdcfg */
92863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
92963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			ISIF_BW656_ENABLE;
93063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		break;
93163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_BT1120:
93263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
93363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
93463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			return -EINVAL;
93563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
93663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(3, REC656IF);
93763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		break;
93863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
93963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_YCBCR_SYNC_8:
94063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		ccdcfg |= ISIF_DATA_PACK8;
94163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		ccdcfg |= ISIF_YCINSWP_YCBCR;
94263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
94363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
94463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			return -EINVAL;
94563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
94663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		break;
94763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	case VPFE_YCBCR_SYNC_16:
94863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
94963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
95063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			return -EINVAL;
95163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
95263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		break;
95363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	default:
95463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* should never come here */
95563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		dev_dbg(isif_cfg.dev, "Invalid interface type\n");
95663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return -EINVAL;
95763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
95863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
95963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(modeset, MODESET);
96063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
96163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Set up pix order */
96263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;
96363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
96463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(ccdcfg, CCDCFG);
96563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
96663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* configure video window */
96763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if ((isif_cfg.if_type == VPFE_BT1120) ||
96863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	    (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
96963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_setwin(&params->win, params->frm_fmt, 1);
97063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	else
97163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_setwin(&params->win, params->frm_fmt, 2);
97263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
97363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
97463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * configure the horizontal line offset
97563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * this is done by rounding up width to a multiple of 16 pixels
97663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * and multiply by two to account for y:cb:cr 4:2:2 data
97763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
97863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5), HSIZE);
97963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
98063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* configure the memory line offset */
98163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if ((params->frm_fmt == CCDC_FRMFMT_INTERLACED) &&
98263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	    (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED))
98363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		/* two fields are interleaved in memory */
98463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		regw(0x00000249, SDOFST);
98563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
98663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Setup test pattern if enabled */
98763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.bayer.config_params.test_pat_gen) {
98863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		sync.ccdpg_hdpol = params->hd_pol;
98963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		sync.ccdpg_vdpol = params->vd_pol;
99063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		dm365_vpss_set_sync_pol(sync);
99163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		dm365_vpss_set_pg_frame_size(frame_size);
99263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
99363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
99463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
99563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
99663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_configure(void)
99763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
99863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.if_type == VPFE_RAW_BAYER)
99963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return isif_config_raw();
100063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return isif_config_ycbcr();
100163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
100263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
100363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_close(struct device *device)
100463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
100563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* copy defaults to module params */
100663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_cfg.bayer.config_params = isif_config_defaults;
100763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
100863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
100963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
101063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic struct ccdc_hw_device isif_hw_dev = {
101163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.name = "ISIF",
101263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.owner = THIS_MODULE,
101363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.hw_ops = {
101463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.open = isif_open,
101563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.close = isif_close,
101663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.enable = isif_enable,
101763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.enable_out_to_sdram = isif_enable_output_to_sdram,
101863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.set_hw_if_params = isif_set_hw_if_params,
101963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.configure = isif_configure,
102063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.set_buftype = isif_set_buftype,
102163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.get_buftype = isif_get_buftype,
102263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.enum_pix = isif_enum_pix,
102363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.set_pixel_format = isif_set_pixel_format,
102463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.get_pixel_format = isif_get_pixel_format,
102563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.set_frame_format = isif_set_frame_format,
102663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.get_frame_format = isif_get_frame_format,
102763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.set_image_window = isif_set_image_window,
102863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.get_image_window = isif_get_image_window,
102963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.get_line_length = isif_get_line_length,
103063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.setfbaddr = isif_setfbaddr,
103163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.getfid = isif_getfid,
103263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
103363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri};
103463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
103563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int __init isif_probe(struct platform_device *pdev)
103663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
103763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	void (*setup_pinmux)(void);
103863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct resource	*res;
103963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	void *__iomem addr;
104063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	int status = 0, i;
104163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
104263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
104363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * first try to register with vpfe. If not correct platform, then we
104463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * don't have to iomap
104563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
104663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	status = vpfe_register_ccdc_device(&isif_hw_dev);
104763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (status < 0)
104863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		return status;
104963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
105063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Get and enable Master clock */
105163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_cfg.mclk = clk_get(&pdev->dev, "master");
105263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (IS_ERR(isif_cfg.mclk)) {
105363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		status = PTR_ERR(isif_cfg.mclk);
105463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		goto fail_mclk;
105563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
105663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (clk_enable(isif_cfg.mclk)) {
105763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		status = -ENODEV;
105863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		goto fail_mclk;
105963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
106063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
106163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Platform data holds setup_pinmux function ptr */
106263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (NULL == pdev->dev.platform_data) {
106363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		status = -ENODEV;
106463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		goto fail_mclk;
106563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
106663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	setup_pinmux = pdev->dev.platform_data;
106763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/*
106863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * setup Mux configuration for ccdc which may be different for
106963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 * different SoCs using this CCDC
107063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	 */
107163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	setup_pinmux();
107263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
107363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	i = 0;
107463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	/* Get the ISIF base address, linearization table0 and table1 addr. */
107563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	while (i < 3) {
107663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
107763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (!res) {
107863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			status = -ENODEV;
107963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			goto fail_nobase_res;
108063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
108163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		res = request_mem_region(res->start, resource_size(res),
108263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri					 res->name);
108363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (!res) {
108463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			status = -EBUSY;
108563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			goto fail_nobase_res;
108663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
108763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		addr = ioremap_nocache(res->start, resource_size(res));
108863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (!addr) {
108963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			status = -ENOMEM;
109063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			goto fail_base_iomap;
109163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
109263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		switch (i) {
109363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		case 0:
109463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* ISIF base address */
109563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			isif_cfg.base_addr = addr;
109663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			break;
109763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		case 1:
109863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* ISIF linear tbl0 address */
109963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			isif_cfg.linear_tbl0_addr = addr;
110063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			break;
110163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		default:
110263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			/* ISIF linear tbl0 address */
110363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			isif_cfg.linear_tbl1_addr = addr;
110463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			break;
110563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		}
110663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		i++;
110763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
110863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	isif_cfg.dev = &pdev->dev;
110963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
111063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	printk(KERN_NOTICE "%s is registered with vpfe.\n",
111163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		isif_hw_dev.name);
111263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
111363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicherifail_base_iomap:
111463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	release_mem_region(res->start, resource_size(res));
111563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	i--;
111663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicherifail_nobase_res:
111763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.base_addr)
111863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		iounmap(isif_cfg.base_addr);
111963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	if (isif_cfg.linear_tbl0_addr)
112063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		iounmap(isif_cfg.linear_tbl0_addr);
112163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
112263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	while (i >= 0) {
112363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
112463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		release_mem_region(res->start, resource_size(res));
112563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		i--;
112663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
112763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicherifail_mclk:
112863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	clk_put(isif_cfg.mclk);
112963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	vpfe_unregister_ccdc_device(&isif_hw_dev);
113063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return status;
113163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
113263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
113363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic int isif_remove(struct platform_device *pdev)
113463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri{
113563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	struct resource	*res;
113663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	int i = 0;
113763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
113863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	iounmap(isif_cfg.base_addr);
113963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	iounmap(isif_cfg.linear_tbl0_addr);
114063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	iounmap(isif_cfg.linear_tbl1_addr);
114163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	while (i < 3) {
114263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
114363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		if (res)
114463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri			release_mem_region(res->start, resource_size(res));
114563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		i++;
114663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	}
114763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	vpfe_unregister_ccdc_device(&isif_hw_dev);
114863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	return 0;
114963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri}
115063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
115163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheristatic struct platform_driver isif_driver = {
115263e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.driver = {
115363e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.name	= "isif",
115463e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri		.owner = THIS_MODULE,
115563e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	},
115663e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.remove = __devexit_p(isif_remove),
115763e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri	.probe = isif_probe,
115863e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri};
115963e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
11601d6629b1561ad34a6e6d17ece00bd65e1bab3724Axel Linmodule_platform_driver(isif_driver);
116163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri
116263e3ab142fa3f46c290891655681c6a6304bd2b3Murali KaricheriMODULE_LICENSE("GPL");
1163