int __ispccdc_enable_lsc(u8 enable) { if (!is_isplsc_activated()) return -ENODEV; if (enable) { if (!ispccdc_busy()) { isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, ISPCTRL_SBL_SHARED_RPORTB | ISPCTRL_SBL_RD_RAM_EN); isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG, 0x1); ispccdc_obj.lsc_state = 1; } else { /* Postpone enabling LSC */ ispccdc_obj.lsc_enable = 1; return -EBUSY; } } else { isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG, 0xFFFE); ispccdc_obj.lsc_state = ispccdc_obj.lsc_enable = 0; } return 0; }
/** * ispresizer_config_datapath - Specifies which input to use in resizer module * @input: Indicates the module that gives the image to resizer. * * Sets up the default resizer configuration according to the arguments. * * Returns 0 if successful, or -1 if an unsupported input was requested. **/ int ispresizer_config_datapath(enum ispresizer_input input) { u32 cnt = 0; DPRINTK_ISPRESZ("ispresizer_config_datapath()+\n"); ispres_obj.resinput = input; switch (input) { case RSZ_OTFLY_YUV: cnt &= ~ISPRSZ_CNT_INPTYP; cnt &= ~ISPRSZ_CNT_INPSRC; ispresizer_set_inaddr(0); ispresizer_config_inlineoffset(0); break; case RSZ_MEM_YUV: cnt |= ISPRSZ_CNT_INPSRC; cnt &= ~ISPRSZ_CNT_INPTYP; break; case RSZ_MEM_COL8: cnt |= ISPRSZ_CNT_INPSRC; cnt |= ISPRSZ_CNT_INPTYP; break; default: DPRINTK_ISPRESZ( "ISP_ERR : Wrong Input\n"); return -1; } isp_reg_or(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, cnt); //ispresizer_config_ycpos(0); ispresizer_config_ycpos(1); ispresizer_config_filter_coef(&ispreszdefcoef); ispresizer_enable_cbilin(0); ispresizer_config_luma_enhance(&ispreszdefaultyenh); DPRINTK_ISPRESZ("ispresizer_config_datapath()-\n"); return 0; }
/** * ispccdc_request - Reserves the CCDC module. * * Reserves the CCDC module and assures that is used only once at a time. * * Returns 0 if successful, or -EBUSY if CCDC module is busy. **/ int ispccdc_request(void) { mutex_lock(&ispccdc_obj.mutexlock); if (ispccdc_obj.ccdc_inuse) { mutex_unlock(&ispccdc_obj.mutexlock); DPRINTK_ISPCCDC("ISP_ERR : CCDC Module Busy\n"); return -EBUSY; } ispccdc_obj.ccdc_inuse = 1; mutex_unlock(&ispccdc_obj.mutexlock); isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, ISPCTRL_CCDC_RAM_EN | ISPCTRL_CCDC_CLK_EN | ISPCTRL_SBL_WR1_RAM_EN); isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_VDLC); return 0; }
/** * ispresizer_set_start_phase - Sets the horizontal and vertical start phase. * @phase: horizontal and vertical start phase (0 - 7). * * This API just updates the isp_res struct. Actual register write happens in * ispresizer_config_size. **/ void ispresizer_set_start_phase(struct device *dev, struct isprsz_phase *phase) { /* clear bits */ isp_reg_and(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~(ISPRSZ_CNT_HSTPH_MASK | ISPRSZ_CNT_VSTPH_MASK)); if (phase != NULL) { isp_reg_or(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ((phase->h_phase << ISPRSZ_CNT_HSTPH_SHIFT) & ISPRSZ_CNT_HSTPH_MASK) | ((phase->v_phase << ISPRSZ_CNT_VSTPH_SHIFT) & ISPRSZ_CNT_VSTPH_MASK)); } else { isp_reg_or(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ((DEFAULTSTPHASE << ISPRSZ_CNT_HSTPH_SHIFT) & ISPRSZ_CNT_HSTPH_MASK) | ((DEFAULTSTPHASE << ISPRSZ_CNT_VSTPH_SHIFT) & ISPRSZ_CNT_VSTPH_MASK)); } }
/* * ispresizer_set_intype - Input type select * @isp_res: Device context. * @type: Pixel format type. */ static void ispresizer_set_intype(struct isp_res_device *res, enum resizer_colors_type type) { struct isp_device *isp = to_isp_device(res); if (type == RSZ_COLOR8) isp_reg_or(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_INPTYP); else isp_reg_and(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~ISPRSZ_CNT_INPTYP); }
/* * ispresizer_set_source - Input source select * @isp_res: Device context. * @source: Input source type * * If this field is set to RESIZER_INPUT_VP, the resizer input is fed from * Preview/CCDC engine, otherwise from memory. */ static void ispresizer_set_source(struct isp_res_device *res, enum resizer_input_entity source) { struct isp_device *isp = to_isp_device(res); if (source == RESIZER_INPUT_MEMORY) isp_reg_or(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_INPSRC); else isp_reg_and(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~ISPRSZ_CNT_INPSRC); }
/* * ispresizer_set_bilinear - Chrominance horizontal algorithm select * @isp_res: Device context. * @type: Filtering interpolation type. * * Filtering that is same as luminance processing is * intended only for downsampling, and bilinear interpolation * is intended only for upsampling. */ static void ispresizer_set_bilinear(struct isp_res_device *res, enum resizer_chroma_algo type) { struct isp_device *isp = to_isp_device(res); if (type == RSZ_BILINEAR) isp_reg_or(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_CBILIN); else isp_reg_and(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~ISPRSZ_CNT_CBILIN); }
/** * ispccdc_config_outlineoffset - Configures the output line offset * @offset: Must be twice the Output width and aligned on 32 byte boundary * @oddeven: Specifies the odd/even line pattern to be chosen to store the * output. * @numlines: Set the value 0-3 for +1-4lines, 4-7 for -1-4lines. * * - Configures the output line offset when stored in memory * - Sets the odd/even line pattern to store the output * (EVENEVEN (1), ODDEVEN (2), EVENODD (3), ODDODD (4)) * - Configures the number of even and odd line fields in case of rearranging * the lines. * * Returns 0 if successful, or -EINVAL if the offset is not in 32 byte * boundary. **/ int ispccdc_config_outlineoffset(u32 offset, u8 oddeven, u8 numlines) { if ((offset & ISP_32B_BOUNDARY_OFFSET) == offset) { isp_reg_writel((offset & 0xFFFF), OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF); } else { DPRINTK_ISPCCDC("ISP_ERR : Offset should be in 32 byte" " boundary\n"); return -EINVAL; } isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, ~ISPCCDC_SDOFST_FINV); isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, ~ISPCCDC_SDOFST_FOFST_4L); switch (oddeven) { case EVENEVEN: isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, (numlines & 0x7) << ISPCCDC_SDOFST_LOFST0_SHIFT); break; case ODDEVEN: isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, (numlines & 0x7) << ISPCCDC_SDOFST_LOFST1_SHIFT); break; case EVENODD: isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, (numlines & 0x7) << ISPCCDC_SDOFST_LOFST2_SHIFT); break; case ODDODD: isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, (numlines & 0x7) << ISPCCDC_SDOFST_LOFST3_SHIFT); break; default: break; } return 0; }
/** * ispresizer_set_intype - Input type select * @isp_res: Device context. * @type: Pixel format type. */ static inline void ispresizer_set_intype(struct isp_res_device *isp_res, enum resizer_input type) { struct device *dev = to_device(isp_res); if (type == RSZ_MEM_COL8) isp_reg_or(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_INPTYP); else isp_reg_and(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~ISPRSZ_CNT_INPTYP); dev_dbg(dev, "%s: In type: %u\n", __func__, type); }
/** * ispresizer_set_source - Input source select * @isp_res: Device context. * @source: Input source type * * If this field is set to RSZ_OTFLY_YUV, the resizer input is fed from * Preview/CCDC engine, otherwise from memory. */ static inline void ispresizer_set_source(struct isp_res_device *isp_res, enum resizer_input source) { struct device *dev = to_device(isp_res); if (source != RSZ_OTFLY_YUV) isp_reg_or(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_INPSRC); else isp_reg_and(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~ISPRSZ_CNT_INPSRC); dev_dbg(dev, "%s: In source: %u\n", __func__, source); }
/* * ispresizer_set_ycpos - Luminance and chrominance order * @isp_res: Device context. * @order: order type. */ static void ispresizer_set_ycpos(struct isp_res_device *res, enum v4l2_mbus_pixelcode pixelcode) { struct isp_device *isp = to_isp_device(res); switch (pixelcode) { case V4L2_MBUS_FMT_YUYV16_1X16: isp_reg_or(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ISPRSZ_CNT_YCPOS); break; case V4L2_MBUS_FMT_UYVY16_1X16: isp_reg_and(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~ISPRSZ_CNT_YCPOS); break; default: return; } }
/** * ispresizer_config_datapath - Specifies which input to use in resizer module * @input: Indicates the module that gives the image to resizer. * * Sets up the default resizer configuration according to the arguments. * * Returns 0 if successful, or -EINVAL if an unsupported input was requested. **/ int ispresizer_config_datapath(enum ispresizer_input input) { u32 cnt = 0; DPRINTK_ISPRESZ("ispresizer_config_datapath()+\n"); ispres_obj.resinput = input; switch (input) { case RSZ_OTFLY_YUV: cnt &= ~ISPRSZ_CNT_INPTYP; cnt &= ~ISPRSZ_CNT_INPSRC; ispresizer_set_inaddr(0); ispresizer_config_inlineoffset(0); break; case RSZ_MEM_YUV: cnt |= ISPRSZ_CNT_INPSRC; cnt &= ~ISPRSZ_CNT_INPTYP; break; case RSZ_MEM_COL8: cnt |= ISPRSZ_CNT_INPSRC; cnt |= ISPRSZ_CNT_INPTYP; break; default: printk(KERN_ERR "ISP_ERR : Wrong Input\n"); return -EINVAL; } isp_reg_or(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, cnt); /* Use bilinear interpolation for upsampling per TRM */ if (ispres_obj.outputwidth > ispres_obj.inputwidth) ispresizer_enable_cbilin(1); else ispresizer_enable_cbilin(0); ispresizer_config_ycpos(0); ispresizer_config_filter_coef(&ispreszdefcoef); ispresizer_config_luma_enhance(&ispreszdefaultyenh); DPRINTK_ISPRESZ("ispresizer_config_datapath()-\n"); return 0; }