From: Sergio Aguirre <saaguirre@xxxxxx> OMAP: CAM: Add MMS Kernel changes This adds MMS changes to the OMAP34xx camera driver. Including: - HQ capture NOTE: Credits to MMS crew for all this. Signed-off-by: Sergio Aguirre <saaguirre@xxxxxx> --- drivers/media/video/isp/isp.c | 40 ++++++++--- drivers/media/video/isp/isp_af.c | 28 +++++--- drivers/media/video/isp/ispccdc.c | 117 ++++++++++++++++++++++++++++++++--- drivers/media/video/isp/ispccdc.h | 4 - drivers/media/video/isp/isph3a.c | 12 +++ drivers/media/video/isp/ispmmu.h | 2 drivers/media/video/isp/isppreview.c | 3 drivers/media/video/isp/isppreview.h | 9 ++ 8 files changed, 180 insertions(+), 35 deletions(-) Index: omapkernel/drivers/media/video/isp/isp.c =================================================================== --- omapkernel.orig/drivers/media/video/isp/isp.c 2008-10-15 19:37:26.000000000 -0500 +++ omapkernel/drivers/media/video/isp/isp.c 2008-10-15 19:40:02.000000000 -0500 @@ -71,6 +71,10 @@ .description = "Bayer10 (GrR/BGb)", .pixelformat = V4L2_PIX_FMT_SGRBG10, }, + { + .description = "Bayer10 (pattern)", + .pixelformat = V4L2_PIX_FMT_PATT, + } }; /* ISP Crop capabilities */ @@ -980,6 +984,14 @@ goto out; } + if ((irqstatus & HS_VS) == HS_VS) { + if (irqdis->isp_callbk[CBK_HS_VS]) + irqdis->isp_callbk[CBK_HS_VS](HS_VS, + irqdis->isp_callbk_arg1[CBK_HS_VS], + irqdis->isp_callbk_arg2[CBK_HS_VS]); + is_irqhandled = 1; + } + if ((irqstatus & CCDC_VD1) == CCDC_VD1) { if (irqdis->isp_callbk[CBK_CCDC_VD1]) irqdis->isp_callbk[CBK_CCDC_VD1](CCDC_VD1, @@ -1028,14 +1040,6 @@ is_irqhandled = 1; } - if ((irqstatus & HS_VS) == HS_VS) { - if (irqdis->isp_callbk[CBK_HS_VS]) - irqdis->isp_callbk[CBK_HS_VS](HS_VS, - irqdis->isp_callbk_arg1[CBK_HS_VS], - irqdis->isp_callbk_arg2[CBK_HS_VS]); - is_irqhandled = 1; - } - if ((irqstatus & H3A_AF_DONE) == H3A_AF_DONE) { if (irqdis->isp_callbk[CBK_H3A_AF_DONE]) irqdis->isp_callbk[CBK_H3A_AF_DONE](H3A_AF_DONE, @@ -1191,6 +1195,9 @@ is_isppreview_enabled()) isppreview_enable(1); + /* clear any pending IRQs */ + omap_writel(0xFFFFFFFF, ISP_IRQ0STATUS); + return; } EXPORT_SYMBOL(isp_start); @@ -1258,7 +1265,8 @@ isp_release_resources(); if ((pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10) && - (pix_output->pixelformat != V4L2_PIX_FMT_SGRBG10)) { + ((pix_output->pixelformat == V4L2_PIX_FMT_YUYV) || + (pix_output->pixelformat == V4L2_PIX_FMT_UYVY))) { ispmodule_obj.isp_pipeline = OMAP_ISP_CCDC | OMAP_ISP_PREVIEW | OMAP_ISP_RESIZER; ispccdc_request(); @@ -1277,15 +1285,23 @@ isppreview_config_datapath(PRV_RAW_CCDC, PREVIEW_RSZ); ispresizer_config_datapath(RSZ_OTFLY_YUV); #endif - } else { + } else if (pix_input->pixelformat == pix_output->pixelformat) { ispmodule_obj.isp_pipeline = OMAP_ISP_CCDC; ispccdc_request(); if (pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10) ispccdc_config_datapath(CCDC_RAW, CCDC_OTHERS_MEM); - else + else if (pix_input->pixelformat == V4L2_PIX_FMT_PATT) { + /* MMS */ + ispccdc_config_datapath(CCDC_RAW_PATTERN, + CCDC_OTHERS_LSC_MEM); + } else if ((pix_input->pixelformat == V4L2_PIX_FMT_YUYV) || + (pix_input->pixelformat == V4L2_PIX_FMT_UYVY)) { ispccdc_config_datapath(CCDC_YUV_SYNC, CCDC_OTHERS_MEM); - } + } else + return -EINVAL; + } else + return -EINVAL; return 0; } Index: omapkernel/drivers/media/video/isp/isp_af.c =================================================================== --- omapkernel.orig/drivers/media/video/isp/isp_af.c 2008-10-15 19:37:24.000000000 -0500 +++ omapkernel/drivers/media/video/isp/isp_af.c 2008-10-15 19:40:49.000000000 -0500 @@ -313,9 +313,10 @@ busyaf = omap_readl(ISPH3A_PCR); if ((busyaf & AF_BUSYAF) == AF_BUSYAF) { - DPRINTK_ISPH3A("AF_register_setup_ERROR : Engine Busy"); - DPRINTK_ISPH3A("\n Configuration cannot be done "); - return -AF_ERR_ENGINE_BUSY; + /* DPRINTK_ISPH3A("AF_register_setup_ERROR : Engine Busy"); */ + /* DPRINTK_ISPH3A("\n Configuration cannot be done "); */ + /* return -AF_ERR_ENGINE_BUSY; */ + isp_af_enable(0); } /*Check IIR Coefficient and start Values */ @@ -396,8 +397,6 @@ /*Set configuration flag to indicate HW setup done */ if (af_dev_configptr->config->af_config) isp_af_enable(1); - else - isp_af_enable(0); /*Success */ return 0; @@ -702,9 +701,8 @@ /* Function to Enable/Disable AF Engine */ int isp_af_enable(int enable) { - unsigned int pcr; - - pcr = omap_readl(ISPH3A_PCR); + /* Before enabling AF H3A we need to clear pending interrupts */ + omap_writel(IRQ0STATUS_H3A_AF_DONE_IRQ, ISP_IRQ0STATUS); /* Set AF_EN bit in PCR Register */ if (enable) { @@ -714,12 +712,20 @@ return -EINVAL; } - pcr |= AF_EN; + omap_writel((omap_readl(ISPH3A_PCR) | AF_EN), ISPH3A_PCR); } else { + u32 timeout = 20; isp_unset_callback(CBK_H3A_AF_DONE); - pcr &= ~AF_EN; + omap_writel((omap_readl(ISPH3A_PCR) & ~AF_EN), ISPH3A_PCR); + while ((omap_readl(ISPH3A_PCR) & AF_BUSYAF) && timeout) { + mdelay(10); + timeout--; + } + if (timeout == 0) { + printk(KERN_DEBUG "%s - can't disable AF H3A\n", + __func__); + } } - omap_writel(pcr, ISPH3A_PCR); return 0; } Index: omapkernel/drivers/media/video/isp/ispccdc.c =================================================================== --- omapkernel.orig/drivers/media/video/isp/ispccdc.c 2008-10-15 19:37:25.000000000 -0500 +++ omapkernel/drivers/media/video/isp/ispccdc.c 2008-10-15 19:42:28.000000000 -0500 @@ -189,6 +189,11 @@ } else { if ((ISP_ABS_CCDC_BLCLAMP & ccdc_struct->update) == ISP_ABS_CCDC_BLCLAMP) { + if (copy_from_user(&bclamp_t, + (struct ispccdc_bclamp *)(ccdc_struct->bclamp), + sizeof(struct ispccdc_bclamp))) + goto copy_from_user_err; + ispccdc_enable_black_clamp(0); ispccdc_config_black_clamp(bclamp_t); } @@ -571,6 +576,19 @@ ispccdc_config_vp(vpcfg); ispccdc_enable_vp(1); break; + case CCDC_OTHERS_LSC_MEM: /* Added by MMS */ + syn_mode |= ISPCCDC_SYN_MODE_VP2SDR; + syn_mode |= ISPCCDC_SYN_MODE_WEN; + /* Generally cam_wen is used with cam_hs, vs signals */ + syn_mode |= ISPCCDC_SYN_MODE_EXWEN; + omap_writel((omap_readl(ISPCCDC_CFG)) + | ISPCCDC_CFG_WENLOG, ISPCCDC_CFG); + /* Video Port Configuration */ + vpcfg.bitshift_sel = BIT9_0; + vpcfg.freq_sel = PIXCLKBY2; + ispccdc_config_vp(vpcfg); + ispccdc_enable_vp(1); + break; default: DPRINTK_ISPCCDC("ISP_ERR: Wrong CCDC Output"); return -EINVAL; @@ -616,6 +634,32 @@ blkcfg.dcsubval = 0; ispccdc_config_black_clamp(blkcfg); break; + /* Added by MMS */ + case CCDC_RAW_PATTERN: + /* Slave mode */ + syncif.ccdc_mastermode = 0; + /* Normal */ + syncif.datapol = 0; + syncif.datsz = DAT8; + /* Progressive Mode */ + syncif.fldmode = 0; + /* Input */ + syncif.fldout = 0; + /* Positive */ + syncif.fldpol = 0; + /* Odd Field */ + syncif.fldstat = 0; + /* Positive */ + syncif.hdpol = 0; + syncif.ipmod = RAW; + /* Positive */ + syncif.vdpol = 0; + ispccdc_config_sync_if(syncif); + ispccdc_config_imgattr(colptn); + /* Config DC sub */ + blkcfg.dcsubval = 42; + ispccdc_config_black_clamp(blkcfg); + break; case CCDC_YUV_BT: break; case CCDC_OTHERS: @@ -644,6 +688,7 @@ u32 syn_mode = omap_readl(ISPCCDC_SYN_MODE); syn_mode |= ISPCCDC_SYN_MODE_VDHDEN; + syn_mode &= ~ISPCCDC_SYN_MODE_PACK8; /* Added by MMS */ if (syncif.fldstat) syn_mode |= ISPCCDC_SYN_MODE_FLDSTAT; @@ -668,6 +713,7 @@ switch (syncif.datsz) { case DAT8: syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_8; + syn_mode |= ISPCCDC_SYN_MODE_PACK8; /* Added by MMS */ break; case DAT10: syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_10; @@ -837,10 +883,11 @@ { u32 blcomp_val = 0; - blcomp_val |= blcomp.b_mg << ISPCCDC_BLKCMP_B_MG_SHIFT; - blcomp_val |= blcomp.gb_g << ISPCCDC_BLKCMP_GB_G_SHIFT; - blcomp_val |= blcomp.gr_cy << ISPCCDC_BLKCMP_GR_CY_SHIFT; - blcomp_val |= blcomp.r_ye << ISPCCDC_BLKCMP_R_YE_SHIFT; + blcomp_val |= (((u32)blcomp.b_mg & 0xFF) << ISPCCDC_BLKCMP_B_MG_SHIFT); + blcomp_val |= (((u32)blcomp.gb_g & 0xFF) << ISPCCDC_BLKCMP_GB_G_SHIFT); + blcomp_val |= (((u32)blcomp.gr_cy & 0xFF) << + ISPCCDC_BLKCMP_GR_CY_SHIFT); + blcomp_val |= (((u32)blcomp.r_ye & 0xFF) << ISPCCDC_BLKCMP_R_YE_SHIFT); omap_writel(blcomp_val, ISPCCDC_BLKCMP); } @@ -1087,7 +1134,9 @@ if ((ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_MEM) || (ispccdc_obj.ccdc_outfmt == - CCDC_OTHERS_VP_MEM)) { + CCDC_OTHERS_VP_MEM) || + (ispccdc_obj.ccdc_outfmt == + CCDC_OTHERS_LSC_MEM)) { if (*output_w % 16) { *output_w -= (*output_w % 16); *output_w += 16; @@ -1197,10 +1246,17 @@ (ispccdc_obj.ccdcout_h << ISPCCDC_VP_OUT_VERT_NUM_SHIFT), ISPCCDC_VP_OUT); +/* MMS: fix wrong pattern */ +/* omap_writel(0 << ISPCCDC_HORZ_INFO_SPH_SHIFT | ((ispccdc_obj.ccdcout_w - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT), ISPCCDC_HORZ_INFO); +*/ + omap_writel(1 << ISPCCDC_HORZ_INFO_SPH_SHIFT | + ((ispccdc_obj.ccdcout_w - 1) << + ISPCCDC_HORZ_INFO_NPH_SHIFT), + ISPCCDC_HORZ_INFO); omap_writel(0 << ISPCCDC_VERT_START_SLV0_SHIFT, ISPCCDC_VERT_START); omap_writel((ispccdc_obj.ccdcout_h - 1) << @@ -1212,10 +1268,47 @@ ISPCCDC_VDINT_0_SHIFT) | ((50 & ISPCCDC_VDINT_1_MASK) << ISPCCDC_VDINT_1_SHIFT), ISPCCDC_VDINT); + } else if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_LSC_MEM) { + /* Added by MMS */ + /* Start with 1 pixel apart */ + omap_writel((1 << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) + | (ispccdc_obj.ccdcin_w + << ISPCCDC_FMT_HORZ_FMTLNH_SHIFT), + ISPCCDC_FMT_HORZ); + + omap_writel((0 << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) + | ((ispccdc_obj.ccdcin_h) + << ISPCCDC_FMT_VERT_FMTLNV_SHIFT), + ISPCCDC_FMT_VERT); + + omap_writel((ispccdc_obj.ccdcout_w + << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) + | (ispccdc_obj.ccdcout_h + << ISPCCDC_VP_OUT_VERT_NUM_SHIFT), + ISPCCDC_VP_OUT); + omap_writel(0 << ISPCCDC_HORZ_INFO_SPH_SHIFT + | ((ispccdc_obj.ccdcout_w - 1) + << ISPCCDC_HORZ_INFO_NPH_SHIFT), + ISPCCDC_HORZ_INFO); + omap_writel(0 << ISPCCDC_VERT_START_SLV0_SHIFT, + ISPCCDC_VERT_START); + omap_writel((ispccdc_obj.ccdcout_h - 1) + << ISPCCDC_VERT_LINES_NLV_SHIFT, + ISPCCDC_VERT_LINES); + /*Configure the HSIZE_OFF with output buffer width*/ + + ispccdc_config_outlineoffset((ispccdc_obj.ccdcout_w * 2), 0, 0); + omap_writel((((ispccdc_obj.ccdcout_h - 25) + & ISPCCDC_VDINT_0_MASK) + << ISPCCDC_VDINT_0_SHIFT) + | (((50) & ISPCCDC_VDINT_1_MASK) + << ISPCCDC_VDINT_1_SHIFT), + ISPCCDC_VDINT); } if (is_isplsc_activated()) { - if (ispccdc_obj.ccdc_inpfmt == CCDC_RAW) { + if ((ispccdc_obj.ccdc_inpfmt == CCDC_RAW) || + (ispccdc_obj.ccdc_inpfmt == CCDC_RAW_PATTERN)) { ispccdc_config_lsc(&lsc_config); ispccdc_load_lsc(lsc_config.size); } @@ -1318,9 +1411,10 @@ { if (enable) { if (ccdc_use_lsc && !ispccdc_obj.lsc_en && - (ispccdc_obj.ccdc_inpfmt == CCDC_RAW)) + ((ispccdc_obj.ccdc_inpfmt == CCDC_RAW) || + (ispccdc_obj.ccdc_inpfmt == CCDC_RAW_PATTERN))) ispccdc_enable_lsc(1); - + mdelay(10); omap_writel(omap_readl(ISPCCDC_PCR) | (ISPCCDC_PCR_EN), ISPCCDC_PCR); } else { @@ -1442,6 +1536,13 @@ omap_readl(ISPCCDC_LSC_TABLE_BASE)); DPRINTK_ISPCCDC("###CCDC LSC TABLE OFFSET=0x%x\n", omap_readl(ISPCCDC_LSC_TABLE_OFFSET)); + /* Added by MMS */ + DPRINTK_ISPCCDC("###CCDC ISPCCDC_BLKCMP=0x%x\n", + omap_readl(ISPCCDC_BLKCMP)); + DPRINTK_ISPCCDC("###CCDC ISPCCDC_DCSUB=0x%x\n", + omap_readl(ISPCCDC_DCSUB)); + DPRINTK_ISPCCDC("###CCDC ISPCCDC_FPC=0x%x\n", omap_readl(ISPCCDC_FPC)); + } EXPORT_SYMBOL(ispccdc_print_status); Index: omapkernel/drivers/media/video/isp/ispccdc.h =================================================================== --- omapkernel.orig/drivers/media/video/isp/ispccdc.h 2008-10-15 19:25:00.000000000 -0500 +++ omapkernel/drivers/media/video/isp/ispccdc.h 2008-10-15 19:39:20.000000000 -0500 @@ -42,6 +42,7 @@ CCDC_RAW, CCDC_YUV_SYNC, CCDC_YUV_BT, + CCDC_RAW_PATTERN, CCDC_OTHERS }; @@ -50,7 +51,8 @@ CCDC_YUV_MEM_RSZ, CCDC_OTHERS_VP, CCDC_OTHERS_MEM, - CCDC_OTHERS_VP_MEM + CCDC_OTHERS_VP_MEM, + CCDC_OTHERS_LSC_MEM }; /* Enumeration constants for the sync interface parameters */ Index: omapkernel/drivers/media/video/isp/isph3a.c =================================================================== --- omapkernel.orig/drivers/media/video/isp/isph3a.c 2008-10-15 19:37:24.000000000 -0500 +++ omapkernel/drivers/media/video/isp/isph3a.c 2008-10-15 19:43:30.000000000 -0500 @@ -28,6 +28,7 @@ #include <linux/io.h> #include <linux/uaccess.h> #include <asm/cacheflush.h> +#include <linux/delay.h> #include "isp.h" #include "ispreg.h" @@ -215,9 +216,20 @@ ISPH3A_PCR); DPRINTK_ISPH3A(" H3A enabled \n"); } else { + int timeout = 20; aewb_regs.reg_pcr &= ~ISPH3A_PCR_AEW_EN; omap_writel(omap_readl(ISPH3A_PCR) & ~ISPH3A_PCR_AEW_EN, ISPH3A_PCR); + while ((omap_readl(ISPH3A_PCR) & ISPH3A_PCR_AEW_BUSY) && + timeout) { + mdelay(10); + timeout--; + } + if (timeout == 0) { + printk(KERN_DEBUG "%s - can't disable AEWB H3A\n", + __func__); + } + DPRINTK_ISPH3A(" H3A disabled \n"); } aewb_config_local.aewb_enable = enable; Index: omapkernel/drivers/media/video/isp/ispmmu.h =================================================================== --- omapkernel.orig/drivers/media/video/isp/ispmmu.h 2008-10-15 19:25:00.000000000 -0500 +++ omapkernel/drivers/media/video/isp/ispmmu.h 2008-10-15 19:39:20.000000000 -0500 @@ -65,7 +65,7 @@ * to keep track of these 16 L2 page table's status. */ #define L2P_TABLE_SIZE 1024 -#define L2P_TABLE_NR 41 /* Currently supports 4*5MP shots */ +#define L2P_TABLE_NR 62 /* Currently supports 4*5MP shots */ #define L2P_TABLES_SIZE (L2P_TABLE_SIZE * L2P_TABLE_NR) /* Extra memory allocated to get ttb aligned on 16KB */ Index: omapkernel/drivers/media/video/isp/isppreview.c =================================================================== --- omapkernel.orig/drivers/media/video/isp/isppreview.c 2008-10-15 19:37:25.000000000 -0500 +++ omapkernel/drivers/media/video/isp/isppreview.c 2008-10-15 19:44:09.000000000 -0500 @@ -69,7 +69,8 @@ {ISPPRV_CDC_THR1, 0x0000}, {ISPPRV_CDC_THR2, 0x0000}, {ISPPRV_CDC_THR3, 0x0000}, - {ISPPRV_PCR, 0x0000}, +/* Removed by MMS */ +/* {ISPPRV_PCR, 0x0000}, */ {ISP_TOK_TERM, 0x0000} }; Index: omapkernel/drivers/media/video/isp/isppreview.h =================================================================== --- omapkernel.orig/drivers/media/video/isp/isppreview.h 2008-10-15 19:37:24.000000000 -0500 +++ omapkernel/drivers/media/video/isp/isppreview.h 2008-10-15 19:44:50.000000000 -0500 @@ -28,13 +28,20 @@ #define ISPPRV_BRIGHT_DEF 0x1 #define ISPPRV_BRIGHT_LOW 0x0 #define ISPPRV_BRIGHT_HIGH 0xF -#define ISPPRV_BRIGHT_UNITS 0x7 +#define ISPPRV_BRIGHT_UNITS 0x1 +/* #define ISPPRV_CONTRAST_STEP 0x1 #define ISPPRV_CONTRAST_DEF 0x2 #define ISPPRV_CONTRAST_LOW 0x0 #define ISPPRV_CONTRAST_HIGH 0xF #define ISPPRV_CONTRAST_UNITS 0x5 +*/ +#define ISPPRV_CONTRAST_STEP 0x1 +#define ISPPRV_CONTRAST_DEF 0x1 /* MMS */ +#define ISPPRV_CONTRAST_LOW 0x0 +#define ISPPRV_CONTRAST_HIGH 0xF +#define ISPPRV_CONTRAST_UNITS 0x16 /* MMS */ #define NO_AVE 0x0 #define AVE_2_PIX 0x1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html