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(¶ms->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(¶ms->win, params->frm_fmt, 1); 97063e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri else 97163e3ab142fa3f46c290891655681c6a6304bd2b3Murali Karicheri isif_setwin(¶ms->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